r61499 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r61498‎ | r61499 | r61500 >
Date:20:13, 25 January 2010
Author:tparscal
Status:ok
Tags:
Comment:
Moved the JS for event binding within the iframe to the outter frame, since the iframe's scripts get run on the first load, so for IE which needs them to be run on second load (designMode = on causes body to be dumped and reloaded) the bindings weren't surviving. This also simplifies things, and we no longer need the inherit plugin at all.
Modified paths:
  • /trunk/extensions/UsabilityInitiative/Makefile (modified) (history)
  • /trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins.combined.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins.combined.min.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins/jquery.inherit.js (deleted) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.html (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.js (modified) (history)

Diff [purge]

Index: trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php
@@ -123,11 +123,6 @@
124124 'version' => 1
125125 ),
126126 array(
127 - 'src' => 'js/plugins/jquery.inherit.js',
128 - 'class' => 'inherit',
129 - 'version' => 3
130 - ),
131 - array(
132127 'src' => 'js/plugins/jquery.namespaceSelect.js',
133128 'class' => 'j.fn.namespaceSelector',
134129 'version' => 1
@@ -140,7 +135,7 @@
141136 array(
142137 'src' => 'js/plugins/jquery.wikiEditor.js',
143138 'class' => 'j.wikiEditor',
144 - 'version' => 64
 139+ 'version' => 65
145140 ),
146141 array(
147142 'src' => 'js/plugins/jquery.wikiEditor.highlight.js',
@@ -178,10 +173,10 @@
179174 'version' => 1 ),
180175 ),
181176 'combined' => array(
182 - array( 'src' => 'js/plugins.combined.js', 'version' => 171 ),
 177+ array( 'src' => 'js/plugins.combined.js', 'version' => 172 ),
183178 ),
184179 'minified' => array(
185 - array( 'src' => 'js/plugins.combined.min.js', 'version' => 171 ),
 180+ array( 'src' => 'js/plugins.combined.min.js', 'version' => 172 ),
186181 ),
187182 ),
188183 );
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.inherit.js
@@ -1,120 +0,0 @@
2 -/*!
3 - * jQuery iFrame Inheritance
4 - *
5 - * Copyright (c) 2009 Eric Garside (http://eric.garside.name)
6 - * Dual licensed under:
7 - * MIT: http://www.opensource.org/licenses/mit-license.php
8 - * GPLv3: http://www.opensource.org/licenses/gpl-3.0.html
9 - */
10 -( function( $ ) {
11 -
12 -// Create a function in the Global Namespace so we can access it from the iFrame by calling parent.inherit()
13 -this.inherit = function( child ) {
14 - // First, bind a copy of jQuery down into the DOM of the iFrame, so we can hook in functionality. Things may get a
15 - // bit confusing here, as we're creating this function in the parent, but have to set it up internally to get called
16 - // as if it were in the child.
17 - child.jQueryInherit = this.parent.jQuery;
18 - // Bind a special ready callback binding function, to handle the scope of responding to the document.ready hook
19 - // instead of the parent's document.ready
20 - child.jQueryInherit.fn.ready = function( fn ) {
21 - // Attach the listeners
22 - child.jQueryInherit.hooks.bindReady();
23 - // If the DOM is already ready
24 - if ( child.jQueryInherit.hooks.isReady ) {
25 - // Simply trigger the callback
26 - fn.call( child.document, child.jQueryInherit );
27 - } else {
28 - // Otherwise, remember it so we can trigger it later
29 - child.jQueryInherit.hooks.readyList.push( fn );
30 - }
31 - return this;
32 - };
33 - // Create a namespace for hooking some functionality to the iFrame, like document.ready detection and handling
34 - var hooks = child.jQueryInherit.hooks = {
35 - isReady: false,
36 - readyBound: false,
37 - readyList: [],
38 - // Mimic the readyBind() function in the child, so it can set up the listeners for document.ready
39 - bindReady: function() {
40 - if ( hooks.readyBound ) {
41 - return;
42 - }
43 - hooks.readyBound = true;
44 - // Mozilla, Opera, and webkit nightlies support
45 - if ( child.document.addEventListener ) {
46 - child.document.addEventListener(
47 - "DOMContentLoaded",
48 - function() {
49 - child.document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
50 - hooks.ready();
51 - },
52 - false
53 - );
54 - }
55 - // For IE
56 - else if ( child.document.attachEvent ) {
57 - // Ensure firing before onload, maybe late but safe also for iframes
58 - child.document.attachEvent(
59 - "onreadystatechange",
60 - function(){
61 - if ( child.document.readyState === "complete" ) {
62 - child.document.detachEvent( "onreadystatechange", arguments.callee );
63 - hooks.ready();
64 - }
65 - }
66 - );
67 - // If IE and not an iframe continually check to see if the document is ready
68 - if ( child.document.documentElement.doScroll && child == child.top ) {
69 - if ( !hooks.isReady ) {
70 - try {
71 - // If IE is used, use the trick by Diego Perini http://javascript.nwbox.com/IEContentLoaded/
72 - child.document.documentElement.doScroll( "left" );
73 - } catch ( error ) {
74 - setTimeout( arguments.callee, 0 );
75 - return;
76 - }
77 - // And execute any waiting functions
78 - hooks.ready();
79 - }
80 - }
81 - }
82 - // A fallback to window.onload, that will always work
83 - jQuery.event.add( child, "load", hooks.ready );
84 - },
85 - // Hook the ready trigger to fire off the hook bindings
86 - ready: function() {
87 - // Make sure the DOM is not already loaded
88 - if ( !hooks.isReady ) {
89 - // Remember that the DOM is ready
90 - hooks.isReady = true;
91 - // If there are functions bound...
92 - if ( hooks.readyList ) {
93 - // Execute them all
94 - jQuery.each( hooks.readyList, function() {
95 - this.call( child.document, child.jQueryInherit );
96 - } );
97 - // Reset the list of functions
98 - hooks.readyList = null;
99 - }
100 - // Trigger any bound ready events
101 - jQuery( child.document ).triggerHandler( 'ready' );
102 - }
103 - }
104 - };
105 - return child.jQuery = child.$j = function( selector, context ) {
106 - // Test and see if we're handling a shortcut bind for the document.ready function. This occurs when the selector
107 - // is a function. Because firefox throws xpconnect objects around in iFrames, the standard
108 - // jQuery.isFunction test returns false negatives.
109 - // PATCHED: Disable this check because it breaks subtly on IE7 and we don't use $j( function() { ... } ) anyway
110 - if ( false && selector.constructor.toString().match( /Function/ ) != null ) {
111 - return child.jQueryInherit.fn.ready( selector );
112 - }
113 - // Otherwise, just let the jQuery init function handle the rest. Be sure we pass in proper context of the
114 - // child document, or we'll never select anything useful.
115 - else {
116 - return child.jQueryInherit.fn.init( selector || this.document, context || this.document );
117 - }
118 - };
119 -}
120 -
121 -} )( jQuery );
\ No newline at end of file
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.html
@@ -84,24 +84,6 @@
8585 /*font-weight: bold; -- not sure about this styling just yet */
8686 }
8787 </style>
88 - <script type="text/javascript">
89 - parent.inherit( window )( function() {
90 - function get( name ) {
91 - // Extracts the value of a given URL parameter from the current window location
92 - var v = ( new RegExp( '[\\?&]' + name.replace( /\[|\]/g, '\\\$1' ) + '=([^&#]*)' ) )
93 - .exec( window.location.href );
94 - return v == null ? '' : v[1];
95 - }
96 - var context = window.parent.jQuery.wikiEditor.instances[get( 'instance' )].data( 'wikiEditor-context' );
97 - $j( document )
98 - .bind( 'keyup mouseup paste cut encapsulateSelection', function( event ) {
99 - context.fn.trigger( 'change', event );
100 - } )
101 - .delayedBind( 250, 'keyup mouseup paste cut encapsulateSelection', function( event ) {
102 - context.fn.trigger( 'delayedChange', event );
103 - } );
104 - } );
105 - </script>
10688 </head>
10789 <body></body>
10890 </html>
\ No newline at end of file
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.js
@@ -901,6 +901,14 @@
902902 context.$iframe.show();
903903 // Let modules know we're ready to start working with the content
904904 context.fn.trigger( 'ready' );
 905+ // Setup event handling on the iframe
 906+ context.$content
 907+ .bind( 'keyup mouseup paste cut encapsulateSelection', function( event ) {
 908+ context.fn.trigger( 'change', event );
 909+ } )
 910+ .delayedBind( 250, 'keyup mouseup paste cut encapsulateSelection', function( event ) {
 911+ context.fn.trigger( 'delayedChange', event );
 912+ } );
