r57100 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r57099‎ | r57100 | r57101 >
Date:13:01, 30 September 2009
Author:catrope
Status:deferred
Tags:
Comment:
* EditToolbar: (bug 20901) Cursor doesn't move to end of inserted table in Opera.
* Hopefully fix bug 20900 (JS error blocking table insertion in IE and Opera)
* Select contents of inserted table
* When inserting text or finding/replacing text, don't scroll the selection to the top if it's already visible
Modified paths:
  • /trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.php (modified) (history)
  • /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.textSelection.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.toc.js (modified) (history)

Diff [purge]

Index: trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php
@@ -63,20 +63,20 @@
6464 array( 'src' => 'js/plugins/jquery.delayedBind.js', 'version' => 1 ),
6565 array( 'src' => 'js/plugins/jquery.namespaceSelect.js', 'version' => 1 ),
6666 array( 'src' => 'js/plugins/jquery.suggestions.js', 'version' => 4 ),
67 - array( 'src' => 'js/plugins/jquery.textSelection.js', 'version' => 13 ),
 67+ array( 'src' => 'js/plugins/jquery.textSelection.js', 'version' => 14 ),
6868 array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 7 ),
6969 array( 'src' => 'js/plugins/jquery.wikiEditor.toolbar.js', 'version' => 11 ),
7070 array( 'src' => 'js/plugins/jquery.wikiEditor.dialogs.js', 'version' => 3 ),
71 - array( 'src' => 'js/plugins/jquery.wikiEditor.toc.js', 'version' => 12 ),
 71+ array( 'src' => 'js/plugins/jquery.wikiEditor.toc.js', 'version' => 13 ),
7272 // FIXME: jQuery UI doesn't belong here, should move to no_js2
7373 // once we figure out how to do jQuery UI properly in JS2
7474 array( 'src' => 'js/js2/jquery-ui-1.7.2.js', 'version' => '1.7.2y' ),
7575 ),
7676 'combined' => array(
77 - array( 'src' => 'js/plugins.combined.js', 'version' => 32 ),
 77+ array( 'src' => 'js/plugins.combined.js', 'version' => 33 ),
7878 ),
7979 'minified' => array(
80 - array( 'src' => 'js/plugins.combined.min.js', 'version' => 32 ),
 80+ array( 'src' => 'js/plugins.combined.min.js', 'version' => 33 ),
8181 ),
8282 ),
8383 );
Index: trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.js
@@ -1111,7 +1111,6 @@
11121112 var rows = parseInt( $j( '#edittoolbar-table-dimensions-rows' ).val() );
11131113 var cols = parseInt( $j( '#edittoolbar-table-dimensions-columns' ).val() );
11141114 var header = Math.min( 1, $j( '#edittoolbar-table-dimensions-header:checked' ).size() );
1115 - var table = "{|\n";
11161115 if ( isNaN( rows ) || isNaN( cols ) ) {
11171116 alert( gM( 'edittoolbar-tool-table-invalidnumber' ) );
11181117 return;
@@ -1124,6 +1123,7 @@
11251124 alert( gM( 'edittoolbar-tool-table-toomany', 1000 ) );
11261125 return;
11271126 }
 1127+ var table = "";
