Fix r90743.
[lhc/web/wiklou.git] / skins / common / edit.js
1 // This file is still referenced from
2 // tests/selenium/data/SimpleSeleniumTestDB.sql
3 // includes/specials/SpecialUpload.php
4 // /extensions/SemanticForms/specials/SF_UploadWindow2.php
5 window.currentFocused = undefined;
6
7 // this function adds a toolbar button to the mwEditButtons list
8 window.addButton = function( imageFile, speedTip, tagOpen, tagClose, sampleText, imageId, selectText ) {
9 // Don't generate buttons for browsers which don't fully
10 // support it.
11 mwEditButtons.push({
12 'imageId': imageId,
13 'imageFile': imageFile,
14 'speedTip': speedTip,
15 'tagOpen': tagOpen,
16 'tagClose': tagClose,
17 'sampleText': sampleText,
18 'selectText': selectText
19 });
20 };
21
22 // this function adds one toolbar button from a mwEditButtons/mwCustomEditButtons item
23 window.mwInsertEditButton = function( parent, item ) {
24 var image = document.createElement( 'img' );
25 image.width = 23;
26 image.height = 22;
27 image.className = 'mw-toolbar-editbutton';
28 if ( item.imageId ) {
29 image.id = item.imageId;
30 }
31 image.src = item.imageFile;
32 image.border = 0;
33 image.alt = item.speedTip;
34 image.title = item.speedTip;
35 image.style.cursor = 'pointer';
36 image.onclick = function() {
37 insertTags( item.tagOpen, item.tagClose, item.sampleText, item.selectText );
38 // click tracking
39 if ( ( typeof $ != 'undefined' ) && ( typeof $.trackAction != 'undefined' ) ) {
40 $.trackAction( 'oldedit.' + item.speedTip.replace(/ /g, '-') );
41 }
42 return false;
43 };
44
45 parent.appendChild( image );
46 return true;
47 };
48
49 // this function generates the actual toolbar buttons with localized text
50 // we use it to avoid creating the toolbar where javascript is not enabled
51 window.mwSetupToolbar = function() {
52 var toolbar = document.getElementById( 'toolbar' );
53 var i = 0;
54 if ( !toolbar ) {
55 return false;
56 }
57
58 // Don't generate buttons for browsers which don't fully
59 // support it.
60 // but don't assume wpTextbox1 is always here
61 var textboxes = document.getElementsByTagName( 'textarea' );
62 if ( !textboxes.length ) {
63 // No toolbar if we can't find any textarea
64 return false;
65 }
66 // Only check for selection capability if the textarea is visible - errors will occur otherwise - just because
67 // the textarea is not visible, doesn't mean we shouldn't build out the toolbar though - it might have been replaced
68 // with some other kind of control
69 if ( textboxes[0].style.display != 'none' ) {
70 if ( !( document.selection && document.selection.createRange )
71 && textboxes[0].selectionStart === null ) {
72 return false;
73 }
74 }
75 for ( i = 0; i < mwEditButtons.length; i++ ) {
76 mwInsertEditButton( toolbar, mwEditButtons[i] );
77 }
78 for ( i = 0; i < mwCustomEditButtons.length; i++ ) {
79 mwInsertEditButton( toolbar, mwCustomEditButtons[i] );
80 }
81 return true;
82 };
83
84 // apply tagOpen/tagClose to selection in textarea,
85 // use sampleText instead of selection if there is none
86 window.insertTags = function( tagOpen, tagClose, sampleText, selectText) {
87 if ( typeof $ != 'undefined' && typeof $.fn.textSelection != 'undefined' && currentFocused &&
88 ( currentFocused.nodeName.toLowerCase() == 'iframe' || currentFocused.id == 'wpTextbox1' ) ) {
89 $( '#wpTextbox1' ).textSelection(
90 'encapsulateSelection', { 'pre': tagOpen, 'peri': sampleText, 'post': tagClose }
91 );
92 return;
93 }
94 var txtarea;
95 if ( document.editform ) {
96 txtarea = currentFocused;
97 } else {
98 // some alternate form? take the first one we can find
99 var areas = document.getElementsByTagName( 'textarea' );
100 txtarea = areas[0];
101 }
102 var selText, isSample = false;
103
104 function checkSelectedText() {
105 if ( !selText ) {
106 selText = sampleText;
107 isSample = true;
108 } else if ( selText.charAt(selText.length - 1) == ' ' ) { // exclude ending space char
109 selText = selText.substring(0, selText.length - 1);
110 tagClose += ' ';
111 }
112 }
113
114 if ( document.selection && document.selection.createRange ) { // IE/Opera
115 // save window scroll position
116 var winScroll = null;
117 if ( document.documentElement && document.documentElement.scrollTop ) {
118 winScroll = document.documentElement.scrollTop;
119 } else if ( document.body ) {
120 winScroll = document.body.scrollTop;
121 }
122 // get current selection
123 txtarea.focus();
124 var range = document.selection.createRange();
125 selText = range.text;
126 // insert tags
127 checkSelectedText();
128 range.text = tagOpen + selText + tagClose;
129 // mark sample text as selected if not switched off by option
130 if ( selectText !== false ) {
131 if ( isSample && range.moveStart ) {
132 if ( window.opera ) {
133 tagClose = tagClose.replace(/\n/g,'');
134 }
135 range.moveStart('character', - tagClose.length - selText.length);
136 range.moveEnd('character', - tagClose.length);
137 }
138 range.select();
139 }
140 // restore window scroll position
141 if ( document.documentElement && document.documentElement.scrollTop ) {
142 document.documentElement.scrollTop = winScroll;
143 } else if ( document.body ) {
144 document.body.scrollTop = winScroll;
145 }
146
147 } else if ( txtarea.selectionStart || txtarea.selectionStart == '0' ) { // Mozilla
148 // save textarea scroll position
149 var textScroll = txtarea.scrollTop;
150 // get current selection
151 txtarea.focus();
152 var startPos = txtarea.selectionStart;
153 var endPos = txtarea.selectionEnd;
154 selText = txtarea.value.substring( startPos, endPos );
155 // insert tags
156 checkSelectedText();
157 txtarea.value = txtarea.value.substring(0, startPos)
158 + tagOpen + selText + tagClose
159 + txtarea.value.substring(endPos, txtarea.value.length);
160 // set new selection
161 if ( isSample && ( selectText !== false )) {
162 txtarea.selectionStart = startPos + tagOpen.length;
163 txtarea.selectionEnd = startPos + tagOpen.length + selText.length;
164 } else {
165 txtarea.selectionStart = startPos + tagOpen.length + selText.length + tagClose.length;
166 txtarea.selectionEnd = txtarea.selectionStart;
167 }
168 // restore textarea scroll position
169 txtarea.scrollTop = textScroll;
170 }
171
172 };
173
174 /**
175 * Restore the edit box scroll state following a preview operation,
176 * and set up a form submission handler to remember this state
177 */
178 window.scrollEditBox = function() {
179 var editBox = document.getElementById( 'wpTextbox1' );
180 var scrollTop = document.getElementById( 'wpScrolltop' );
181 var editForm = document.getElementById( 'editform' );
182 if( editForm && editBox && scrollTop ) {
183 if( scrollTop.value ) {
184 editBox.scrollTop = scrollTop.value;
185 }
186 addHandler( editForm, 'submit', function() {
187 scrollTop.value = editBox.scrollTop;
188 } );
189 }
190 };
191 hookEvent( 'load', scrollEditBox );
192 hookEvent( 'load', mwSetupToolbar );
193 hookEvent( 'load', function() {
194 currentFocused = document.getElementById( 'wpTextbox1' );
195 // http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
196 // focus does not bubble normally, but using a trick we can do event delegation
197 // on the focus event on all text inputs to make the toolbox usable on all of them
198 var editForm = document.getElementById( 'editform' );
199 if ( !editForm ) {
200 return;
201 }
202 function onfocus( e ) {
203 var elm = e.target || e.srcElement;
204 if ( !elm ) {
205 return;
206 }
207 var tagName = elm.tagName.toLowerCase();
208 var type = elm.type || '';
209 if ( tagName !== 'textarea' && tagName !== 'input' ) {
210 return;
211 }
212 if ( tagName === 'input' && type.toLowerCase() !== 'text' ) {
213 return;
214 }
215
216 currentFocused = elm;
217 }
218
219 if ( editForm.addEventListener ) {
220 // Gecko, WebKit, Opera, etc... (all standards compliant browsers)
221 editForm.addEventListener( 'focus', onfocus, true ); // This MUST be true to work
222 } else if ( editForm.attachEvent ) {
223 // IE needs a specific trick here since it doesn't support the standard
224 editForm.attachEvent( 'onfocusin', function() { onfocus( event ); } );
225 }
226
227 // HACK: make currentFocused work with the usability iframe
228 // With proper focus detection support (HTML 5!) this'll be much cleaner
229 if ( typeof $ != 'undefined' ) {
230 var iframe = $( '.wikiEditor-ui-text iframe' );
231 if ( iframe.length > 0 ) {
232 $( iframe.get( 0 ).contentWindow.document )
233 .add( iframe.get( 0 ).contentWindow.document.body ) // for IE
234 .focus( function() { currentFocused = iframe.get( 0 ); } );
235 }
236 }
237
238 } );