905913 } );
906914 // Attach a submit handler to the form so that when the form is submitted the content of the iframe gets decoded and
907915 // copied over to the textarea
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.js
@@ -5545,126 +5545,7 @@
55465546 }
55475547 } );
55485548 } )( jQuery );
5549 -/*!
5550 - * jQuery iFrame Inheritance
5551 - *
5552 - * Copyright (c) 2009 Eric Garside (http://eric.garside.name)
5553 - * Dual licensed under:
5554 - * MIT: http://www.opensource.org/licenses/mit-license.php
5555 - * GPLv3: http://www.opensource.org/licenses/gpl-3.0.html
5556 - */
5557 -( function( $ ) {
5558 -
5559 -// Create a function in the Global Namespace so we can access it from the iFrame by calling parent.inherit()
5560 -this.inherit = function( child ) {
5561 - // First, bind a copy of jQuery down into the DOM of the iFrame, so we can hook in functionality. Things may get a
5562 - // bit confusing here, as we're creating this function in the parent, but have to set it up internally to get called
5563 - // as if it were in the child.
5564 - child.jQueryInherit = this.parent.jQuery;
5565 - // Bind a special ready callback binding function, to handle the scope of responding to the document.ready hook
5566 - // instead of the parent's document.ready
5567 - child.jQueryInherit.fn.ready = function( fn ) {
5568 - // Attach the listeners
5569 - child.jQueryInherit.hooks.bindReady();
5570 - // If the DOM is already ready
5571 - if ( child.jQueryInherit.hooks.isReady ) {
5572 - // Simply trigger the callback
5573 - fn.call( child.document, child.jQueryInherit );
5574 - } else {
5575 - // Otherwise, remember it so we can trigger it later
5576 - child.jQueryInherit.hooks.readyList.push( fn );
5577 - }
5578 - return this;
5579 - };
5580 - // Create a namespace for hooking some functionality to the iFrame, like document.ready detection and handling
5581 - var hooks = child.jQueryInherit.hooks = {
5582 - isReady: false,
5583 - readyBound: false,
5584 - readyList: [],
5585 - // Mimic the readyBind() function in the child, so it can set up the listeners for document.ready
5586 - bindReady: function() {
5587 - if ( hooks.readyBound ) {
5588 - return;
5589 - }
5590 - hooks.readyBound = true;
5591 - // Mozilla, Opera, and webkit nightlies support
5592 - if ( child.document.addEventListener ) {
5593 - child.document.addEventListener(
5594 - "DOMContentLoaded",
5595 - function() {
5596 - child.document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
5597 - hooks.ready();
5598 - },
5599 - false
5600 - );
5601 - }
5602 - // For IE
5603 - else if ( child.document.attachEvent ) {
5604 - // Ensure firing before onload, maybe late but safe also for iframes
5605 - child.document.attachEvent(
5606 - "onreadystatechange",
5607 - function(){
5608 - if ( child.document.readyState === "complete" ) {
5609 - child.document.detachEvent( "onreadystatechange", arguments.callee );
5610 - hooks.ready();
5611 - }
5612 - }
5613 - );
5614 - // If IE and not an iframe continually check to see if the document is ready
5615 - if ( child.document.documentElement.doScroll && child == child.top ) {
5616 - if ( !hooks.isReady ) {
5617 - try {
5618 - // If IE is used, use the trick by Diego Perini http://javascript.nwbox.com/IEContentLoaded/
5619 - child.document.documentElement.doScroll( "left" );
5620 - } catch ( error ) {
5621 - setTimeout( arguments.callee, 0 );
5622 - return;
5623 - }
5624 - // And execute any waiting functions
5625 - hooks.ready();
5626 - }
5627 - }
5628 - }
5629 - // A fallback to window.onload, that will always work
5630 - jQuery.event.add( child, "load", hooks.ready );
5631 - },
5632 - // Hook the ready trigger to fire off the hook bindings
5633 - ready: function() {
5634 - // Make sure the DOM is not already loaded
5635 - if ( !hooks.isReady ) {
5636 - // Remember that the DOM is ready
5637 - hooks.isReady = true;
5638 - // If there are functions bound...
5639 - if ( hooks.readyList ) {
5640 - // Execute them all
5641 - jQuery.each( hooks.readyList, function() {
5642 - this.call( child.document, child.jQueryInherit );
5643 - } );
5644 - // Reset the list of functions
5645 - hooks.readyList = null;
5646 - }
5647 - // Trigger any bound ready events
5648 - jQuery( child.document ).triggerHandler( 'ready' );
5649 - }
5650 - }
5651 - };
5652 - return child.jQuery = child.$j = function( selector, context ) {
5653 - // Test and see if we're handling a shortcut bind for the document.ready function. This occurs when the selector
5654 - // is a function. Because firefox throws xpconnect objects around in iFrames, the standard
5655 - // jQuery.isFunction test returns false negatives.
5656 - // PATCHED: Disable this check because it breaks subtly on IE7 and we don't use $j( function() { ... } ) anyway
5657 - if ( false && selector.constructor.toString().match( /Function/ ) != null ) {
5658 - return child.jQueryInherit.fn.ready( selector );
5659 - }
5660 - // Otherwise, just let the jQuery init function handle the rest. Be sure we pass in proper context of the
5661 - // child document, or we'll never select anything useful.
5662 - else {
5663 - return child.jQueryInherit.fn.init( selector || this.document, context || this.document );
5664 - }
5665 - };
5666 -}
5667 -
5668 -} )( jQuery );/**
 5549+/**
56695550 * Plugin that fills a <select> with namespaces
56705551 */
56715552
@@ -7382,6 +7263,14 @@
73837264 context.$iframe.show();
73847265 // Let modules know we're ready to start working with the content
73857266 context.fn.trigger( 'ready' );
 7267+ // Setup event handling on the iframe
 7268+ context.$content
 7269+ .bind( 'keyup mouseup paste cut encapsulateSelection', function( event ) {
 7270+ context.fn.trigger( 'change', event );
 7271+ } )
 7272+ .delayedBind( 250, 'keyup mouseup paste cut encapsulateSelection', function( event ) {
 7273+ context.fn.trigger( 'delayedChange', event );
 7274+ } );
