Hey all,
Just a reminder that jQuery will (after almost 4 years of deprecation!) drop $.browser [1] in jQuery 1.9.
Please check your scripts and make sure you are are no longer using "$.browser" (or "jQuery.browser"). After jQuery 1.9 is released, from the next MediaWiki deployment after that $.browser will be undefined and old code trying to access a property of it will throw a TypeError for accessing a property of undefined.
Don't be alarmed, this has been a long time coming. It's been almost 4 years, and by the time this is deployed it will probably have been 4 years.
For those who just realised their script is still using it, or if you read this later to fix someone else's script that just broke (hello future, did the world end in 2012?), I'll briefly describe two migration paths you can take from here:
== Feature detection
In most (if not all) cases of people using $.browser it is because they want different behaviour for browsers that don't support a certain something. Please take a minute to look at the code and find out what it is you are special-casing for that apparently doesn't work in a certain browser.
Research on the internet and look for a way to detect this properly (examples below). Browser detection (instead of feature detection) is not reliable, nor is it very effective. For example, Internet Explorer has changed a lot since IE6. Blindly doing A for IE and B for non-IE isn't very useful anymore as most (if not all) of the new features will work fine in IE8, IE9 or IE10.
The opposite is also true. If you do something cool for Chrome, you're missing other WebKit-based browsers that should get the same awesomeness (Safari, Chromium, iPhone/iPod/iPad, possibly Android, Flock, etc.) these all share the exact same engine that backs Chrome). And what if Firefox and IE also start to support this new awesome feature?
There are many ways to do feature detection. jQuery comes with various detectors built-in in the object "jQuery.support"[2]. This contains for example "support.ajax", "support.opacity" and many more[2]. You can also easily make your own feature detector:
* var supportPlaceholder = 'placeholder ' in document.createElement('input'); * var supportJSON = !!window.JSON; etc.
If you need any help with feature detection, I'd recommend asking in one of the following channels on irc.freenode.net:
* ##javascript (recommended) * #jquery * #wikimedia-dev
== jQuery.client [3]
If you can't figure out how to detect what you really want to switch for, there is an elaborate plugin in MediaWiki that does the same thing that jQuery.browser used to do (and more). This can be used as an alternative migration path. To give an impression:
jQuery.browser
< { chrome: true, version: "22.0.1229.94", webkit: true }
$.client.profile();
< { name: "chrome", layout: "webkit", layoutVersion: 537, platform: "mac", version: "22.0.1229.94", versionBase: "22", versionNumber: 22 }
For example:
if ( $.browser.chrome ) {}
Would become:
++ dependency: jquery.client var profile = $.client.profile();
if ( profile.name === 'chrome ) {}
But:
if ( $.browser.msie ) { // IE doesn't support opacity el.style.filter = 'alpha(opacity=50)'; } else { .. }
Should become:
if ( $.support.opacity ) { el.style.filter = 'alpha(opacity=50)'; } else { .. }
Or better yet, since this is supported by jQuery core for a while now, like this:
$(el).css('opacity', 0.5);
Which will do the right thing for newer browsers and old IE respectively.
-- Krinkle
[1] http://api.jquery.com/jQuery.browser/ [2] http://api.jquery.com/jQuery.support/ [3] https://www.mediawiki.org/wiki/RL/DM#jQuery.client
On 7 November 2012 03:09, Krinkle krinklemail@gmail.com wrote: ..
== Feature detection
In most (if not all) cases of people using $.browser it is because they want different behaviour for browsers that don't support a certain something. Please take a minute to look at the code and find out what it is you are special-casing for that apparently doesn't work in a certain browser.
Research on the internet and look for a way to detect this properly (examples below). Browser detection (instead of feature detection) is not reliable, nor is it very effective. For example, Internet Explorer has changed a lot since IE6. Blindly doing A for IE and B for non-IE isn't very useful anymore as most (if not all) of the new features will work fine in IE8, IE9 or IE10.
The other day I detected that IE don't support deleting <option> elements from inside a <optgroup>. The element is removed from the DOM, but is still visible on the webpage ( Yes, the DOM and the webpage become unsynced: you see elements that don't really exist). I have googled this, and nobody has find this bug (maybe nobody is using <optgroup> in a DHTML way before, or is doing under a closed door, not public. Or people avoid advanced features, to avoid IE bugs ). I can't imagine the pain of the creators of something like Google Docs. And If Google, with all his money and resources, talented workers and influence, can't support IE7 [1], ... What I can do?
I suppose the fix will come close, with a plugin that will add again the feature.
[1] http://googleenterprise.blogspot.com.es/2011/06/our-plans-to-support-modern-...
-- -- ℱin del ℳensaje.
Hi Timo,
2012/11/7 Krinkle krinklemail@gmail.com:
Just a reminder that jQuery will (after almost 4 years of deprecation!) drop $.browser [1] in jQuery 1.9.
Thanks for the reminder: it was still used in the MediaWiki:Commons.js of the French Wikipedia. What frightens me a bit is that I've been unable to find it using the internal MediaWiki search engine; I've had to search by myself.
Best regards,
On 07/11/12 13:09, Krinkle wrote:
In most (if not all) cases of people using $.browser it is because they want different behaviour for browsers that don't support a certain something. Please take a minute to look at the code and find out what it is you are special-casing for that apparently doesn't work in a certain browser.
In OggHandler we used browser detection for several things. It is not affected by this change because it never used jQuery, but I would still be interested to know how such code could possibly be migrated to feature detection.
For example:
if ( this.safari ) { // Detect https://bugs.webkit.org/show_bug.cgi?id=25575 var match = /AppleWebKit/([0-9]+)/.exec( navigator.userAgent ); if ( match && parseInt( match[1] ) < 531 ) { this.safariControlsBug = true; } }
...
if ( !this.safariControlsBug ) { html += ' controls'; }
The issue is that if you use the "controls" attribute in Safari before version 531, it segfaults. Last time I checked, JavaScript didn't have the ability to generate different attributes depending on whether or not its host segfaults.
I can understand the rationale behind removing jQuery.browser: apparently most developers are too stupid to be trusted with it. Maybe the idea is to use per-project reimplementation of jQuery.browser as an intelligence test. The trouble is, I think even the stupidest developers are able to copy and paste.
-- Tim Starling
On Thu, Nov 8, 2012 at 5:17 PM, Tim Starling tstarling@wikimedia.org wrote:
I can understand the rationale behind removing jQuery.browser: apparently most developers are too stupid to be trusted with it. Maybe the idea is to use per-project reimplementation of jQuery.browser as an intelligence test. The trouble is, I think even the stupidest developers are able to copy and paste.
Yes, there are legitimate reasons for using browser detection, in cases where feature detection doesn't work. The Safari segfault is a good example. In fact, VisualEditor uses browser detection to disable itself in browsers with broken contentEditable support, because it's very hard or impossible to feature-detect this. I believe Timo was working on cleaning up a different UA detection plugin somewhere on github and using that for VE's browser detection.
tl;dr: browser detection is evil, you should think twice before using it, but sometimes you have to
Roan
On Nov 9, 2012, at 2:17 AM, Tim Starling tstarling@wikimedia.org wrote:
I can understand the rationale behind removing jQuery.browser: apparently most developers are too stupid to be trusted with it. Maybe the idea is to use per-project reimplementation of jQuery.browser as an intelligence test. The trouble is, I think even the stupidest developers are able to copy and paste.
-- Tim Starling
jQuery will publish a jquery-compat plugin as they always do when removing major features. However I would recommend strongly against using it (at least inside MediaWiki) because:
To use it, you'll have to add it to your dependencies. In which case you might as well keep your editor open for another minute and use jquery.client instead.
And, the old jQuery.browser was pretty basic anyway: https://github.com/jquery/jquery/blob/1.8.3/src/deprecated.js#L12
But if you're working outside MediaWiki and need it is good enough for you, you'd copy and paste those dozen or so lines. Or (after jQuery 1.9 is released) simply load the jquery-compat version on your web page.
-- Krinkle
wikitech-l@lists.wikimedia.org