r63841 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r63840‎ | r63841 | r63842 >
Date:22:38, 16 March 2010
Author:catrope
Status:deferred
Tags:
Comment:
UsabilityInitative: Redo r63579, with some fixes. Also take out iframe requirement for S&R dialog that was causing the iframe to be loaded unnecessarily and compromised the accuracy of some of our tests, fix order assumption in getOffset() and remove an unneeded purgeOffsets() call.
Modified paths:
  • /trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/WikiEditor/Modules/Toolbar/Toolbar.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/WikiEditor/WikiEditor.combined.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/WikiEditor/WikiEditor.combined.min.js (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.cookie.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins/jquery.textSelection.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.delayedBind.js', 'version' => 1 ),
7474 array( 'src' => 'js/plugins/jquery.suggestions.js', 'version' => 7 ),
7575 array( 'src' => 'js/plugins/jquery.textSelection.js', 'version' => 27 ),
76 - array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 173 ),
77 - array( 'src' => 'js/plugins/jquery.wikiEditor.highlight.js', 'version' => 48 ),
 76+ array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 174 ),
 77+ array( 'src' => 'js/plugins/jquery.wikiEditor.highlight.js', 'version' => 49 ),
7878 array( 'src' => 'js/plugins/jquery.wikiEditor.toolbar.js', 'version' => 52 ),
7979 array( 'src' => 'js/plugins/jquery.wikiEditor.dialogs.js', 'version' => 21 ),
8080 array( 'src' => 'js/plugins/jquery.wikiEditor.toc.js', 'version' => 97 ),
@@ -82,10 +82,10 @@
8383 array( 'src' => 'js/plugins/jquery.wikiEditor.publish.js', 'version' => 3 ),
8484 ),
8585 'combined' => array(
86 - array( 'src' => 'js/plugins.combined.js', 'version' => 348 ),
 86+ array( 'src' => 'js/plugins.combined.js', 'version' => 349 ),
8787 ),
8888 'minified' => array(
89 - array( 'src' => 'js/plugins.combined.min.js', 'version' => 348 ),
 89+ array( 'src' => 'js/plugins.combined.min.js', 'version' => 349 ),
9090 ),
9191 ),
9292 );
Index: trunk/extensions/UsabilityInitiative/WikiEditor/WikiEditor.combined.js
@@ -1655,7 +1655,6 @@
16561656 'chrome': [['>=', 3]]
16571657 }
16581658 },
1659 - 'req': [ 'iframe' ],
16601659 filters: [ '#wpTextbox1.toolbar-dialogs' ],
16611660 titleMsg: 'wikieditor-toolbar-tool-replace-title',
16621661 id: 'wikieditor-toolbar-replace-dialog',
Index: trunk/extensions/UsabilityInitiative/WikiEditor/WikiEditor.combined.min.js
@@ -142,7 +142,7 @@
143143 classes.push('sortable');var classStr=classes.length>0?' class="'+classes.join(' ')+'"':'';$j.wikiEditor.modules.toolbar.fn.doAction($j(this).data('context'),{type:'replace',options:{pre:'{|'+classStr+"\n",peri:table,post:'|}',ownline:true}},$j(this));$j('#wikieditor-toolbar-table-dimensions-rows').val(4);$j('#wikieditor-toolbar-table-dimensions-columns').val(3);if(!$j('#wikieditor-toolbar-table-dimensions-header').is(':checked'))
144144 $j('#wikieditor-toolbar-table-dimensions-header').click();if(!$j('#wikieditor-toolbar-table-wikitable').is(':checked'))
145145 $j('#wikieditor-toolbar-table-wikitable').click();if($j('#wikieditor-toolbar-table-sortable').is(':checked'))
146 -$j('#wikieditor-toolbar-table-sortable').click();$j(this).dialog('close');},'wikieditor-toolbar-tool-table-cancel':function(){$j(this).dialog('close');}},open:function(){$j('#wikieditor-toolbar-table-dimensions-rows').focus();if(!($j(this).data('dialogkeypressset'))){$j(this).data('dialogkeypressset',true);$j(this).closest('.ui-dialog').keypress(function(e){if((e.keyCode||e.which)==13){var button=$j(this).data('dialogaction')||$j(this).find('button:first');button.click();e.preventDefault();}});$j(this).closest('.ui-dialog').find('button').focus(function(){$j(this).closest('.ui-dialog').data('dialogaction',this);});}}}},'search-and-replace':{'browsers':{'ltr':{'msie':[['>=',7]],'firefox':[['>=',2]],'opera':false,'safari':[['>=',3]],'chrome':[['>=',3]]},'rtl':{'msie':[['>=',8]],'firefox':[['>=',2]],'opera':false,'safari':[['>=',3]],'chrome':[['>=',3]]}},'req':['iframe'],filters:['#wpTextbox1.toolbar-dialogs'],titleMsg:'wikieditor-toolbar-tool-replace-title',id:'wikieditor-toolbar-replace-dialog',html:'\
 146+$j('#wikieditor-toolbar-table-sortable').click();$j(this).dialog('close');},'wikieditor-toolbar-tool-table-cancel':function(){$j(this).dialog('close');}},open:function(){$j('#wikieditor-toolbar-table-dimensions-rows').focus();if(!($j(this).data('dialogkeypressset'))){$j(this).data('dialogkeypressset',true);$j(this).closest('.ui-dialog').keypress(function(e){if((e.keyCode||e.which)==13){var button=$j(this).data('dialogaction')||$j(this).find('button:first');button.click();e.preventDefault();}});$j(this).closest('.ui-dialog').find('button').focus(function(){$j(this).closest('.ui-dialog').data('dialogaction',this);});}}}},'search-and-replace':{'browsers':{'ltr':{'msie':[['>=',7]],'firefox':[['>=',2]],'opera':false,'safari':[['>=',3]],'chrome':[['>=',3]]},'rtl':{'msie':[['>=',8]],'firefox':[['>=',2]],'opera':false,'safari':[['>=',3]],'chrome':[['>=',3]]}},filters:['#wpTextbox1.toolbar-dialogs'],titleMsg:'wikieditor-toolbar-tool-replace-title',id:'wikieditor-toolbar-replace-dialog',html:'\
147147 <div id="wikieditor-toolbar-replace-message">\
148148 <div id="wikieditor-toolbar-replace-nomatch" rel="wikieditor-toolbar-tool-replace-nomatch"></div>\
149149 <div id="wikieditor-toolbar-replace-success"></div>\
Index: trunk/extensions/UsabilityInitiative/WikiEditor/Modules/Toolbar/Toolbar.js
@@ -1606,7 +1606,6 @@
16071607 'chrome': [['>=', 3]]
16081608 }
16091609 },
1610 - 'req': [ 'iframe' ],
16111610 filters: [ '#wpTextbox1.toolbar-dialogs' ],
16121611 titleMsg: 'wikieditor-toolbar-tool-replace-title',
16131612 id: 'wikieditor-toolbar-replace-dialog',
Property changes on: trunk/extensions/UsabilityInitiative/js/plugins/jquery.textSelection.js
___________________________________________________________________
Name: svn:mergeinfo
16141613 -
Property changes on: trunk/extensions/UsabilityInitiative/js/plugins/jquery.cookie.js
___________________________________________________________________
Name: svn:mergeinfo
16151614 -
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.js
@@ -393,13 +393,13 @@
394394
395395 //surround by <p> if it does not already have it
396396 var cursorPos = context.fn.getCaretPosition();
397 - var t = context.fn.getOffset(cursorPos[0]);
 397+ var t = context.fn.getOffset( cursorPos[0] );