73867275 } );
73877276 // Attach a submit handler to the form so that when the form is submitted the content of the iframe gets decoded and
73887277 // copied over to the textarea
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.min.js
@@ -372,14 +372,7 @@
373373 $.fn.extend({delayedBind:function(timeout,event,data,callback){var encEvent=encodeEvent(event);return this.each(function(){var that=this;if(!($(this).data('_delayedBindBound-'+encEvent+'-'+timeout))){$(this).data('_delayedBindBound-'+encEvent+'-'+timeout,true);$(this).bind(event,function(){var timerID=$(this).data('_delayedBindTimerID-'+encEvent+'-'+timeout);if(typeof timerID!='undefined')
374374 clearTimeout(timerID);timerID=setTimeout(function(){$(that).trigger('_delayedBind-'+encEvent+'-'+timeout);},timeout);$(this).data('_delayedBindTimerID-'+encEvent+'-'+timeout,timerID);});}
375375 $(this).bind('_delayedBind-'+encEvent+'-'+timeout,data,callback);});},delayedBindCancel:function(timeout,event){var encEvent=encodeEvent(event);return this.each(function(){var timerID=$(this).data('_delayedBindTimerID-'+encEvent+'-'+timeout);if(typeof timerID!='undefined')
376 -clearTimeout(timerID);});},delayedBindUnbind:function(timeout,event,callback){var encEvent=encodeEvent(event);return this.each(function(){$(this).unbind('_delayedBind-'+encEvent+'-'+timeout,callback);});}});})(jQuery);(function($){this.inherit=function(child){child.jQueryInherit=this.parent.jQuery;child.jQueryInherit.fn.ready=function(fn){child.jQueryInherit.hooks.bindReady();if(child.jQueryInherit.hooks.isReady){fn.call(child.document,child.jQueryInherit);}else{child.jQueryInherit.hooks.readyList.push(fn);}
377 -return this;};var hooks=child.jQueryInherit.hooks={isReady:false,readyBound:false,readyList:[],bindReady:function(){if(hooks.readyBound){return;}
378 -hooks.readyBound=true;if(child.document.addEventListener){child.document.addEventListener("DOMContentLoaded",function(){child.document.removeEventListener("DOMContentLoaded",arguments.callee,false);hooks.ready();},false);}
379 -else if(child.document.attachEvent){child.document.attachEvent("onreadystatechange",function(){if(child.document.readyState==="complete"){child.document.detachEvent("onreadystatechange",arguments.callee);hooks.ready();}});if(child.document.documentElement.doScroll&&child==child.top){if(!hooks.isReady){try{child.document.documentElement.doScroll("left");}catch(error){setTimeout(arguments.callee,0);return;}
380 -hooks.ready();}}}
381 -jQuery.event.add(child,"load",hooks.ready);},ready:function(){if(!hooks.isReady){hooks.isReady=true;if(hooks.readyList){jQuery.each(hooks.readyList,function(){this.call(child.document,child.jQueryInherit);});hooks.readyList=null;}
382 -jQuery(child.document).triggerHandler('ready');}}};return child.jQuery=child.$j=function(selector,context){if(false&&selector.constructor.toString().match(/Function/)!=null){return child.jQueryInherit.fn.ready(selector);}
383 -else{return child.jQueryInherit.fn.init(selector||this.document,context||this.document);}};}})(jQuery);(function($){$.fn.namespaceSelector=function(defaultNS){if(typeof defaultNS=='undefined')
 376+clearTimeout(timerID);});},delayedBindUnbind:function(timeout,event,callback){var encEvent=encodeEvent(event);return this.each(function(){$(this).unbind('_delayedBind-'+encEvent+'-'+timeout,callback);});}});})(jQuery);(function($){$.fn.namespaceSelector=function(defaultNS){if(typeof defaultNS=='undefined')
384377 defaultNS=0;return this.each(function(){for(var id in wgFormattedNamespaces){var opt=$('<option />').attr('value',id).text(wgFormattedNamespaces[id]);if(id==defaultNS)
385378 opt.attr('selected','selected');opt.appendTo($(this));}});};})(jQuery);(function($){$.suggestions={cancel:function(context){if(context.data.timerID!=null){clearTimeout(context.data.timerID);}
386379 if(typeof context.config.cancel=='function'){context.config.cancel.call(context.data.$textbox);}},restore:function(context){context.data.$textbox.val(context.data.prevText);},update:function(context,delayed){function maybeFetch(){if(context.data.$textbox.val()!==context.data.prevText){context.data.prevText=context.data.$textbox.val();if(typeof context.config.fetch=='function'){context.config.fetch.call(context.data.$textbox,context.data.$textbox.val());}}}
@@ -493,7 +486,7 @@
494487 html=prefix+suffix;}else{html=html.replace(/(^|\n) /g,"$1&nbsp;");}
495488 html=html.replace(/\t/g,'<span class="wikiEditor-tab"></span>');}
496489 context.$content.html(html.replace(/\r?\n/g,'<br />'));if($('body').is('.rtl')){context.$content.addClass('rtl').attr('dir','rtl');}
497 -context.$textarea.attr('disabled',true);context.$textarea.hide();context.$iframe.show();context.fn.trigger('ready');});context.$textarea.closest('form').submit(function(){context.$textarea.attr('disabled',false);context.$textarea.val(context.$textarea.textSelection('getContents'));});}
 490+context.$textarea.attr('disabled',true);context.$textarea.hide();context.$iframe.show();context.fn.trigger('ready');context.$content.bind('keyup mouseup paste cut encapsulateSelection',function(event){context.fn.trigger('change',event);}).delayedBind(250,'keyup mouseup paste cut encapsulateSelection',function(event){context.fn.trigger('delayedChange',event);});});context.$textarea.closest('form').submit(function(){context.$textarea.attr('disabled',false);context.$textarea.val(context.$textarea.textSelection('getContents'));});}