11281128 for ( var r = 0; r < rows + header; r++ ) {
11291129 table += "|-\n";
11301130 for ( var c = 0; c < cols; c++ ) {
@@ -1141,13 +1141,14 @@
11421142 // table[table.length - 1] is read-only
11431143 table = table.substr( 0, table.length - 1 ) + "\n";
11441144 }
1145 - table += "|}";
11461145 $j.wikiEditor.modules.toolbar.fn.doAction(
11471146 $j(this).data( 'context' ),
11481147 {
11491148 type: 'encapsulate',
11501149 options: {
1151 - pre: table,
 1150+ pre: "{|\n",
 1151+ peri: table,
 1152+ post: "|}",
11521153 ownline: true
11531154 }
11541155 },
@@ -1252,6 +1253,9 @@
12531254 } else {
12541255 var start = text.indexOf( matches[0],
12551256 $j(this).data( 'offset' ) );
 1257+ if ( start == -1 )
 1258+ // Search hit BOTTOM, continuing at TOP
 1259+ start = text.indexOf( matches[0] );
12561260 var end = start + matches[0].length;
12571261 var newEnd = start + replaceStr.length;
12581262 $textarea.setSelection( start, end );
Index: trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.php
@@ -19,7 +19,7 @@
2020 /* Configuration */
2121
2222 // Bump the version number every time you change any of the .css/.js files
23 -$wgEditToolbarStyleVersion = 45;
 23+$wgEditToolbarStyleVersion = 46;
2424
2525 // Set this to true to simply override the stock toolbar for everyone
2626 $wgEditToolbarGlobalEnable = false;
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.textSelection.js
@@ -43,15 +43,42 @@
4444 } else if ( selText.charAt( selText.length - 1 ) == ' ' ) {
4545 // Exclude ending space char
4646 selText = selText.substring(0, selText.length - 1);
47 - post += ' '
 47+ post += ' ';
4848 }
4949 }
5050 var selText = $(this).getSelection();
5151 var isSample = false;
5252 if ( this.style.display == 'none' ) {
5353 // Do nothing
 54+ } else if ( this.selectionStart || this.selectionStart == '0' ) {
 55+ // Mozilla/Opera
 56+ $(this).focus();
 57+ var startPos = this.selectionStart;
 58+ var endPos = this.selectionEnd;
 59+ checkSelectedText();
 60+ if ( ownline ) {
 61+ if ( startPos != 0 && this.value.charAt( startPos - 1 ) != "\n" ) {
 62+ pre = "\n" + pre;
 63+ }
 64+ if ( this.value.charAt( endPos ) != "\n" ) {
 65+ post += "\n";
 66+ }
 67+ }
 68+ this.value = this.value.substring( 0, startPos ) + pre + selText + post + this.value.substring( endPos, this.value.length );
 69+ if ( window.opera ) {
 70+ pre = pre.replace( /\r?\n/g, "\r\n" );
 71+ selText = selText.replace( /\r?\n/g, "\r\n" );
 72+ post = post.replace( /\r?\n/g, "\r\n" );
 73+ }
 74+ if ( isSample ) {
 75+ this.selectionStart = startPos + pre.length;
 76+ this.selectionEnd = startPos + pre.length + selText.length;
 77+ } else {
 78+ this.selectionStart = startPos + pre.length + selText.length + post.length;
 79+ this.selectionEnd = this.selectionStart;
 80+ }
5481 } else if ( document.selection && document.selection.createRange ) {
55 - // IE/Opera
 82+ // IE
5683 $(this).focus();
5784 var range = document.selection.createRange();
5885 if ( ownline && range.moveStart ) {
@@ -59,7 +86,7 @@
6087 range2.collapse();
6188 range2.moveStart( 'character', -1 );
6289 // FIXME: Which check is correct?
63 - if ( range2.text != "\r" && range2.text != "\n" && range3.text != "" ) {
 90+ if ( range2.text != "\r" && range2.text != "\n" && range2.text != "" ) {
6491 pre = "\n" + pre;
6592 }
6693 var range3 = document.selection.createRange();
@@ -72,35 +99,10 @@
73100 checkSelectedText();
74101 range.text = pre + selText + post;
75102 if ( isSample && range.moveStart ) {
76 - if ( window.opera ) {
77 - post = post.replace( /\n/g, '' );
78 - }
79103 range.moveStart( 'character', - post.length - selText.length );
80104 range.moveEnd( 'character', - post.length );
81105 }
82106 range.select();
83 - } else if ( this.selectionStart || this.selectionStart == '0' ) {
84 - // Mozilla
85 - $(this).focus();
86 - var startPos = this.selectionStart;
87 - var endPos = this.selectionEnd;
88 - checkSelectedText();
89 - if ( ownline ) {
90 - if ( startPos != 0 && this.value.charAt( startPos - 1 ) != "\n" ) {
91 - pre = "\n" + pre;
92 - }
93 - if ( this.value.charAt( endPos ) != "\n" ) {
94 - post += "\n";
95 - }
96 - }
97 - this.value = this.value.substring( 0, startPos ) + pre + selText + post + this.value.substring( endPos, this.value.length );
98 - if ( isSample ) {
99 - this.selectionStart = startPos + pre.length;
100 - this.selectionEnd = startPos + pre.length + selText.length;
101 - } else {
102 - this.selectionStart = startPos + pre.length + selText.length + post.length;
103 - this.selectionEnd = this.selectionStart;
104 - }
105107 }
106108 // Scroll the textarea to the inserted text
107109 $(this).scrollToCaretPosition();
@@ -219,9 +221,10 @@
220222 *
221223 * Scroll a textarea to the current cursor position. You can set the cursor
222224 * position with setSelection()
223 - * @param pos Byte offset
 225+ * @param force boolean Whether to force a scroll even if the caret position
 226+ * is already visible. Defaults to false
224227 */
225 -scrollToCaretPosition: function() {
 228+scrollToCaretPosition: function( force ) {
226229 function getLineLength( e ) {
227230 return Math.floor( e.scrollWidth / ( $.os.name == 'linux' ? 7 : 8 ) );
228231 }
@@ -272,12 +275,15 @@
273276 $(this).focus();
274277 if ( this.selectionStart || this.selectionStart == '0' ) {
275278 // Mozilla
276 - $(this).scrollTop( getCaretScrollPosition( this ) );
 279+ var scroll = getCaretScrollPosition( this );
 280+ if ( force || scroll < $(this).scrollTop() ||
 281+ scroll > $(this).scrollTop() + $(this).height() )
 282+ $(this).scrollTop( scroll );
277283 } else if ( document.selection && document.selection.createRange ) {
278284 // IE / Opera
279285 /*
280286 * IE automatically scrolls the selected text to the
281 - * bottom of the textarea at setSelection() time, except
 287+ * bottom of the textarea at range.select() time, except
282288 * if it was already in view and the cursor position
283289 * wasn't changed, in which case it does nothing. To
284290 * cover that case, we'll force it to act by moving one
@@ -285,13 +291,17 @@
286292 */
287293 var range = document.selection.createRange();
288294 var pos = $(this).getCaretPosition();
 295+ var oldScrollTop = this.scrollTop;
289296 range.moveToElementText( this );
290297 range.collapse();
291298 range.move( 'character', pos + 1);
292299 range.select();
293 - this.scrollTop += range.offsetTop;
294 - range.move( 'character', -1 );
295 - range.select();
 300+ if ( this.scrollTop != oldScrollTop )
 301+ this.scrollTop += range.offsetTop;
 302+ else if ( force ) {
 303+ range.move( 'character', -1 );
 304+ range.select();
 305+ }
296306 }
297307 $(this).trigger( 'scrollToPosition' );
298308 } );
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.toc.js
@@ -159,7 +159,7 @@
160160 .click( function( event ) {
161161 $(this).data( 'textbox' )
162162 .setSelection( $(this).data( 'position' ) )
163 - .scrollToCaretPosition();
 163+ .scrollToCaretPosition( true );
164164 event.preventDefault();
165165 } )
166166 .text( structure[i].text )
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.js
@@ -855,15 +855,42 @@
856856 } else if ( selText.charAt( selText.length - 1 ) == ' ' ) {
857857 // Exclude ending space char
858858 selText = selText.substring(0, selText.length - 1);
859 - post += ' '
 859+ post += ' ';
860860 }
861861 }
862862 var selText = $(this).getSelection();
863863 var isSample = false;
864864 if ( this.style.display == 'none' ) {
865865 // Do nothing
 866+ } else if ( this.selectionStart || this.selectionStart == '0' ) {
 867+ // Mozilla/Opera
 868+ $(this).focus();
 869+ var startPos = this.selectionStart;
 870+ var endPos = this.selectionEnd;
 871+ checkSelectedText();
 872+ if ( ownline ) {
 873+ if ( startPos != 0 && this.value.charAt( startPos - 1 ) != "\n" ) {
 874+ pre = "\n" + pre;
 875+ }
 876+ if ( this.value.charAt( endPos ) != "\n" ) {
 877+ post += "\n";
 878+ }
 879+ }
 880+ this.value = this.value.substring( 0, startPos ) + pre + selText + post + this.value.substring( endPos, this.value.length );
 881+ if ( window.opera ) {
 882+ pre = pre.replace( /\r?\n/g, "\r\n" );
 883+ selText = selText.replace( /\r?\n/g, "\r\n" );
 884+ post = post.replace( /\r?\n/g, "\r\n" );
 885+ }
 886+ if ( isSample ) {
 887+ this.selectionStart = startPos + pre.length;
 888+ this.selectionEnd = startPos + pre.length + selText.length;
 889+ } else {
 890+ this.selectionStart = startPos + pre.length + selText.length + post.length;
 891+ this.selectionEnd = this.selectionStart;
 892+ }
866893 } else if ( document.selection && document.selection.createRange ) {
867 - // IE/Opera
 894+ // IE
868895 $(this).focus();
869896 var range = document.selection.createRange();
870897 if ( ownline && range.moveStart ) {
@@ -871,7 +898,7 @@
872899 range2.collapse();
873900 range2.moveStart( 'character', -1 );
874901 // FIXME: Which check is correct?
875 - if ( range2.text != "\r" && range2.text != "\n" && range3.text != "" ) {
 902+ if ( range2.text != "\r" && range2.text != "\n" && range2.text != "" ) {
876903 pre = "\n" + pre;
877904 }
878905 var range3 = document.selection.createRange();
@@ -884,35 +911,10 @@
885912 checkSelectedText();
886913 range.text = pre + selText + post;
887914 if ( isSample && range.moveStart ) {
888 - if ( window.opera ) {
889 - post = post.replace( /\n/g, '' );
890 - }
891915 range.moveStart( 'character', - post.length - selText.length );
892916 range.moveEnd( 'character', - post.length );
893917 }
894918 range.select();
895 - } else if ( this.selectionStart || this.selectionStart == '0' ) {
896 - // Mozilla
897 - $(this).focus();
898 - var startPos = this.selectionStart;
899 - var endPos = this.selectionEnd;
900 - checkSelectedText();
901 - if ( ownline ) {
902 - if ( startPos != 0 && this.value.charAt( startPos - 1 ) != "\n" ) {
903 - pre = "\n" + pre;
904 - }
905 - if ( this.value.charAt( endPos ) != "\n" ) {
906 - post += "\n";
907 - }
908 - }
909 - this.value = this.value.substring( 0, startPos ) + pre + selText + post + this.value.substring( endPos, this.value.length );
910 - if ( isSample ) {
911 - this.selectionStart = startPos + pre.length;
912 - this.selectionEnd = startPos + pre.length + selText.length;
913 - } else {
914 - this.selectionStart = startPos + pre.length + selText.length + post.length;
915 - this.selectionEnd = this.selectionStart;
916 - }
917919 }
918920 // Scroll the textarea to the inserted text
919921 $(this).scrollToCaretPosition();
@@ -1031,9 +1033,10 @@
10321034 *
10331035 * Scroll a textarea to the current cursor position. You can set the cursor
10341036 * position with setSelection()
1035 - * @param pos Byte offset
 1037+ * @param force boolean Whether to force a scroll even if the caret position
 1038+ * is already visible. Defaults to false
10361039 */
1037 -scrollToCaretPosition: function() {
 1040+scrollToCaretPosition: function( force ) {
10381041 function getLineLength( e ) {
10391042 return Math.floor( e.scrollWidth / ( $.os.name == 'linux' ? 7 : 8 ) );
10401043 }
@@ -1084,12 +1087,15 @@
10851088 $(this).focus();
10861089 if ( this.selectionStart || this.selectionStart == '0' ) {
10871090 // Mozilla
1088 - $(this).scrollTop( getCaretScrollPosition( this ) );
 1091+ var scroll = getCaretScrollPosition( this );
 1092+ if ( force || scroll < $(this).scrollTop() ||
 1093+ scroll > $(this).scrollTop() + $(this).height() )
 1094+ $(this).scrollTop( scroll );
10891095 } else if ( document.selection && document.selection.createRange ) {
10901096 // IE / Opera
10911097 /*
10921098 * IE automatically scrolls the selected text to the
1093 - * bottom of the textarea at setSelection() time, except
 1099+ * bottom of the textarea at range.select() time, except
10941100 * if it was already in view and the cursor position
10951101 * wasn't changed, in which case it does nothing. To
10961102 * cover that case, we'll force it to act by moving one
@@ -1097,13 +1103,17 @@
10981104 */
10991105 var range = document.selection.createRange();
11001106 var pos = $(this).getCaretPosition();
 1107+ var oldScrollTop = this.scrollTop;
11011108 range.moveToElementText( this );
11021109 range.collapse();
11031110 range.move( 'character', pos + 1);
11041111 range.select();
1105 - this.scrollTop += range.offsetTop;
1106 - range.move( 'character', -1 );
1107 - range.select();
 1112+ if ( this.scrollTop != oldScrollTop )
 1113+ this.scrollTop += range.offsetTop;
 1114+ else if ( force ) {
 1115+ range.move( 'character', -1 );
 1116+ range.select();
 1117+ }
11081118 }
11091119 $(this).trigger( 'scrollToPosition' );
11101120 } );
@@ -2157,7 +2167,7 @@
21582168 .click( function( event ) {
21592169 $(this).data( 'textbox' )
21602170 .setSelection( $(this).data( 'position' ) )
2161 - .scrollToCaretPosition();
 2171+ .scrollToCaretPosition( true );
21622172 event.preventDefault();
21632173 } )
21642174 .text( structure[i].text )
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.min.js
@@ -52,14 +52,14 @@
5353 context.data.$textbox.focus();})).appendTo($('body'));$(this).attr('autocomplete','off').keydown(function(e){context.data.keypressed=(e.keyCode==undefined)?e.which:e.keyCode;context.data.keypressedCount=0;switch(context.data.keypressed){case 40:e.preventDefault();e.stopImmediatePropagation();break;case 38:case 27:case 13:if(context.data.$container.is(':visible')){e.preventDefault();e.stopImmediatePropagation();}}}).keypress(function(e){context.data.keypressedCount++;$.suggestions.keypress(e,context,context.data.keypressed);}).keyup(function(e){if(context.data.keypressedCount==0){$.suggestions.keypress(e,context,context.data.keypressed);}}).blur(function(){if(context.data.mouseDownOn.size()>0){return;}
5454 context.data.$container.hide();$.suggestions.cancel(context);});}
5555 $(this).data('suggestions-context',context);});return returnValue!==null?returnValue:$(this);};})(jQuery);(function($){$.fn.extend({getSelection:function(){var e=this.jquery?this[0]:this;var retval='';if(e.style.display=='none'){}else if(document.selection&&document.selection.createRange){var range=document.selection.createRange();retval=range.text;}else if(e.selectionStart||e.selectionStart=='0'){retval=e.value.substring(e.selectionStart,e.selectionEnd);}
56 -return retval;},encapsulateSelection:function(pre,peri,post,ownline,replace){return this.each(function(){function checkSelectedText(){if(!selText){selText=peri;isSample=true;}else if(replace){selText=peri;}else if(selText.charAt(selText.length-1)==' '){selText=selText.substring(0,selText.length-1);post+=' '}}
57 -var selText=$(this).getSelection();var isSample=false;if(this.style.display=='none'){}else if(document.selection&&document.selection.createRange){$(this).focus();var range=document.selection.createRange();if(ownline&&range.moveStart){var range2=document.selection.createRange();range2.collapse();range2.moveStart('character',-1);if(range2.text!="\r"&&range2.text!="\n"&&range3.text!=""){pre="\n"+pre;}
 56+return retval;},encapsulateSelection:function(pre,peri,post,ownline,replace){return this.each(function(){function checkSelectedText(){if(!selText){selText=peri;isSample=true;}else if(replace){selText=peri;}else if(selText.charAt(selText.length-1)==' '){selText=selText.substring(0,selText.length-1);post+=' ';}}
 57+var selText=$(this).getSelection();var isSample=false;if(this.style.display=='none'){}else if(this.selectionStart||this.selectionStart=='0'){$(this).focus();var startPos=this.selectionStart;var endPos=this.selectionEnd;checkSelectedText();if(ownline){if(startPos!=0&&this.value.charAt(startPos-1)!="\n"){pre="\n"+pre;}
 58+if(this.value.charAt(endPos)!="\n"){post+="\n";}}
 59+this.value=this.value.substring(0,startPos)+pre+selText+post+this.value.substring(endPos,this.value.length);if(window.opera){pre=pre.replace(/\r?\n/g,"\r\n");selText=selText.replace(/\r?\n/g,"\r\n");post=post.replace(/\r?\n/g,"\r\n");}
 60+if(isSample){this.selectionStart=startPos+pre.length;this.selectionEnd=startPos+pre.length+selText.length;}else{this.selectionStart=startPos+pre.length+selText.length+post.length;this.selectionEnd=this.selectionStart;}}else if(document.selection&&document.selection.createRange){$(this).focus();var range=document.selection.createRange();if(ownline&&range.moveStart){var range2=document.selection.createRange();range2.collapse();range2.moveStart('character',-1);if(range2.text!="\r"&&range2.text!="\n"&&range2.text!=""){pre="\n"+pre;}
5861 var range3=document.selection.createRange();range3.collapse(false);range3.moveEnd('character',1);if(range3.text!="\r"&&range3.text!="\n"&&range3.text!=""){post+="\n";}}
59 -checkSelectedText();range.text=pre+selText+post;if(isSample&&range.moveStart){if(window.opera){post=post.replace(/\n/g,'');}
60 -range.moveStart('character',-post.length-selText.length);range.moveEnd('character',-post.length);}
61 -range.select();}else if(this.selectionStart||this.selectionStart=='0'){$(this).focus();var startPos=this.selectionStart;var endPos=this.selectionEnd;checkSelectedText();if(ownline){if(startPos!=0&&this.value.charAt(startPos-1)!="\n"){pre="\n"+pre;}
62 -if(this.value.charAt(endPos)!="\n"){post+="\n";}}
63 -this.value=this.value.substring(0,startPos)+pre+selText+post+this.value.substring(endPos,this.value.length);if(isSample){this.selectionStart=startPos+pre.length;this.selectionEnd=startPos+pre.length+selText.length;}else{this.selectionStart=startPos+pre.length+selText.length+post.length;this.selectionEnd=this.selectionStart;}}
 62+checkSelectedText();range.text=pre+selText+post;if(isSample&&range.moveStart){range.moveStart('character',-post.length-selText.length);range.moveEnd('character',-post.length);}
 63+range.select();}
6464 $(this).scrollToCaretPosition();$(this).trigger('encapsulateSelection',[pre,peri,post,ownline,replace]);});},getCaretPosition:function(){function getCaret(e){var caretPos=0;if($.browser.msie){var postFinished=false;var periFinished=false;var postFinished=false;var preText,rawPreText,periText;var rawPeriText,postText,rawPostText;var periRange=document.selection.createRange().duplicate();var preRange=document.body.createTextRange();preRange.moveToElementText(e);preRange.setEndPoint("EndToStart",periRange);var postRange=document.body.createTextRange();postRange.moveToElementText(e);postRange.setEndPoint("StartToEnd",periRange);preText=rawPreText=preRange.text;periText=rawPeriText=periRange.text;postText=rawPostText=postRange.text;do{if(!postFinished){if(preRange.compareEndPoints("StartToEnd",preRange)==0){postFinished=true;}else{preRange.moveEnd("character",-1)
6565 if(preRange.text==preText){rawPreText+="\r\n";}else{postFinished=true;}}}
6666 if(!periFinished){if(periRange.compareEndPoints("StartToEnd",periRange)==0){periFinished=true;}else{periRange.moveEnd("character",-1)
@@ -68,13 +68,15 @@
6969 if(postRange.text==postText){rawPostText+="\r\n";}else{postFinished=true;}}}}while((!postFinished||!periFinished||!postFinished));caretPos=rawPreText.replace(/\r\n/g,"\n").length;}else if(e.selectionStart||e.selectionStart=='0'){caretPos=e.selectionStart;}
7070 return caretPos;}
7171 return getCaret(this.get(0));},setSelection:function(start,end){if(typeof end=='undefined')
72 -end=start;return this.each(function(){if(this.selectionStart||this.selectionStart=='0'){this.selectionStart=start;this.selectionEnd=end;}else if(document.body.createTextRange){var selection=document.body.createTextRange();selection.moveToElementText(this);var length=selection.text.length;selection.moveStart('character',start);selection.moveEnd('character',-length+end);selection.select();}});},scrollToCaretPosition:function(){function getLineLength(e){return Math.floor(e.scrollWidth/($.os.name=='linux'?7:8));}
 72+end=start;return this.each(function(){if(this.selectionStart||this.selectionStart=='0'){this.selectionStart=start;this.selectionEnd=end;}else if(document.body.createTextRange){var selection=document.body.createTextRange();selection.moveToElementText(this);var length=selection.text.length;selection.moveStart('character',start);selection.moveEnd('character',-length+end);selection.select();}});},scrollToCaretPosition:function(force){function getLineLength(e){return Math.floor(e.scrollWidth/($.os.name=='linux'?7:8));}
7373 function getCaretScrollPosition(e){var text=e.value.replace(/\r/g,"");var caret=$(e).getCaretPosition();var lineLength=getLineLength(e);var row=0;var charInLine=0;var lastSpaceInLine=0;for(i=0;i<caret;i++){charInLine++;if(text.charAt(i)==" "){lastSpaceInLine=charInLine;}else if(text.charAt(i)=="\n"){lastSpaceInLine=0;charInLine=0;row++;}
7474 if(charInLine>lineLength){if(lastSpaceInLine>0){charInLine=charInLine-lastSpaceInLine;lastSpaceInLine=0;row++;}}}
7575 var nextSpace=0;for(j=caret;j<caret+lineLength;j++){if(text.charAt(j)==" "||text.charAt(j)=="\n"||caret==text.length){nextSpace=j;break;}}
7676 if(nextSpace>lineLength&&caret<=lineLength){charInLine=caret-lastSpaceInLine;row++;}
7777 return($.os.name=='mac'?13:($.os.name=='linux'?15:16))*row;}
78 -return this.each(function(){$(this).focus();if(this.selectionStart||this.selectionStart=='0'){$(this).scrollTop(getCaretScrollPosition(this));}else if(document.selection&&document.selection.createRange){var range=document.selection.createRange();var pos=$(this).getCaretPosition();range.moveToElementText(this);range.collapse();range.move('character',pos+1);range.select();this.scrollTop+=range.offsetTop;range.move('character',-1);range.select();}
 78+return this.each(function(){$(this).focus();if(this.selectionStart||this.selectionStart=='0'){var scroll=getCaretScrollPosition(this);if(force||scroll<$(this).scrollTop()||scroll>$(this).scrollTop()+$(this).height())
 79+$(this).scrollTop(scroll);}else if(document.selection&&document.selection.createRange){var range=document.selection.createRange();var pos=$(this).getCaretPosition();var oldScrollTop=this.scrollTop;range.moveToElementText(this);range.collapse();range.move('character',pos+1);range.select();if(this.scrollTop!=oldScrollTop)
 80+this.scrollTop+=range.offsetTop;else if(force){range.move('character',-1);range.select();}}
7981 $(this).trigger('scrollToPosition');});}});})(jQuery);(function($){$.wikiEditor={'modules':{},'instances':[],'supportedBrowsers':{'ltr':{'msie':7,'firefox':2,'opera':9,'safari':3,'chrome':1,'camino':1},'rtl':{'msie':8,'firefox':2,'opera':9,'safari':3,'chrome':1,'camino':1}},imgPath:wgScriptPath+'/extensions/UsabilityInitiative/images/wikiEditor/'};$.wikiEditor.isSupportKnown=function(){return(function(supportedBrowsers){return $.browser.name in supportedBrowsers;})($.wikiEditor.supportedBrowsers[$('body.rtl').size()?'rtl':'ltr']);};$.wikiEditor.isSupported=function(){return(function(supportedBrowsers){return $.browser.name in supportedBrowsers&&$.browser.versionNumber>=supportedBrowsers[$.browser.name];})($.wikiEditor.supportedBrowsers[$('body.rtl').size()?'rtl':'ltr']);};$.wikiEditor.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;}}}
8082 if(property in object){return object[property];}else if(property+'Msg'in object){return gM(object[property+'Msg']);}else{return'';}};$.wikiEditor.fixOperaBrokenness=function(s){if(typeof $.isOperaBroken=='undefined'&&$.wikiEditor.instances.length>0){var div=$('<div />').height(0).width(0).insertBefore($.wikiEditor.instances[0]);var textarea=$('<textarea></textarea').height(0).appendTo(div).val("foo\r\nbar");var index=textarea.val().indexOf('bar');textarea.select();textarea.setSelection(index,index+3);textarea.encapsulateSelection('','BAR','',false,true);if(textarea.val().substr(-1)=='R')
8183 $.isOperaBroken=false;else
@@ -142,7 +144,7 @@
143145 context.modules.$toc.scrollTop(scrollTop+relTop+sectionHeight-divHeight);}},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;}
144146 sections[sections.length]=outline[i];}else if(outline[i].nLevel<level){break;}}
145147 return sections;}
146 -function buildList(structure){var list=$('<ul></ul>');for(i in structure){var item=$('<li></li>').append($('<a></a>').attr('href','#').addClass('section-'+structure[i].index).data('textbox',context.$textarea).data('position',structure[i].position).click(function(event){$(this).data('textbox').setSelection($(this).data('position')).scrollToCaretPosition();event.preventDefault();}).text(structure[i].text));if(structure[i].sections!==undefined){item.append(buildList(structure[i].sections));}
 148+function buildList(structure){var list=$('<ul></ul>');for(i in structure){var item=$('<li></li>').append($('<a></a>').attr('href','#').addClass('section-'+structure[i].index).data('textbox',context.$textarea).data('position',structure[i].position).click(function(event){$(this).data('textbox').setSelection($(this).data('position')).scrollToCaretPosition(true);event.preventDefault();}).text(structure[i].text));if(structure[i].sections!==undefined){item.append(buildList(structure[i].sections));}
147149 list.append(item);}
148150 return list;}
149151 var outline=[];var wikitext='\n'+$.wikiEditor.fixOperaBrokenness(context.$textarea.val())+'\n';var headings=wikitext.match(/(\r|\n)={1,5}.*={1,5}(?=(\r|\n))/g);var offset=0;headings=$.makeArray(headings);for(var h=0;h<headings.length;h++){text=headings[h];var position=wikitext.indexOf(text,offset);if(position>offset){offset=position+1;}else if(position==-1){continue;}

Follow-up revisions

RevisionCommit summaryAuthorDate
r57409EditToolbar: (bug 20900) Tables inserted on top regardless of cursor position...catrope21:43, 5 October 2009

Status & tagging log