can Chrome option page access indexedDB created by my background script? - google-chrome-extension

I am working on a chrome extension, and really want to have my chrome option page access the data in the IndexedDB, but there seems no support for this?
Error as:
Uncaught TypeError: Cannot read property 'transaction' of undefined option.js:42
var request = indexedDB.open(DB_NAME, DB_VERSION);
//console.log(request); /* The created indexedDB can be checked */
request.onsuccess = function (evt) {
console.log("Database Open Successfully: " + evt);
db = this.result;
/* Get the initialised logIndex*/
var storeLog = db.transaction(DB_STORE1, 'readonly').objectStore(DB_STORE1);
var req = storeLog.openCursor(null, 'prev');
req.onsuccess = function (evt) {
console.log("Inner Successfully");
}
req.onerror = function(evt){
console.error("Inner error" + evt.target.errorCode);
}
};
request.onerror = function (evt) {
console.error("Database Error: " + evt.target.errorCode);
};
want to know whether it is possible to access the IndexedDB in the "chrome option_page"

A short answer to your stated question is "yes, IndexedDB is fully supported in extension pages". The fact that your request.onsuccess is fired is sufficient evidence to that.
It seems like your problems are not specific to Chrome Extensions; I suggest that you look at some IndexedDB tutorials like this one to debug your code.
Note that you might need to request "unlimitedStorage" permission in the manifest to store large amounts of data.

Related

alert in SSJS Library

