2 * Legacy emulation for the now depricated skins/common/edit.js
9 $.extend( true, mw
.legacy
, {
11 /* Global Variables */
13 'currentFocused': null,
18 * Generates the actual toolbar buttons with localized text we use it to avoid creating the toolbar
19 * where javascript is not enabled
21 'addButton': function( imageFile
, speedTip
, tagOpen
, tagClose
, sampleText
, imageId
) {
22 // Don't generate buttons for browsers which don't fully support it.
23 mw
.legacy
.mwEditButtons
.push( {
25 'imageFile': imageFile
,
29 'sampleText': sampleText
33 * Generates the actual toolbar buttons with localized text we use it to avoid creating the toolbar where JavaScript
36 'mwInsertEditButton': function( parent
, item
) {
37 var $image
= $( '<img />' )
41 'class': 'mw-toolbar-editbutton',
42 'id': item
.imageId
? item
.imageId
: null,
43 'src': = item
.imageFile
,
46 'title': item
.speedTip
48 .css( 'cursor', 'pointer' )
50 mw
.legacy
.insertTags( item
.tagOpen
, item
.tagClose
, item
.sampleText
);
52 if ( typeof $.trackAction
!= 'undefined' ) {
53 $.trackAction( 'oldedit.' + item
.speedTip
.replace( / /g
, '-' ) );
57 .appendTo( $( parent
) );
63 'mwSetupToolbar': function() {
64 var $toolbar
= $( '#toolbar' );
65 var $textbox
= $( 'textarea' ).get( 0 );
66 if ( !$toolbar
.length
|| !$textbox
.length
) {
69 // Only check for selection capability if the textarea is visible - errors will occur otherwise - just because
70 // the textarea is not visible, doesn't mean we shouldn't build out the toolbar though - it might have been
71 // replaced with some other kind of control
73 $textbox
.is( ':visible' ) &&
74 !( document
.selection
&& document
.selection
.createRange
) &&
75 textboxes
[0].selectionStart
=== null
79 for ( var i
= 0; i
< mw
.legacy
.mwEditButtons
.length
; i
++ ) {
80 mw
.legacy
.mwInsertEditButton( $toolbar
, mw
.legacy
.mwEditButtons
[i
] );
82 for ( var i
= 0; i
< mw
.legacy
.mwCustomEditButtons
.length
; i
++ ) {
83 mw
.legacy
.mwInsertEditButton( $toolbar
, mw
.legacy
.mwCustomEditButtons
[i
] );
88 * Apply tagOpen/tagClose to selection in textarea, use sampleText instead of selection if there is none
90 'insertTags': function( tagOpen
, tagClose
, sampleText
) {
91 function checkSelectedText() {
95 } else if ( selText
.charAt( selText
.length
- 1 ) == ' ' ) { // exclude ending space char
96 selText
= selText
.substring( 0, selText
.length
- 1 );
100 var currentFocused
= $( mw
.legacy
.currentFocused
);
102 typeof $.fn
.textSelection
!= 'undefined' &&
103 ( $currentFocused
.name().toLowerCase() == 'iframe' || $currentFocused
.attr( 'id' ) == 'wpTextbox1' )
105 $j( '#wpTextbox1' ).textSelection(
106 'encapsulateSelection', { 'pre': tagOpen
, 'peri': sampleText
, 'post': tagClose
}
111 if ( $( 'form[name=editform]' ) {
112 $textarea
= $currentFocused
;
114 // Some alternate form? take the first one we can find
115 $textarea
= $( 'textarea' ).get( 0 );
117 var selText
, isSample
= false;
118 // Text selection implementation for IE and Opera
119 if ( document
.selection
&& document
.selection
.createRange
) {
120 // Save window scroll position
121 if ( document
.documentElement
&& document
.documentElement
.scrollTop
) {
122 var winScroll
= document
.documentElement
.scrollTop
123 } else if ( document
.body
) {
124 var winScroll
= document
.body
.scrollTop
;
126 // Get current selection
128 var range
= document
.selection
.createRange();
129 selText
= range
.text
;
132 range
.text
= tagOpen
+ selText
+ tagClose
;
133 // Mark sample text as selected
134 if ( isSample
&& range
.moveStart
) {
135 if ( window
.opera
) {
136 tagClose
= tagClose
.replace( /\n/g,'' );
138 range
.moveStart( 'character', - tagClose
.length
- selText
.length
);
139 range
.moveEnd( 'character', - tagClose
.length
);
142 // Restore window scroll position
143 if ( document
.documentElement
&& document
.documentElement
.scrollTop
) {
144 document
.documentElement
.scrollTop
= winScroll
;
145 } else if ( document
.body
) {
146 document
.body
.scrollTop
= winScroll
;
149 // Text selection implementation for Mozilla, Chrome and Safari
150 else if ( $textarea
[0].selectionStart
|| $textarea
[0].selectionStart
== '0' ) {
151 // Save textarea scroll position
152 var textScroll
= $textarea
.scrollTop
;
153 // Get current selection
155 var startPos
= $textarea
[0].selectionStart
;
156 var endPos
= $textarea
[0].selectionEnd
;
157 selText
= $textarea
.value
.substring( startPos
, endPos
);
161 $textarea
.val().substring( 0, startPos
) +
162 tagOpen
+ selText
+ tagClose
+
163 $textarea
.val().substring( endPos
, $textarea
.val().length
)
167 $textarea
[0].selectionStart
= startPos
+ tagOpen
.length
;
168 $textarea
[0].selectionEnd
= startPos
+ tagOpen
.length
+ selText
.length
;
170 $textarea
[0].selectionStart
= startPos
+ tagOpen
.length
+ selText
.length
+ tagClose
.length
;
171 $textarea
[0].selectionEnd
= $textarea
[0].selectionStart
;
173 // Restore textarea scroll position
174 $textarea
[0].scrollTop
= textScroll
;
178 * Restore the edit box scroll state following a preview operation,
179 * and set up a form submission handler to remember this state
181 'scrollEditBox': function() {
182 var $textbox
= $( '#wpTextbox1' );
183 var $scrollTop
= $( '#wpScrolltop' );
184 var $editForm
= $( '#editform' );
185 if ( $editForm
.length
&& $textbox
.length
&& $scrollTop
.length
) {
186 if ( scrollTop
.val() ) {
187 $textbox
.scrollTop
= $scrollTop
.val();
189 $editForm
.submit( function() {
190 $scrollTop
.val( $textbox
.scrollTop
);
198 $( document
).ready( function() {
199 mw
.legacy
.scrollEditBox();
200 mw
.legacy
.mwSetupToolbar();
201 mw
.legacy
.currentFocused
= $( '#wpTextbox1' ).get( 0 );
202 // http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html focus does not bubble normally, but using a
203 // trick we can do event delegation on the focus event on all text inputs to make the toolbox usable on all of them
204 $( '#editform' ).focus( function() {
205 $(this).each( function( e
) {
206 var elm
= e
.target
|| e
.srcElement
;
210 var tagName
= elm
.tagName
.toLowerCase();
211 var type
= elm
.type
|| '';
212 if ( tagName
!== 'textarea' && tagName
!== 'input' ) {
215 if ( tagName
=== 'input' && type
.toLowerCase() !== 'text' ) {
218 mw
.legacy
.currentFocused
= elm
;
221 // HACK: make currentFocused work with the usability iframe - with proper focus detection support (HTML 5!) this'll
223 var $iframe
= $j( '.wikiEditor-ui-text iframe' );
224 if ( $iframe
.length
> 0 ) {
225 $j( $iframe
.get( 0 ).contentWindow
.document
)
227 .add( $iframe
.get( 0 ).contentWindow
.document
.body
)
228 .focus( function() { mw
.legacy
.currentFocused
= $iframe
.get( 0 ); } );
230 // Make sure edit summary does not exceed byte limit
231 var $summary
= $( '#wpSummary' );
232 if ( !$summary
.length
) {
235 // L must be capitalized in length
236 $summary
.get( 0 ).maxLength
= 250;
237 $summary
.keypress( function( e
) {
238 // First check to see if this is actually a character key being pressed. Based on key-event info from
239 // http://unixpapa.com/js/key.html note === sign, if undefined, still could be a real key
240 if ( e
.which
=== 0 || e
.charCode
=== 0 || e
.ctrlKey
|| e
.altKey
|| e
.metaKey
) {
241 // A special key (backspace, etc) so don't interefere.
244 // This basically figures out how many bytes a utf-16 string (which is what js sees) will take in utf-8 by
245 // replacing a 2 byte character with 2 *'s, etc, and counting that. Note, surogate (\uD800-\uDFFF) characters
246 // are counted as 2 bytes, since theres two of them and the actual character takes 4 bytes in utf-8 (2*2=4).
247 // Might not work perfectly in edge cases such as such as illegal sequences, but that should never happen.
249 .replace(/[\u0080-\u07FF\uD800-\uDFFF]/g, '**')
250 .replace(/[\u0800-\uD7FF\uE000-\uFFFF]/g, '***')
252 // 247 as this doesn't count character about to be inserted.
254 if ( e
.preventDefault
) {
258 e
.returnValue
= false;
264 } )( jQuery
, mediaWiki
);