r61958 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r61957‎ | r61958 | r61959 >
Date:23:40, 3 February 2010
Author:catrope
Status:deferred
Tags:
Comment:
UsabilityInitiative: Fix some more IE issues. This unbreaks the search&replace dialog in IE
* Faulty if() check caused a <p> at the beginning of the document to not receive an extra newline. Removed the if()
* Use ancestor instead of depth to keep the traverser inside the <body> ; the latter is not reliable when we deliberately hack around it
* In IE, an empty <p> shows up as "<p>&nbsp;</p>" in context.$content.html(). Clean this up in a clone of the iframe DOM before grabbing the .html()
* IE's selection functions account for <p>s and <br>s, but count one newline too many for <p>Foo</p><br><br><p>Bar</p>. Compensate for this
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)

Diff [purge]

Index: trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php
@@ -72,7 +72,7 @@
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' => 27 ),
76 - array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 99 ),
 76+ array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 100 ),
7777 array( 'src' => 'js/plugins/jquery.wikiEditor.highlight.js', 'version' => 29 ),
7878 array( 'src' => 'js/plugins/jquery.wikiEditor.toolbar.js', 'version' => 47 ),
7979 array( 'src' => 'js/plugins/jquery.wikiEditor.dialogs.js', 'version' => 12 ),
@@ -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' => 216 ),
 86+ array( 'src' => 'js/plugins.combined.js', 'version' => 217 ),
