r61811 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r61810‎ | r61811 | r61812 >
Date:19:18, 1 February 2010
Author:catrope
Status:deferred
Tags:
Comment:
UsabilityInitiative: Rewrite context.highlight.fn.mark()'s handling of removed markers to avoid unnecessary DOM manipulation. Also avoid unnecessary DOM manipulation in TOC's onSkip(), and fix TOC's getAnchor() for <p> wrapping
Modified paths:
  • /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.wikiEditor.highlight.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.toc.js (modified) (history)

Diff [purge]

Index: trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php
@@ -73,19 +73,19 @@
7474 array( 'src' => 'js/plugins/jquery.suggestions.js', 'version' => 7 ),
7575 array( 'src' => 'js/plugins/jquery.textSelection.js', 'version' => 26 ),
7676 array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 92 ),
77 - array( 'src' => 'js/plugins/jquery.wikiEditor.highlight.js', 'version' => 27 ),
 77+ array( 'src' => 'js/plugins/jquery.wikiEditor.highlight.js', 'version' => 29 ),
7878 array( 'src' => 'js/plugins/jquery.wikiEditor.toolbar.js', 'version' => 45 ),
7979 array( 'src' => 'js/plugins/jquery.wikiEditor.dialogs.js', 'version' => 11 ),
80 - array( 'src' => 'js/plugins/jquery.wikiEditor.toc.js', 'version' => 77 ),
 80+ array( 'src' => 'js/plugins/jquery.wikiEditor.toc.js', 'version' => 78 ),
8181 array( 'src' => 'js/plugins/jquery.wikiEditor.preview.js', 'version' => 10 ),
8282 array( 'src' => 'js/plugins/jquery.wikiEditor.templateEditor.js', 'version' => 17 ),
8383 array( 'src' => 'js/plugins/jquery.wikiEditor.publish.js', 'version' => 2 ),
8484 ),
8585 'combined' => array(
86 - array( 'src' => 'js/plugins.combined.js', 'version' => 206 ),
 86+ array( 'src' => 'js/plugins.combined.js', 'version' => 208 ),
8787 ),
8888 'minified' => array(
89 - array( 'src' => 'js/plugins.combined.min.js', 'version' => 206 ),
 89+ array( 'src' => 'js/plugins.combined.min.js', 'version' => 208 ),
9090 ),
9191 ),
9292 );
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.toc.js
@@ -97,14 +97,16 @@
9898 },
9999 onSkip: function( node ) {
100100 var marker = $( node ).data( 'marker' );
101 - $( node )
102 - .removeClass( 'wikiEditor-toc-section-' + $( node ).data( 'section' ) )
103 - .addClass( 'wikiEditor-toc-section-' + marker.index )
104 - .data( 'section', marker.index );
 101+ if ( $( node ).data( 'section' ) != marker.index ) {
 102+ $( node )
 103+ .removeClass( 'wikiEditor-toc-section-' + $( node ).data( 'section' ) )
 104+ .addClass( 'wikiEditor-toc-section-' + marker.index )
 105+ .data( 'section', marker.index );
 106+ }
105107 },
106108 getAnchor: function( ca1, ca2 ) {
107 - return $( ca1.previousSibling ).is( 'div.wikiEditor-toc-header' ) ?
108 - ca1.previousSibling : null;
 109+ return $( ca1.parentNode.previousSibling ).is( 'div.wikiEditor-toc-header' ) ?
 110+ ca1.parentNode.previousSibling : null;
109111 }
110112 } );
111113 hash += tokenArray[i].match[2] + '\n';
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.highlight.js
@@ -165,6 +165,8 @@
166166 context.modules.highlight.markersStr = markersStr;
167167
168168 // Traverse the iframe DOM, inserting markers where they're needed.
 169+ // Store visited markers here so we know which markers should be removed
 170+ var visited = [];
169171 for ( var i = 0; i < markers.length; i++ ) {
170172 // We want to isolate each marker, so we may need to split textNodes
171173 // if a marker starts or ends halfway one.
@@ -291,23 +293,32 @@
292294 }
293295
294296 $( newNode ).data( 'marker', markers[i] )
295 - .addClass( 'wikiEditor-highlight wikiEditor-highlight-tmp' );
 297+ .addClass( 'wikiEditor-highlight' );
 298+ visited[i] = newNode;