498491 arguments=$.makeArray(arguments);if(arguments.length>0){var call=arguments.shift();if(call in context.api){context.api[call](context,typeof arguments[0]=='undefined'?{}:arguments[0]);}}
499492 return $(this).data('wikiEditor-context',context);};})(jQuery);RegExp.escape=function(s){return s.replace(/([.*+?^${}()|\/\\[\]])/g,'\\$1');};(function($){$.wikiEditor.modules.dialogs={api:{addDialog:function(context,data){$.wikiEditor.modules.dialogs.fn.create(context,data)},openDialog:function(context,module){if(module in $.wikiEditor.modules.dialogs.modules){$('#'+$.wikiEditor.modules.dialogs.modules[module].id).dialog('open');}},closeDialog:function(context,data){if(module in $.wikiEditor.modules.dialogs.modules){$('#'+$.wikiEditor.modules.dialogs.modules[module].id).dialog('close');}}},fn:{create:function(context,config){for(module in config){$.wikiEditor.modules.dialogs.modules[module]=config[module];}
500493 mw.load(['$j.ui','$j.ui.dialog','$j.ui.draggable','$j.ui.resizable'],function(){for(module in $.wikiEditor.modules.dialogs.modules){var module=$.wikiEditor.modules.dialogs.modules[module];if($('#'+module.id).size()==0){var configuration=module.dialog;configuration.bgiframe=true;configuration.autoOpen=false;configuration.modal=true;configuration.title=$.wikiEditor.autoMsg(module,'title');configuration.newButtons={};for(msg in configuration.buttons)
Index: trunk/extensions/UsabilityInitiative/Makefile
@@ -24,7 +24,6 @@
2525 js/plugins/jquery.collapsibleTabs.js\
2626 js/js2stopgap/jquery.cookie.js\
2727 js/plugins/jquery.delayedBind.js\
28 - js/plugins/jquery.inherit.js\
2928 js/plugins/jquery.namespaceSelect.js\
3029 js/plugins/jquery.suggestions.js\
3130 js/js2stopgap/jquery.textSelection.js\

Follow-up revisions

RevisionCommit summaryAuthorDate
r61502UsabilityInitiative:...catrope21:43, 25 January 2010

Status & tagging log