8787 ),
8888 'minified' => array(
89 - array( 'src' => 'js/plugins.combined.min.js', 'version' => 216 ),
 89+ array( 'src' => 'js/plugins.combined.min.js', 'version' => 217 ),
9090 ),
9191 ),
9292 );
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.js
@@ -458,15 +458,13 @@
459459 // Converting <p>s is wrong if there's nothing before them, so check that.
460460 // .find( '* + p' ) isn't good enough because textnodes aren't considered
461461 $pre.find( 'p' ).each( function() {
462 - if ( this.previousSibling || this.parentNode != $pre.get( 0 ) ) {
463462 var text = $( this ).text();
464463 // If this <p> is preceded by some text, add a \n at the beginning, and if
465464 // it's followed by a textnode, add a \n at the end
466465 // We need the traverser because there can be other weird stuff in between
467466
468467 // Check for preceding text
469 - // FIXME: Add an option to disable depth checking, -10 is a hack
470 - var t = new context.fn.rawTraverser( this.firstChild, -10, this ).prev();
 468+ var t = new context.fn.rawTraverser( this.firstChild, 0, this, $pre.get( 0 ) ).prev();
471469 while ( t && t.node.nodeName != '#text' && t.node.nodeName != 'BR' && t.node.nodeName != 'P' ) {
472470 t = t.prev();
473471 }
@@ -475,7 +473,7 @@
476474 }
477475
478476 // Check for following text
479 - t = new context.fn.rawTraverser( this.lastChild, -10, this ).next();
 477+ t = new context.fn.rawTraverser( this.lastChild, 0, this, $pre.get( 0 ) ).next();
480478 while ( t && t.node.nodeName != '#text' && t.node.nodeName != 'BR' && t.node.nodeName != 'P' ) {
481479 t = t.next();
482480 }
@@ -484,7 +482,6 @@
485483 text += "\n";
486484 }
487485 $( this ).text( text );
488 - }
489486 } );
490487 var retval;
491488 if ( $.browser.msie ) {
@@ -508,7 +505,22 @@
509506 * Gets the complete contents of the iframe (in plain text, not HTML)
510507 */
511508 'getContents': function() {
512 - return context.fn.htmlToText( context.$content.html() );
 509+ // For <p></p>, .html() returns <p>&nbsp;</p> in IE
 510+ // This seems to convince IE while not affecting display
 511+ var html;
 512+ if ( $.browser.msie ) {
 513+ // Don't manipulate the iframe DOM itself, causes cursor jumping issues
 514+ var $c = $( context.$content.get( 0 ).cloneNode( true ) );
 515+ $c.find( 'p' ).each( function() {
 516+ if ( $(this).html() == '' ) {
 517+ $(this).replaceWith( '<p></p>' );
 518+ }
 519+ } );
 520+ html = $c.html();
 521+ } else {
 522+ html = context.$content.html();
 523+ }
 524+ return context.fn.htmlToText( html );
513525 },
514526 /**
515527 * Gets the currently selected text in the content
@@ -737,15 +749,38 @@
738750 if ( sc ) {
739751 range.moveToElementText( sc );
740752 }
741 - range.moveStart( 'character', options.start );
 753+ range.collapse();
 754+ range.moveEnd( 'character', options.start );
 755+
742756 var range2 = context.$iframe[0].contentWindow.document.body.createTextRange();
743757 if ( ec ) {
744758 range2.moveToElementText( ec );
745759 }
746760 range2.collapse();
747761 range2.moveEnd( 'character', options.end );
748 - range.setEndPoint( 'EndToEnd', range2 );
749 - range.select();
 762+
 763+ // IE does newline emulation for <p>s: <p>foo</p><p>bar</p> becomes foo\nbar just fine
 764+ // but <p>foo</p><br><br><p>bar</p> becomes foo\n\n\n\nbar , one \n too many
 765+ // Correct for this
 766+ var matches, counted = 0;
 767+ // while ( matches = range.htmlText.match( regex ) && matches.length <= counted ) doesn't work
 768+ // because the assignment side effect hasn't happened yet when the second term is evaluated
 769+ while ( matches = range.htmlText.match( /\<\/p\>(\<br[^\>]*\>)+\<p\>/gi ) ) {
 770+ if ( matches.length <= counted )
 771+ break;
 772+ range.moveEnd( 'character', matches.length );
 773+ counted += matches.length;
 774+ }
 775+ range2.moveEnd( 'character', counted );
 776+ while ( matches = range2.htmlText.match( /\<\/p\>(\<br[^\>]*\>)+\<p\>/gi ) ) {
 777+ if ( matches.length <= counted )
 778+ break;
 779+ range2.moveEnd( 'character', matches.length );
 780+ counted += matches.length;
 781+ }
 782+
 783+ range2.setEndPoint( 'StartToEnd', range );
 784+ range2.select();
750785 }
751786 return context.$textarea;
752787 },
@@ -863,10 +898,11 @@
864899 /**
865900 * Object used by traverser(). Don't use this unless you know what you're doing
866901 */
867 - 'rawTraverser': function( node, depth, inP ) {
 902+ 'rawTraverser': function( node, depth, inP, ancestor ) {
868903 this.node = node;
869904 this.depth = depth;
870905 this.inP = inP;
 906+ this.ancestor = ancestor;
871907 this.next = function() {
872908 var p = this.node;
873909 var nextDepth = this.depth;
@@ -874,8 +910,8 @@
875911 while ( p && !p.nextSibling ) {
876912 p = p.parentNode;
877913 nextDepth--;
878 - if ( nextDepth == 0 ) {
879 - // We're back at the start node
 914+ if ( p == ancestor ) {
 915+ // We're back at the ancestor, stop here
880916 p = null;
881917 }
882918 if ( p && p.nodeName == "P" ) {
@@ -901,7 +937,7 @@
902938 }
903939 }
904940 } while ( p && p.firstChild );
905 - return p ? new context.fn.rawTraverser( p, nextDepth, nextInP ) : null;
 941+ return p ? new context.fn.rawTraverser( p, nextDepth, nextInP, this.ancestor ) : null;
906942 };
907943 this.prev = function() {
908944 var p = this.node;
@@ -910,8 +946,8 @@
911947 while ( p && !p.previousSibling ) {
912948 p = p.parentNode;
913949 prevDepth--;
914 - if ( prevDepth == 0 ) {
915 - // We're back at the start node
 950+ if ( p == ancestor ) {
 951+ // We're back at the ancestor, stop here
916952 p = null;
917953 }
918954 if ( p && p.nodeName == "P" ) {
@@ -937,7 +973,7 @@
938974 }
939975 }
940976 } while ( p && p.lastChild );
941 - return p ? new context.fn.rawTraverser( p, prevDepth, prevInP ) : null;
 977+ return p ? new context.fn.rawTraverser( p, prevDepth, prevInP, this.ancestor ) : null;
942978 };
943979 },
944980 /**
@@ -971,7 +1007,7 @@
9721008 }
9731009 }
9741010 } while ( node && node.firstChild );
975 - return new context.fn.rawTraverser( node, depth, inP );
 1011+ return new context.fn.rawTraverser( node, depth, inP, node );
9761012 },
9771013 'getOffset': function( offset ) {
9781014 if ( !context.offsets ) {
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.js
@@ -6891,15 +6891,13 @@
68926892 // Converting <p>s is wrong if there's nothing before them, so check that.
68936893 // .find( '* + p' ) isn't good enough because textnodes aren't considered
68946894 $pre.find( 'p' ).each( function() {
6895 - if ( this.previousSibling || this.parentNode != $pre.get( 0 ) ) {
68966895 var text = $( this ).text();
68976896 // If this <p> is preceded by some text, add a \n at the beginning, and if
68986897 // it's followed by a textnode, add a \n at the end
68996898 // We need the traverser because there can be other weird stuff in between
69006899
69016900 // Check for preceding text
6902 - // FIXME: Add an option to disable depth checking, -10 is a hack
6903 - var t = new context.fn.rawTraverser( this.firstChild, -10, this ).prev();
 6901+ var t = new context.fn.rawTraverser( this.firstChild, 0, this, $pre.get( 0 ) ).prev();
69046902 while ( t && t.node.nodeName != '#text' && t.node.nodeName != 'BR' && t.node.nodeName != 'P' ) {
69056903 t = t.prev();
69066904 }
@@ -6908,7 +6906,7 @@
69096907 }
69106908
69116909 // Check for following text
6912 - t = new context.fn.rawTraverser( this.lastChild, -10, this ).next();
 6910+ t = new context.fn.rawTraverser( this.lastChild, 0, this, $pre.get( 0 ) ).next();
69136911 while ( t && t.node.nodeName != '#text' && t.node.nodeName != 'BR' && t.node.nodeName != 'P' ) {
69146912 t = t.next();
69156913 }
@@ -6917,7 +6915,6 @@
69186916 text += "\n";
69196917 }
69206918 $( this ).text( text );
6921 - }
69226919 } );
69236920 var retval;
69246921 if ( $.browser.msie ) {
@@ -6941,7 +6938,22 @@
69426939 * Gets the complete contents of the iframe (in plain text, not HTML)
69436940 */
69446941 'getContents': function() {
6945 - return context.fn.htmlToText( context.$content.html() );
 6942+ // For <p></p>, .html() returns <p>&nbsp;</p> in IE
 6943+ // This seems to convince IE while not affecting display
 6944+ var html;
 6945+ if ( $.browser.msie ) {
 6946+ // Don't manipulate the iframe DOM itself, causes cursor jumping issues
 6947+ var $c = $( context.$content.get( 0 ).cloneNode( true ) );
 6948+ $c.find( 'p' ).each( function() {
 6949+ if ( $(this).html() == '' ) {
 6950+ $(this).replaceWith( '<p></p>' );
 6951+ }
 6952+ } );
 6953+ html = $c.html();
 6954+ } else {
 6955+ html = context.$content.html();
 6956+ }
 6957+ return context.fn.htmlToText( html );
69466958 },
69476959 /**
69486960 * Gets the currently selected text in the content
@@ -7170,15 +7182,38 @@
71717183 if ( sc ) {
71727184 range.moveToElementText( sc );
71737185 }
7174 - range.moveStart( 'character', options.start );
 7186+ range.collapse();
 7187+ range.moveEnd( 'character', options.start );
 7188+
71757189 var range2 = context.$iframe[0].contentWindow.document.body.createTextRange();
71767190 if ( ec ) {
71777191 range2.moveToElementText( ec );
71787192 }
71797193 range2.collapse();
71807194 range2.moveEnd( 'character', options.end );
7181 - range.setEndPoint( 'EndToEnd', range2 );
7182 - range.select();
 7195+
 7196+ // IE does newline emulation for <p>s: <p>foo</p><p>bar</p> becomes foo\nbar just fine
 7197+ // but <p>foo</p><br><br><p>bar</p> becomes foo\n\n\n\nbar , one \n too many
 7198+ // Correct for this
 7199+ var matches, counted = 0;
 7200+ // while ( matches = range.htmlText.match( regex ) && matches.length <= counted ) doesn't work
 7201+ // because the assignment side effect hasn't happened yet when the second term is evaluated
 7202+ while ( matches = range.htmlText.match( /\<\/p\>(\<br[^\>]*\>)+\<p\>/gi ) ) {
 7203+ if ( matches.length <= counted )
 7204+ break;
 7205+ range.moveEnd( 'character', matches.length );
 7206+ counted += matches.length;
 7207+ }
 7208+ range2.moveEnd( 'character', counted );
 7209+ while ( matches = range2.htmlText.match( /\<\/p\>(\<br[^\>]*\>)+\<p\>/gi ) ) {
 7210+ if ( matches.length <= counted )
 7211+ break;
 7212+ range2.moveEnd( 'character', matches.length );
 7213+ counted += matches.length;
 7214+ }
 7215+
 7216+ range2.setEndPoint( 'StartToEnd', range );
 7217+ range2.select();
71837218 }
71847219 return context.$textarea;
71857220 },
@@ -7296,10 +7331,11 @@
72977332 /**
72987333 * Object used by traverser(). Don't use this unless you know what you're doing
72997334 */
7300 - 'rawTraverser': function( node, depth, inP ) {
 7335+ 'rawTraverser': function( node, depth, inP, ancestor ) {
73017336 this.node = node;
73027337 this.depth = depth;
73037338 this.inP = inP;
 7339+ this.ancestor = ancestor;
73047340 this.next = function() {
73057341 var p = this.node;
73067342 var nextDepth = this.depth;
@@ -7307,8 +7343,8 @@
73087344 while ( p && !p.nextSibling ) {
73097345 p = p.parentNode;
73107346 nextDepth--;
7311 - if ( nextDepth == 0 ) {
7312 - // We're back at the start node
 7347+ if ( p == ancestor ) {
 7348+ // We're back at the ancestor, stop here
73137349 p = null;
73147350 }
73157351 if ( p && p.nodeName == "P" ) {
@@ -7334,7 +7370,7 @@
73357371 }
73367372 }
73377373 } while ( p && p.firstChild );
7338 - return p ? new context.fn.rawTraverser( p, nextDepth, nextInP ) : null;
 7374+ return p ? new context.fn.rawTraverser( p, nextDepth, nextInP, this.ancestor ) : null;
73397375 };
73407376 this.prev = function() {
73417377 var p = this.node;
@@ -7343,8 +7379,8 @@
73447380 while ( p && !p.previousSibling ) {
73457381 p = p.parentNode;
73467382 prevDepth--;
7347 - if ( prevDepth == 0 ) {
7348 - // We're back at the start node
 7383+ if ( p == ancestor ) {
 7384+ // We're back at the ancestor, stop here
73497385 p = null;
73507386 }
73517387 if ( p && p.nodeName == "P" ) {
@@ -7370,7 +7406,7 @@
73717407 }
73727408 }
73737409 } while ( p && p.lastChild );
7374 - return p ? new context.fn.rawTraverser( p, prevDepth, prevInP ) : null;
 7410+ return p ? new context.fn.rawTraverser( p, prevDepth, prevInP, this.ancestor ) : null;
73757411 };
73767412 },
73777413 /**
@@ -7404,7 +7440,7 @@
74057441 }
74067442 }
74077443 } while ( node && node.firstChild );
7408 - return new context.fn.rawTraverser( node, depth, inP );
 7444+ return new context.fn.rawTraverser( node, depth, inP, node );
74097445 },
74107446 'getOffset': function( offset ) {
74117447 if ( !context.offsets ) {
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.min.js
@@ -459,12 +459,13 @@
460460 event.preventDefault();return false;}).text($.wikiEditor.autoMsg(options,'title'))).appendTo(context.$tabs);}
461461 if(!context.$tabs.children().size()){addTab({'name':'wikitext','titleMsg':'wikieditor-wikitext-tab'});}
462462 addTab(options);return $('<div></div>').addClass('wikiEditor-ui-view wikiEditor-ui-view-'+options.name).hide().appendTo(context.$ui);},'htmlToText':function(html){if(html in context.htmlToTextMap){return context.htmlToTextMap[html];}
463 -var origHTML=html;html=html.replace(/\r?\n/g,"").replace(/&nbsp;/g," ").replace(/\<br[^\>]*\>/gi,"\n").replace(/\<\/p\>\<p\>/gi,"\n").replace(/\<\/p\>(\n*)\<p\>/gi,"$1\n");var leading=html.match(/^\s*/)[0];var trailing=html.match(/\s*$/)[0];html=html.substr(leading.length,html.length-leading.length-trailing.length);var $pre=$('<pre>'+html+'</pre>');$pre.find('.wikiEditor-noinclude').each(function(){$(this).remove();});$pre.find('.wikiEditor-tab').each(function(){$(this).text("\t");});$pre.find('br').each(function(){$(this).replaceWith("\n");});$pre.find('p').each(function(){if(this.previousSibling||this.parentNode!=$pre.get(0)){var text=$(this).text();var t=new context.fn.rawTraverser(this.firstChild,-10,this).prev();while(t&&t.node.nodeName!='#text'&&t.node.nodeName!='BR'&&t.node.nodeName!='P'){t=t.prev();}
 463+var origHTML=html;html=html.replace(/\r?\n/g,"").replace(/&nbsp;/g," ").replace(/\<br[^\>]*\>/gi,"\n").replace(/\<\/p\>\<p\>/gi,"\n").replace(/\<\/p\>(\n*)\<p\>/gi,"$1\n");var leading=html.match(/^\s*/)[0];var trailing=html.match(/\s*$/)[0];html=html.substr(leading.length,html.length-leading.length-trailing.length);var $pre=$('<pre>'+html+'</pre>');$pre.find('.wikiEditor-noinclude').each(function(){$(this).remove();});$pre.find('.wikiEditor-tab').each(function(){$(this).text("\t");});$pre.find('br').each(function(){$(this).replaceWith("\n");});$pre.find('p').each(function(){var text=$(this).text();var t=new context.fn.rawTraverser(this.firstChild,0,this,$pre.get(0)).prev();while(t&&t.node.nodeName!='#text'&&t.node.nodeName!='BR'&&t.node.nodeName!='P'){t=t.prev();}
464464 if(t){text="\n"+text;}
465 -t=new context.fn.rawTraverser(this.lastChild,-10,this).next();while(t&&t.node.nodeName!='#text'&&t.node.nodeName!='BR'&&t.node.nodeName!='P'){t=t.next();}
 465+t=new context.fn.rawTraverser(this.lastChild,0,this,$pre.get(0)).next();while(t&&t.node.nodeName!='#text'&&t.node.nodeName!='BR'&&t.node.nodeName!='P'){t=t.next();}
466466 if(t&&!t.inP&&t.node.nodeName=='#text'&&t.node.nodeValue.charAt(0)!='\n'&&t.node.nodeValue.charAt(0)!='\r'){text+="\n";}
467 -$(this).text(text);}});var retval;if($.browser.msie){retval=$('<pre>'+$pre.html()+'</pre>').text().replace(/\r/g,'\n');}else{retval=$pre.text();}
468 -return context.htmlToTextMap[origHTML]=leading+retval+trailing;},'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();if($.browser.opera){if(retval.rangeCount>0){retval=context.fn.htmlToText($('<pre />').append(retval.getRangeAt(0).cloneContents()).html());}else{retval='';}}}else if(context.$iframe[0].contentWindow.document.selection){retval=context.$iframe[0].contentWindow.document.selection.createRange();}
 467+$(this).text(text);});var retval;if($.browser.msie){retval=$('<pre>'+$pre.html()+'</pre>').text().replace(/\r/g,'\n');}else{retval=$pre.text();}
 468+return context.htmlToTextMap[origHTML]=leading+retval+trailing;},'getContents':function(){var html;if($.browser.msie){var $c=$(context.$content.get(0).cloneNode(true));$c.find('p').each(function(){if($(this).html()==''){$(this).replaceWith('<p></p>');}});html=$c.html();}else{html=context.$content.html();}
 469+return context.fn.htmlToText(html);},'getSelection':function(){var retval;if(context.$iframe[0].contentWindow.getSelection){retval=context.$iframe[0].contentWindow.getSelection();if($.browser.opera){if(retval.rangeCount>0){retval=context.fn.htmlToText($('<pre />').append(retval.getRangeAt(0).cloneContents()).html());}else{retval='';}}}else if(context.$iframe[0].contentWindow.document.selection){retval=context.$iframe[0].contentWindow.document.selection.createRange();}
469470 if(typeof retval.text!='undefined'){retval=context.fn.htmlToText(retval.htmlText);}else if(typeof retval.toString!='undefined'){retval=retval.toString();}
470471 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+=' ';}
471472 if(options.splitlines){selTextArr=selText.split(/\n/);}
@@ -483,8 +484,12 @@
484485 var sel=context.$iframe[0].contentWindow.getSelection();while(sc.firstChild&&sc.nodeName!='#text'){sc=sc.firstChild;}
485486 while(ec.firstChild&&ec.nodeName!='#text'){ec=ec.firstChild;}
486487 var range=context.$iframe[0].contentWindow.document.createRange();range.setStart(sc,start);range.setEnd(ec,end);sel.removeAllRanges();sel.addRange(range);context.$iframe[0].contentWindow.focus();}else if(context.$iframe[0].contentWindow.document.body.createTextRange){var range=context.$iframe[0].contentWindow.document.body.createTextRange();if(sc){range.moveToElementText(sc);}
487 -range.moveStart('character',options.start);var range2=context.$iframe[0].contentWindow.document.body.createTextRange();if(ec){range2.moveToElementText(ec);}
488 -range2.collapse();range2.moveEnd('character',options.end);range.setEndPoint('EndToEnd',range2);range.select();}
 488+range.collapse();range.moveEnd('character',options.start);var range2=context.$iframe[0].contentWindow.document.body.createTextRange();if(ec){range2.moveToElementText(ec);}
 489+range2.collapse();range2.moveEnd('character',options.end);var matches,counted=0;while(matches=range.htmlText.match(/\<\/p\>(\<br[^\>]*\>)+\<p\>/gi)){if(matches.length<=counted)
 490+break;range.moveEnd('character',matches.length);counted+=matches.length;}
 491+range2.moveEnd('character',counted);while(matches=range2.htmlText.match(/\<\/p\>(\<br[^\>]*\>)+\<p\>/gi)){if(matches.length<=counted)
 492+break;range2.moveEnd('character',matches.length);counted+=matches.length;}
 493+range2.setEndPoint('StartToEnd',range);range2.select();}
