Infocatcher / Private_Tab

Adds private tabs, restartless extension for Firefox (20.0+) and SeaMonkey (2.17+)
https://addons.mozilla.org/addon/private-tab/
Other
86 stars 20 forks source link

Can't open new private tab, if installed Scriptify-based extension #110

Open Infocatcher opened 11 years ago

Infocatcher commented 11 years ago

Reported here: http://forums.mozillazine.org/viewtopic.php?p=13127597#p13127597 Scriptify: https://addons.mozilla.org/firefox/addon/scriptify/ Test extension: https://addons.mozilla.org/firefox/addon/fb-purity-cleans-up-facebook/

Simple test UserScript:

// ==UserScript==
// @name        Test Scriptify
// @namespace   dev/null
// @include     https://github.com/*
// @version     0.1
// @run-at      document-start
// @grant       none
// ==/UserScript==

if("console" in window && "log" in console)
    console.log("Test Scriptify");

Result: http://infocatcher.ucoz.net/test/ext/test-scriptify.xpi

Looks like Scriptify slowdowns opening of new tabs...

Test code:

_log("setTimeout()");
setTimeout(function() {
    _log("setTimeout() done");
}, 0);
_log("addTab()");
gBrowser.selectedTab = gBrowser.addTab("about:");
_log("addTab() done");

function _log(s) {
    var d = new Date();
    var ms = d.getMilliseconds();
    var timestamp = d.toLocaleFormat("%M:%S:") + "000".substr(String(ms).length) + ms;
    Services.console.logStringMessage("[test] " + timestamp + " " + s);
}

Output:

[test] 07:42:127 setTimeout()
[test] 07:42:127 addTab()
[test] 07:42:134 setTimeout() done
[test] 07:42:159 addTab() done

And without Scriptify setTimeout() done is always after addTab() done because addTab() should be synchronous.

Infocatcher commented 11 years ago

Also failed any codes like

privateTab.readyToOpenTab(true);
BrowserOpenTab();
privateTab.readyToOpenTab(true);
gBrowser.selectedTab = gBrowser.addTab("about:");
Infocatcher commented 11 years ago

=> https://code.google.com/p/scriptify/issues/detail?id=5

Infocatcher commented 11 years ago

Code for "new private tab" function: https://github.com/Infocatcher/Private_Tab/blob/0.1.5/bootstrap.js#L1549 And we use trick with setTimeout() for #84.

Yes, we can increase delay in waitForTab(), but happens something wrong and it's better to somehow fix the real reason...

Infocatcher commented 11 years ago

Oh, the same issue without @run-at document-start:

// ==UserScript==
// @name        Test Scriptify #2
// @namespace   dev/null
// @include     https://github.com/*
// @version     0.1
// @grant       none
// ==/UserScript==

if("console" in window && "log" in console)
    console.log("Test Scriptify #2");

http://infocatcher.ucoz.net/test/ext/test-scriptify-2.xpi

So, looks like any Scriptify-based extension causes strange things with timeouts and addTab().

Infocatcher commented 11 years ago

Test:

var c = 100;
var timerDelay = 0;
var testDelay = 300;

var ok = 0;
var failed = 0;
var tester = asyncTester();
tester.next();

function asyncTester() {
    for(var i = 0; i < c; ++i) {
        progress("Test: " + i + "/" + c + " (" + Math.round(failed/c*100) + "%)");
        asyncTest();
        yield 0;
    }
    progress();
    alert(
        "OK: " + ok
        + "\nFailed: " + failed + " (" + Math.round(failed/c*100) + "%)"
        + "\nTotal: " + (ok + failed) + "/" + c
    );
    yield 0;
}
function asyncTest() {
    var tabOpened = false;
    setTimeout(function() {
        if(tabOpened)
            ++ok;
        else
            ++failed;
    }, timerDelay);
    var tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
    tabOpened = true;
    setTimeout(function() {
        gBrowser.removeTab(tab);
        setTimeout(function() {
            tester.next();
        }, testDelay);
    }, timerDelay);
}
function progress() {
    var root = document.documentElement;
    var tm = root.getAttribute("titlemodifier");
    var tmn = root.getAttribute("titlemodifier_normal");
    progress = function(status) {
        if(status) {
            root.setAttribute("titlemodifier", status);
            root.setAttribute("titlemodifier_normal", status);
        }
        else {
            root.setAttribute("titlemodifier", tm);
            root.setAttribute("titlemodifier_normal", tmn);
            gBrowser.updateTitlebar && gBrowser.updateTitlebar();
        }
    };
    return progress.apply(this, arguments);
}

Failed: timerDelay = 0, testDelay = 100: 51% timerDelay = 0, testDelay = 700: 11%

timerDelay = 50, testDelay = 100: 3% timerDelay = 50, testDelay = 700: 5%

Infocatcher commented 11 years ago

Additional tests:

_log("setTimeout()");
setTimeout(function() {
    _log("setTimeout() done");
}, 0);

_log("mainThread.dispatch()");
Services.tm.mainThread.dispatch(function() {
    _log("mainThread.dispatch() done");
}, 0);

_log("postMessage()");
delayed(function() {
    _log("postMessage() done");
});

_log("addTab()");
gBrowser.selectedTab = gBrowser.addTab("about:");
_log("addTab() done");

function delayed(func) {
    var frame = document.createElement("iframe");
    frame.setAttribute("collapsed", "true");
    document.documentElement.appendChild(frame);
    var fw = frame.contentWindow;
    fw.addEventListener("message", function onMessage(e) {
        fw.removeEventListener("message", onMessage, true);
        frame.parentNode.removeChild(frame);
        func();
    }, true);
    fw.postMessage("", "*");
}
function _log(s) {
    var d = new Date();
    var ms = d.getMilliseconds();
    var timestamp = d.toLocaleFormat("%M:%S:") + "000".substr(String(ms).length) + ms;
    Services.console.logStringMessage("[test] " + timestamp + " " + s);
}

All methods works without Scriptify-based extension and fails otherwise (addTab() done appears after all).

Infocatcher commented 10 years ago

Should works fine since Scriptify 0.2.6: https://addons.mozilla.org/addon/scriptify/versions/0.2.6

  • Don't use frame managers when e10s is disabled, as it leads to spinning the event loop on the main thread.

But only with browser.tabs.remote = false...