r61576 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r61575‎ | r61576 | r61577 >
Date:14:49, 27 January 2010
Author:catrope
Status:deferred
Tags:
Comment:
UsabilityInitiative: (bug 22260) Fix some JS errors occurring when the document is emptied. Caused by r61548 and r61493
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.js (modified) (history)

Diff [purge]

Index: trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php
@@ -72,8 +72,8 @@
7373 array( 'src' => 'js/plugins/jquery.namespaceSelect.js', 'version' => 1 ),
7474 array( 'src' => 'js/plugins/jquery.suggestions.js', 'version' => 7 ),
7575 array( 'src' => 'js/plugins/jquery.textSelection.js', 'version' => 26 ),
76 - array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 72 ),
77 - array( 'src' => 'js/plugins/jquery.wikiEditor.highlight.js', 'version' => 23 ),
 76+ array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 73 ),
 77+ array( 'src' => 'js/plugins/jquery.wikiEditor.highlight.js', 'version' => 24 ),
7878 array( 'src' => 'js/plugins/jquery.wikiEditor.toolbar.js', 'version' => 45 ),
7979 array( 'src' => 'js/plugins/jquery.wikiEditor.dialogs.js', 'version' => 11 ),
8080 array( 'src' => 'js/plugins/jquery.wikiEditor.toc.js', 'version' => 74 ),
@@ -82,10 +82,10 @@
8383 array( 'src' => 'js/plugins/jquery.wikiEditor.publish.js', 'version' => 2 ),
8484 ),
8585 'combined' => array(
86 - array( 'src' => 'js/plugins.combined.js', 'version' => 184 ),
 86+ array( 'src' => 'js/plugins.combined.js', 'version' => 185 ),
8787 ),
8888 'minified' => array(
89 - array( 'src' => 'js/plugins.combined.min.js', 'version' => 184 ),
 89+ array( 'src' => 'js/plugins.combined.min.js', 'version' => 185 ),
9090 ),
9191 ),
9292 );
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.js
@@ -425,8 +425,6 @@
426426 if ( !selText ) {
427427 selText = options.peri;
428428 selectAfter = true;
429 - } else if ( options.splitlines ) {
430 - selTextArr = selText.split( /\n/ );
431429 } else if ( options.replace ) {
432430 selText = options.peri;
433431 } else if ( selText.charAt( selText.length - 1 ) == ' ' ) {
@@ -435,6 +433,10 @@
436434 selText = selText.substring( 0, selText.length - 1 );
437435 post += ' ';
438436 }
 437+ if ( options.splitlines ) {
 438+ selTextArr = selText.split( /\n/ );
 439+ }
 440+
