Localisation updates from https://translatewiki.net.
[mediawiki.git] / resources / mediawiki.action / mediawiki.action.edit.js
blob299fabdc9563ae9ee882bbc23733a64ddce68cf2
1 /**
2  * Interface for the classic edit toolbar.
3  *
4  * @class mw.toolbar
5  * @singleton
6  */
7 ( function ( mw, $ ) {
8         var toolbar, isReady, $toolbar, queue, slice, $currentFocused;
10         /**
11          * Internal helper that does the actual insertion of the button into the toolbar.
12          *
13          * See #addButton for parameter documentation.
14          *
15          * @private
16          */
17         function insertButton( b, speedTip, tagOpen, tagClose, sampleText, imageId ) {
18                 // Backwards compatibility
19                 if ( typeof b !== 'object' ) {
20                         b = {
21                                 imageFile: b,
22                                 speedTip: speedTip,
23                                 tagOpen: tagOpen,
24                                 tagClose: tagClose,
25                                 sampleText: sampleText,
26                                 imageId: imageId
27                         };
28                 }
29                 var $image = $( '<img>' ).attr( {
30                         width : 23,
31                         height: 22,
32                         src   : b.imageFile,
33                         alt   : b.speedTip,
34                         title : b.speedTip,
35                         id    : b.imageId || undefined,
36                         'class': 'mw-toolbar-editbutton'
37                 } ).click( function () {
38                         toolbar.insertTags( b.tagOpen, b.tagClose, b.sampleText );
39                         return false;
40                 } );
42                 $toolbar.append( $image );
43         }
45         isReady = false;
46         $toolbar = false;
47         /**
48          * @private
49          * @property {Array}
50          * Contains button objects (and for backwards compatibilty, it can
51          * also contains an arguments array for insertButton).
52          */
53         queue = [];
54         slice = queue.slice;
56         toolbar = {
58                 /**
59                  * Add buttons to the toolbar.
60                  *
61                  * Takes care of race conditions and time-based dependencies
62                  * by placing buttons in a queue if this method is called before
63                  * the toolbar is created.
64                  *
65                  * For compatiblity, passing the properties listed below as separate arguments
66                  * (in the listed order) is also supported.
67                  *
68                  * @param {Object} button Object with the following properties:
69                  * @param {string} button.imageFile
70                  * @param {string} button.speedTip
71                  * @param {string} button.tagOpen
72                  * @param {string} button.tagClose
73                  * @param {string} button.sampleText
74                  * @param {string} [button.imageId]
75                  */
76                 addButton: function () {
77                         if ( isReady ) {
78                                 insertButton.apply( toolbar, arguments );
79                         } else {
80                                 // Convert arguments list to array
81                                 queue.push( slice.call( arguments ) );
82                         }
83                 },
84                 /**
85                  * Example usage:
86                  *     addButtons( [ { .. }, { .. }, { .. } ] );
87                  *     addButtons( { .. }, { .. } );
88                  *
89                  * @param {Object|Array} [buttons...] An array of button objects or the first
90                  *  button object in a list of variadic arguments.
91                  */
92                 addButtons: function ( buttons ) {
93                         if ( !$.isArray( buttons ) ) {
94                                 buttons = slice.call( arguments );
95                         }
96                         if ( isReady ) {
97                                 $.each( buttons, function () {
98                                         insertButton( this );
99                                 } );
100                         } else {
101                                 // Push each button into the queue
102                                 queue.push.apply( queue, buttons );
103                         }
104                 },
106                 /**
107                  * Apply tagOpen/tagClose to selection in currently focused textarea.
108                  *
109                  * Uses `sampleText` if selection is empty.
110                  *
111                  * @param {string} tagOpen
112                  * @param {string} tagClose
113                  * @param {string} sampleText
114                  */
115                 insertTags: function ( tagOpen, tagClose, sampleText ) {
116                         if ( $currentFocused && $currentFocused.length ) {
117                                 $currentFocused.textSelection(
118                                         'encapsulateSelection', {
119                                                 pre: tagOpen,
120                                                 peri: sampleText,
121                                                 post: tagClose
122                                         }
123                                 );
124                         }
125                 },
127                 // For backwards compatibility,
128                 // Called from EditPage.php, maybe in other places as well.
129                 init: function () {}
130         };
132         // Legacy (for compatibility with the code previously in skins/common.edit.js)
133         mw.log.deprecate( window, 'addButton', toolbar.addButton, 'Use mw.toolbar.addButton instead' );
134         mw.log.deprecate( window, 'insertTags', toolbar.insertTags, 'Use mw.toolbar.insertTags instead' );
136         // Expose API publicly
137         mw.toolbar = toolbar;
139         $( function () {
140                 var i, b, $iframe, editBox, scrollTop, $editForm;
142                 // currentFocus is used to determine where to insert tags
143                 $currentFocused = $( '#wpTextbox1' );
145                 // Populate the selector cache for $toolbar
146                 $toolbar = $( '#toolbar' );
148                 for ( i = 0; i < queue.length; i++ ) {
149                         b = queue[i];
150                         if ( $.isArray( b ) ) {
151                                 // Forwarded arguments array from mw.toolbar.addButton
152                                 insertButton.apply( toolbar, b );
153                         } else {
154                                 // Raw object from mw.toolbar.addButtons
155                                 insertButton( b );
156                         }
157                 }
159                 // Clear queue
160                 queue.length = 0;
162                 // This causes further calls to addButton to go to insertion directly
163                 // instead of to the queue.
164                 // It is important that this is after the one and only loop through
165                 // the the queue
166                 isReady = true;
168                 // Make sure edit summary does not exceed byte limit
169                 $( '#wpSummary' ).byteLimit( 255 );
171                 // Restore the edit box scroll state following a preview operation,
172                 // and set up a form submission handler to remember this state.
173                 editBox = document.getElementById( 'wpTextbox1' );
174                 scrollTop = document.getElementById( 'wpScrolltop' );
175                 $editForm = $( '#editform' );
176                 if ( $editForm.length && editBox && scrollTop ) {
177                         if ( scrollTop.value ) {
178                                 editBox.scrollTop = scrollTop.value;
179                         }
180                         $editForm.submit( function () {
181                                 scrollTop.value = editBox.scrollTop;
182                         });
183                 }
185                 // Apply to dynamically created textboxes as well as normal ones
186                 $( document ).on( 'focus', 'textarea, input:text', function () {
187                         $currentFocused = $( this );
188                 } );
190                 // HACK: make $currentFocused work with the usability iframe
191                 // With proper focus detection support (HTML 5!) this'll be much cleaner
192                 // TODO: Get rid of this WikiEditor code from MediaWiki core!
193                 $iframe = $( '.wikiEditor-ui-text iframe' );
194                 if ( $iframe.length > 0 ) {
195                         $( $iframe.get( 0 ).contentWindow.document )
196                                 // for IE
197                                 .add( $iframe.get( 0 ).contentWindow.document.body )
198                                 .focus( function () {
199                                         $currentFocused = $iframe;
200                                 } );
201                 }
202         });
204 }( mediaWiki, jQuery ) );