disqus reply.html iframe placeholder out of place

Bug reports and enhancement requests
al_9x
Master Bug Buster
Posts: 931
Joined: Thu Mar 19, 2009 4:52 pm

disqus reply.html iframe placeholder out of place

Post by al_9x »

http://torrentfreak.com/utorrent-gets-c ... se-110623/

It shifts about on every load, always out of place. Does it not makes sense to position placeholders relative to the container (in this case dsq-textarea-wrapper), if the blocked embedding is so positioned?
Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0
User avatar
Giorgio Maone
Site Admin
Posts: 9527
Joined: Wed Mar 18, 2009 11:22 pm
Location: Palermo - Italy
Contact:

Re: disqus reply.html iframe placeholder out of place

Post by Giorgio Maone »

Yes it does, but the placeholder already copies all the original object computed styles.
Maybe something that gets added later?
Mozilla/5.0 (Windows NT 5.2; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0
al_9x
Master Bug Buster
Posts: 931
Joined: Thu Mar 19, 2009 4:52 pm

Re: disqus reply.html iframe placeholder out of place

Post by al_9x »

another example: http://www.ibtimes.com/

open any article

The disqus placeholder frequently ends up in the middle of the article. ctrl-f5 to repro more consistently.

Disqus is pretty popular, so this is worth addressing.
Mozilla/5.0 (Windows NT 5.1; rv:6.0) Gecko/20100101 Firefox/6.0
al_9x
Master Bug Buster
Posts: 931
Joined: Thu Mar 19, 2009 4:52 pm

Re: disqus reply.html iframe placeholder out of place

Post by al_9x »

Here's the disqus.js code that creates the iframe

Code: Select all

function z(a) {
	if (r(P)) {
		var d = b.createElement("iframe");
		d.name = B + "TEST";
		q(d.style, {
			position: "absolute",
			left: "-2000px",
			top: "0px"
		});
		b.body.appendChild(d);
		P = d.contentWindow !== c.frames[d.name];
		b.body.removeChild(d)
	}
	P && !~navigator.userAgent.indexOf("Firefox") ? d = b.createElement('<iframe name="' + a.props.name + '"/>') : (d = b.createElement("IFRAME"), d.name = a.props.name);
	d.id = d.name = a.props.name;
	delete a.props.name;
	a.onLoad && C(d, "load", a.onLoad);
	if (typeof a.container == "string") a.container = b.getElementById(a.container);
	if (!a.container)
		d.style.position = "absolute", d.style.top = "-2000px", d.style.left = "0px", a.container = b.body;
	var e = a.props.src;
	delete a.props.src;
	q(d, a.props);
	d.border = d.frameBorder = 0;
	a.container.appendChild(d);
	d.src = e;
	a.props.src = e;
	return d
}
doesn't seem like there's any smoking gun here,

when it works, the placeholder (root div) computed style position is "static" and top, left, bottom, right are "auto"
when it fails (placeholder out of place), the position is "absolute" and top, left, bottom, right have px values, but it's not due to:

Code: Select all

if (!a.container)
	d.style.position = "absolute", d.style.top = "-2000px", d.style.left = "0px", a.container = b.body;
Last edited by al_9x on Thu Aug 04, 2011 7:29 am, edited 1 time in total.
Mozilla/5.0 (Windows NT 5.1; rv:6.0) Gecko/20100101 Firefox/6.0
al_9x
Master Bug Buster
Posts: 931
Joined: Thu Mar 19, 2009 4:52 pm

Re: disqus reply.html iframe placeholder out of place

Post by al_9x »

I found the culprit.

t_c4ca4238a0b923820dcc509a6f75849b.js has the following events:

Code: Select all

h("comments.reply.new.onLoadingStart", function (m) {
	var l = b.nodes.get("#dsq-textarea-wrapper" + (m ? "-" + m : ""));
	b.nodes.addClass(l, "dsq-textarea-loading ");
	var k = b.nodes.get("iframe", l)[0];
	if (k) {
		k.style.position = "absolute";
		k.style.top = "-2000px"
	}
});
h("comments.reply.new.onLoadingEnd", function (m) {
	var l = b.nodes.get("#dsq-textarea-wrapper" + (m ? "-" + m : ""));
	b.nodes.removeClass(l, "dsq-textarea-loading");
	var k = b.nodes.get("iframe", l)[0];
	if (k) {
		k.style.position = "relative";
		k.style.top = "0px"
	}
});
The first one screws up the placeholder style (depending on the timing), and the second one never gets called when the iframe is blocked, and even if it were called it probably wouldn't do any good (is that right?)

So one solution that comes to mind is unregistering one or both:

Code: Select all

DISQUS.dtpl.actions.remove('comments.reply.new.onLoadingStart');
I verified that with these events disabled in the source, the problem goes away.

The question is how to get the timing right, and how to invoke it for all pages with specific allowed script inclusions (disqus), as opposed to a fixed list of orgins (page level surrogates)

The event is registered in t_c4ca4238a0b923820dcc509a6f75849b.js and invoked in the onload of this script element. Perhaps a new type of surrogate for allowed rather than blocked scripts, is worth considering, that gets called in the onload of the script before any other onload handler from content. What do you think?
Last edited by al_9x on Thu Aug 04, 2011 12:13 pm, edited 1 time in total.
Mozilla/5.0 (Windows NT 5.1; rv:6.0) Gecko/20100101 Firefox/6.0
al_9x
Master Bug Buster
Posts: 931
Joined: Thu Mar 19, 2009 4:52 pm

Re: disqus reply.html iframe placeholder out of place

Post by al_9x »

I was wrong, the events (comments.reply.new.onLoadingStart, comments.reply.new.onLoadingEnd) are not registered in the script. They are both registered and invoked and from the load event of the script element. So here's a page level surrogate that demonstrates the feasibility of curing this problem, it simulates a "surrogate" for allowed scripts I proposed in the previous post.

Code: Select all

document.addEventListener('load', function(e) { if (e.target.tagName === 'SCRIPT' && e.target.src === 'http://mediacdn.disqus.com/1312320489/build/themes/t_c4ca4238a0b923820dcc509a6f75849b.js?1') DISQUS.dtpl.actions.register('comments.reply.new.onLoadingStart', function() { DISQUS.dtpl.actions.remove('comments.reply.new.onLoadingStart'); }); }, true);
Mozilla/5.0 (Windows NT 5.1; rv:6.0) Gecko/20100101 Firefox/6.0
al_9x
Master Bug Buster
Posts: 931
Joined: Thu Mar 19, 2009 4:52 pm

Re: disqus reply.html iframe placeholder out of place

Post by al_9x »

Here's a universal disqus surrogate

Code: Select all

user_pref("noscript.surrogate.disqus.sources", "@^http:");
user_pref("noscript.surrogate.disqus.replacement", "document.addEventListener('load', function(e) { if (e.target.tagName === 'SCRIPT' && /^http:\/\/mediacdn\.disqus\.com\/\d+\/build\/themes\/t_c4ca4238a0b923820dcc509a6f75849b\.js/.test(e.target.src)) DISQUS.dtpl.actions.register('comments.reply.new.onLoadingStart', function() { DISQUS.dtpl.actions.remove('comments.reply.new.onLoadingStart'); DISQUS.dtpl.actions.remove('comments.reply.new.onLoadingEnd');}); }, true);");
But like I said, this does not seem like the optimal way to do this, intercepting load events for everything, testing for a particular script. It's duplicating what NS is already probably doing, so NS could expose a script load surrogate in a more efficient manner.
Mozilla/5.0 (Windows NT 5.1; rv:6.0) Gecko/20100101 Firefox/6.0
User avatar
Giorgio Maone
Site Admin
Posts: 9527
Joined: Wed Mar 18, 2009 11:22 pm
Location: Palermo - Italy
Contact:

Re: disqus reply.html iframe placeholder out of place

Post by Giorgio Maone »

al_9x wrote:But like I said, this does not seem like the optimal way to do this, intercepting load events for everything, testing for a particular script. It's duplicating what NS is already probably doing, so NS could expose a script load surrogate in a more efficient manner.
Yes, any universal page surrogate should be avoided if possible, and this is surely a case in favor of surrogates to be run just before a matching external script is loaded.
Mozilla/5.0 (Windows NT 5.2; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0
al_9x
Master Bug Buster
Posts: 931
Joined: Thu Mar 19, 2009 4:52 pm

Re: disqus reply.html iframe placeholder out of place

Post by al_9x »

Giorgio Maone wrote:
al_9x wrote:But like I said, this does not seem like the optimal way to do this, intercepting load events for everything, testing for a particular script. It's duplicating what NS is already probably doing, so NS could expose a script load surrogate in a more efficient manner.
Yes, any universal page surrogate should be avoided if possible, and this is surely a case in favor of surrogates to be run just before a matching external script is loaded.
Here it would need to be after, not before, my disqus surrogate does its work in the load event for the script element, before the page's own script load handler has run, and wouldn't work otherwise.
Mozilla/5.0 (Windows NT 5.1; rv:6.0) Gecko/20100101 Firefox/6.0
User avatar
Giorgio Maone
Site Admin
Posts: 9527
Joined: Wed Mar 18, 2009 11:22 pm
Location: Palermo - Italy
Contact:

Re: disqus reply.html iframe placeholder out of place

Post by Giorgio Maone »

al_9x wrote:Here it would need to be after, not before, my disqus surrogate does its work in the load event for the script element, before the page's own script load handler has run
I don't get it. Your page-level surrogate currently runs before any other script runs (@), why running just before would be different than running long before?
Furthermore, running before is not just easier to implement, but is also more flexible than running after, as you can modify the environment for the code about to run and possibly prepare some code to run after.
Mozilla/5.0 (Windows NT 5.2; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0
al_9x
Master Bug Buster
Posts: 931
Joined: Thu Mar 19, 2009 4:52 pm

Re: disqus reply.html iframe placeholder out of place

Post by al_9x »

Giorgio Maone wrote:
al_9x wrote:Here it would need to be after, not before, my disqus surrogate does its work in the load event for the script element, before the page's own script load handler has run
I don't get it. Your page-level surrogate currently runs before any other script runs (@), why running just before would be different than running long before?
If it runs before, I am assuming I would still have to attach a capturing load handler to the document, and still have to match the script src in the handler for the second time (the first time is the surrogate matching the script) That's doesn't seem ideal, considering that for now this is the primary use case.

As to implementation, it should be possible to do both, if the surrogate is configured for before, run it, if after, add it as a load handler to the script element (hopefully you can do that earlier than any content)
Mozilla/5.0 (Windows NT 5.1; rv:6.0) Gecko/20100101 Firefox/6.0
al_9x
Master Bug Buster
Posts: 931
Joined: Thu Mar 19, 2009 4:52 pm

Re: disqus reply.html iframe placeholder out of place

Post by al_9x »

al_9x wrote: if after, add it as a load handler to the script element
Although that probably doesn't guarantee it runs ahead of all other possible load handlers for that script.

Are you able to register for a script load that guarantees you'll be first?
Mozilla/5.0 (Windows NT 5.1; rv:6.0) Gecko/20100101 Firefox/6.0
User avatar
Giorgio Maone
Site Admin
Posts: 9527
Joined: Wed Mar 18, 2009 11:22 pm
Location: Palermo - Italy
Contact:

Re: disqus reply.html iframe placeholder out of place

Post by Giorgio Maone »

al_9x wrote:Are you able to register for a script load that guarantees you'll be first?
A capture event handler attached to an element higher than content (i.e. in chrome) will run first (capture handlers are ran "topmost first").
Unfortunately a surrogate, being ran entirely in content, can't attach event handlers higher than the window object.
However, if you're suggesting that NoScript should hook the event on its side and run "after" surrogate from its handler, I'm not sure the added complexity is worth the benefits, considering as you said that this is the only use case so far.
Mozilla/5.0 (Windows NT 5.2; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0
al_9x
Master Bug Buster
Posts: 931
Joined: Thu Mar 19, 2009 4:52 pm

Re: disqus reply.html iframe placeholder out of place

Post by al_9x »

I would say that running before is less useful than after. If you want to mod the behavior of an external script library (don't you think this could be generally useful?) you have to let it do its internal construction/init first and then patch the established objects and functions before they are used. Running before, there is nothing yet to mod.

Disqus is the first use case, but I am sure not the last. If patching/modding based on origins (page level) is useful then so will patching script libraries be (regardless of origin, before they can be used). Also disqus is quite popular, and it needs this (better than page level) surrogate solution. I am hoping you will implement the after surrogate.
Mozilla/5.0 (Windows NT 5.1; rv:6.0) Gecko/20100101 Firefox/6.0
User avatar
Giorgio Maone
Site Admin
Posts: 9527
Joined: Wed Mar 18, 2009 11:22 pm
Location: Palermo - Italy
Contact:

Re: disqus reply.html iframe placeholder out of place

Post by Giorgio Maone »

al_9x wrote:I am hoping you will implement the after surrogate.
A "before" surrogate can be easily turned into an "after" surrogate by registering a throw away capturing onload event handler, while the opposite (an "after" surrogate to modify the environment for the included script) is impossible.
So implementing the "before" surrogate only should cover all use cases without unnecessary complications.
Mozilla/5.0 (Windows NT 5.2; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0
Post Reply