439441 if ( context.$iframe[0].contentWindow.getSelection ) {
440442 // Firefox and Opera
441443 var range = context.$iframe[0].contentWindow.getSelection().getRangeAt( 0 );
@@ -504,7 +506,9 @@
505507 if ( options.splitlines ) {
506508 for( var i = 0; i < selTextArr.length; i++ ) {
507509 insertText = insertText + pre + selTextArr[i] + post;
508 - if( i != selTextArr.length - 1 ) insertText += "\n";
 510+ if( i != selTextArr.length - 1 ) {
 511+ insertText += "\n";
 512+ }
509513 }
510514 } else {
511515 insertText = pre + selText + post;
@@ -548,10 +552,10 @@
549553 if ( !sc || !ec ) {
550554 var s = context.fn.getOffset( start );
551555 var e = context.fn.getOffset( end );
552 - sc = s.node;
553 - ec = e.node;
554 - start = s.offset;
555 - end = e.offset;
 556+ sc = s ? s.node : null;
 557+ ec = e ? e.node : null;
 558+ start = s ? s.offset : null;
 559+ end = e ? e.offset : null;
556560 }
557561 if ( !sc || !ec ) {
558562 // The requested offset isn't in the offsets array
@@ -775,21 +779,25 @@
776780 return context.offsets[offset];
777781 }
778782 // Our offset is not pre-cached. Find the highest offset below it and interpolate
779 - var lowerBound = 0;
 783+ var lowerBound = -1;
780784 for ( var o in context.offsets ) {
781785 if ( o > offset ) {
782786 break;
783787 }
784788 lowerBound = o;
785789 }
 790+ if ( !( lowerBound in context.offsets ) ) {
 791+ // Weird edge case: either offset is too large or the document is empty
 792+ return null;
 793+ }
786794 var base = context.offsets[lowerBound];
787795 return context.offsets[offset] = {
788796 'node': base.node,
789797 'offset': base.offset + offset - o,
790798 'length': base.length,
791799 'depth': base.depth,
792 - 'lastTextNode': lastTextNode,
793 - 'lastTextNodeDepth': lastTextNodeDepth
 800+ 'lastTextNode': base.lastTextNode,
 801+ 'lastTextNodeDepth': base.lastTextNodeDepth
794802 };
795803 },
796804 'purgeOffsets': function() {
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.highlight.js
@@ -157,6 +157,10 @@
158158 // if a marker starts or ends halfway one.
159159 var start = markers[i].start;
160160 var s = context.fn.getOffset( start );
 161+ if ( !s ) {
 162+ // This shouldn't happen
 163+ continue;
 164+ }
161165 var startNode = s.node;
162166 var startDepth = s.depth;
163167 // The next marker starts somewhere in this textNode or at this BR
@@ -178,6 +182,10 @@
179183
180184 var end = markers[i].end;
181185 var e = context.fn.getOffset( end );
 186+ if ( !e ) {
 187+ // This shouldn't happen
 188+ continue;
 189+ }
182190 var endNode = e.node;
183191 var endDepth = e.depth;
184192 if ( e.offset < e.length - 1 ) {
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.js
@@ -6849,8 +6849,6 @@
68506850 if ( !selText ) {
68516851 selText = options.peri;
68526852 selectAfter = true;
6853 - } else if ( options.splitlines ) {
6854 - selTextArr = selText.split( /\n/ );
68556853 } else if ( options.replace ) {
68566854 selText = options.peri;
68576855 } else if ( selText.charAt( selText.length - 1 ) == ' ' ) {
@@ -6859,6 +6857,10 @@
68606858 selText = selText.substring( 0, selText.length - 1 );
68616859 post += ' ';
68626860 }
 6861+ if ( options.splitlines ) {
 6862+ selTextArr = selText.split( /\n/ );
 6863+ }
 6864+
68636865 if ( context.$iframe[0].contentWindow.getSelection ) {
68646866 // Firefox and Opera
68656867 var range = context.$iframe[0].contentWindow.getSelection().getRangeAt( 0 );
@@ -6928,7 +6930,9 @@
69296931 if ( options.splitlines ) {
69306932 for( var i = 0; i < selTextArr.length; i++ ) {
69316933 insertText = insertText + pre + selTextArr[i] + post;
6932 - if( i != selTextArr.length - 1 ) insertText += "\n";
 6934+ if( i != selTextArr.length - 1 ) {
 6935+ insertText += "\n";
 6936+ }
69336937 }
69346938 } else {
69356939 insertText = pre + selText + post;
@@ -6972,10 +6976,10 @@
69736977 if ( !sc || !ec ) {
69746978 var s = context.fn.getOffset( start );
69756979 var e = context.fn.getOffset( end );
6976 - sc = s.node;
6977 - ec = e.node;
6978 - start = s.offset;
6979 - end = e.offset;
 6980+ sc = s ? s.node : null;
 6981+ ec = e ? e.node : null;
 6982+ start = s ? s.offset : null;
 6983+ end = e ? e.offset : null;
69806984 }
69816985 if ( !sc || !ec ) {
69826986 // The requested offset isn't in the offsets array
@@ -7199,21 +7203,25 @@
72007204 return context.offsets[offset];
72017205 }
72027206 // Our offset is not pre-cached. Find the highest offset below it and interpolate
7203 - var lowerBound = 0;
 7207+ var lowerBound = -1;
72047208 for ( var o in context.offsets ) {
72057209 if ( o > offset ) {
72067210 break;
72077211 }
72087212 lowerBound = o;
72097213 }
 7214+ if ( !( lowerBound in context.offsets ) ) {
 7215+ // Weird edge case: either offset is too large or the document is empty
 7216+ return null;
 7217+ }
72107218 var base = context.offsets[lowerBound];
72117219 return context.offsets[offset] = {
72127220 'node': base.node,
72137221 'offset': base.offset + offset - o,
72147222 'length': base.length,
72157223 'depth': base.depth,
7216 - 'lastTextNode': lastTextNode,
7217 - 'lastTextNodeDepth': lastTextNodeDepth
 7224+ 'lastTextNode': base.lastTextNode,
 7225+ 'lastTextNodeDepth': base.lastTextNodeDepth
72187226 };
72197227 },
72207228 'purgeOffsets': function() {
@@ -7711,6 +7719,10 @@
77127720 // if a marker starts or ends halfway one.
77137721 var start = markers[i].start;
77147722 var s = context.fn.getOffset( start );
 7723+ if ( !s ) {
 7724+ // This shouldn't happen
 7725+ continue;
 7726+ }
77157727 var startNode = s.node;
77167728 var startDepth = s.depth;
77177729 // The next marker starts somewhere in this textNode or at this BR
@@ -7732,6 +7744,10 @@
77337745
77347746 var end = markers[i].end;
77357747 var e = context.fn.getOffset( end );
 7748+ if ( !e ) {
 7749+ // This shouldn't happen
 7750+ continue;
 7751+ }
77367752 var endNode = e.node;
77377753 var endDepth = e.depth;
77387754 if ( e.offset < e.length - 1 ) {
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.min.js
@@ -452,16 +452,17 @@
453453 html.replace(/\r?\n/g,"").replace(/\<br[^\>]*\>/gi,"\n").replace(/&nbsp;/g," ").replace(/\<p[^\>]*\>/gi,"\n").replace(/\<\/p[^\>]*\>/gi,"")
454454 +'</pre>');$pre.find('.wikiEditor-noinclude').each(function(){$(this).remove();});$pre.find('.wikiEditor-tab').each(function(){$(this).text("\t")});return $pre.text();},'getContents':function(){return context.fn.htmlToText(context.$content.html());},'getSelection':function(){var retval;if(context.$iframe[0].contentWindow.getSelection){retval=context.$iframe[0].contentWindow.getSelection();}else if(context.$iframe[0].contentWindow.document.selection){retval=context.$iframe[0].contentWindow.document.selection.createRange();}
455455 if(typeof retval.text!='undefined'){retval=context.fn.htmlToText(retval.htmlText);}else if(retval.toString){retval=retval.toString();}
456 -return retval;},'encapsulateSelection':function(options){var selText=$(this).textSelection('getSelection');var selTextArr;var selectAfter=false;var pre=options.pre,post=options.post;if(!selText){selText=options.peri;selectAfter=true;}else if(options.splitlines){selTextArr=selText.split(/\n/);}else if(options.replace){selText=options.peri;}else if(selText.charAt(selText.length-1)==' '){selText=selText.substring(0,selText.length-1);post+=' ';}
 456+return retval;},'encapsulateSelection':function(options){var selText=$(this).textSelection('getSelection');var selTextArr;var selectAfter=false;var pre=options.pre,post=options.post;if(!selText){selText=options.peri;selectAfter=true;}else if(options.replace){selText=options.peri;}else if(selText.charAt(selText.length-1)==' '){selText=selText.substring(0,selText.length-1);post+=' ';}
 457+if(options.splitlines){selTextArr=selText.split(/\n/);}
457458 if(context.$iframe[0].contentWindow.getSelection){var range=context.$iframe[0].contentWindow.getSelection().getRangeAt(0);if(options.ownline){var body=context.$content.get(0);if(range.startOffset!=0&&range.startContainer!=body){pre="\n"+options.pre;}
458459 if(range.endContainer!=body){post+="\n";}}
459460 var insertText="";if(options.splitlines){for(var i=0;i<selTextArr.length;i++){insertText=insertText+pre+selTextArr[i]+post;if(i!=selTextArr.length-1)insertText+="\n";}}else{insertText=pre+selText+post;}
460461 var insertLines=insertText.split("\n");range.extractContents();var lastNode;for(var i=insertLines.length-1;i>=0;i--){range.insertNode(context.$iframe[0].contentWindow.document.createTextNode(insertLines[i]));if(i>0){lastNode=range.insertNode(context.$iframe[0].contentWindow.document.createElement('br'));}}
461462 if(lastNode){context.fn.scrollToTop(lastNode);}}else if(context.$iframe[0].contentWindow.document.selection){context.$iframe[0].contentWindow.focus();var range=context.$iframe[0].contentWindow.document.selection.createRange();if(options.ownline&&range.moveStart){var range2=context.$iframe[0].contentWindow.document.selection.createRange();range2.collapse();range2.moveStart('character',-1);if(range2.text!="\r"&&range2.text!="\n"&&range2.text!=""){pre="\n"+pre;}
462463 var range3=context.$iframe[0].contentWindow.document.selection.createRange();range3.collapse(false);range3.moveEnd('character',1);if(range3.text!="\r"&&range3.text!="\n"&&range3.text!=""){post+="\n";}}
463 -var insertText="";if(options.splitlines){for(var i=0;i<selTextArr.length;i++){insertText=insertText+pre+selTextArr[i]+post;if(i!=selTextArr.length-1)insertText+="\n";}}else{insertText=pre+selText+post;}
 464+var insertText="";if(options.splitlines){for(var i=0;i<selTextArr.length;i++){insertText=insertText+pre+selTextArr[i]+post;if(i!=selTextArr.length-1){insertText+="\n";}}}else{insertText=pre+selText+post;}
464465 range.pasteHTML(insertText.replace(/\</g,'&lt;').replace(/>/g,'&gt;').replace(/\r?\n/g,'<br />'));}
465 -$(context.$iframe[0].contentWindow.document).trigger('encapsulateSelection',[pre,options.peri,post,options.ownline,options.replace]);return context.$textarea;},'getCaretPosition':function(options){},'setSelection':function(options){var sc=options.startContainer,ec=options.endContainer;sc=sc&&sc.jquery?sc[0]:sc;ec=ec&&ec.jquery?ec[0]:ec;if(context.$iframe[0].contentWindow.getSelection){var start=options.start,end=options.end;if(!sc||!ec){var s=context.fn.getOffset(start);var e=context.fn.getOffset(end);sc=s.node;ec=e.node;start=s.offset;end=e.offset;}
 466+$(context.$iframe[0].contentWindow.document).trigger('encapsulateSelection',[pre,options.peri,post,options.ownline,options.replace]);return context.$textarea;},'getCaretPosition':function(options){},'setSelection':function(options){var sc=options.startContainer,ec=options.endContainer;sc=sc&&sc.jquery?sc[0]:sc;ec=ec&&ec.jquery?ec[0]:ec;if(context.$iframe[0].contentWindow.getSelection){var start=options.start,end=options.end;if(!sc||!ec){var s=context.fn.getOffset(start);var e=context.fn.getOffset(end);sc=s?s.node:null;ec=e?e.node:null;start=s?s.offset:null;end=e?e.offset:null;}
466467 if(!sc||!ec){return context.$textarea;}
467468 var sel=context.$iframe[0].contentWindow.getSelection();while(sc.firstChild&&sc.nodeName!='#text'){sc=sc.firstChild;}
468469 while(ec.firstChild&&ec.nodeName!='#text'){ec=ec.firstChild;}
@@ -486,9 +487,10 @@
487488 var node=start.jquery?start.get(0):start;var depth=0;var inP=node.nodeName=="P";do{while(node&&(' '+node.className+' ').indexOf(' wikiEditor-noinclude ')!=-1){node=node.nextSibling;}
488489 if(node&&node.firstChild){node=node.firstChild;depth++;if(node.nodeName=="P"){inP=true;}}}while(node&&node.firstChild);return new Traverser(node,depth,inP);},'getOffset':function(offset){if(!context.offsets){context.fn.refreshOffsets();}
489490 if(offset in context.offsets){return context.offsets[offset];}
490 -var lowerBound=0;for(var o in context.offsets){if(o>offset){break;}
 491+var lowerBound=-1;for(var o in context.offsets){if(o>offset){break;}
491492 lowerBound=o;}
492 -var base=context.offsets[lowerBound];return context.offsets[offset]={'node':base.node,'offset':base.offset+offset-o,'length':base.length,'depth':base.depth,'lastTextNode':lastTextNode,'lastTextNodeDepth':lastTextNodeDepth};},'purgeOffsets':function(){context.offsets=null;},'refreshOffsets':function(){context.offsets=[];var t=context.fn.traverser(context.$content);var pos=0,lastTextNode=null,lastTextNodeDepth=null;while(t){if(t.node.nodeName!='#text'&&t.node.nodeName!='BR'){t=t.next();continue;}
 493+if(!(lowerBound in context.offsets)){return null;}
 494+var base=context.offsets[lowerBound];return context.offsets[offset]={'node':base.node,'offset':base.offset+offset-o,'length':base.length,'depth':base.depth,'lastTextNode':base.lastTextNode,'lastTextNodeDepth':base.lastTextNodeDepth};},'purgeOffsets':function(){context.offsets=null;},'refreshOffsets':function(){context.offsets=[];var t=context.fn.traverser(context.$content);var pos=0,lastTextNode=null,lastTextNodeDepth=null;while(t){if(t.node.nodeName!='#text'&&t.node.nodeName!='BR'){t=t.next();continue;}
493495 var nextPos=t.node.nodeName=='#text'?pos+t.node.nodeValue.length:pos+1;var nextT=t.next();var leavingP=t.inP&&nextT&&!nextT.inP;context.offsets[pos]={'node':t.node,'offset':0,'length':nextPos-pos+(leavingP?1:0),'depth':t.depth,'lastTextNode':lastTextNode,'lastTextNodeDepth':lastTextNodeDepth};if(leavingP){context.offsets[nextPos]={'node':t.node,'offset':nextPos-pos,'length':nextPos-pos+1,'depth':t.depth,'lastTextNode':lastTextNode,'lastTextNodeDepth':lastTextNodeDepth};}
494496 pos=nextPos+(leavingP?1:0);if(t.node.nodeName=='#text'){lastTextNode=t.node;lastTextNodeDepth=t.depth;}
495497 t=nextT;}}};context.$textarea.wrap($('<div></div>').addClass('wikiEditor-ui')).wrap($('<div></div>').addClass('wikiEditor-ui-view wikiEditor-ui-view-wikitext')).wrap($('<div></div>').addClass('wikiEditor-ui-left')).wrap($('<div></div>').addClass('wikiEditor-ui-bottom')).wrap($('<div></div>').addClass('wikiEditor-ui-text'));context.$ui=context.$textarea.parent().parent().parent().parent().parent();context.$wikitext=context.$textarea.parent().parent().parent().parent();context.$wikitext.before($('<div></div>').addClass('wikiEditor-ui-controls').append($('<div></div>').addClass('wikiEditor-ui-tabs').hide()).append($('<div></div>').addClass('wikiEditor-ui-buttons'))).before($('<div style="clear:both;"></div>'));context.$controls=context.$ui.find('.wikiEditor-ui-buttons').hide();context.$buttons=context.$ui.find('.wikiEditor-ui-buttons');context.$tabs=context.$ui.find('.wikiEditor-ui-tabs');context.$ui.after($('<div style="clear:both;"></div>'));context.$wikitext.append($('<div></div>').addClass('wikiEditor-ui-right'));context.$wikitext.find('.wikiEditor-ui-left').prepend($('<div></div>').addClass('wikiEditor-ui-top'));context.view='wikitext';$(window).resize(function(event){context.fn.trigger('resize',event)});context.$iframe=$('<iframe></iframe>').attr({'frameBorder':0,'border':0,'src':wgScriptPath+'/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.html?'+'instance='+context.instance+'&ts='+(new Date()).getTime(),'id':'wikiEditor-iframe-'+context.instance}).css({'backgroundColor':'white','width':'100%','height':context.$textarea.height(),'display':'none','overflow-y':'scroll','overflow-x':'hidden'}).insertAfter(context.$textarea).load(function(){if(!this.isSecondRun){context.$iframe[0].contentWindow.document.designMode='on';if($.browser.msie){this.isSecondRun=true;return;}}
@@ -506,9 +508,11 @@
507509 var tokenArray=context.modules.highlight.tokenArray=[];var text=context.fn.getContents();for(module in context.modules){if(module in $.wikiEditor.modules&&'exp'in $.wikiEditor.modules[module]){for(var i=0;i<$.wikiEditor.modules[module].exp.length;i++){var regex=$.wikiEditor.modules[module].exp[i].regex;var label=$.wikiEditor.modules[module].exp[i].label;var markAfter=false;if(typeof $.wikiEditor.modules[module].exp[i].markAfter!='undefined'){markAfter=true;}
508510 match=text.match(regex);var oldOffset=0;while(match!=null){var markOffset=0;var tokenStart=match.index+oldOffset+markOffset;if(markAfter){markOffset+=match[0].length;}
509511 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);}}}}
510 -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;});for(var i=0;i<markers.length;i++){var start=markers[i].start;var s=context.fn.getOffset(start);var startNode=s.node;var startDepth=s.depth;if(s.offset>0){startNode=startNode.splitText(s.offset);}
 512+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;});for(var i=0;i<markers.length;i++){var start=markers[i].start;var s=context.fn.getOffset(start);if(!s){continue;}
 513+var startNode=s.node;var startDepth=s.depth;if(s.offset>0){startNode=startNode.splitText(s.offset);}
511514 while(startNode.nodeName=='BR'&&start+1 in offsets){start++;startNode=s.node;startDepth=s.depth;}
512 -var end=markers[i].end;var e=context.fn.getOffset(end);var endNode=e.node;var endDepth=e.depth;if(e.offset<e.length-1){endNode.splitText(e.offset+1);}
 515+var end=markers[i].end;var e=context.fn.getOffset(end);if(!e){continue;}
 516+var endNode=e.node;var endDepth=e.depth;if(e.offset<e.length-1){endNode.splitText(e.offset+1);}
513517 if(endNode.nodeName=='BR'){endNode=e.lastTextNode;endDepth=e.lastTextNodeDepth;}
514518 var ca1=startNode,ca2=endNode;if(startDepth>endDepth){for(var j=0;j<startDepth-endDepth&&ca1;j++){ca1=ca1.parentNode.firstChild==ca1?ca1.parentNode:null;}}
515519 else if(startDepth<endDepth){for(var j=0;j<endDepth-startDepth&&ca2;j++){ca2=ca2.parentNode.lastChild==ca2?ca2.parentNode:null;}}

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r61493Adding a split lines option for applying toolbar commands to each line separe...adam17:05, 25 January 2010
r61548UsabilityInitiative: Performance fixes for TOC building...catrope01:12, 27 January 2010

Status & tagging log