398398 if ( t.node.nodeName == '#text' && t.node.parentNode.nodeName.toLowerCase() == 'body' ) {
399399 $( t.node ).wrap( "<p></p>" );
400400 context.fn.purgeOffsets();
401401 context.fn.setSelection( { start: cursorPos[0], end: cursorPos[1] } );
402402 }
403 - }
 403+ }
404404
405405 context.fn.updateHistory( event.data.scope == 'realchange' );
406406 return true;
@@ -897,12 +897,14 @@
898898 return context.offsets[offset];
899899 }
900900 // Our offset is not pre-cached. Find the highest offset below it and interpolate
 901+ // We need to traverse the entire object because for() doesn't traverse in order
 902+ // We don't do in-order traversal because the object is sparse
901903 var lowerBound = -1;
902904 for ( var o in context.offsets ) {
903 - if ( o > offset ) {
904 - break;
 905+ var realO = parseInt( o );
 906+ if ( realO < offset && realO > lowerBound) {
 907+ lowerBound = realO;
905908 }
906 - lowerBound = o;
907909 }
908910 if ( !( lowerBound in context.offsets ) ) {
909911 // Weird edge case: either offset is too large or the document is empty
@@ -984,7 +986,6 @@
985987 context.history.length == 0 ||
986988 ( htmlChange && context.oldDelayedHistoryPosition == context.historyPosition )
987989 ) {
988 - context.fn.purgeOffsets();
989990 context.oldDelayedSel = newSel;
990991 // Do we need to trim extras from our history?
991992 // FIXME: this should really be happing on change, not on the delay
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.highlight.js
@@ -213,10 +213,40 @@
214214 // Split off the prefix
215215 // This leaves the prefix in the current node and puts
216216 // the rest in a new node which is our start node
217 - startNode = startNode.splitText( s.offset < s.node.nodeValue.length ?
 217+ var newStartNode = startNode.splitText( s.offset < s.node.nodeValue.length ?
218218 s.offset : s.node.nodeValue.length - 1
219219 );
220 - context.fn.purgeOffsets();
 220+ var oldStartNode = startNode;
 221+ startNode = newStartNode;
 222+
 223+ // Update offset objects. We don't need purgeOffsets(), simply
 224+ // manipulating the existing offset objects will suffice
 225+ // FIXME: This manipulates context.offsets directly, which is ugly,
 226+ // but the performance improvement vs. purgeOffsets() is worth it
 227+ // This code doesn't set lastTextNode to newStartNode for offset objects
 228+ // with lastTextNode == oldStartNode, but that doesn't really matter
 229+ var subtracted = s.offset;
 230+ var oldLength = s.length;
 231+
 232+ var j, o;
 233+ // Update offset objects referring to oldStartNode
 234+ for ( j = start - subtracted; j < start; j++ ) {
 235+ if ( j in context.offsets ) {
 236+ o = context.offsets[j];
 237+ o.node = oldStartNode;
 238+ o.length = subtracted;
 239+ }
 240+ }
 241+ // Update offset objects referring to newStartNode
 242+ for ( j = start; j < start - subtracted + oldLength; j++ ) {
 243+ if ( j in context.offsets ) {
 244+ o = context.offsets[j];
 245+ o.node = newStartNode;
 246+ o.offset -= subtracted;
 247+ o.length -= subtracted;
 248+ o.lastTextNode = oldStartNode;
 249+ }
 250+ }
221251 }
222252
223253 var end = markers[i].end;
@@ -230,10 +260,39 @@
231261 var endNode = e.node;
232262 if ( e.offset + 1 < e.length - 1 && endNode.nodeName == '#text' ) {
233263 // Split off the suffix. This puts the suffix in a new node and leaves the rest in endNode
234 - var endNode = endNode.splitText( e.offset + 1 );
 264+ var oldEndNode = endNode;
 265+ var newEndNode = endNode.splitText( e.offset + 1 );
235266
236267 // Update offset objects
237 - context.fn.purgeOffsets();
 268+ var subtracted = e.offset + 1;
 269+ var oldLength = e.length;
 270+
 271+ var j, o;
 272+ // Update offset objects referring to oldEndNode
 273+ for ( j = end - subtracted; j < end; j++ ) {
 274+ if ( j in context.offsets ) {
 275+ o = context.offsets[j];
 276+ o.node = oldEndNode;
 277+ o.length = subtracted;
 278+ }
 279+ }
 280+ // We have to insert this one, as it might not exist: we didn't call getOffset( end )
 281+ context.offsets[end] = {
 282+ 'node': newEndNode,
 283+ 'offset': 0,
 284+ 'length': oldLength - subtracted,
 285+ 'lastTextNode': oldEndNode
 286+ };
 287+ // Update offset objects referring to newEndNode
 288+ for ( j = end + 1; j < end - subtracted + oldLength; j++ ) {
 289+ if ( j in context.offsets ) {
 290+ o = context.offsets[j];
 291+ o.node = newEndNode;
 292+ o.offset -= subtracted;
 293+ o.length -= subtracted;
 294+ o.lastTextNode = oldEndNode;
 295+ }
 296+ }
238297 }
239298
240299 // Don't wrap trailing BRs, doing that causes weird issues
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.js
@@ -6936,13 +6936,13 @@
69376937
69386938 //surround by <p> if it does not already have it
69396939 var cursorPos = context.fn.getCaretPosition();
6940 - var t = context.fn.getOffset(cursorPos[0]);
 6940+ var t = context.fn.getOffset( cursorPos[0] );
69416941 if ( t.node.nodeName == '#text' && t.node.parentNode.nodeName.toLowerCase() == 'body' ) {
69426942 $( t.node ).wrap( "<p></p>" );
69436943 context.fn.purgeOffsets();
69446944 context.fn.setSelection( { start: cursorPos[0], end: cursorPos[1] } );
69456945 }
6946 - }
 6946+ }
