r59678 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r59677‎ | r59678 | r59679 >
Date:21:02, 2 December 2009
Author:catrope
Status:deferred
Tags:
Comment:
UsabilityInitiative: Rewrite TOC's parsing code to be recursive, some attempts at making cursor moving work
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.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.toc.js (modified) (history)

Diff [purge]

Index: trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php
@@ -70,19 +70,19 @@
7171 array( 'src' => 'js/plugins/jquery.namespaceSelect.js', 'version' => 1 ),
7272 array( 'src' => 'js/plugins/jquery.suggestions.js', 'version' => 6 ),
7373 array( 'src' => 'js/plugins/jquery.textSelection.js', 'version' => 21 ),
74 - array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 24 ),
 74+ array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 25 ),
7575 array( 'src' => 'js/plugins/jquery.wikiEditor.highlight.js', 'version' => 1 ),
7676 array( 'src' => 'js/plugins/jquery.wikiEditor.toolbar.js', 'version' => 34 ),
7777 array( 'src' => 'js/plugins/jquery.wikiEditor.dialogs.js', 'version' => 9 ),
78 - array( 'src' => 'js/plugins/jquery.wikiEditor.toc.js', 'version' => 43 ),
 78+ array( 'src' => 'js/plugins/jquery.wikiEditor.toc.js', 'version' => 44 ),