296299
297300 // Allow the module adding this marker to manipulate it
298301 markers[i].afterWrap( newNode, markers[i] );
299302 } else {
300 - // Temporarily add a class for bookkeeping purposes
301 - $( anchor )
302 - .addClass( 'wikiEditor-highlight-tmp' )
303 - .data( 'marker', markers[i] );
 303+ visited[i] = anchor;
 304+ // Update the marker object
 305+ $( anchor ).data( 'marker', markers[i] );
304306 markers[i].onSkip( anchor );
305307 }
306308 }
307309 }
308310
309311 // Remove markers that were previously inserted but weren't passed to this function
310 - // TODO: Find a better way to do this that involves less DOM manipulation
311 - context.$content.find( 'div.wikiEditor-highlight:not(.wikiEditor-highlight-tmp)' ).each( function() {
 312+ // This function works because visited[] contains the visited elements in order and find() and each()
 313+ // preserve order
 314+ var j = 0;
 315+ context.$content.find( 'div.wikiEditor-highlight' ).each( function() {
 316+ if ( visited[j] == this ) {
 317+ // This marker is legit, leave it in
 318+ j++;
 319+ return true;
 320+ }
 321+
 322+ // Remove this marker
312323 if ( $(this).data( 'marker' ) && typeof $(this).data( 'marker' ).unwrap == 'function' )
313324 $(this).data( 'marker' ).unwrap( this );
314325 if ( $(this).children().size() > 0 ) {
@@ -316,8 +327,6 @@
317328 $(this).replaceWith( $(this).html() );
318329 }
319330 });
320 - // Remove temporary class
321 - context.$content.find( 'div.wikiEditor-highlight-tmp' ).removeClass( 'wikiEditor-highlight-tmp' );
322331 }
323332 }
324333
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.js
@@ -7886,6 +7886,8 @@
78877887 context.modules.highlight.markersStr = markersStr;
78887888
78897889 // Traverse the iframe DOM, inserting markers where they're needed.
 7890+ // Store visited markers here so we know which markers should be removed
 7891+ var visited = [];
78907892 for ( var i = 0; i < markers.length; i++ ) {
78917893 // We want to isolate each marker, so we may need to split textNodes
78927894 // if a marker starts or ends halfway one.
@@ -8012,23 +8014,32 @@
80138015 }
80148016
80158017 $( newNode ).data( 'marker', markers[i] )
8016 - .addClass( 'wikiEditor-highlight wikiEditor-highlight-tmp' );
 8018+ .addClass( 'wikiEditor-highlight' );
 8019+ visited[i] = newNode;
