loge.hixie.ch

Hixie's Natural Log

2011-02-03 05:37 UTC Script execution order post-mortem

LABjs, a JavaScript library for loading JavaScript libraries, relied on one of two behaviours to implement its asynchronous loading behaviour:

It would use the first behaviour if the browser implemented the MozAppearance property in the CSSOM (a Mozilla extension) or if the browser had an opera property, and it would use the second behaviour otherwise.

Unfortunately, neither of these behaviours were defined: historically, the HTML spec has been incredibly vague about what order dynamically-inserted scripts should execute in and when to download scripts. This is why the browsers didn't all do the same thing.

With the WHATWG effort, we try to pin all these behaviours down so that browsers can converge on one set of behaviours and Web developers don't have to worry about sniffing to use different behaviours in different browsers, like LABjs does.

When browsers don't have good interoperability, we usually pick the saner behaviour. In this case, that meant not downloading scripts that wouldn't execute anyway, and not applying a strict execution order on scripts that get inserted into the document dynamically. Both of these decisions are intended to improve performance.

Over time, browsers converged on these behaviours. First, Gecko removed the ordering on dynamic scripts. This broke LABjs. Arnout Kazemier was first to report the breakage in Firefox nightly builds. Kyle Simpson, who works on LABjs, posted about the issue on the Getify blog. A Mozilla evangelist noticed and pointed the situation out to Henri Sivonen, who subsequently started a public-html thread to discuss possible solutions; discussion later migrated to a WHATWG wiki page.

Thankfully, Henri was able to coordinate with Kyle and other Web developers, as well as with the other browser vendors, to come up with a solution (mostly based on Kyle's suggestions), which he documented in detail (See also: Mozilla bug, WebKit bug).

In the near future, WebKit builds will likely stop downloading scripts that it isn't going to execute (this has already changed for parser-inserted elements, but script-inserted elements haven't yet had this change applied). I've updated the HTML spec with the above proposal, so they'll likely implement that too.

The solution is basically to add a magic flag which can be reset from script. The flag is only set on script elements created from script, and causes the browser to assume that the async attribute is set. If you reset this flag (by setting script.async = false in script) then the attribute is honoured.

I must admit to not being a huge fan of the solution. Magic like that is highly unintuitive. However, in this particular instance Henri took the lead and got the key stakeholders of the moment on board, and that often has more weight than getting a perfect solution.

2010-04-02 20:29 UTC Acid3 update for :link/:visited privacy changes

David Baron has proposed a possible solution for the :link/:visited privacy problem. I've changed Acid3 so that it won't fail if you implement his proposal. The following is the diff:

--- index.html.prev  2009-08-14 00:00:00.000000000 +0000
+++ index.html       2010-04-02 20:13:49.000000000 +0000
@@ -129,8 +129,12 @@
 
   /* rules specific to the tests below */
   #instructions:last-child { white-space: pre-wrap; white-space: x-bogus; }
-  #linktest:link { display: block; color: red; text-align: center; text-decoration: none; }
-  #linktest.pending, #linktest:visited { display: none; }
+  /* replaced for http://dbaron.org/mozilla/visited-privacy with the three rules after it:
+     #linktest:link { display: block; color: red; text-align: center; text-decoration: none; }
+     #linktest.pending, #linktest:visited { display: none; } */
+  #linktest { position: absolute; left: 17px; top: 18px; color: red; width: 80px; text-decoration: none; font: 900 small-caps 10px sans-serif; }
+  #linktest:link { color: red; }
+  #linktest.pending, #linktest:visited { color: white; }
   #\ { color: transparent; color: hsla(0, 0, 0, 1); position: fixed; top: 10px; left: 10px; font: 40px Arial, sans-serif; }
   #\  #result, #\  #score { position: fixed; top: 10%; left: 10%; width: 4em; z-index: 1; color: yellow; font-size: 50px; background: fuchsia; border: solid 1em purple; }
  </style>
@@ -1869,7 +1873,7 @@
       var iframe = document.getElementById("selectors");
       var number = (new Date()).valueOf();
       var a = document.createElement('a');
-      a.appendChild(document.createTextNode('LINKTEST FAILED'));
+      a.appendChild(document.createTextNode('YOU SHOULD NOT SEE THIS AT ALL')); // changed text when fixing http://dbaron.org/mozilla/visited-privacy
       a.setAttribute('id', 'linktest');
       a.setAttribute('class', 'pending');
       a.setAttribute('href', iframe.getAttribute('src') + "?" + number);