7979 array( 'src' => 'js/plugins/jquery.wikiEditor.preview.js', 'version' => 4 ),
8080 array( 'src' => 'js/plugins/jquery.wikiEditor.publish.js', 'version' => 0 ),
8181 ),
8282 'combined' => array(
83 - array( 'src' => 'js/plugins.combined.js', 'version' => 93 ),
 83+ array( 'src' => 'js/plugins.combined.js', 'version' => 94 ),
8484 ),
8585 'minified' => array(
86 - array( 'src' => 'js/plugins.combined.min.js', 'version' => 93 ),
 86+ array( 'src' => 'js/plugins.combined.min.js', 'version' => 94 ),
8787 ),
8888 ),
8989 );
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.toc.js
@@ -139,7 +139,7 @@
140140 *
141141 * @param {Object} event Event object with context as data
142142 */
143 - expand: function( event) {
 143+ expand: function( event ) {
144144 var $this = $( this ),
145145 context = $this.data( 'context' ),
146146 openWidth = context.modules.$toc.data( 'openWidth' );
@@ -197,8 +197,12 @@
198198 var div = $( '<div />' )
199199 .addClass( 'section-' + structure[i].index )
200200 .data( 'wrapper', structure[i].wrapper )
201 - .mousedown( function( event ) {
 201+ .click( function( event ) {
202202 context.fn.scrollToTop( $(this).data( 'wrapper' ) );
 203+ context.$textarea.textSelection( 'setSelection', {
 204+ 'start': 0,
 205+ 'startContainer': $(this).data( 'wrapper' )
 206+ } );
203207 if ( typeof $.trackAction != 'undefined' )
204208 $.trackAction( 'ntoc.heading' );
205209 event.preventDefault();
@@ -307,60 +311,70 @@
308312 }
309313
310314 // Build outline from wikitext
311 - var outline = [];
 315+ var outline = [], h = 0;
312316
313317 // Traverse all text nodes in context.$content
314 - // FIXME: Doesn't traverse non-top-level text nodes, rewrite as recursive function
315 - var h = 0;
316 - context.$content.contents().add( context.$content.find( '*' ) ).each( function() {
317 - if ( this.nodeName != '#text' && !$(this).is( '.wikiEditor-toc-header' ) )
 318+ function traverseTextNodes() {
 319+ if ( this.nodeName != '#text' ) {
 320+ $( this.childNodes ).each( traverseTextNodes );
318321 return;
 322+ }
319323 var text = this.nodeValue;
320 - if ( $(this).is( 'div' ) ) {
321 - text = $(this).html();
322 - // Edge case: there are more equals signs,
323 - // but they're not all in the <div>. Eat them.
324 - var prev = this.previousSibling;
325 - if ( prev && prev.nodeName == '#text' ) {
326 - var prevText = prev.nodeValue;
327 - while ( prevText.substr( -1 ) == '=' ) {
328 - prevText = prevText.substr( 0, prevText.length - 1 );
329 - text = '=' + text;
330 - }
331 - prev.nodeValue = prevText;
 324+
 325+ // Get the previous and next node in Euler tour order
 326+ var p = this;
 327+ while( !p.previousSibling )
 328+ p = p.parentNode;
 329+ var prev = p.previousSibling;
 330+
 331+ p = this;
 332+ while ( p && !p.nextSibling )
 333+ p = p.parentNode;
 334+ var next = p.nextSibling;
 335+
 336+ // Edge case: there are more equals signs,
 337+ // but they're not all in the <div>. Eat them.
 338+ if ( prev && prev.nodeName == '#text' ) {
 339+ var prevText = prev.nodeValue;
 340+ while ( prevText.substr( -1 ) == '=' ) {
 341+ prevText = prevText.substr( 0, prevText.length - 1 );
 342+ text = '=' + text;
332343 }
333 - var next = this.nextSibling;
334 - if ( next && next.nodeName == '#text' ) {
335 - var nextText = next.nodeValue;
336 - while ( nextText.substr( 0, 1 ) == '=' ) {
337 - nextText = nextText.substr( 1 );
338 - text = text + '=';
339 - }
340 - next.nodeValue = nextText;
 344+ prev.nodeValue = prevText;
 345+ }
 346+ var next = this.nextSibling;
 347+ if ( next && next.nodeName == '#text' ) {
 348+ var nextText = next.nodeValue;
 349+ while ( nextText.substr( 0, 1 ) == '=' ) {
 350+ nextText = nextText.substr( 1 );
 351+ text = text + '=';
341352 }
342 - if ( text != $(this).html() )
343 - $(this).html( text );
 353+ next.nodeValue = nextText;
344354 }
 355+ if ( text != this.nodeValue )
 356+ this.nodeValue = text;
345357
346358 var match = text.match( /^(={1,6})(.+?)\1\s*$/ );
347359 if ( !match ) {
348 - if ( $(this).is( '.wikiEditor-toc-header' ) )
 360+ if ( $(this).parent().is( '.wikiEditor-toc-header' ) )
349361 // Header has become invalid
350362 // Remove the class but keep the <div> intact
351363 // to prevent issues with Firefox
352364 // TODO: Fix this issue
353 - //$(this).removeClass( 'wikiEditor-toc-header' );
354 - $(this).replaceWith( $(this).html() );
 365+ //$(this).parent()
 366+ // .removeClass( 'wikiEditor-toc-header' );
 367+ $(this).parent().replaceWith( text );
355368 return;
356369 }
 370+
357371 // Wrap the header in a <div>, unless it's already wrapped
358372 var div;
359 - if ( $(this).is( '.wikiEditor-toc-header' ) )
360 - div = $(this);
361 - else if ( $(this).is( 'div' ) )
362 - div = $(this).addClass( 'wikiEditor-toc-header' );
 373+ if ( $(this).parent().is( '.wikiEditor-toc-header' ) )
 374+ div = $(this).parent();
 375+ else if ( $(this).parent().is( 'div' ) )
 376+ div = $(this).parent().addClass( 'wikiEditor-toc-header' );
363377 else {
364 - div = $j( '<div />' )
 378+ div = $( '<div />' )
365379 .text( text )
366380 .css( 'display', 'inline' )
367381 .addClass( 'wikiEditor-toc-header' );
@@ -368,7 +382,9 @@
369383 }
370384 outline[h] = { 'text': match[2], 'wrapper': div, 'level': match[1].length, 'index': h + 1 };
371385 h++;
372 - });
 386+ }
 387+ context.$content.each( traverseTextNodes );
 388+
373389 // Normalize heading levels for list creation
374390 // This is based on Linker::generateTOC(), so it should behave like the
375391 // TOC on rendered articles does - which is considdered to be correct
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.js
@@ -108,7 +108,7 @@
109109 'getIcon': function( icon, path, lang ) {
110110 lang = lang || wgUserLanguage;
111111 path = path || $.wikiEditor.imgPath;
112 - var src = icon[lang] || icon.default || icon;
 112+ var src = icon[lang] || icon['default'] || icon;
113113 // Prepend path if src is not absolute
114114 if ( src.substr( 0, 7 ) != 'http://' && src.substr( 0, 8 ) != 'https://' &&
115115 src[0] != '/' )
@@ -434,9 +434,10 @@
435435 // TODO: IE
436436 var sel = context.$iframe[0].contentWindow.getSelection();
437437 // TODO: Can this be done in one call?
438 - sel.extend( startContainer, start );
 438+ sel.removeAllRanges();
 439+ sel.extend( options.startContainer, options.start );
439440 sel.collapseToStart();
440 - sel.extend( endContainer, end );
 441+ sel.extend( options.endContainer, options.end );
441442 },
442443 /**
443444 * Scroll a textarea to the current cursor position. You can set the cursor position with setSelection()
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.js
@@ -1418,7 +1418,7 @@
14191419 'getIcon': function( icon, path, lang ) {
14201420 lang = lang || wgUserLanguage;
14211421 path = path || $.wikiEditor.imgPath;
1422 - var src = icon[lang] || icon.default || icon;
 1422+ var src = icon[lang] || icon['default'] || icon;
14231423 // Prepend path if src is not absolute
14241424 if ( src.substr( 0, 7 ) != 'http://' && src.substr( 0, 8 ) != 'https://' &&
14251425 src[0] != '/' )
@@ -1744,9 +1744,10 @@
17451745 // TODO: IE
17461746 var sel = context.$iframe[0].contentWindow.getSelection();
17471747 // TODO: Can this be done in one call?
1748 - sel.extend( startContainer, start );
 1748+ sel.removeAllRanges();
 1749+ sel.extend( options.startContainer, options.start );
17491750 sel.collapseToStart();
1750 - sel.extend( endContainer, end );
 1751+ sel.extend( options.endContainer, options.end );
17511752 },
17521753 /**
17531754 * Scroll a textarea to the current cursor position. You can set the cursor position with setSelection()
@@ -2450,7 +2451,7 @@
24512452 *
24522453 * @param {Object} event Event object with context as data
24532454 */
2454 - expand: function( event) {
 2455+ expand: function( event ) {
24552456 var $this = $( this ),
24562457 context = $this.data( 'context' ),
24572458 openWidth = context.modules.$toc.data( 'openWidth' );
@@ -2508,8 +2509,12 @@
25092510 var div = $( '<div />' )
25102511 .addClass( 'section-' + structure[i].index )
25112512 .data( 'wrapper', structure[i].wrapper )
2512 - .mousedown( function( event ) {
 2513+ .click( function( event ) {
25132514 context.fn.scrollToTop( $(this).data( 'wrapper' ) );
 2515+ context.$textarea.textSelection( 'setSelection', {
 2516+ 'start': 0,
 2517+ 'startContainer': $(this).data( 'wrapper' )
 2518+ } );
25142519 if ( typeof $.trackAction != 'undefined' )
25152520 $.trackAction( 'ntoc.heading' );
25162521 event.preventDefault();
@@ -2618,60 +2623,70 @@
26192624 }
26202625
26212626 // Build outline from wikitext
2622 - var outline = [];
 2627+ var outline = [], h = 0;
26232628
26242629 // Traverse all text nodes in context.$content
2625 - // FIXME: Doesn't traverse non-top-level text nodes, rewrite as recursive function
2626 - var h = 0;
2627 - context.$content.contents().add( context.$content.find( '*' ) ).each( function() {
2628 - if ( this.nodeName != '#text' && !$(this).is( '.wikiEditor-toc-header' ) )
 2630+ function traverseTextNodes() {
 2631+ if ( this.nodeName != '#text' ) {
 2632+ $( this.childNodes ).each( traverseTextNodes );
26292633 return;
 2634+ }
26302635 var text = this.nodeValue;
2631 - if ( $(this).is( 'div' ) ) {
2632 - text = $(this).html();
2633 - // Edge case: there are more equals signs,
2634 - // but they're not all in the <div>. Eat them.
2635 - var prev = this.previousSibling;
2636 - if ( prev && prev.nodeName == '#text' ) {
2637 - var prevText = prev.nodeValue;
2638 - while ( prevText.substr( -1 ) == '=' ) {
2639 - prevText = prevText.substr( 0, prevText.length - 1 );
2640 - text = '=' + text;
2641 - }
2642 - prev.nodeValue = prevText;
 2636+
 2637+ // Get the previous and next node in Euler tour order
 2638+ var p = this;
 2639+ while( !p.previousSibling )
 2640+ p = p.parentNode;
 2641+ var prev = p.previousSibling;
 2642+
 2643+ p = this;
 2644+ while ( p && !p.nextSibling )
 2645+ p = p.parentNode;
 2646+ var next = p.nextSibling;
 2647+
 2648+ // Edge case: there are more equals signs,
 2649+ // but they're not all in the <div>. Eat them.
 2650+ if ( prev && prev.nodeName == '#text' ) {
 2651+ var prevText = prev.nodeValue;
 2652+ while ( prevText.substr( -1 ) == '=' ) {
 2653+ prevText = prevText.substr( 0, prevText.length - 1 );
 2654+ text = '=' + text;
26432655 }
2644 - var next = this.nextSibling;
2645 - if ( next && next.nodeName == '#text' ) {
2646 - var nextText = next.nodeValue;
2647 - while ( nextText.substr( 0, 1 ) == '=' ) {
2648 - nextText = nextText.substr( 1 );
2649 - text = text + '=';
2650 - }
2651 - next.nodeValue = nextText;
 2656+ prev.nodeValue = prevText;
 2657+ }
 2658+ var next = this.nextSibling;
 2659+ if ( next && next.nodeName == '#text' ) {
 2660+ var nextText = next.nodeValue;
 2661+ while ( nextText.substr( 0, 1 ) == '=' ) {
 2662+ nextText = nextText.substr( 1 );
 2663+ text = text + '=';
26522664 }
2653 - if ( text != $(this).html() )
2654 - $(this).html( text );
 2665+ next.nodeValue = nextText;
26552666 }
 2667+ if ( text != this.nodeValue )
 2668+ this.nodeValue = text;
26562669
26572670 var match = text.match( /^(={1,6})(.+?)\1\s*$/ );
26582671 if ( !match ) {
2659 - if ( $(this).is( '.wikiEditor-toc-header' ) )
 2672+ if ( $(this).parent().is( '.wikiEditor-toc-header' ) )
26602673 // Header has become invalid
26612674 // Remove the class but keep the <div> intact
26622675 // to prevent issues with Firefox
26632676 // TODO: Fix this issue
2664 - //$(this).removeClass( 'wikiEditor-toc-header' );
2665 - $(this).replaceWith( $(this).html() );
 2677+ //$(this).parent()
 2678+ // .removeClass( 'wikiEditor-toc-header' );
 2679+ $(this).parent().replaceWith( text );
26662680 return;
26672681 }
 2682+
26682683 // Wrap the header in a <div>, unless it's already wrapped
26692684 var div;
2670 - if ( $(this).is( '.wikiEditor-toc-header' ) )
2671 - div = $(this);
2672 - else if ( $(this).is( 'div' ) )
2673 - div = $(this).addClass( 'wikiEditor-toc-header' );
 2685+ if ( $(this).parent().is( '.wikiEditor-toc-header' ) )
 2686+ div = $(this).parent();
 2687+ else if ( $(this).parent().is( 'div' ) )
 2688+ div = $(this).parent().addClass( 'wikiEditor-toc-header' );
26742689 else {
2675 - div = $j( '<div />' )
 2690+ div = $( '<div />' )
26762691 .text( text )
26772692 .css( 'display', 'inline' )
26782693 .addClass( 'wikiEditor-toc-header' );
@@ -2679,7 +2694,9 @@
26802695 }
26812696 outline[h] = { 'text': match[2], 'wrapper': div, 'level': match[1].length, 'index': h + 1 };
26822697 h++;
2683 - });
 2698+ }
 2699+ context.$content.each( traverseTextNodes );
 2700+
26842701 // Normalize heading levels for list creation
26852702 // This is based on Linker::generateTOC(), so it should behave like the
26862703 // TOC on rendered articles does - which is considdered to be correct
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.min.js
@@ -86,7 +86,7 @@
8787 return $.wikiEditor.supported;if(!$.wikiEditor.isSupportKnown){return $.wikiEditor.supported=true;}
8888 var browser=$.wikiEditor.browsers[$('body').is('.rtl')?'rtl':'ltr'][$.browser.name];for(condition in browser){var op=browser[condition][0];var val=browser[condition][1];if(typeof val=='string'){if(!(eval('$.browser.version'+op+'"'+val+'"'))){return $.wikiEditor.supported=false;}}else if(typeof val=='number'){if(!(eval('$.browser.versionNumber'+op+val))){return $.wikiEditor.supported=false;}}}
8989 return $.wikiEditor.supported=true;},'autoMsg':function(object,property){if(typeof property=='object'){for(i in property){if(property[i]in object||property[i]+'Msg'in object){property=property[i];break;}}}
90 -if(property in object){return object[property];}else if(property+'Msg'in object){return gM(object[property+'Msg']);}else{return'';}},'getIcon':function(icon,path,lang){lang=lang||wgUserLanguage;path=path||$.wikiEditor.imgPath;var src=icon[lang]||icon.default||icon;if(src.substr(0,7)!='http://'&&src.substr(0,8)!='https://'&&src[0]!='/')
 90+if(property in object){return object[property];}else if(property+'Msg'in object){return gM(object[property+'Msg']);}else{return'';}},'getIcon':function(icon,path,lang){lang=lang||wgUserLanguage;path=path||$.wikiEditor.imgPath;var src=icon[lang]||icon['default']||icon;if(src.substr(0,7)!='http://'&&src.substr(0,8)!='https://'&&src[0]!='/')
9191 src=path+src;return src+'?'+wgWikiEditorIconVersion;},'fixOperaBrokenness':function(s){return s;}};$.fn.wikiEditor=function(){if($j.wikiEditor.isSupportKnown()&&!$j.wikiEditor.isSupported()){return $(this);}
9292 var context=$(this).data('wikiEditor-context');if(typeof context=='undefined'){var instance=$.wikiEditor.instances.length;context={'$textarea':$(this),'views':{},'modules':{},'data':{},'instance':instance};$.wikiEditor.instances[instance]=$(this);context.api={'addModule':function(context,data){function callModuleApi(module,call,data){if(module in $.wikiEditor.modules&&'fn'in $.wikiEditor.modules[module]&&call in $.wikiEditor.modules[module].fn){$.wikiEditor.modules[module].fn[call](context,data);}}
9393 if(typeof data=='string'){callModuleApi(data,'create',{});}else if(typeof data=='object'){for(module in data){if(typeof module=='string'){callModuleApi(module,'create',data[module]);}}}}};for(module in $.wikiEditor.modules){if('api'in $.wikiEditor.modules[module]){for(call in $.wikiEditor.modules[module].api){if(!(call in context.api)){context.api[call]=$.wikiEditor.modules[module].api[call];}}}}
@@ -104,7 +104,7 @@
105105 post+="\n";}
106106 var insertText=pre+selText+post;var insertLines=insertText.split("\n");range.extractContents();var lastNode;for(var i=insertLines.length-1;i>=0;i--){range.insertNode(document.createTextNode(insertLines[i]));if(i>0){lastNode=range.insertNode(document.createElement('br'));}}
107107 if(lastNode){context.fn.scrollToTop(lastNode);}
108 -context.$content.trigger('encapsulateSelection',[pre,options.peri,post,options.ownline,options.replace]);return context.$textarea;},'getCaretPosition':function(options){},'setSelection':function(options){var sel=context.$iframe[0].contentWindow.getSelection();sel.extend(startContainer,start);sel.collapseToStart();sel.extend(endContainer,end);},'scrollToCaretPosition':function(options){},'scrollToTop':function($element,force){var body=context.$content.closest('body');var y=$element.offset().top-context.$content.offset().top;if(force||y<body.scrollTop()||y>body.scrollTop()+body.height())
 108+context.$content.trigger('encapsulateSelection',[pre,options.peri,post,options.ownline,options.replace]);return context.$textarea;},'getCaretPosition':function(options){},'setSelection':function(options){var sel=context.$iframe[0].contentWindow.getSelection();sel.removeAllRanges();sel.extend(options.startContainer,options.start);sel.collapseToStart();sel.extend(options.endContainer,options.end);},'scrollToCaretPosition':function(options){},'scrollToTop':function($element,force){var body=context.$content.closest('body');var y=$element.offset().top-context.$content.offset().top;if(force||y<body.scrollTop()||y>body.scrollTop()+body.height())
109109 body.scrollTop(y);$element.trigger('scrollToTop');}};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';context.$iframe=$('<iframe></iframe>').attr('frameborder',0).css({'backgroundColor':'white','width':'100%','height':context.$textarea.height(),'display':'none','overflow-y':'scroll','overflow-x':'hidden',}).insertAfter(context.$textarea);setTimeout(function(){context.fn.setup();},1);context.$textarea.closest('form').submit(function(){context.$textarea.attr('disabled',false);context.$textarea.val(context.$textarea.textSelection('getContents'));});}
110110 if(arguments.length>0&&typeof arguments[0]=='object'){if(context.fn.isSetup())
111111 context.api.addModule(context,arguments[0]);else{var args=arguments;setTimeout(function(){context.api.addModule(context,args[0]);},2);}}else{arguments=$.makeArray(arguments);if(arguments.length>0){var call=arguments.shift();if(call in context.api){if(context.fn.isSetup())
@@ -150,7 +150,7 @@
151151 context.modules.$toc.scrollTop(scrollTop+relTop+sectionHeight-divHeight);}},collapse:function(event){var $this=$(this),context=$this.data('context'),pT=$this.parent().position().top-1;$this.parent().css('position','absolute').css({'left':'auto','right':0,'top':pT}).fadeOut('fast',function(){$(this).hide().css('width','1px');context.$ui.find('.wikiEditor-ui-toc-expandControl').fadeIn('fast');}).prev().animate({'marginRight':'-1px'},'fast',function(){$(this).css('marginRight',0);}).children().animate({'marginRight':'1px'},'fast',function(){$(this).css('marginRight',0);});$.cookie('wikiEditor-'+context.instance+'-toc-width',0);return false;},expand:function(event){var $this=$(this),context=$this.data('context'),openWidth=context.modules.$toc.data('openWidth');context.$ui.find('.wikiEditor-ui-toc-expandControl').hide();$this.parent().show().animate({'width':openWidth},'fast',function(){context.$content.trigger('mouseup');$(this).css({'position':'relative','right':'auto','top':'auto'});}).prev().animate({'marginRight':(parseFloat(openWidth)*-1)},'fast').children().animate({'marginRight':openWidth},'fast');$.cookie('wikiEditor-'+context.instance+'-toc-width',context.modules.$toc.data('openWidth'));return false;},build:function(context){function buildStructure(outline,offset,level){if(offset==undefined)offset=0;if(level==undefined)level=1;var sections=[];for(var i=offset;i<outline.length;i++){if(outline[i].nLevel==level){var sub=buildStructure(outline,i+1,level+1);if(sub.length){outline[i].sections=sub;}
152152 sections[sections.length]=outline[i];}else if(outline[i].nLevel<level){break;}}
153153 return sections;}
154 -function buildList(structure){var list=$('<ul />');for(i in structure){var div=$('<div />').addClass('section-'+structure[i].index).data('wrapper',structure[i].wrapper).mousedown(function(event){context.fn.scrollToTop($(this).data('wrapper'));if(typeof $.trackAction!='undefined')
 154+function buildList(structure){var list=$('<ul />');for(i in structure){var div=$('<div />').addClass('section-'+structure[i].index).data('wrapper',structure[i].wrapper).click(function(event){context.fn.scrollToTop($(this).data('wrapper'));context.$textarea.textSelection('setSelection',{'start':0,'startContainer':$(this).data('wrapper')});if(typeof $.trackAction!='undefined')
155155 $.trackAction('ntoc.heading');event.preventDefault();}).text(structure[i].text);if(structure[i].text=='')
156156 div.html('&nbsp;');var item=$('<li />').append(div);if(structure[i].sections!==undefined){item.append(buildList(structure[i].sections));}
157157 list.append(item);}
@@ -158,19 +158,21 @@
159159 function buildCollapseControls(){var $collapseControl=$('<div />'),$expandControl=$('<div />');$collapseControl.addClass('tab').addClass('tab-toc').append('<a href="#" />').bind('click.wikiEditor-toc',function(){context.modules.$toc.trigger('collapse.wikiEditor-toc');return false;}).find('a').text(gM('wikieditor-toc-hide'));$expandControl.addClass('wikiEditor-ui-toc-expandControl').append('<a href="#" />').bind('click.wikiEditor-toc',function(){context.modules.$toc.trigger('expand.wikiEditor-toc');return false;}).hide().find('a').text(gM('wikieditor-toc-show'));$collapseControl.insertBefore(context.modules.$toc);context.$ui.find('.wikiEditor-ui-left .wikiEditor-ui-top').append($expandControl);}
160160 function buildResizeControls(){context.$ui.data('resizableDone',true).find('.wikiEditor-ui-right').data('wikiEditor-ui-left',context.$ui.find('.wikiEditor-ui-left')).resizable({handles:'w,e',preventPositionLeftChange:true,minWidth:50,start:function(e,ui){var $this=$(this);$('<div />').addClass('wikiEditor-ui-resize-mask').css({'position':'absolute','z-index':2,'left':0,'top':0,'bottom':0,'right':0}).appendTo(context.$ui.find('.wikiEditor-ui-left'));$this.resizable('option','maxWidth',$this.parent().width()-450);},resize:function(e,ui){$(this).css({'width':ui.size.width,'top':'auto','height':'auto'}).data('wikiEditor-ui-left').css('marginRight',(-1*ui.size.width)).children().css('marginRight',ui.size.width);},stop:function(e,ui){context.$ui.find('.wikiEditor-ui-resize-mask').remove();context.$content.trigger('mouseup');if(ui.size.width<parseFloat($.wikiEditor.modules.toc.minimumWidth)){context.modules.$toc.trigger('collapse');}else{context.modules.$toc.data('openWidth',ui.size.width);$.cookie('wikiEditor-'+context.instance+'-toc-width',ui.size.width);}}});context.$ui.find('.ui-resizable-e').removeClass('ui-resizable-e').addClass('ui-resizable-w').addClass('wikiEditor-ui-toc-resize-grip');context.modules.$toc.bind('collapse.wikiEditor-toc',$.wikiEditor.modules.toc.fn.collapse).bind('expand.wikiEditor-toc',$.wikiEditor.modules.toc.fn.expand);context.modules.$toc.data('openWidth',$.wikiEditor.modules.toc.defaultWidth);if($.cookie('wikiEditor-'+context.instance+'-toc-width')==0){context.modules.$toc.trigger('collapse.wikiEditor-toc',{data:context});}else if($.cookie('wikiEditor-'+context.instance+'-toc-width')>0){var initialWidth=$.cookie('wikiEditor-'+context.instance+'-toc-width');if(initialWidth<parseFloat($.wikiEditor.modules.toc.minimumWidth))
161161 initialWidth=parseFloat($.wikiEditor.modules.toc.minimumWidth)+1;context.modules.$toc.data('openWidth',initialWidth+'px');context.$ui.find('.wikiEditor-ui-right').css('width',initialWidth+'px');context.$ui.find('.wikiEditor-ui-left').css('marginRight',(parseFloat(initialWidth)*-1)+'px').children().css('marginRight',initialWidth+'px');}}
162 -var outline=[];var h=0;context.$content.contents().add(context.$content.find('*')).each(function(){if(this.nodeName!='#text'&&!$(this).is('.wikiEditor-toc-header'))
163 -return;var text=this.nodeValue;if($(this).is('div')){text=$(this).html();var prev=this.previousSibling;if(prev&&prev.nodeName=='#text'){var prevText=prev.nodeValue;while(prevText.substr(-1)=='='){prevText=prevText.substr(0,prevText.length-1);text='='+text;}
 162+var outline=[],h=0;function traverseTextNodes(){if(this.nodeName!='#text'){$(this.childNodes).each(traverseTextNodes);return;}
 163+var text=this.nodeValue;var p=this;while(!p.previousSibling)
 164+p=p.parentNode;var prev=p.previousSibling;p=this;while(p&&!p.nextSibling)
 165+p=p.parentNode;var next=p.nextSibling;if(prev&&prev.nodeName=='#text'){var prevText=prev.nodeValue;while(prevText.substr(-1)=='='){prevText=prevText.substr(0,prevText.length-1);text='='+text;}
164166 prev.nodeValue=prevText;}
165167 var next=this.nextSibling;if(next&&next.nodeName=='#text'){var nextText=next.nodeValue;while(nextText.substr(0,1)=='='){nextText=nextText.substr(1);text=text+'=';}
166168 next.nodeValue=nextText;}
167 -if(text!=$(this).html())
168 -$(this).html(text);}
169 -var match=text.match(/^(={1,6})(.+?)\1\s*$/);if(!match){if($(this).is('.wikiEditor-toc-header'))
170 -$(this).replaceWith($(this).html());return;}
171 -var div;if($(this).is('.wikiEditor-toc-header'))
172 -div=$(this);else if($(this).is('div'))
173 -div=$(this).addClass('wikiEditor-toc-header');else{div=$j('<div />').text(text).css('display','inline').addClass('wikiEditor-toc-header');$(this).replaceWith(div);}
174 -outline[h]={'text':match[2],'wrapper':div,'level':match[1].length,'index':h+1};h++;});var lastLevel=0;var nLevel=0;for(var i=0;i<outline.length;i++){if(outline[i].level>lastLevel){nLevel++;}
 169+if(text!=this.nodeValue)
 170+this.nodeValue=text;var match=text.match(/^(={1,6})(.+?)\1\s*$/);if(!match){if($(this).parent().is('.wikiEditor-toc-header'))
 171+$(this).parent().replaceWith(text);return;}
 172+var div;if($(this).parent().is('.wikiEditor-toc-header'))
 173+div=$(this).parent();else if($(this).parent().is('div'))
 174+div=$(this).parent().addClass('wikiEditor-toc-header');else{div=$('<div />').text(text).css('display','inline').addClass('wikiEditor-toc-header');$(this).replaceWith(div);}
 175+outline[h]={'text':match[2],'wrapper':div,'level':match[1].length,'index':h+1};h++;}
 176+context.$content.each(traverseTextNodes);var lastLevel=0;var nLevel=0;for(var i=0;i<outline.length;i++){if(outline[i].level>lastLevel){nLevel++;}
175177 else if(outline[i].level<lastLevel){nLevel-=Math.max(1,lastLevel-outline[i].level);}
176178 if(nLevel<=0){nLevel=1;}
177179 outline[i].nLevel=nLevel;lastLevel=outline[i].level;}

Status & tagging log