489494 return context.$textarea;},'scrollToCaretPosition':function(options){},'scrollToTop':function($element,force){var html=context.$content.closest('html'),body=context.$content.closest('body'),parentHtml=$('html'),parentBody=$('body');var y=$element.offset().top;if(!$.browser.msie&&!$element.is('body')){y=parentHtml.scrollTop()>0?y+html.scrollTop()-parentHtml.scrollTop():y;y=parentBody.scrollTop()>0?y+body.scrollTop()-parentBody.scrollTop():y;}
490495 var topBound=html.scrollTop()>body.scrollTop()?html.scrollTop():body.scrollTop(),bottomBound=topBound+context.$iframe.height();if(force||y<topBound||y>bottomBound){html.scrollTop(y);body.scrollTop(y);}
491496 $element.trigger('scrollToTop');},'beforeSelection':function(classname,strict){if(typeof classname=='undefined'){classname='';}
@@ -496,16 +501,16 @@
497502 var classStr=' '+classname+' ';while(e){if(!strict&&(!classname||(' '+e.className+' ').indexOf(classStr)!=-1)){return $(e);}
498503 var next=e.previousSibling;while(next&&next.lastChild){next=next.lastChild;}
499504 e=next||e.parentNode;strict=false;}
500 -return $([]);},'rawTraverser':function(node,depth,inP){this.node=node;this.depth=depth;this.inP=inP;this.next=function(){var p=this.node;var nextDepth=this.depth;var nextInP=this.inP;while(p&&!p.nextSibling){p=p.parentNode;nextDepth--;if(nextDepth==0){p=null;}
 505+return $([]);},'rawTraverser':function(node,depth,inP,ancestor){this.node=node;this.depth=depth;this.inP=inP;this.ancestor=ancestor;this.next=function(){var p=this.node;var nextDepth=this.depth;var nextInP=this.inP;while(p&&!p.nextSibling){p=p.parentNode;nextDepth--;if(p==ancestor){p=null;}
501506 if(p&&p.nodeName=="P"){nextInP=null;}}
502507 p=p?p.nextSibling:null;if(p&&p.nodeName=="P"){nextInP=p;}
503508 do{while(p&&(' '+p.className+' ').indexOf(' wikiEditor-noinclude ')!=-1){p=p.nextSibling;}
504 -if(p&&p.firstChild){p=p.firstChild;nextDepth++;if(p.nodeName=="P"){nextInP=p;}}}while(p&&p.firstChild);return p?new context.fn.rawTraverser(p,nextDepth,nextInP):null;};this.prev=function(){var p=this.node;var prevDepth=this.depth;var prevInP=this.inP;while(p&&!p.previousSibling){p=p.parentNode;prevDepth--;if(prevDepth==0){p=null;}
 509+if(p&&p.firstChild){p=p.firstChild;nextDepth++;if(p.nodeName=="P"){nextInP=p;}}}while(p&&p.firstChild);return p?new context.fn.rawTraverser(p,nextDepth,nextInP,this.ancestor):null;};this.prev=function(){var p=this.node;var prevDepth=this.depth;var prevInP=this.inP;while(p&&!p.previousSibling){p=p.parentNode;prevDepth--;if(p==ancestor){p=null;}
505510 if(p&&p.nodeName=="P"){prevInP=null;}}
506511 p=p?p.previousSibling:null;if(p&&p.nodeName=="P"){prevInP=p;}
507512 do{while(p&&(' '+p.className+' ').indexOf(' wikiEditor-noinclude ')!=-1){p=p.previousSibling;}
508 -if(p&&p.lastChild){p=p.lastChild;prevDepth++;if(p.nodeName=="P"){prevInP=p;}}}while(p&&p.lastChild);return p?new context.fn.rawTraverser(p,prevDepth,prevInP):null;};},'traverser':function(start){var node=start.jquery?start.get(0):start;var depth=0;var inP=node.nodeName=="P"?node:null;do{while(node&&(' '+node.className+' ').indexOf(' wikiEditor-noinclude ')!=-1){node=node.nextSibling;}
509 -if(node&&node.firstChild){node=node.firstChild;depth++;if(node.nodeName=="P"){inP=node;}}}while(node&&node.firstChild);return new context.fn.rawTraverser(node,depth,inP);},'getOffset':function(offset){if(!context.offsets){context.fn.refreshOffsets();}
 513+if(p&&p.lastChild){p=p.lastChild;prevDepth++;if(p.nodeName=="P"){prevInP=p;}}}while(p&&p.lastChild);return p?new context.fn.rawTraverser(p,prevDepth,prevInP,this.ancestor):null;};},'traverser':function(start){var node=start.jquery?start.get(0):start;var depth=0;var inP=node.nodeName=="P"?node:null;do{while(node&&(' '+node.className+' ').indexOf(' wikiEditor-noinclude ')!=-1){node=node.nextSibling;}
 514+if(node&&node.firstChild){node=node.firstChild;depth++;if(node.nodeName=="P"){inP=node;}}}while(node&&node.firstChild);return new context.fn.rawTraverser(node,depth,inP,node);},'getOffset':function(offset){if(!context.offsets){context.fn.refreshOffsets();}
510515 if(offset in context.offsets){return context.offsets[offset];}
511516 var lowerBound=-1;for(var o in context.offsets){if(o>offset){break;}
512517 lowerBound=o;}

Status & tagging log