I have a function in SSJS Library. I would like get Client Side alert in Library. What i tried was not worked. I think I miss something. :(
function docAlive()
{
try
{
var otherDoc:NotesDocument= null;
if (funcDoc.getItemValueString("DocUNID")!="")
{
var otherDoc:NotesDocument = dbKontak.getDocumentByUNID(funcDoc.getItemValueString("DocUNID"))
if (otherDoc==null)
{
hataKod = "10001";
hataMsg = "There is no document :( Created One";
print (hataKod +": "+hataMsg);
view.postScript("alert('"+hataKod + " - " +hataMsg+"');");
}
}
return otherDoc;
}
catch (e)
{
e.toString();
}
}
view.postScript() will trigger a client-side alert, but as Tim Tripcony mentions, not in all events. And the alert will only be triggered after the function and any other code for the partial refresh has completed. At that point the HTML to trigger the (Client-Side) JavaScript alert will be posted back to the browser and the browser will action it.
If you want to throw an error back to the browser, I would strongly recommend XPages OpenLog Logger (and not just because I contribute and support it on OpenNTF). openLogBean.addError(e) will log the error to OpenLog and post an error message back to the browser.
The message is passed to the server using facesMessage.addMessage(), as documented here http://www.intec.co.uk/returning-error-messages-from-ssjs-through-the-facescontext/. I believe there are additional options for managing different message levels (e.g. WARNING, CONFIRMATION). FacesMessage is a standard Java (in this case, JSF) construct, so the documentation for it on the web is valid for XPages as well.

Chrome DevTools extension can't access storage

I'm writing a Chrome extension where I would like to access the Chrome Storage API from the Devtools page. The chrome.storage.local variable (with the get/set functions) are available, but when I call them the callback never get's called. When I use my background page to access the storage API it works as expected.
I could, of course, send the request via the background page and pass it to the Devtools page through messages but I'm looking for a more cleaner approach. Am I doing something wrong?
I hope that you understand my question, to illustrate my problem I have created a little sample of what I'm coping with, ready for download here; http://g2f.nl/0w2kko9.
It includes the following test which verifies that the API is available but does not work as expected;
document.getElementById("p").innerHTML += "chrome.storage.local.set = " + !!chrome.storage.local.set
+ "<br>chrome.storage.local.get = " + !!chrome.storage.local.get;
chrome.storage.local.set( {'foo' : 'bar'} , function () {
document.getElementById("p").innerHTML += '<br>foo = bar';
});
setTimeout(function () {
document.getElementById("p").innerHTML += '<br>That was one second';
chrome.storage.local.get('foo', function (result) {
document.getElementById("p").innerHTML += '<br>foo = ' + result;
});
}, 1000);

Chrome/FF/Safari extension: Load hidden web page in incognito-like mode

Is it possible to build an 'incognito mode' for loading background web-pages in a browser extension?
I am writing a non-IE cross-browser extension that periodically checks web-pages on the user's behalf. There are two requirements:
Page checks are done in the background, to be as unobtrusive as possible. I believe this could be done by opening the page in a new unfocussed browser tab, or hidden in a sandboxed iframe in the extension's background page.
The page checks should operate in 'incognito mode', and not use/update the user's cookies, history, or local storage. This is to stop the checks polluting the user's actual browsing behavior as much as possible.
Any thoughts on how to implement this 'incognito mode'?
It would ideally work in as many browser types as possible (not IE).
My current ideas are:
Filter out cookie headers from incoming/outgoing http requests associated with the page checks (if I can identify all of these) (not possible in Safari?)
After each page check, filter out the page from the user's history.
Useful SO questions I've found:
Chrome extension: loading a hidden page (without iframe)
Firefox addon development, open a hidden web browser
Identify requests originating in the hiddenDOMWindow (or one of its iframes)
var Cu = Components.utils;
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/devtools/Console.jsm');
var win = Services.appShell.hiddenDOMWindow
var iframe = win.document.createElementNS('http://www.w3.org/1999/xhtml', 'iframe');
iframe.addEventListener('DOMContentLoaded', function(e) {
var win = e.originalTarget.defaultView;
console.log('done loaded', e.document.location);
if (win.frameElement && win.frameElement != iframe) {
//its a frame in the in iframe that load
}
}, false);
win.document.documentElement.appendChild(iframe);
must keep a global var reference to iframe we added.
then you can change the iframe location like this, and when its loaded it triggers the event listener above
iframe.contentWindow.location = 'http://www.bing.com/'
that DOMContentLoaded identifies all things loaded in that iframe. if the page has frames it detects that too.
to remove from history, into the DOMContentLoaded function use the history service to remove win.location from history:
https://developer.mozilla.org/en-US/docs/Using_the_Places_history_service
now to strip the cookies from requests in that page use this code:
const {classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu, results: Cr, manager: Cm} = Components;
Cu.import('resource://gre/modules/Services.jsm');
var myTabToSpoofIn = Services.wm.getMostRecentBrowser('navigator:browser').gBrowser.tabContainer[0]; //will spoof in the first tab of your browser
var httpRequestObserver = {
observe: function (subject, topic, data) {
var httpChannel, requestURL;
if (topic == "http-on-modify-request") {
httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
var goodies = loadContextGoodies(httpChannel)
if (goodies) {
if (goodies.contentWindow.top == iframe.contentWindow.top) {
httpChannel.setRequestHeader('Cookie', '', false);
} else {
//this page load isnt in our iframe so ignore it
}
}
}
}
};
Services.obs.addObserver(httpRequestObserver, "http-on-modify-request", false);
//Services.obs.removeObserver(httpRequestObserver, "http-on-modify-request", false); //run this on shudown of your addon otherwise the observer stags registerd
//this function gets the contentWindow and other good stuff from loadContext of httpChannel
function loadContextGoodies(httpChannel) {
//httpChannel must be the subject of http-on-modify-request QI'ed to nsiHTTPChannel as is done on line 8 "httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);"
//start loadContext stuff
var loadContext;
try {
var interfaceRequestor = httpChannel.notificationCallbacks.QueryInterface(Ci.nsIInterfaceRequestor);
//var DOMWindow = interfaceRequestor.getInterface(Components.interfaces.nsIDOMWindow); //not to be done anymore because: https://developer.mozilla.org/en-US/docs/Updating_extensions_for_Firefox_3.5#Getting_a_load_context_from_a_request //instead do the loadContext stuff below
try {
loadContext = interfaceRequestor.getInterface(Ci.nsILoadContext);
} catch (ex) {
try {
loadContext = subject.loadGroup.notificationCallbacks.getInterface(Ci.nsILoadContext);
} catch (ex2) {}
}
} catch (ex0) {}
if (!loadContext) {
//no load context so dont do anything although you can run this, which is your old code
//this probably means that its loading an ajax call or like a google ad thing
return null;
} else {
var contentWindow = loadContext.associatedWindow;
if (!contentWindow) {
//this channel does not have a window, its probably loading a resource
//this probably means that its loading an ajax call or like a google ad thing
return null;
} else {
var aDOMWindow = contentWindow.top.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
var gBrowser = aDOMWindow.gBrowser;
var aTab = gBrowser._getTabForContentWindow(contentWindow.top); //this is the clickable tab xul element, the one found in the tab strip of the firefox window, aTab.linkedBrowser is same as browser var above //can stylize tab like aTab.style.backgroundColor = 'blue'; //can stylize the tab like aTab.style.fontColor = 'red';
var browser = aTab.linkedBrowser; //this is the browser within the tab //this is where the example in the previous section ends
return {
aDOMWindow: aDOMWindow,
gBrowser: gBrowser,
aTab: aTab,
browser: browser,
contentWindow: contentWindow
};
}
}
//end loadContext stuff
}

How to implement Chrome extension 's chrome.tabs.sendMessage API in Firefox addon

I'm working on a Firefox addon development with Addon-Builder. I have no idea about how to implement Chrome extension 's chrome.tabs.sendMessage API in Firefox addon. The code is like this (the code is in the background.js, something like main.js in the Firefox addon):
function sendMessageToTabs(message, callbackFunc){
chrome.tabs.query({}, function(tabsArray){
for(var i=0; i<tabsArray.length; i++){
//console.log("Tab id: "+tabsArray[i].id);
chrome.tabs.sendMessage(tabsArray[i].id,message,callbackFunc);
}
});
}
So, How can I achieve this?
In add-ons build using the Add-on SDK, content scripts are managed by main.js. There's no built-in way to access all of your add-on's content scripts. To send a message to all tabs, you need to manually keep track of the content scripts.
One-way messages are easily implemented by the existing APIs. Callbacks are not built-in, though.
My browser-action SDK library contains a module called "messaging", which implements the Chrome messaging API. In the following example, the content script and the main script use an object called "extension". This object exposes the onMessage and sendMessage methods, modelled after the Chrome extension messaging APIs.
The following example adds a content script to every page on Stack Overflow, and upon click, the titles of the tabs are logged to the console (the one opened using Ctrl + Shift + J).
lib/main.js
// https://github.com/Rob--W/browser-action-jplib/blob/master/lib/messaging.js
const { createMessageChannel, messageContentScriptFile } = require('messaging');
const { PageMod } = require('sdk/page-mod');
const { data } = require('sdk/self');
// Adds the message API to every page within the add-on
var ports = [];
var pagemod = PageMod({
include: ['http://stackoverflow.com/*'],
contentScriptWhen: 'start',
contentScriptFile: [messageContentScriptFile, data.url('contentscript.js')],
contentScriptOptions: {
channelName: 'whatever you want',
endAtPage: false
},
onAttach: function(worker) {
var extension = createMessageChannel(pagemod.contentScriptOptions, worker.port);
ports.push(extension);
worker.on('detach', function() {
// Remove port from list of workers when the content script is deactivated.
var index = ports.indexOf(extension);
if (index !== -1) ports.splice(index, 1);
});
}
});
function sendMessageToTabs(message, callbackFunc) {
for (var i=0; i<ports.length; i++) {
ports[i].sendMessage(message, callbackFunc);
}
}
// Since we've included the browser-action module, we can use it in the demo
var badge = require('browserAction').BrowserAction({
default_title: 'Click to send a message to all tabs on Stack Overflow'
});
badge.onClicked.addListener(function() {
sendMessageToTabs('gimme title', function(response) {
// Use console.error to make sure that the log is visible in the console.
console.error(response);
});
});
For the record, the interesting part of main.js is inside the onAttach event.
data/contentscript.js
extension.onMessage.addListener(function(message, sender, sendResponse) {
if (message === 'gimme title') {
sendResponse(document.title);
}
});

Retrieving album/playlist information API

I read in another thread (http://stackoverflow.com/questions/9474011/showing-a-album-cover)
that the:
Please don't use any of the sp. APIs - they're private and going away soon.
My question is, what is the correct way of getting album and/or playlist information from the API?
I'm currently playing around with this:
sp.core.getMetadata(uri, {
onSuccess: function(uri) {
// Success
},
onFailure: function() {
// Failure
}
});
I guess this is private and shouldn't be used right? Instead I should get the info from the models.* object? If not, is there another preferred method of dealing with this?
Always use models. Documentation can be found here.
For example:
var sp = getSpotifyApi(1);
var models = sp.require('sp://import/scripts/api/models');
var a = models.Album.fromURI("spotify:album:5zyS3GEyL1FmDWgVXxUvj7", function(album) {
console.log("Album loaded", album.name);
});

Resources