Fixed as per Tim's comments on r60665:
[mediawiki.git] / skins / common / edit.js
blobe39d35b1511c94bd47be36d7180350cc1de932e6
1 var currentFocused;
3 // this function generates the actual toolbar buttons with localized text
4 // we use it to avoid creating the toolbar where javascript is not enabled
5 function addButton( imageFile, speedTip, tagOpen, tagClose, sampleText, imageId ) {
6         // Don't generate buttons for browsers which don't fully
7         // support it.
8         mwEditButtons.push({
9                 'imageId': imageId,
10                 'imageFile': imageFile,
11                 'speedTip': speedTip,
12                 'tagOpen': tagOpen,
13                 'tagClose': tagClose,
14                 'sampleText': sampleText
15         });
18 // this function generates the actual toolbar buttons with localized text
19 // we use it to avoid creating the toolbar where JavaScript is not enabled
20 function mwInsertEditButton( parent, item ) {
21         var image = document.createElement( 'img' );
22         image.width = 23;
23         image.height = 22;
24         image.className = 'mw-toolbar-editbutton';
25         if ( item.imageId ) {
26                 image.id = item.imageId;
27         }
28         image.src = item.imageFile;
29         image.border = 0;
30         image.alt = item.speedTip;
31         image.title = item.speedTip;
32         image.style.cursor = 'pointer';
33         image.onclick = function() {
34                 insertTags( item.tagOpen, item.tagClose, item.sampleText );
35                 // click tracking
36                 if ( ( typeof $j != 'undefined' )  && ( typeof $j.trackAction != 'undefined' ) ) {
37                         $j.trackAction( 'oldedit.' + item.speedTip.replace(/ /g, "-") );
38                 }
39                 return false;
40         };
42         parent.appendChild( image );
43         return true;
46 function mwSetupToolbar() {
47         var toolbar = document.getElementById( 'toolbar' );
48         if ( !toolbar ) {
49                 return false;
50         }
52         // Don't generate buttons for browsers which don't fully
53         // support it.
54         // but don't assume wpTextbox1 is always here
55         var textboxes = document.getElementsByTagName( 'textarea' );
56         if ( !textboxes.length ) {
57                 // No toolbar if we can't find any textarea
58                 return false;
59         }
60         if ( !( document.selection && document.selection.createRange )
61                 && textboxes[0].selectionStart === null ) {
62                 return false;
63         }
65         for ( var i = 0; i < mwEditButtons.length; i++ ) {
66                 mwInsertEditButton( toolbar, mwEditButtons[i] );
67         }
68         for ( var i = 0; i < mwCustomEditButtons.length; i++ ) {
69                 mwInsertEditButton( toolbar, mwCustomEditButtons[i] );
70         }
71         return true;
74 // apply tagOpen/tagClose to selection in textarea,
75 // use sampleText instead of selection if there is none
76 function insertTags( tagOpen, tagClose, sampleText ) {
77         var txtarea;
78         if ( document.editform ) {
79                 txtarea = currentFocused;
80         } else {
81                 // some alternate form? take the first one we can find
82                 var areas = document.getElementsByTagName( 'textarea' );
83                 txtarea = areas[0];
84         }
85         var selText, isSample = false;
87         if ( document.selection  && document.selection.createRange ) { // IE/Opera
88                 // save window scroll position
89                 if ( document.documentElement && document.documentElement.scrollTop ) {
90                         var winScroll = document.documentElement.scrollTop
91                 } else if ( document.body ) {
92                         var winScroll = document.body.scrollTop;
93                 }
94                 // get current selection
95                 txtarea.focus();
96                 var range = document.selection.createRange();
97                 selText = range.text;
98                 // insert tags
99                 checkSelectedText();
100                 range.text = tagOpen + selText + tagClose;
101                 // mark sample text as selected
102                 if ( isSample && range.moveStart ) {
103                         if ( window.opera ) {
104                                 tagClose = tagClose.replace(/\n/g,'');
105                         }
106                         range.moveStart('character', - tagClose.length - selText.length);
107                         range.moveEnd('character', - tagClose.length);
108                 }
109                 range.select();
110                 // restore window scroll position
111                 if ( document.documentElement && document.documentElement.scrollTop ) {
112                         document.documentElement.scrollTop = winScroll;
113                 } else if ( document.body ) {
114                         document.body.scrollTop = winScroll;
115                 }
117         } else if ( txtarea.selectionStart || txtarea.selectionStart == '0' ) { // Mozilla
118                 // save textarea scroll position
119                 var textScroll = txtarea.scrollTop;
120                 // get current selection
121                 txtarea.focus();
122                 var startPos = txtarea.selectionStart;
123                 var endPos = txtarea.selectionEnd;
124                 selText = txtarea.value.substring( startPos, endPos );
125                 // insert tags
126                 checkSelectedText();
127                 txtarea.value = txtarea.value.substring(0, startPos)
128                         + tagOpen + selText + tagClose
129                         + txtarea.value.substring(endPos, txtarea.value.length);
130                 // set new selection
131                 if ( isSample ) {
132                         txtarea.selectionStart = startPos + tagOpen.length;
133                         txtarea.selectionEnd = startPos + tagOpen.length + selText.length;
134                 } else {
135                         txtarea.selectionStart = startPos + tagOpen.length + selText.length + tagClose.length;
136                         txtarea.selectionEnd = txtarea.selectionStart;
137                 }
138                 // restore textarea scroll position
139                 txtarea.scrollTop = textScroll;
140         }
142         function checkSelectedText() {
143                 if ( !selText ) {
144                         selText = sampleText;
145                         isSample = true;
146                 } else if ( selText.charAt(selText.length - 1) == ' ' ) { // exclude ending space char
147                         selText = selText.substring(0, selText.length - 1);
148                         tagClose += ' ';
149                 }
150         }
155  * Restore the edit box scroll state following a preview operation,
156  * and set up a form submission handler to remember this state
157  */
158 function scrollEditBox() {
159         var editBox = document.getElementById( 'wpTextbox1' );
160         var scrollTop = document.getElementById( 'wpScrolltop' );
161         var editForm = document.getElementById( 'editform' );
162         if( editForm && editBox && scrollTop ) {
163                 if( scrollTop.value ) {
164                         editBox.scrollTop = scrollTop.value;
165                 }
166                 addHandler( editForm, 'submit', function() {
167                         scrollTop.value = editBox.scrollTop;
168                 } );
169         }
171 hookEvent( 'load', scrollEditBox );
172 hookEvent( 'load', mwSetupToolbar );
173 hookEvent( 'load', function() {
174         currentFocused = document.getElementById( 'wpTextbox1' );
175         // http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
176         // focus does not bubble normally, but using a trick we can do event delegation
177         // on the focus event on all text inputs to make the toolbox usable on all of them
178         var editForm = document.getElementById( 'editform' );
179         if ( !editForm ) {
180                 return;
181         }
182         function onfocus( e ) {
183                 var elm = e.target;
184                 if ( !elm ) {
185                         return;
186                 }
187                 var tagName = elm.tagName.toLowerCase();
188                 var type = elm.type.toLowerCase();
189                 if ( tagName !== 'textarea' && tagName !== 'input' ) {
190                         return;
191                 }
192                 if ( tagName === 'input' && type && type !== 'text' ) {
193                         return;
194                 }
196                 currentFocused = elm;
197         }
199         if ( editForm.addEventListener ) {
200                 // Gecko, WebKit, Opera, etc... (all standards compliant browsers)
201                 editForm.addEventListener( 'focus', onfocus, true ); // This MUST be true to work
202         } else if ( editForm.attachEvent ) {
203                 // IE needs a specific trick here since it doesn't support the standard
204                 editForm.attachEvent( 'onfocusin', function() { onfocus( event ); } );
205         }
207         editForm
208 } );