80178020
80188021 // Allow the module adding this marker to manipulate it
80198022 markers[i].afterWrap( newNode, markers[i] );
80208023 } else {
8021 - // Temporarily add a class for bookkeeping purposes
8022 - $( anchor )
8023 - .addClass( 'wikiEditor-highlight-tmp' )
8024 - .data( 'marker', markers[i] );
 8024+ visited[i] = anchor;
 8025+ // Update the marker object
 8026+ $( anchor ).data( 'marker', markers[i] );
80258027 markers[i].onSkip( anchor );
80268028 }
80278029 }
80288030 }
80298031
80308032 // Remove markers that were previously inserted but weren't passed to this function
8031 - // TODO: Find a better way to do this that involves less DOM manipulation
8032 - context.$content.find( 'div.wikiEditor-highlight:not(.wikiEditor-highlight-tmp)' ).each( function() {
 8033+ // This function works because visited[] contains the visited elements in order and find() and each()
 8034+ // preserve order
 8035+ var j = 0;
 8036+ context.$content.find( 'div.wikiEditor-highlight' ).each( function() {
 8037+ if ( visited[j] == this ) {
 8038+ // This marker is legit, leave it in
 8039+ j++;
 8040+ return true;
 8041+ }
 8042+
 8043+ // Remove this marker
80338044 if ( $(this).data( 'marker' ) && typeof $(this).data( 'marker' ).unwrap == 'function' )
80348045 $(this).data( 'marker' ).unwrap( this );
80358046 if ( $(this).children().size() > 0 ) {
@@ -8037,8 +8048,6 @@
80388049 $(this).replaceWith( $(this).html() );
80398050 }
80408051 });
8041 - // Remove temporary class
8042 - context.$content.find( 'div.wikiEditor-highlight-tmp' ).removeClass( 'wikiEditor-highlight-tmp' );
80438052 }
80448053 }
80458054
@@ -9018,14 +9027,16 @@
90199028 },
90209029 onSkip: function( node ) {
90219030 var marker = $( node ).data( 'marker' );
9022 - $( node )
9023 - .removeClass( 'wikiEditor-toc-section-' + $( node ).data( 'section' ) )
9024 - .addClass( 'wikiEditor-toc-section-' + marker.index )
9025 - .data( 'section', marker.index );
 9031+ if ( $( node ).data( 'section' ) != marker.index ) {
 9032+ $( node )
 9033+ .removeClass( 'wikiEditor-toc-section-' + $( node ).data( 'section' ) )
 9034+ .addClass( 'wikiEditor-toc-section-' + marker.index )
 9035+ .data( 'section', marker.index );
 9036+ }
90269037 },
90279038 getAnchor: function( ca1, ca2 ) {
9028 - return $( ca1.previousSibling ).is( 'div.wikiEditor-toc-header' ) ?
9029 - ca1.previousSibling : null;
 9039+ return $( ca1.parentNode.previousSibling ).is( 'div.wikiEditor-toc-header' ) ?
 9040+ ca1.parentNode.previousSibling : null;
90309041 }
90319042 } );
90329043 hash += tokenArray[i].match[2] + '\n';
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.min.js
@@ -522,7 +522,7 @@
523523 tokenArray.push(new Token(match.index+oldOffset+markOffset,label,tokenStart,match));oldOffset+=match.index+match[0].length;newSubstring=text.substring(oldOffset);match=newSubstring.match(regex);}}}}
524524 tokenArray.sort(function(a,b){return a.offset-b.offset||a.tokenStart-b.tokenStart;});context.fn.trigger('scan');},mark:function(context,division,tokens){var markers=context.modules.highlight.markers=[];context.fn.trigger('mark');markers.sort(function(a,b){return a.start-b.start||a.end-b.end;});var markersStr='';for(var i=0;i<markers.length;i++){markersStr+=markers[i].start+','+markers[i].end+','+markers[i].type+',';}
525525 if(context.modules.highlight.markersStr==markersStr){return;}
526 -context.modules.highlight.markersStr=markersStr;for(var i=0;i<markers.length;i++){var start=markers[i].start;var s=context.fn.getOffset(start);if(!s){continue;}
 526+context.modules.highlight.markersStr=markersStr;var visited=[];for(var i=0;i<markers.length;i++){var start=markers[i].start;var s=context.fn.getOffset(start);if(!s){continue;}
527527 var startNode=s.node;var startDepth=s.depth;while(startNode.nodeName=='BR'||s.offset==startNode.nodeValue.length){start++;s=context.fn.getOffset(start);startNode=s.node;startDepth=s.depth;}
528528 if(s.offset>0&&s.node.nodeName=='#text'){startNode=startNode.splitText(s.offset);context.fn.purgeOffsets();}
529529 var end=markers[i].end;var e=context.fn.getOffset(end);if(!e){continue;}
@@ -534,9 +534,10 @@
535535 if(ca1&&ca2&&ca1.parentNode){var anchor=markers[i].getAnchor(ca1,ca2);if(!anchor){var newNode=ca1.ownerDocument.createElement('div');var commonAncestor=ca1.parentNode;if(commonAncestor.nodeName=='P'&&commonAncestor.parentNode){commonAncestor=commonAncestor.parentNode;ca1=ca1.parentNode;ca2=ca2.parentNode;}
536536 var nextNode=ca2.nextSibling;if(markers[i].anchor=='wrap'){var n=ca1;while(n!=nextNode){var ns=n.nextSibling;newNode.appendChild(n);n=ns;}
537537 if(nextNode){commonAncestor.insertBefore(newNode,nextNode);}else{commonAncestor.appendChild(newNode);}}else if(markers[i].anchor=='before'){commonAncestor.insertBefore(newNode,ca1);}else if(markers[i].anchor=='after'){if(nextNode){commonAncestor.insertBefore(newNode,nextNode);}else{commonAncestor.appendChild(newNode);}}
538 -$(newNode).data('marker',markers[i]).addClass('wikiEditor-highlight wikiEditor-highlight-tmp');markers[i].afterWrap(newNode,markers[i]);}else{$(anchor).addClass('wikiEditor-highlight-tmp').data('marker',markers[i]);markers[i].onSkip(anchor);}}}
539 -context.$content.find('div.wikiEditor-highlight:not(.wikiEditor-highlight-tmp)').each(function(){if($(this).data('marker')&&typeof $(this).data('marker').unwrap=='function')
540 -$(this).data('marker').unwrap(this);if($(this).children().size()>0){$(this).replaceWith($(this).children());}else{$(this).replaceWith($(this).html());}});context.$content.find('div.wikiEditor-highlight-tmp').removeClass('wikiEditor-highlight-tmp');}}};})(jQuery);(function($){$.wikiEditor.modules.preview={fn:{create:function(context,config){if('initialized'in context.modules.preview){return;}
 538+$(newNode).data('marker',markers[i]).addClass('wikiEditor-highlight');visited[i]=newNode;markers[i].afterWrap(newNode,markers[i]);}else{visited[i]=anchor;$(anchor).data('marker',markers[i]);markers[i].onSkip(anchor);}}}
 539+var j=0;context.$content.find('div.wikiEditor-highlight').each(function(){if(visited[j]==this){j++;return true;}
 540+if($(this).data('marker')&&typeof $(this).data('marker').unwrap=='function')
 541+$(this).data('marker').unwrap(this);if($(this).children().size()>0){$(this).replaceWith($(this).children());}else{$(this).replaceWith($(this).html());}});}}};})(jQuery);(function($){$.wikiEditor.modules.preview={fn:{create:function(context,config){if('initialized'in context.modules.preview){return;}
541542 context.modules.preview={'initialized':true,'previewText':null,'changesText':null};context.modules.preview.$preview=context.fn.addView({'name':'preview','titleMsg':'wikieditor-preview-tab','init':function(context){var wikitext=context.fn.getContents();if(context.modules.preview.previewText==wikitext){return;}
542543 context.modules.preview.$preview.find('.wikiEditor-preview-contents').empty();context.modules.preview.$preview.find('.wikiEditor-preview-loading').show();$.post(wgScriptPath+'/api.php',{'action':'parse','title':wgPageName,'text':wikitext,'prop':'text','pst':'','format':'json'},function(data){if(typeof data.parse=='undefined'||typeof data.parse.text=='undefined'||typeof data.parse.text['*']=='undefined'){return;}
543544 context.modules.preview.previewText=wikitext;context.modules.preview.$preview.find('.wikiEditor-preview-loading').hide();context.modules.preview.$preview.find('.wikiEditor-preview-contents').html(data.parse.text['*']).find('a:not([href^=#])').click(function(){return false;});},'json');}});context.$changesTab=context.fn.addView({'name':'changes','titleMsg':'wikieditor-preview-changes-tab','init':function(context){var wikitext=context.fn.getContents();if(context.modules.preview.changesText==wikitext){return;}
@@ -610,7 +611,7 @@
611612 if(!context.modules.toc.$toc.data('collapsed')){context.modules.toc.$toc.height(context.$ui.find('.wikiEditor-ui-left').height()-
612613 context.$ui.find('.tab-toc').outerHeight());}
613614 context.modules.toc.$toc.data('previousWidth',context.$wikitext.width());},mark:function(context,event){var hash='';var markers=context.modules.highlight.markers;var tokenArray=context.modules.highlight.tokenArray;var outline=context.data.outline=[];var h=0;for(var i=0;i<tokenArray.length;i++){if(tokenArray[i].label!='TOC_HEADER'){continue;}
614 -h++;markers.push({index:h,start:tokenArray[i].tokenStart,end:tokenArray[i].offset,type:'toc',anchor:'before',afterWrap:function(node){var marker=$(node).data('marker');$(node).addClass('wikiEditor-toc-header').addClass('wikiEditor-toc-section-'+marker.index).data('section',marker.index);},onSkip:function(node){var marker=$(node).data('marker');$(node).removeClass('wikiEditor-toc-section-'+$(node).data('section')).addClass('wikiEditor-toc-section-'+marker.index).data('section',marker.index);},getAnchor:function(ca1,ca2){return $(ca1.previousSibling).is('div.wikiEditor-toc-header')?ca1.previousSibling:null;}});hash+=tokenArray[i].match[2]+'\n';outline.push({'text':tokenArray[i].match[2],'level':tokenArray[i].match[1].length,'index':h});}
 615+h++;markers.push({index:h,start:tokenArray[i].tokenStart,end:tokenArray[i].offset,type:'toc',anchor:'before',afterWrap:function(node){var marker=$(node).data('marker');$(node).addClass('wikiEditor-toc-header').addClass('wikiEditor-toc-section-'+marker.index).data('section',marker.index);},onSkip:function(node){var marker=$(node).data('marker');if($(node).data('section')!=marker.index){$(node).removeClass('wikiEditor-toc-section-'+$(node).data('section')).addClass('wikiEditor-toc-section-'+marker.index).data('section',marker.index);}},getAnchor:function(ca1,ca2){return $(ca1.parentNode.previousSibling).is('div.wikiEditor-toc-header')?ca1.parentNode.previousSibling:null;}});hash+=tokenArray[i].match[2]+'\n';outline.push({'text':tokenArray[i].match[2],'level':tokenArray[i].match[1].length,'index':h});}
615616 if(typeof context.modules.toc.lastHash=='undefined'||context.modules.toc.lastHash!==hash){$.wikiEditor.modules.toc.fn.build(context);$.wikiEditor.modules.toc.fn.update(context);context.modules.toc.lastHash=hash;}}},exp:[{'regex':/^(={1,6})([^\r\n]+?)\1\s*$/m,'label':'TOC_HEADER','markAfter':true}],fn:{create:function(context,config){if('$toc'in context.modules.toc){return;}
616617 $.wikiEditor.modules.toc.cfg.rtl=config.rtl;var height=context.$ui.find('.wikiEditor-ui-left').height();context.modules.toc.$toc=$('<div />').addClass('wikiEditor-ui-toc').data('context',context).data('positionMode','regular').data('collapsed',false);context.$ui.find('.wikiEditor-ui-right').append(context.modules.toc.$toc);context.modules.toc.$toc.height(context.$ui.find('.wikiEditor-ui-left').height());$.wikiEditor.modules.toc.fn.redraw(context,$.wikiEditor.modules.toc.cfg.defaultWidth);},redraw:function(context,fixedWidth){var fixedWidth=parseFloat(fixedWidth);if(context.modules.toc.$toc.data('positionMode')=='regular'){context.$ui.find('.wikiEditor-ui-right').css('width',fixedWidth+'px');context.$ui.find('.wikiEditor-ui-left').css('marginRight',(-1*fixedWidth)+'px').children().css('marginRight',fixedWidth+'px');}else if(context.modules.toc.$toc.data('positionMode')=='goofy'){context.$ui.find('.wikiEditor-ui-left').css('width',fixedWidth);context.$ui.find('.wikiEditor-ui-right').css($.wikiEditor.modules.toc.cfg.rtl?'right':'left',fixedWidth);context.$wikitext.css('height',context.$ui.find('.wikiEditor-ui-right').height());}},switchLayout:function(context){var width,height=context.$ui.find('.wikiEditor-ui-right').height();if(context.modules.toc.$toc.data('positionMode')=='regular'&&!context.modules.toc.$toc.data('collapsed')){context.modules.toc.$toc.data('positionMode','goofy');context.modules.toc.$toc.data('positionModeChangeAt',context.$ui.find('.wikiEditor-ui-right').width());width=$.wikiEditor.modules.toc.cfg.textMinimumWidth;context.$ui.find('.wikiEditor-ui-left').css({'marginRight':'','position':'absolute','float':'none','left':$.wikiEditor.modules.toc.cfg.rtl?'auto':0,'right':$.wikiEditor.modules.toc.cfg.rtl?0:'auto'}).children().css('marginRight','');context.$ui.find('.wikiEditor-ui-right').css({'width':'auto','position':'absolute','float':'none','right':$.wikiEditor.modules.toc.cfg.rtl?'auto':0,'left':$.wikiEditor.modules.toc.cfg.rtl?0:'auto'});context.$wikitext.css('position','relative');}else if(context.modules.toc.$toc.data('positionMode')=='goofy'){context.modules.toc.$toc.data('positionMode','regular');width=context.$wikitext.width()-context.$ui.find('.wikiEditor-ui-left').width();if(width>context.modules.toc.$toc.data('positionModeChangeAt')){width=context.modules.toc.$toc.data('positionModeChangeAt');}
617618 context.$wikitext.css({'position':'','height':''});context.$ui.find('.wikiEditor-ui-right').css({'marginRight':'','position':'','left':'','right':'','float':'','top':'','height':''});context.$ui.find('.wikiEditor-ui-left').css({'width':'','position':'','left':'','float':'','right':''});}

Status & tagging log