@@ -3106,23 +3110,25 @@
     },
     function () {
       // test 80: remove the iframes and the object
+      // (when fixing the test for http://dbaron.org/mozilla/visited-privacy,
+      // this section was flipped around so the linktest check is done first;
+      // this is to prevent the 'retry' from failing the second time since by
+      // then the kungFuDeathGrip has been nullified, if we do it first)
+      // first, check that the linktest is loaded
+      var a = document.links[1];
+      assert(!(a == null), "linktest was null");
+      assert(a.textContent == "YOU SHOULD NOT SEE THIS AT ALL", "linktest link couldn't be found"); // changed text when fixing http://dbaron.org/mozilla/visited-privacy
+      if (a.hasAttribute('class'))
+        return "retry"; // linktest onload didn't fire -- could be a networking issue, check that first
       assert(!(kungFuDeathGrip == null), "kungFuDeathGrip was null");
       assert(!(kungFuDeathGrip.parentNode == null), "kungFuDeathGrip.parentNode was null");
+      // ok, now remove the iframes
       kungFuDeathGrip.parentNode.removeChild(kungFuDeathGrip);
       kungFuDeathGrip = null;
       // check that the xhtml files worked right
       assert(notifications['xhtml.1'], "Script in XHTML didn't execute");
       assert(!notifications['xhtml.2'], "XML well-formedness error didn't stop script from executing");
       assert(!notifications['xhtml.3'], "Script executed despite having wrong namespace");
-      // while we're at it, check that the linktest is loaded
-      // since the other iframes have forcibly loaded by now, we assume that
-      // there's no way this can't have loaded by now
-      // (probably a safe bet)
-      var a = document.links[1];
-      assert(!(a == null), "linktest was null");
-      assert(a.textContent == "LINKTEST FAILED", "linktest link couldn't be found");
-      if (a.hasAttribute('class'))
-        return "retry"; // linktest onload didn't fire -- could be a networking issue, check that first
       return 5;
     },
 

A new copy of the Acid3 tarball is now available also.

Pingbacks: 1 2

2010-02-12 09:42 UTC Consistency

Adobe CEO Shantanu Narayen, June 2009, when asked about HTML5: To the extent that an improved HTML standard accelerates innovation and consistent reach for web content, we’re very supportive. (context)

Adobe CTO Kevin Lynch, February 2010: Adobe supports HTML and its evolution. (context)

Adobe Evangelist Dave McCallister, July 2009: For Adobe, "open" is all aspects of communications and technologies. For us, those are open source, standards, and community. [...] We make sure that we talk to our communities, that we play with the standards groups, [...] We are actually one of the most open companies that are active. (context)

Someone whom I can't identify publicly, since he posted only on one of the secret W3C member lists, contributed to the following thread over the last few days: 1 2 3

Larry Masinter, Adobe, quoted in the minutes of yesterday's weekly phone status report for the HTML working group: do I need to repeat objections?

Net result: the latest publication of HTML5 is now blocked by Adobe, via an objection that has still not been made public (despite yesterday's promise to make it so).

With friends like these...

Pingbacks: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

2010-01-20 08:02 UTC T-Mobile makes no sense

For reasons that aren't material to this rant, I'm trying to get a T-Mobile SIM card set up with T-Mobile's ridiculously named "Even More Plus 500 Talk + Text + Web" plan. At this point I have a SIM card, and after much pain and suffering in phone conversations and online chat support, I have an account that is fully paid up.

Let's log in to the "My T-Mobile" site's "Billing & Payments" page to see how much I currenly owe:

Ok it says I owe $62.42 by 1/19/2010 (today) for service from 2/9/2010 - 3/8/2010 (next month). But it also says that my monthly charges for my previous bill are $127.42 due on 3/9/2010 (two months from now).

None of those numbers seem to add up to $59.99, which is what the "Even More Plus 500 Talk + Text + Web" plan is advertised as costing, but I suppose $62.42 could equal $59.99 if one were to imagine that T-Mobile felt they could put a few "fees" on there that for whatever reason could be assumed not to count. But what's with the $127.42? And what's with the due dates? Let's click "See details" to see details:

Up comes a page titled 'See bill summary'.

Wait, bill summary? I wanted details! And hold on, this page says my account balance is $0.00, and that I paid $62.42 on 1/20/10 (tomorrow). It also gives my monthly charges twice... once as $0.00, and once as $127.42! I guess if you average them it adds up to $63.71, which is similar to $62.42...

Oh look, the details are below the fold.

This says the next service period is $63.71, that they've received $62.42, that the previous balance was $63.71, and that they "adjusted" my account by $65.00 (the result of my calling billing support because they hadn't applied the $63.71 they actually charged me to my account), and apparently that all adds up to me owing $0.00... by 02/05/2010.

