Closed
Bug 932345
Opened 12 years ago
Closed 3 years ago
IndexedDatabaseManager::InitWindowless fails with NS_ERROR_FAILURE in FF27
Categories
(Core :: Storage: IndexedDB, defect, P5)
Tracking
()
RESOLVED
DUPLICATE
of bug 1019194
People
(Reporter: 4mr.minj, Unassigned)
References
Details
OK, so AFAIK, you must use initWindowless to be able to access IDB from chrome until FF26.
Bug 832883 says it is to be removed in the future but calling it in FF27 breaks our add-on with NS_ERROR_FAILURE even though that function is still defined.
So how do you figure we should test for this?
| Reporter | ||
Comment 1•12 years ago
|
||
It happens during initialization of IDB functionality (calling Services.scriptloader.loadSubScript() in bootstrap.js)
Comment 2•12 years ago
|
||
(In reply to 4mr.minj from comment #1)
> It happens during initialization of IDB functionality (calling
> Services.scriptloader.loadSubScript() in bootstrap.js)
Can you provide more details ?
| Reporter | ||
Comment 3•12 years ago
|
||
We add a window listener
>Cc['@mozilla.org/appshell/window-mediator;1'].getService(Ci.nsIWindowMediator).addListener()
with
>onOpenWindow: function(aWindow) {
> // Wait for the window to finish loading
> let domWindow = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
> .getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
> domWindow.addEventListener('load', function() {
> domWindow.removeEventListener('load', arguments.callee, false);
> _gLoader.loadIntoWindow(domWindow);
> }, false);
>}
_gloader is the scope of another script created with loadSubScript()
loadIntoWindow() checks for domWindow.document and #appcontent and initializes our global object Foo where
>Services.scriptloader.loadSubScript(url, domWindow, 'UTF-8');
is called for each script (our add-on is divided into modules).
The IDB specific script runs
>var idbManager = Cc["@mozilla.org/dom/indexeddb/manager;1"]
> .getService(Components.interfaces.nsIIndexedDatabaseManager);
>if (typeof idbManager.initWindowless === 'function') {
> Foo.IDBProxy = {};
> idbManager.initWindowless(Foo.IDBProxy);
>}
and fails at this point with
>Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIIndexedDatabaseManager.initWindowless]" nsresult: "0x80004005 (NS_ERROR_FAILURE)"
| Reporter | ||
Comment 4•12 years ago
|
||
OK, here is the fix:
(In reply to Jan Varga [:janv] from https://bugzilla.mozilla.org/show_bug.cgi?id=832883#c36)
> Hm, take a look at this JS code:
> http://mxr.mozilla.org/mozilla-central/source/addon-sdk/source/lib/sdk/
> indexed-db.js#30
>
> and let me know if that doesn't work for you
>
> Btw, this is going to change again, bug 921478.
> One will have to call
> |Components.utils.importGlobalProperties(["indexedDB"])| to get IndexedDB
> e.g. in chrome.
Comment 5•12 years ago
|
||
Ok, so the first thing you need to know is that initWindowless() takes only global objects.
Anyway, you shouldn't need to call it in FF 27.
If you extension needs to be backwards compatible, you can just check if |indexedDB| is already defined, something like this:
http://mxr.mozilla.org/mozilla-central/source/addon-sdk/source/lib/sdk/indexed-db.js#30
| Reporter | ||
Comment 6•12 years ago
|
||
OK, but this won't do. I forgot why I needed this in the first place.
indexedDB is defined in domWindow anyway...
However we also have a chrome://preferences.html page which includes the same script and fails with
> UnknownError: The operation failed for reasons unrelated to the database itself and not covered by any other error code.
at the |typeof indexedDB| check itself!
Back to the original question: How do I test for this? :/
| Reporter | ||
Comment 7•12 years ago
|
||
you can try it yourself by running it in web console (ctrl+shift+K) of e.g. about:addons
Comment 8•12 years ago
|
||
Hm, I don't know why |typeof indexedDB| would throw.
Will need to debug it...
| Reporter | ||
Comment 9•12 years ago
|
||
I got the idea to use initWindowless from https://bugzilla.mozilla.org/show_bug.cgi?id=587797#c50
And it worked fine until FF27.
Comment 10•12 years ago
|
||
Hm, I see.
If you are in a chrome window, the getter nsGlobalWindow::GetIndexedDB() actually tries to init IndexedDB, but it fails in ThirdPartyUtils or something.
A brutal way how to solve your problem could be to just wrap initWindowless() in a try/catch block.
InitWindowless returns NS_ERROR_FAILURE if the passed object is not a global object or indexedDB is already defined on the object.
Comment 11•12 years ago
|
||
A better approach would be to use something like typeof which doesn't call the getter for indexedDB.
Take a look at:
http://stackoverflow.com/questions/1894792/determining-if-a-javascript-object-has-a-given-property
| Reporter | ||
Comment 12•12 years ago
|
||
(In reply to Jan Varga [:janv] from comment #11)
> A better approach would be to use something like typeof which doesn't call
> the getter for indexedDB.
> Take a look at:
> http://stackoverflow.com/questions/1894792/determining-if-a-javascript-
> object-has-a-given-property
You are kidding right?
Did you forget what I've written?
> you can try it yourself by running it in web console (ctrl+shift+K) of e.g. about:addons
http://i.imagebanana.com/img/mfg9fs46/AddonsManagerMozillaFirefox_001.png
This is FF25, does not happen in FF27.
> Ok, so the first thing you need to know is that initWindowless() takes only
> global objects.
I don't know what you mean by 'global objects' but in FF25 in that context this === self === content === window and calling initWindowless() on any of them throws NS_ERROR_FAILURE
gBrowser is undefined.
A working solution:
>var hasIDB = false;
>try {
> // works in bootstrap.js and FF27 chrome (preferences.html)
> hasIDB = (typeof indexedDB !== 'undefined' || typeof mozIndexedDB !== 'undefined');
>}
>catch (e) {
> // FF25 preferences.html throws 'UnknownError'
>}
>finally {
> if (!hasIDB) {
> var idbManager = Cc['@mozilla.org/dom/indexeddb/manager;1']
> .getService(Ci.nsIIndexedDatabaseManager);
> if (typeof idbManager.initWindowless === 'function') {
> // FF26 and earlier
> Foo.IDBProxy = {};
> idbManager.initWindowless(Foo.IDBProxy);
> }
> else {
> // in the future in FF28?
> Cu.importGlobalProperties(['indexedDB']);
> }
> }
>}
This is messed up.
Comment 13•12 years ago
|
||
importGlobalProperties(['indexedDB']) just landed on the trunk (FF28) and I'm going to request a permission to land on aurora too (FF 27), so the "automatic lazy IDB initialization" shouldn't appear in official releases.
| Reporter | ||
Comment 15•12 years ago
|
||
FF27 lets us make use of importGlobalProperties so there is no need to call initWindowless.
However, prior to FF27, there is no simple way of getting indexedDB to work in chrome://myapp/preferences.html
Sure you can call FF26 obsolete unless some of our users happen to be using it :P
AFAIK FF24 is ESR now.
Comment 16•12 years ago
|
||
I'm sorry, the fix for bug 921478 wasn't backported to FF 27, and now it's too late :(
Next ESR shouldn't be affected. The problem should be visible only in FF 27.
FF 28 and later releases will provide importGlobalProperties([indexedDB]).
Flags: needinfo?(Jan.Varga)
Updated•8 years ago
|
Priority: -- → P5
Updated•3 years ago
|
Severity: normal → S3
Comment 18•3 years ago
|
||
nsIIndexedDatabaseManager and initWindowless were removed in bug 1019194.
Status: UNCONFIRMED → RESOLVED
Closed: 3 years ago
Duplicate of bug: 1019194
Resolution: --- → DUPLICATE
You need to log in
before you can comment on or make changes to this bug.
Description
•