The 1JS experiment has failed. Let's return to plan A.
On Wednesday, December 26, 2012, Mark S. Miller wrote:
Hi Brian, thanks for accumulating this data!
Between
- this data,
- Apple's decision as recorded at bugs.webkit.org/show_bug.cgi?id=27226#c4,
- the new function syntax micro-modes,
- and the "let" issues already discussed, I reiterate that we should stop trying to twist the language to somehow shoehorn ES6 features into non-strict mode.
For both "function" and "let", when we first discussed trying to retrofit sense into ES6 non-strict mode, we knew that this was speculative, because non-strict mode cannot include web-breaking incompatible changes. This experiment has failed, so we should now return to plan A. Any ES6 features that don't fit into non-strict mode without contortion, including "let" and nested "function", should be available only in strict mode. For new function syntax, if shoe-horning it into non-strict mode requires micro-modes as previously discussed, then we shouldn't. Whatever the complaints about living with one mode distinction, we're certainly not addressing these complaints by introducing more mode distinctions.
Proclaiming 1JS has failed just because we've learned that block scoped function declarations (arguably an awful and unnecessary idea) is counter-productive rhetoric. 1JS is more important than this "feature" and like typeof null === "null", I'd rather abandon the one feature for the greater good.
Well, before I start arguing with you, I'd like to know what argument you're making. ;-)
Are you saying we should go back to having a MIME-type (and/or pragma) opt-in? Your subject line suggests that. Or are you saying we should simply not support some of the new features in non-strict code? Because your points only seem to be arguing for the latter, not the former.
I think the MIME type idea, while obviously attractive for our purposes, would've had terrible consequences for programmers, and I really hope we don't have to relitigate that debate.
I cited four "features". Blocked scoped functions are simply the straw that makes the condition of the camel's back more obvious.
As for the greater good, we're all working for that. We just differ on which path leads there.
On Wed, Dec 26, 2012 at 2:27 PM, David Herman <dherman at mozilla.com> wrote:
Well, before I start arguing with you, I'd like to know what argument you're making. ;-)
Are you saying we should go back to having a MIME-type (and/or pragma) opt-in? Your subject line suggests that. Or are you saying we should simply not support some of the new features in non-strict code? Because your points only seem to be arguing for the latter, not the former.
Sorry, I'd completely forgotten about those earlier options. I am arguing only the latter. Specifically "Any ES6 features that don't fit into non-strict mode without contortion, including "let" and nested "function", should be available only in strict mode."
Mark, you cite some issues we need to work through, but opt-in via pragma syntax beyond "use strict" is not one of them.
What's more, the big-picture claim in your Subject line ("has failed" especially) is not true. In an overriding sense, 1JS can't fail, because versioning is an anti-pattern (or at best retrospective, not prescriptive) on the web. To be more precise, ES6 will fail if it requires opt-in versioning apart from the new syntax itself. This applies to "use strict" too, since it has costs (both performance and semantic changes that double testing while old browsers are in the field).
Now, on the specific JSC bug you cite, bugs.webkit.org/show_bug.cgi?id=27226. This is actually from 2009, filed based on a misunderstanding of ES3 and not on any real-world web content, and finally marked invalid in February. It is old news. The comments from February do not prove that "[t]he 1JS experiment has failed". And JSC design decisions are not authoritative over TC39 as a whole -- rather, the reverse!.
Anyway, we can certainly make function-in-block ES6 semantics require "use strict" opt-in, but that will both diminish the use-frequency of function-in-block with sane and standard semantics, and as Andy Wingo pointed out in the JSC bug, confuse users with two semantics for the same syntax.
More in reply to Brian Terlson's thread.
On Wednesday, December 26, 2012, Mark S. Miller wrote:
Hi Rick, I cited four "features".
Unless I misread, 2 of them both concerned block scoped functions and I assumed you were referring to the let[0]=1; which was discussed and consensus on further research towards Luke's resolution was agreed to at the last meeting. I'm actually not sure what new function syntax micro-modes you're referring to, can you clarify?
On Wed, Dec 26, 2012 at 2:58 PM, Brendan Eich <brendan at mozilla.com> wrote:
Mark, you cite some issues we need to work through, but opt-in via pragma syntax beyond "use strict" is not one of them.
Sorry for the confusion. As I just clarified in my response to Dave, I am not suggesting any of those previous MIME type or additional pragma ideas. I am just suggesting that we stop twisting the language to try to fit ES6 features into non-strict mode when these don't fit well.
What's more, the big-picture claim in your Subject line ("has failed" especially) is not true. In an overriding sense, 1JS can't fail, because versioning is an anti-pattern (or at best retrospective, not prescriptive) on the web. To be more precise, ES6 will fail if it requires opt-in versioning apart from the new syntax itself.
I am not suggesting any new opt-in beyond what we've already got. I am suggesting that we use that opt-in, rather than contort the language for the sake of non-strict mode. We all know that the non-strict mode of JavaScript can never grow into a decent language. As you've long said about the arguments object, let's stop polishing this turd.
This applies to "use strict" too, since it has costs (both performance and semantic changes that double testing while old browsers are in the field).
I thought we'd settled the performance issue. I'm surprised you're still raising it.
The purpose of testing is to alert you to places in your code where bugs may reside. Even if you never plan to run your code in strict mode, you should still test in strict mode, since anything that fails in strict mode is likely enough a bug in your code that you should investigate.
Now, on the specific JSC bug you cite, bugs.webkit.org/show_bug.cgi?id=27226. This is actually from 2009, filed based on a misunderstanding of ES3 and not on any real-world web content, and finally marked invalid in February. It is old news. The comments from February do not prove that "[t]he 1JS experiment has failed".
I was unaware of the history, thanks. I withdraw that bullet point. I acknowledge that my case is substantially weaker without it.
And JSC design decisions are not authoritative over TC39 as a whole -- rather, the reverse!.
We all know that this issue isn't so unidirectional. If TC39 mandates something and the browser makers decide to do something else, we all have a problem. The pressure to avoid these problems cuts both ways.
Anyway, we can certainly make function-in-block ES6 semantics require "use strict" opt-in, but that will both diminish the use-frequency of function-in-block with sane and standard semantics,
Since only strict mode provides sane and standard semantics anyway... ;)
and as Andy Wingo pointed out in the JSC bug, confuse users with two semantics for the same syntax.
We've already got that. To avoid confusion, "use strict".
Mark S. Miller wrote:
On Wed, Dec 26, 2012 at 2:58 PM, Brendan Eich<brendan at mozilla.com> wrote:
Mark, you cite some issues we need to work through, but opt-in via pragma syntax beyond "use strict" is not one of them.
Sorry for the confusion. As I just clarified in my response to Dave, I am not suggesting any of those previous MIME type or additional pragma ideas. I am just suggesting that we stop twisting the language to try to fit ES6 features into non-strict mode when these don't fit well.
Your subject was a declarative sentence, past tense, not a suggestion! It also meant other than what you clarified.
Ok, I don't mean to vent -- moving right along:
What's more, the big-picture claim in your Subject line ("has failed" especially) is not true. In an overriding sense, 1JS can't fail, because versioning is an anti-pattern (or at best retrospective, not prescriptive) on the web. To be more precise, ES6 will fail if it requires opt-in versioning apart from the new syntax itself.
I am not suggesting any new opt-in beyond what we've already got. I am suggesting that we use that opt-in, rather than contort the language for the sake of non-strict mode. We all know that the non-strict mode of JavaScript can never grow into a decent language. As you've long said about the arguments object, let's stop polishing this turd.
But it's not the same turd. Rest parameters combined with destructuring and default parameters can do more than arguments could do, and crucially do so via new syntax. There's no comparison to function in block, which syntax already exists in the de-facto standard, whose meaning ES6 proposes to change.
Let's move away from feces metaphors :-|.
The major issue I see outstanding between us is that the economics of strict mode as faced by most developers must be considered, on top of the desirability of the feature that doesn't fit in sloppy mode.
This is a human factors problem in part. We should do quantitative studies. I just asked in re: Brian's head post whether his crawl checked for "use strict" usage. Another thing we could try: for the 4% of scripts used by the 2235 sites crawled that use funciton-in-block, how many can "use strict" without any revision?
The economics of strict mode is subject to pedagogy, better optimizations for strict code over time, and the death of pre-ES5-strict browsers over time, too. So again I'm not beating up on strict mode. But I do think we must look at the thing in the field, including its human factors, and not just say "use strict" always, be happy. It's not always an option in large projects or even small ones using libraries that aren't strict-ready. More below.
This applies to "use strict" too, since it has costs (both performance and semantic changes that double testing while old browsers are in the field).
I thought we'd settled the performance issue. I'm surprised you're still raising it.
It's not quite superstition. Look at the strict vs. non-strict differences in the charts for these three:
jsperf.com/calling-into-strict, jsperf.com/use-strict-vs-array/2, jsperf.com/use-strict-vs-array/3
In theory, apart from freakish cases involving arguments objects and parameter aliasing, strict mode should not be a performance penalty and could even help. In practice we aren't there yet -- and developers know this.
The purpose of testing is to alert you to places in your code where bugs may reside. Even if you never plan to run your code in strict mode, you should still test in strict mode, since anything that fails in strict mode is likely enough a bug in your code that you should investigate.
You don't need to tell me!
The problems is the added burden and the inevitable failure of real developers to take it on with the same diligence they use on one-mode JS -- which may be less diligence than you would like, but hold that equal! The testing burden has gone up.
I'm describing, not prescribing. Old pre-strict browsers will die off, we'll be in a better place. I like strict mode in general and won't quibble about a few corners here. But the problem isn't my opinion of it or yours. The problem is that strict mode has meant more to go wrong, more to test, and some performance faults.
Now, on the specific JSC bug you cite, bugs.webkit.org/show_bug.cgi?id=27226. This is actually from 2009, filed based on a misunderstanding of ES3 and not on any real-world web content, and finally marked invalid in February. It is old news. The comments from February do not prove that "[t]he 1JS experiment has failed".
I was unaware of the history, thanks. I withdraw that bullet point. I acknowledge that my case is substantially weaker without it.
Ok, thanks.
And JSC design decisions are not authoritative over TC39 as a whole -- rather, the reverse!.
We all know that this issue isn't so unidirectional. If TC39 mandates something and the browser makers decide to do something else, we all have a problem. The pressure to avoid these problems cuts both ways.
And how! We've already heard some feedback on temporal dead zones from one TC39 implementor-rep at the September meeting. I never said implementor feedback doesn't count, though. Only that the authority-arrow runs the other way from what your bullet point suggested.
It's pure mischief for implementors to "vote" outside of TC39 by making random deviations from draft-ES6 on purpose and then asserting precedent or authority.
I know you didn't endorse that but your citing this bug under the inflammatory subject was going in that direction.
Anyway, we can certainly make function-in-block ES6 semantics require "use strict" opt-in, but that will both diminish the use-frequency of function-in-block with sane and standard semantics,
Since only strict mode provides sane and standard semantics anyway... ;)
and as Andy Wingo pointed out in the JSC bug, confuse users with two semantics for the same syntax.
We've already got that. To avoid confusion, "use strict".
That's a prospective, prescriptive, pedagogical approach. It will help over time, but right now, not so much. Real developers face real code, most of it non-strict. They can't always afford to make it all strict. They therefore face the confusing schism in function-in-block semantics that Andy cited.
As an aside, ES itself can't self-host its own builtins in strict mode because of the (two of the very few) semantic differences that exist between strict mode and non-strict mode: non-strict thrower properties (which I've come to consider an annoying blight that punishes developers in order to influence implementers) and strict this-mode differences. Every semantic difference you mandate furthers this gap.
Er I meant ThrowTypeError.
As an aside, ES itself can't self-host its own builtins in strict mode because of the (two of the very few) semantic differences that exist between strict mode and non-strict mode: non-strict thrower properties (which I've come to consider an annoying blight that punishes developers in order to influence implementers) and strict this-mode differences. Every semantic difference you mandate furthers this gap.
I understand that throwing exceptions (that wouldn’t be thrown in sloppy mode) is a problem. But why is this? How would this not pointing to the global object inside a strict-mode builtin be observable to the outside?
Le 27/12/2012 02:52, Brandon Benvie a écrit :
As an aside, ES itself can't self-host its own builtins in strict mode because of the (two of the very few) semantic differences that exist between strict mode and non-strict mode: non-strict thrower properties (which I've come to consider an annoying blight that punishes developers in order to influence implementers) and strict this-mode differences. Every semantic difference you mandate furthers this gap.
I fail to understand why built-ins can't be implemented in strict mode. Can you provide a concrete example of something that can't?
Thanks,
I ave to recant on this after having doing some research (and actually
making it work). The original reason about ThisMode may still be true but
I'm less sure. It was basically about being unable to identify the correct
global this in strict mode since its not automatically provided for you,
and multiple global is now a common thing in es6, but I don't think this
ended up gmpering anything in actual usage.
The other reason was because of ThrowTypeError, which requires a.) adding multiple accessor own properties to every function object, and b.) modified GetOwnProperty semantics. Upon inspection, I couldn't actually find anything in the spec that prohibits builtin functions from having those ThrowTypeError accessors like I had originally supposed there was. In my implementation I cheat and use magic to remove them even though the functions are compiled as strict (they're in implicit module bodies) but I now realize that's not necessary, at least to be spec compliant.
To elaborate on the ThisMode scenario, take the following example (also available at gist.github.com/4401538):
var value = 10;
module X {
// implicit "use strict"
var value = 20;
export class Builtin {
constructor(){
if (this == null) {
// what global am I?
}
}
method(){
if (this == null) {
// what global am I?
return value;
}
}
}
}
module Y {
// implicit "use strict"
var value = 30;
var global = this;
var x = new X.Builtin;
export function getValue(){
return x.method.call(null);
}
}
console.log(Y.getValue());
I'm fairly sure in a userland code scenario the result should be 20. My
concern was whether any code in the ES6 stdlib is this sensitive in such
a way that either value should be either 10 or 30. I haven't identified
any in which it should be, but I'm not confident none such example exists.
thanks for accumulating this data!
Between
For both "function" and "let", when we first discussed trying to retrofit sense into ES6 non-strict mode, we knew that this was speculative, because non-strict mode cannot include web-breaking incompatible changes. This experiment has failed, so we should now return to plan A. Any ES6 features that don't fit into non-strict mode without contortion, including "let" and nested "function", should be available only in strict mode. For new function syntax, if shoe-horning it into non-strict mode requires micro-modes as previously discussed, then we shouldn't. Whatever the complaints about living with one mode distinction, we're certainly not addressing these complaints by introducing more mode distinctions.
Hi Brian, thanks for accumulating this data! Between * this data, * Apple's decision as recorded at <https://bugs.webkit.org/show_bug.cgi?id=27226#c4>, * the new function syntax micro-modes, * and the "let" issues already discussed, I reiterate that we should stop trying to twist the language to somehow shoehorn ES6 features into non-strict mode. For both "function" and "let", when we first discussed trying to retrofit sense into ES6 non-strict mode, we knew that this was speculative, because non-strict mode cannot include web-breaking incompatible changes. This experiment has failed, so we should now return to plan A. Any ES6 features that don't fit into non-strict mode without contortion, including "let" and nested "function", should be available only in strict mode. For new function syntax, if shoe-horning it into non-strict mode requires micro-modes as previously discussed, then we shouldn't. Whatever the complaints about living with one mode distinction, we're certainly not addressing these complaints by introducing more mode distinctions. On Wed, Dec 26, 2012 at 1:04 PM, Brian Terlson <Brian.Terlson at microsoft.com> wrote: > I have some data on patterns and sites that may break due to the proposed > change to semantics of function decls in block scope. I am not advocating > for any changes here but merely dumping some data I’ve gathered. I will > continue gathering data about this breaking change and potentially others > (eg. let[x] = 1), so any further data you folks are interested in let me > know. I think the January meeting would be a good venue to discuss any of > this in detail if warranted. > > On December 17th, 2235 sites were crawled and their scripts downloaded. > These scripts were then processed in an attempt to identify likely breakages > due to the change to the semantics of func decls in block scope. In this > dataset, 4% of the scripts contained a function declaration in block scope > (mostly inside if and try, although pretty much every node contains a > function somewhere in this dataset). However, most of these scripts use the > function within the same block and so won’t be broken. 20 sites, however, > will likely be broken by this change in some way. There is also a chance > that the tool used to identify breakages has missed some code that will > breka. > > > > Below are some examples of code on the web today that will be broken. For > each I include a snippet of code that is heavily edited in an attempt to > convey the pattern used and the developer intent. I also attempt to identify > what functionality will actually be broken. > > > > Most of the breakages occur in non-library code, with two exceptions: qTip > 1.0, and thickbox 3. > > > > # http://ninemsn.com.au > > > > RenderModal = function () { > > if (x) { // is an array of shortcuts that can be added. Is statically > non-empty. > > function K() { > > // process the array of shortcuts in some way > > } > > } > > K(); > > }; > > > > ## Scenario > > > > 1. Navigate to main page. > > 2. Click “Add other shortcuts” > > 3. Click “View more shortcuts” – this will not work. > > > > > > # http://yandex.ru > > > > if (_ycssjs("BaH0Fmmo2Sg24lRmTPrK0B8qpaA")) { > > function cp(g, c, d) { /* ...*/ } > > > > function csh_ifgsid(c, b) { /*...*/ } } > > > > // ... thousands of lines of code ... > > > > > > if (_ycssjs("rO+QIoSf2L0NwDn6vjJjy+27nxI")) { > > function news() { > > csh_if_gsid(); > > } > > } > > > > if (_ycssjs("YRPF0QVjJmhRiKRu6cvi3YXqYo8")) { > > // ... bunch of stuff ... > > cp(); > > } > > > > ## Scenario > > > > Unknown > > > > > > # http://g.espncdn.com/nfl-primetime-payoff/en/module/entry?matchupid=478 > > > > if (isIE && isWin) { > > // ... > > } else { > > function JSGetSwfVer(i){ > > // ... > > } > > } > > > > function checkFlash(myRev) { > > // ... > > > > if (isIE && isWin) { > > // ... > > } else { > > aV = JSGetSwfVer(rV); > > } > > > > } > > > > ## Scenario > > > > Can’t find a page which uses this code. > > > > > > # http://www.t-online.de > > > > if (!Adition_Environment) { > > var Adition_Environment = (function () { > > var _this = {}; > > // ... > > _this.getPrf = function (cuId) { > > var prf = ""; > > try { > > prf = Adition_Prfstr(cuId); > > } catch (e) { } > > return prf; > > }; > > // ... > > })(); > > } > > > > // snip 1k lines > > if (typeof Adition_Prfstr == "undefined") { > > function Adition_Prfstr(ADITION_CONTENTUNIT_ID) { > > // ... > > } > > } > > > > ## Scenario > > > > Required to display advertisements on the page. > > > > > > > > # http://manormystery.com > > > > if (!window._ate) { > > window._ate = { /* ... */ }; > > function addthis_open() { /* ... */ } } else { _ate.inst++; } > > > > if (_atc.abf) { > > addthis_open(document.getElementById("ab"), "emailab", > window.addthis_url || "[URL]", window.addthis_title || "[TITLE]"); } > > > > ## Scenario > > > > Social sharing popups broken at least. This may be a general utility used in > a number of places. > > > > > > > > # http://manhunt.net (NSFW, DO NOT VISIT AT WORK) > > > > /** @todo isFlashInstalled() should probably be gotten by include from > js/cmmn/flashDetect.js or upfunc.js. */ > > > > if (typeof isFlashInstalled == 'undefined') { > > function isFlashInstalled() { > > var requiredMajorVersion = 6; // Major version of Flash required > > var requiredMinorVersion = 0; // Minor version of Flash required > > var requiredRevision = 0; // Minor version of Flash required > > var s = new SWFObject(); > > if (!s) return false; > > var version = s.installedVer; > > if (!version) return false; > > return (version.major >= requiredMajorVersion && version.minor >= > requiredMinorVersion && version.rev >= requiredRevision); > > } > > } > > isFlashInstalled(); > > > > ## Scenario > > > > I avoided this site at work for obvious reasons, but it looks like all login > functionality will be broken. > > > > > > > > > > # http://www.163.com > > > > NTESAD_Couplet.prototype = { > > NTESCreate: function () { > > > > var widthsmall = this.options.widthsmall; > > var width = this.options.width; > > > > if (this.options.leftbig != "" && this.options.leftsmall != "") { > > function bighide() { > > coupletLeft.style.display = "none"; > > coupletLeftsmall.style.display = "block"; > > } > > > > function smallhide() { > > coupletLeftsmall.style.display = "none"; > > coupletLeft.style.display = "block"; > > } > > } > > > > if (this.options.rightbig != "" && this.options.rightsmall != "") { > > function Rbighide() { > > coupletRight.style.display = "none"; > > coupletRightsmall.style.display = "block"; > > } > > } > > > > if (this.NTESPosition()) { > > if (this.options.leftbig != "" && this.options.leftsmall != "" > && this.options.rightbig != "" && this.options.rightsmall != "") { > > this.NTESBind(coupletclose, "click", function () { > bighide(); Rbighide(); coupletRightsmall.style.display = "none"; > coupletLeftsmall.style.display = "none"; }); > > this.NTESBind(coupletclose2, "click", function () { > bighide(); Rbighide(); coupletRightsmall.style.display = "none"; > coupletLeftsmall.style.display = "none"; }); > > } > > } > > } > > } > > > > ## Scenario > > > > Unknown. > > > > > > > > # http://www22.verizon.com > > > > if (floatStyle.match(/Content/)) { > > var contentDiv = d.getElementById(_b.Preferences.Render.main_content_id > || "content"); > > if (contentDiv == null) { > > floatStyle = this.Preferences.Render.float_style = 'fixed' > > } > > function getRightOfContent() { > > return contentDiv.offsetWidth + contentDiv.offsetLeft + 1 > > } > > function fixBackground() { > > if (_b.Preferences.Render.fix_background) { > > db.style.backgroundAttachment = "scroll"; > > var margin = null; > > if (document.defaultView && > document.defaultView.getComputedStyle) { > > margin = > parseInt(document.defaultView.getComputedStyle(contentDiv, > null).getPropertyValue("margin-left"), 10) > > } else { > > margin = parseInt(contentDiv.currentStyle.marginLeft, 10) > > } > > if (isNaN(margin) || margin == 0) { > > margin = contentDiv.offsetLeft || 0 > > } > > db.style.backgroundPosition = (Math.floor(contentDiv.scrollWidth > * -0.5) - 2 + margin) + 'px 0' > > } > > } > > } > > > > // getRightOfContent/fixBackground used repeatedly after this. > > > > ## Scenario > > > > Couldn’t find a scenario where this code was hit, but the site is expansive. > Also, the above code is found in at least 2 different scripts across the > site. > > > > > > > > > > # http://www.jeuxvideo.com > > > > if (typeof getAppNexusMegaTag == 'undefined' || typeof getAppNexusMegaTag != > 'function') { > > function getSize1080667() { > > return '250x250'; > > } > > } > > > > if (typeof inFIF != "undefined" && inFIF == true) { > > try { > > parent.getSize1080667 = getSize1080667; > > } catch (e) { } > > } > > > > > > ## Scenario > > Ad won’t display. > > > > > > > > # http://msn.foxsports.com > > /* this function is much faster, so if possible we use it. Some IEs are the > only ones I know of that need the idiotic second function, generated by an > if clause. */ function add32(a, b) { > > return (a + b) & 0xFFFFFFFF; > > } > > > > if (md5('hello') != '5d41402abc4b2a76b9719d911017c592') { > > function add32(x, y) { > > var lsw = (x & 0xFFFF) + (y & 0xFFFF), > > msw = (x >> 16) + (y >> 16) + (lsw >> 16); > > return (msw << 16) | (lsw & 0xFFFF); > > } > > } > > > > ## Scenario > > > > Nothing is necessary broken about this, as long as the first add32 functions > properly (today everyone with this code is using the second function). This > is a fairly common MD5 library (do a search for “idiotic second function” to > get an idea, however this was only found once in the dataset). > > > > > > > > > > > > # http://iwiw.hu/i/belepes > > > > (function () { > > if (jQuery.fn.lazyload) { > > function a() { > > return typeof f !== "undefined" ? f : (f = > jQuery("body").hasClass("lazyloadimages")) > > } > > } > > jQuery(function () { > > if (a()) { > > d.apply(document.body) > > } > > }) > > })(); > > > > ## Scenario > > > > Unknown > > > > > > > > > > # http://www.laposte.net > > > > if (!window.$extend) { > > function $extend(c, a) { > > for (var b in (a || {})) { > > c[b] = a[b] > > } return c > > } > > } > > // $extend used repeatedly after this > > > > ## Scenario > > Unknown > > > > > > > > # http://atpworldtour.com > > > > /* > > * Stores hash values for localization. > > * Will need duplicating for each language. > > */ > > > > if (typeof registerNS == "undefined") { > > function registerNS(ns) { > > var nsParts = ns.split("."); > > var root = window; > > for (var i = 0; i < nsParts.length; i++) { > > if (typeof root[nsParts[i]] == "undefined") > > root[nsParts[i]] = new Object(); > > root = root[nsParts[i]]; > > } > > } > > } > > > > registerNS("atp.utilities"); > > // called repeatedly after this. > > > > ## Scenario > > > > Entire site is unusable. > > > > > > > > > > # http://atwiki.jp > > > > if (typeof AddClipsFlag == "undefined") { > > var AddClipsFlag = 'addclips'; > > // ... > > function AddClipsLoad() { /* ... */ } > > // ... > > } > > > > AddClipsLoad(); > > > > ## Scenario > > > > RSS functionality broken. This appears to be a library of some kind (see > www.addclips.org). > > > > > > > > # Library: qTip 1.0: > https://github.com/Craga89/qTip1/blob/master/1.0.0-rc3/jquery.qtip-1.0.0-rc3.js > as seen on Zoompanel.com > > > > if (t.options.hide.when.event == "inactive") { > > function y(z) { > > > > } > > } else { > > // ... > > } > > function x(z) { > > if (t.options.hide.when.event == "inactive") { > > y() > > } > > } > > > > ## Scenario > > > > Used on zoompanel.com. Tooltips will never disappear after showing up. > > > > > > # Library: thickbox 3 (http://thickbox.net/), in use on runescape.com and > baixaki.com.br if (!(TB_PrevHTML === "")) { > > function goPrev(){ > > } > > $("#TB_prev").click(goPrev); > > } > > > > if (!(TB_NextHTML === "")) { > > function goNext(){ > > } > > $("#TB_next").click(goNext); > > > > } > > > > document.onkeydown = function (e) { > > if (keycode == 190) { // display previous image > > if (!(TB_NextHTML == "")) { > > document.onkeydown = ""; > > goNext(); > > } > > } else if (keycode == 188) { // display next image > > if (!(TB_PrevHTML == "")) { > > document.onkeydown = ""; > > goPrev(); > > } > > } > > } > > > > ## Scenario > > > > Going back/forward with keyboard is broken. > > > > > > > > > > # http://kankan.com > > Snippet > > if (typeof getCookie == 'undefined') { > > function getCookie(name) { > > > > } > > } > > > > // ... > > > > if (getCookie('tpar')) { > > var irStartTime = new Date().getTime(); > > window.attachEvent('onunload', irTimeStat); } > > > > ## Scenario > > Unknown, possibly just for tracking purposes. > > > > > > # Google +1 library (only seen on TMZ.com, possibly this lib is out of date) > try { > > function h(a) { > > throw a; > > } > > // plus a ton of other decls > > } catch (e) { } > > > > try { > > h(Error("foo")); > > // plus a ton of calls to other block scoped functions } catch (e) { } > > > > ## Scenario > > > > Plus one button is broken. > > > > > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -- Cheers, --MarkM