69476947
69486948 context.fn.updateHistory( event.data.scope == 'realchange' );
69496949 return true;
@@ -7440,12 +7440,14 @@
74417441 return context.offsets[offset];
74427442 }
74437443 // Our offset is not pre-cached. Find the highest offset below it and interpolate
 7444+ // We need to traverse the entire object because for() doesn't traverse in order
 7445+ // We don't do in-order traversal because the object is sparse
74447446 var lowerBound = -1;
74457447 for ( var o in context.offsets ) {
7446 - if ( o > offset ) {
7447 - break;
 7448+ var realO = parseInt( o );
 7449+ if ( realO < offset && realO > lowerBound) {
 7450+ lowerBound = realO;
74487451 }
7449 - lowerBound = o;
74507452 }
74517453 if ( !( lowerBound in context.offsets ) ) {
74527454 // Weird edge case: either offset is too large or the document is empty
@@ -7527,7 +7529,6 @@
75287530 context.history.length == 0 ||
75297531 ( htmlChange && context.oldDelayedHistoryPosition == context.historyPosition )
75307532 ) {
7531 - context.fn.purgeOffsets();
75327533 context.oldDelayedSel = newSel;
75337534 // Do we need to trim extras from our history?
75347535 // FIXME: this should really be happing on change, not on the delay
@@ -8748,10 +8749,40 @@
87498750 // Split off the prefix
87508751 // This leaves the prefix in the current node and puts
87518752 // the rest in a new node which is our start node
8752 - startNode = startNode.splitText( s.offset < s.node.nodeValue.length ?
 8753+ var newStartNode = startNode.splitText( s.offset < s.node.nodeValue.length ?
87538754 s.offset : s.node.nodeValue.length - 1
87548755 );
8755 - context.fn.purgeOffsets();
 8756+ var oldStartNode = startNode;
 8757+ startNode = newStartNode;
 8758+
 8759+ // Update offset objects. We don't need purgeOffsets(), simply
 8760+ // manipulating the existing offset objects will suffice
 8761+ // FIXME: This manipulates context.offsets directly, which is ugly,
 8762+ // but the performance improvement vs. purgeOffsets() is worth it
 8763+ // This code doesn't set lastTextNode to newStartNode for offset objects
 8764+ // with lastTextNode == oldStartNode, but that doesn't really matter
 8765+ var subtracted = s.offset;
 8766+ var oldLength = s.length;
 8767+
 8768+ var j, o;
 8769+ // Update offset objects referring to oldStartNode
 8770+ for ( j = start - subtracted; j < start; j++ ) {
 8771+ if ( j in context.offsets ) {
 8772+ o = context.offsets[j];
 8773+ o.node = oldStartNode;
 8774+ o.length = subtracted;
 8775+ }
 8776+ }
 8777+ // Update offset objects referring to newStartNode
 8778+ for ( j = start; j < start - subtracted + oldLength; j++ ) {
 8779+ if ( j in context.offsets ) {
 8780+ o = context.offsets[j];
 8781+ o.node = newStartNode;
 8782+ o.offset -= subtracted;
 8783+ o.length -= subtracted;
 8784+ o.lastTextNode = oldStartNode;
 8785+ }
 8786+ }
87568787 }
87578788
87588789 var end = markers[i].end;
@@ -8765,10 +8796,39 @@
87668797 var endNode = e.node;
87678798 if ( e.offset + 1 < e.length - 1 && endNode.nodeName == '#text' ) {
87688799 // Split off the suffix. This puts the suffix in a new node and leaves the rest in endNode
8769 - var endNode = endNode.splitText( e.offset + 1 );
 8800+ var oldEndNode = endNode;
 8801+ var newEndNode = endNode.splitText( e.offset + 1 );
87708802
87718803 // Update offset objects
8772 - context.fn.purgeOffsets();
 8804+ var subtracted = e.offset + 1;
 8805+ var oldLength = e.length;
 8806+
 8807+ var j, o;
 8808+ // Update offset objects referring to oldEndNode
 8809+ for ( j = end - subtracted; j < end; j++ ) {
 8810+ if ( j in context.offsets ) {
 8811+ o = context.offsets[j];
 8812+ o.node = oldEndNode;
 8813+ o.length = subtracted;
 8814+ }
 8815+ }
 8816+ // We have to insert this one, as it might not exist: we didn't call getOffset( end )
 8817+ context.offsets[end] = {
 8818+ 'node': newEndNode,
 8819+ 'offset': 0,
 8820+ 'length': oldLength - subtracted,
 8821+ 'lastTextNode': oldEndNode
 8822+ };
 8823+ // Update offset objects referring to newEndNode
 8824+ for ( j = end + 1; j < end - subtracted + oldLength; j++ ) {
 8825+ if ( j in context.offsets ) {
 8826+ o = context.offsets[j];
 8827+ o.node = newEndNode;
 8828+ o.offset -= subtracted;
 8829+ o.length -= subtracted;
 8830+ o.lastTextNode = oldEndNode;
 8831+ }
 8832+ }
87738833 }
87748834
87758835 // Don't wrap trailing BRs, doing that causes weird issues
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.min.js
@@ -507,15 +507,14 @@
508508 if(p&&p.lastChild){p=p.lastChild;if(p.nodeName=="P"){prevInP=p;}}}while(p&&p.lastChild);return p?{'node':p,'inP':prevInP,'ancestor':this.ancestor,'skipNoinclude':this.skipNoinclude,'next':this.next,'prev':this.prev}:null;};},'traverser':function(start){var startNode=start.jquery?start.get(0):start;var node=startNode;var inP=node.nodeName=="P"?node:null;do{while(node&&(' '+node.className+' ').indexOf(' wikiEditor-noinclude ')!=-1){node=node.nextSibling;}
509509 if(node&&node.firstChild){node=node.firstChild;if(node.nodeName=="P"){inP=node;}}}while(node&&node.firstChild);return new context.fn.rawTraverser(node,inP,startNode,true);},'getOffset':function(offset){if(!context.offsets){context.fn.refreshOffsets();}
510510 if(offset in context.offsets){return context.offsets[offset];}
511 -var lowerBound=-1;for(var o in context.offsets){if(o>offset){break;}
512 -lowerBound=o;}
 511+var lowerBound=-1;for(var o in context.offsets){var realO=parseInt(o);if(realO<offset&&realO>lowerBound){lowerBound=realO;}}
513512 if(!(lowerBound in context.offsets)){return null;}
514513 var base=context.offsets[lowerBound];return context.offsets[offset]={'node':base.node,'offset':base.offset+offset-lowerBound,'length':base.length,'lastTextNode':base.lastTextNode};},'purgeOffsets':function(){context.offsets=null;},'refreshOffsets':function(){context.offsets=[];var t=context.fn.traverser(context.$content);var pos=0,lastTextNode=null;while(t){if(t.node.nodeName!='#text'&&t.node.nodeName!='BR'){t=t.next();continue;}
515514 var nextPos=t.node.nodeName=='#text'?pos+t.node.nodeValue.length:pos+1;var nextT=t.next();var leavingP=t.node.nodeName=='#text'&&t.inP&&nextT&&(!nextT.inP||nextT.inP!=t.inP);context.offsets[pos]={'node':t.node,'offset':0,'length':nextPos-pos+(leavingP?1:0),'lastTextNode':lastTextNode};if(leavingP){context.offsets[nextPos]={'node':t.node,'offset':nextPos-pos,'length':nextPos-pos+1,'lastTextNode':lastTextNode};}
516515 pos=nextPos+(leavingP?1:0);if(t.node.nodeName=='#text'){lastTextNode=t.node;}
517516 t=nextT;}},'saveSelection':function(){if(!$.browser.msie){return;}
518517 context.$iframe[0].contentWindow.focus();context.savedSelection=context.$iframe[0].contentWindow.document.selection.createRange();},'restoreSelection':function(){if(!$.browser.msie||context.savedSelection===null){return;}
519 -context.$iframe[0].contentWindow.focus();context.savedSelection.select();context.savedSelection=null;},'updateHistory':function(htmlChange){var newHTML=context.$content.html();var newSel=context.fn.getCaretPosition();if(context.history.length==0||(htmlChange&&context.oldDelayedHistoryPosition==context.historyPosition)){context.fn.purgeOffsets();context.oldDelayedSel=newSel;if(context.historyPosition<-1){context.history.splice(context.history.length+context.historyPosition+1);context.historyPosition=-1;}
 518+context.$iframe[0].contentWindow.focus();context.savedSelection.select();context.savedSelection=null;},'updateHistory':function(htmlChange){var newHTML=context.$content.html();var newSel=context.fn.getCaretPosition();if(context.history.length==0||(htmlChange&&context.oldDelayedHistoryPosition==context.historyPosition)){context.oldDelayedSel=newSel;if(context.historyPosition<-1){context.history.splice(context.history.length+context.historyPosition+1);context.historyPosition=-1;}
520519 context.history.push({'html':newHTML,'sel':newSel});while(context.history.length>10){context.history.shift();}}else if(context.oldDelayedSel!=newSel){context.oldDelayedSel=newSel;context.history[context.history.length+context.historyPosition].sel=newSel;}
521520 context.oldDelayedHistoryPosition=context.historyPosition;},'setupIframe':function(){context.$iframe=$('<iframe></iframe>').attr({'frameBorder':0,'border':0,'tabindex':1,'src':wgScriptPath+'/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.html?'+'instance='+context.instance+'&ts='+(new Date()).getTime()+'&is=content','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;}}
522521 context.$content=$(context.$iframe[0].contentWindow.document.body);var html=context.$textarea.val().replace(/&esc;/g,'&esc;esc;').replace(/\<p\>/g,'&esc;&lt;p&gt;').replace(/\<\/p\>/g,'&esc;&lt;/p&gt;').replace(/\<span class="wikiEditor-tab"\>\<\/span\>/g,'&esc;&lt;span&nbsp;class=&quot;wikiEditor-tab&quot;&gt;&lt;/span&gt;').replace(/&nbsp;/g,'&esc;&amp;nbsp;');if($.browser.msie){html=html.replace(/\t/g,'<span class="wikiEditor-tab"></span>');if($.browser.versionNumber<=7){html=html.replace(/ /g,"&nbsp;");}else{html=html.replace(/(^|\n) /g,"$1&nbsp;");}}
@@ -594,9 +593,11 @@
595594 context.modules.highlight.markersStr=markersStr;var visited=[],v=0;for(var i=0;i<markers.length;i++){if(typeof markers[i].skipDivision!=='undefined'&&(division==markers[i].skipDivision)){continue;}
596595 var start=markers[i].start;var s=context.fn.getOffset(start);if(!s){continue;}
597596 var startNode=s.node;while(startNode.nodeName=='BR'||s.offset==startNode.nodeValue.length){start++;s=context.fn.getOffset(start);startNode=s.node;}
598 -if(s.offset>0&&s.node.nodeName=='#text'){startNode=startNode.splitText(s.offset<s.node.nodeValue.length?s.offset:s.node.nodeValue.length-1);context.fn.purgeOffsets();}
 597+if(s.offset>0&&s.node.nodeName=='#text'){var newStartNode=startNode.splitText(s.offset<s.node.nodeValue.length?s.offset:s.node.nodeValue.length-1);var oldStartNode=startNode;startNode=newStartNode;var subtracted=s.offset;var oldLength=s.length;var j,o;for(j=start-subtracted;j<start;j++){if(j in context.offsets){o=context.offsets[j];o.node=oldStartNode;o.length=subtracted;}}
 598+for(j=start;j<start-subtracted+oldLength;j++){if(j in context.offsets){o=context.offsets[j];o.node=newStartNode;o.offset-=subtracted;o.length-=subtracted;o.lastTextNode=oldStartNode;}}}
599599 var end=markers[i].end;var e=context.fn.getOffset(end-1);if(!e){continue;}
600 -var endNode=e.node;if(e.offset+1<e.length-1&&endNode.nodeName=='#text'){var endNode=endNode.splitText(e.offset+1);context.fn.purgeOffsets();}
 600+var endNode=e.node;if(e.offset+1<e.length-1&&endNode.nodeName=='#text'){var oldEndNode=endNode;var newEndNode=endNode.splitText(e.offset+1);var subtracted=e.offset+1;var oldLength=e.length;var j,o;for(j=end-subtracted;j<end;j++){if(j in context.offsets){o=context.offsets[j];o.node=oldEndNode;o.length=subtracted;}}
 601+context.offsets[end]={'node':newEndNode,'offset':0,'length':oldLength-subtracted,'lastTextNode':oldEndNode};for(j=end+1;j<end-subtracted+oldLength;j++){if(j in context.offsets){o=context.offsets[j];o.node=newEndNode;o.offset-=subtracted;o.length-=subtracted;o.lastTextNode=oldEndNode;}}}
601602 if(endNode.nodeName=='BR'){endNode=e.lastTextNode;}
602603 if(startNode.parentNode!=endNode.parentNode){var startP=$(startNode).closest('p').get(0);var t=new context.fn.rawTraverser(startNode,startP,context.$content.get(0),false);var afterStart=startNode.nextSibling;var lastP=startP;var nextT=t.next();while(nextT&&t.node!=endNode){t=nextT;nextT=t.next();if(t.node.parentNode!=startNode.parentNode){var oldParent=t.node.parentNode;if(afterStart){if(lastP!=t.inP){startNode.parentNode.insertBefore(startNode.ownerDocument.createElement('br'),afterStart);}
603604 if(!(oldParent.childNodes.length==1&&oldParent.firstChild.nodeName=='BR')){while(oldParent.firstChild){startNode.parentNode.insertBefore(oldParent.firstChild,afterStart);}}}else{if(lastP!=t.inP){startNode.parentNode.appendChild(startNode.ownerDocument.createElement('br'));}

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r63579UsabilityInitiative: Some performance improvements for the highlighter...catrope22:04, 10 March 2010

Status & tagging log