Clearly maths is not their strong point. Also not their strong point: being consistent about how they mark up dates. Or how they decide what dates are important.

Oh and... also not their strong point: matching reality. So far they've only actually charged me $63.71, once, though I have in fact tried to pay more than once (earlier today I also tried to pay the $62.42 that some of these pages claim I owe, though my bank has yet to see that charge).

Still, the $127.42 is a bit confusing. Let's see what the "View Bill" button under that number brings up.

Whaaaa!? FPEvenMorePlus 500TTW $119.98? What on earth is that? "Amount due 2/05/10: $127.42"? That completely contradicts the previous page! How much do I owe on that day, $0, or $127.42??

They say the way to work out how much you owe is to dial #225# from the phone, so let's try that... Ok, that says $0. I guess the phone would know best.

I give up trying to work out how much I owe; let's instead try to get the "Unlimited Data" working on this phone. I've heard rumours that one has to buy a $0 optional extra "Unlimited Web" service since otherwise the "Even More Plus Unlimited Web" is actually limited. Add additional services on this line... Internet & E-mail... Aha, here we go. "T-Mobile Smartphone Unlimited Web with FlexPay". That sounds promising. And it's free! Just like the rumours. Let's "buy" that and quickly review the charges:

Added plan and services... $0, yup. Unchanged plan and services... $59.99. Yup. So, the grand total is... $89.99. Wait, wait, hold on, let me recheck the maths here... $0... plus $59.99... carry the one... What??

Ok, ok, clearly it got confused. Let's close the browser and start over. Add additional services on this line... Internet & E-mail... "T-Mobile Smartphone Unlimited Web with FlexPay". And it says FREE. So we click it again, and let's see how much $59.99 + FREE equals this time:

$10088.99

TEN THOUSAND AND EIGHTY EIGHT DOLLARS AND NINETY NINE CENTS?!

I give up. I'll try calling them tomorrow.

Pingbacks: 1

2010-01-07 00:33 UTC Phone "support"

I'm on hold with T-Mobile. The guy is very nice, but there's so much interference I can barely hear what he's saying half the time. Something about me having to pay a month in advance instead of at the end of the month (which I prefer anyway), and something about the order not going through for "reasons unknown" though he has already done "the credit check". Beats me why a credit check is necessary if I'm paying in advance without a contract, by the way, but that's another story. Same thing happened when I paid cash to buy a car recently. "We need to run a credit check". You knock yourself out.

Why can't all this stuff be done by e-mail? Really? I hate phones.

Time passes.

Hey check this out. The support guy gave up, and now I'm doing this all over again with sales! At least the connection is clearer now. Ok so I want the $59.99 plan, which of course comes with a $1.21 non-tax non-government "regulatory" fee and a $35 "activation" fee (given how hard this has been so far, I understand charging an activation fee, though I wonder if we could come to some arrangement wherein I get paid for my part in this ordeal also).

"Sir, what is your phone number?" Well, I don't know, aren't you supposed to tell me that? I mean, I don't have a phone, that's why I'm buying a phone. After trying to explain that I just gave them my Google Voice number — it's not connected to anything but at least they can leave me voicemail, I guess.

Ok, now we have to go through the terms of service... don't forget to opt out of the "you can't use the legal system if we screw you over" option.

"Actually sir, you can't have Flex Pay, you have to have Take Control." I have no idea what that sentence means. I wasn't aware I was trying to get either of those. What are you talking about. "Um..." time passes again "Ok it's going to be $59.99 plus $1.25 tax" (it's not a tax, that's a lie, but we'll let that slide) "so that's a total of $70." I'm going to briefly ignore the fact that those numbers don't add up, and ask where the activation fee went.

"Um... there's no activation fee with this plan."

"It's still the 500-minute, unlimited web, unlimited sms plan?"

"Sure."

"And how do I transfer an existing number to this SIM card?"

"Oh, uh, call technical support when you've received the SIM card. Yeah. We can't do that now but we can do that once we've taken your money, I'm sure."

I so have no idea what I've purchased.

Pingbacks: 1