Closed Bug 638423 Opened 13 years ago Closed 13 years ago

Page load event occurs only once

Categories

(Firefox for Android Graveyard :: Extension Compatibility, defect)

x86
Windows Vista
defect
Not set
normal

Tracking

(Not tracked)

RESOLVED INVALID

People

(Reporter: spektom, Unassigned)

Details

Attachments

(3 files)

583 bytes, application/x-javascript
Details
821 bytes, application/x-javascript
Details
515 bytes, text/plain
Details
User-Agent:       Opera/9.80 (Windows NT 6.0; U; en) Presto/2.7.62 Version/11.01
Build Identifier: Mozilla/5.0 (Windows NT 6.0; rv:20b12pre) Gecko/20110217 Firefox/4.0b12pre Fennec/4.0b5

I'm porting on a simple extension from Firefox to Fennec:

var MyAddon = {
    onLoad: function(aEvent){
        var appcontent = document.getElementById("appcontent"); // Firefox
        if (!appcontent) {
            appcontent = document.getElementById("browsers"); // Fennec
        }
        if (appcontent) {
            appcontent.addEventListener("DOMContentLoaded", MyAddon.onDocumentLoad, true);
        }
    },

    onUnLoad: function(aEvent){
        var appcontent = document.getElementById("appcontent"); // Firefox
        if (!appcontent) {
            appcontent = document.getElementById("browsers"); // Fennec
        }
        if (appcontent) {
            appcontent.removeEventListener("DOMContentLoaded", MyAddon.onDocumentLoad, true);
        }
    },

    onUIReady: function(aEvent){
    },

    onUIReadyDelayed: function(aEvent) {
    },

    onDocumentLoad: function(aEvent) {
        alert("OK");
    }
};

window.addEventListener("load", MyAddon.onLoad, false);
window.addEventListener("unload", MyAddon.onUnLoad, false);
window.addEventListener("UIReady", MyAddon.onUIReady, false);
window.addEventListener("UIReadyDelayed", MyAddon.onUIReadyDelayed, false);

The problem is that alert is shown only one time when browser is started (in Fennec), I'd expect it to show on every page that loads. This extension works perfectly in Firefox.


Reproducible: Always
Thanks for the bug report.

The problem you encounter is not because Fennec fired only one load event, but because Fennec has different behaviors depending if the page is "remote" or not (basically all local pages chrome://..., about:home, ... are non-remote and the rest of the world is)

If the page is not remote you will be able to listen for events the way you used with firefox.


But, if the page is remote, it is loaded into another process (this is what is called e10s or electrolysis), and this mean you don't have a direct access to the DOM of the page through the chrome UI where you're used to put an overlay for the extension.

As a result you need to think about fennec as:
 * a UI where lives the main browser code and all the local page, this is usually refers as the chrome process
 * the webpages that render and execute JS into another process, which is usually called the content process


If the page is remote (so likely every page you're interested in) you need to do a bit of new work to listen for event:

On the chrome process:
 * write a separate JS file and load it like via: messageManager.loadFrameScript("chrome://extensionname/content/scriptname.js", true);

 Or if you want to load this script for only one particular <browser/>  they have their own messageManager accessible as a property

 * Listen for a particular message the script will send back to you like: messageManager.addMessageListener("ExtensionName:AMessageName", {
  receiveMessage: function(aMessage) {
    let json = aMessage.json;
    let browser = aMessage.target;

    // process your json data
  }
});

On the content process (access via the file loaded by the previous API I described):
 * listen to events like here http://hg.mozilla.org/mobile-browser/file/5d299232e62a/chrome/content/content.js#261
 and use 'addEventListener' instead of window.addEventListener, this is important because there is not direct access to the 'window' here (the main object is content) and addEventListener ensure you listen for all new pages.

 * Once you've caught an event you need to send it back throught the messaging API asynchronously or synchronously like here: http://hg.mozilla.org/mobile-browser/file/5d299232e62a/chrome/content/content.js#l302

 The data sent this way are JSON you gonna retrieve on the chrome side via aMessage.json;


Don't hesitate if you need more informations :)
Status: UNCONFIRMED → RESOLVED
Closed: 13 years ago
Resolution: --- → INVALID
(In reply to comment #1)
> Thanks for the bug report.
> 
....
> Don't hesitate if you need more informations :)

Wow, and thank you for such a descriptive answer!
Attached file content.js
Attached file overlay.js
Attached file overlay.xul
(In reply to comment #3)
> For more details, see:
> https://wiki.mozilla.org/Mobile/Fennec/Extensions/Electrolysis

I'm still not able to create a simple extension that injects some HTML elements into the loaded page. Please see the attached extension files.

The problem is that for the first time (when Fennec starts) it prints the document title (Fennec Start), but for the subsequent pages it prints nothing. Debug console reports: alert() is not defined.

I try to make an extension that will work in both: electrolysis and non-electrolysis browser.
 
I'll appreciate any help!
When I try to run this add-on, it looks like the onWindowLoad function is never called.  I don't think you can rely on DOMContentLoaded events bubbling up to <browser> elements in Fennec.

Note: You shouldn't need separate code for Firefox and Fennec.  loadFrameScript works even in single-process Firefox.

If I move the loadFrameScript call into onChromeLoad, then content.js is run, but it fails with "alert is not defined".  You can fix that by replacing alert with content.alert.
It looks like the app-info service is not available in the content process.  So the "isMultiProc" check is throwing an exception when it is run in remote browsers.  The add-on works as expected after removing that code.
(In reply to comment #9)
> It looks like the app-info service is not available in the content process.  So
> the "isMultiProc" check is throwing an exception when it is run in remote
> browsers.  The add-on works as expected after removing that code.

Thanks, this has helped me much!

Sorry to bother you with stupid questions, but are there changes to cookie service in Fennec? This code seems to not work anymore:

var ios = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
var cookieSvc = Components.classes["@mozilla.org/cookieService;1"].getService(Components.interfaces.nsICookieService);
    
var cookieUri = ios.newURI("http://.somehost.com", null, null);
cookieSvc.setCookieString(cookieUri, null, "key=value; path=/", null);

Thanks!
Presuming you're running those lines in the content process, setCookieString should be throwing an error.  For various consistency reasons, functions like setCookieString and addPermission that modify shared values (shared between chrome and content, that is) are not permitted in the content process.
(In reply to comment #11)
> Presuming you're running those lines in the content process, setCookieString
> should be throwing an error.  For various consistency reasons, functions like
> setCookieString and addPermission that modify shared values (shared between
> chrome and content, that is) are not permitted in the content process.

I run this code in a chrome context (message listener callback), but cookies are not set. I've set up an alert call after the "setCookieString" line (see Comment #10), and it seems like the execution of this line succeeds, but cookies are still not set. Do you see any other reason why this may happen?

Thanks!
Attachment #517088 - Attachment mime type: application/octet-stream → text/xml
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: