Page 1 of 1

setTimeout/setInterval with disabled JavaScript

Posted: Wed Oct 03, 2012 4:33 pm
by Infocatcher
Bookmarklet:

Code: Select all

javascript: (function() { for(var i = 1; i <= 52; ++i) delayed(i); function delayed(i) { setTimeout(function() { console.log(i); }, 0); } })();
"Source":

Code: Select all

(function() {
	for(var i = 1; i <= 52; ++i)
		delayed(i);
	function delayed(i) {
		setTimeout(function() {
			console.log(i);
		}, 0);
	}
})();
(Open Tools - Web Developer - Web Console before!)
For pages with enabled JavaScript:
1 ... 52
With disabled JavaScript:
52 ... 3
(only last 49!)

noscript-2.5.6-sm+fx+fn.xpi\components\noscriptService.js

Code: Select all

            while (tt.length && count++ < 50) { // let's prevent infinite pseudo-loops
              tt.sort(function(b, a) { return a.d < b.d ? -1 : (a.d > b.d ? 1 : 0); });
              t = tt.pop();
              t.f.call(window, t.a);
            }
You should, at least, use Array.shift(), not .pop().

And this is very simple way to do something pseudo asynchronously:

Code: Select all

Array.forEach(
	document.getElementsByTagName("*"),
	function processAsync(item) {
		setTimeout(function() {
			process(item); // Something slow
		}, 0);
	}
);
And unfortunately following trick fails:

Code: Select all

var delayed = {
	maxActive: 15,
	active: 0,
	queue: [],
	add: function(func, args) {
		if(this.active >= this.maxActive) {
			console.log("wait...");
			this.queue.push(arguments);
			return;
		}
		++this.active;
		var _this = this;
		setTimeout(function() {
			_this.next(--_this.active);
			func.apply(window, args);
		}, 0);
	},
	next: function(cnt) {
		while(cnt++ < this.maxActive && this.queue.length)
			this.add.apply(this, this.queue.shift());
	}
};
function processAsync(item) {
	delayed.add(process, arguments);
}
Some real examples:
https://github.com/Infocatcher/Bookmark ... rs.js#L171
https://github.com/Infocatcher/UserScri ... er.js#L353


P.S. I get
Ooops, something in your posting triggered my antispam filter...
Please use the "Back" button to modify your content and retry.
for

Code: Select all

Tools \– Web Developer \– Web Console
without "\". :)

Re: setTimeout/setInterval with disabled JavaScript

Posted: Wed Oct 03, 2012 8:49 pm
by iDrugoy
Giorgio,

Code: Select all

–/–
^replace "/" here with a space and your anti-spam won't let you post it.

Re: setTimeout/setInterval with disabled JavaScript

Posted: Fri Oct 05, 2012 12:06 am
by GµårÐïåñ
Spam filter is a work in progress due to the massive amount of crap we get, so be patient, it will be tweaked as we get false positives. Thanks.

Re: setTimeout/setInterval with disabled JavaScript

Posted: Fri Oct 05, 2012 1:53 pm
by Giorgio Maone
Infocatcher wrote: You should, at least, use Array.shift(), not .pop().
Yes, this is a bug and is gonna be fixed in next release.
Infocatcher wrote: And this is very simple way to do something pseudo asynchronously:
Unfortunately I have to keep it synchronous because bookmarklets temporary set "Allow scripts globally" for compatibility reasons, and you don't want this to happen periodically in an asynchronous fashion ;)
Infocatcher wrote: Ooops, something in your posting triggered my antispam filter...
Fixed: you were using an Unicode hyphen character, which was caught by my filter against foreign languages (esp. Russian and Chinese) spam.
Now it's more specific, letting symbols go through.

Re: setTimeout/setInterval with disabled JavaScript

Posted: Fri Oct 05, 2012 2:22 pm
by Infocatcher
Giorgio Maone wrote:Unfortunately I have to keep it synchronous because bookmarklets temporary set "Allow scripts globally" for compatibility reasons, and you don't want this to happen periodically in an asynchronous fashion ;)
But what about current limit of setTimeout/setInterval calls?
May be just replace setTimeout/setInterval by synchronous equivalents, without any arrays for "queue" (and without delays, of course)?
Or replace it by corresponding functions from window with enabled scripts.
Or can I detect, that scripts are disabled and don't call asynchronous things in this case?

[Upd]
Or create asynchronous equivalents using window.postMessage() or createEvent()/dispatchEvent()?

Re: setTimeout/setInterval with disabled JavaScript

Posted: Fri Oct 05, 2012 8:20 pm
by Giorgio Maone
Fixed in latest development build 2.5.7rc5.
I raised the limit to 200 and fixed the ordering.
Making them unconstrained or asynchronous is out of discussion because of the need for allowing scripts globally in a controlled and safe way.
Anyway if scripts are allowed for the page, no emulation occurs and the timeout callbacks happen "normally", as expected.

Re: setTimeout/setInterval with disabled JavaScript

Posted: Sat Oct 06, 2012 2:56 pm
by Infocatcher
Giorgio Maone wrote:I raised the limit to 200 and fixed the ordering.
Thanks!

Anyway I can get real

Code: Select all

function (f, d, a) {
    if (typeof f != "function") {
        f = new Function(f || "");
    }
    tt.push({f: f, d: d, a: a});
    return 0;
}
for

Code: Select all

alert("setTimeout:\n" + setTimeout);
from bookmarklet, so I can do some corrections from my side.
[Upd]: Improve compatibility with NoScript + disabled scripts

And another issue:

Code: Select all

javascript: setTimeout(function(a, b, c, d, e) { alert(Array.join(arguments, ", ")); }, 0, 1, 2, 3, 4, 5); void 0;
Firefox only, as I know, but built-in setTimeout produce "1, 2, 3, 4, 5", not only "1".

Another idea: use evalInSandbox() (as Greasemonkey) - works in pages with disabled scripts, but setTimeout/setInterval doesn't work for now (see https://github.com/greasemonkey/greasem ... ef-7eccacb).