Language patch pt-br for login.txt
[dokuwiki.git] / lib / scripts / edit.js
blob2253d05cff287a9dcebfa3e500e300e5b61009a2
1 /**
2  * Functions for text editing (toolbar stuff)
3  *
4  * @todo most of the stuff in here should be revamped and then moved to toolbar.js
5  * @author Andreas Gohr <andi@splitbrain.org>
6  */
8 /**
9  * Creates a toolbar button through the DOM
10  * Called for each entry of toolbar definition array (built by inc/toolbar.php and extended via js)
11  *
12  * Style the buttons through the toolbutton class
13  *
14  * @param {string} icon      image filename, relative to folder lib/images/toolbar/
15  * @param {string} label     title of button, show on mouseover
16  * @param {string} key       hint in title of button for access key
17  * @param {string} id        id of button, and '<id>_ico' of icon
18  * @param {string} classname for styling buttons
19  *
20  * @author Andreas Gohr <andi@splitbrain.org>
21  * @author Michal Rezler <m.rezler@centrum.cz>
22  */
23 function createToolButton(icon,label,key,id,classname){
24     var $btn = jQuery(document.createElement('button')),
25         $ico = jQuery(document.createElement('img'));
27     // prepare the basic button stuff
28     $btn.addClass('toolbutton');
29     if(classname){
30         $btn.addClass(classname);
31     }
33     $btn.attr('title', label).attr('aria-controls', 'wiki__text');
34     if(key){
35         $btn.attr('title', label + ' ['+key.toUpperCase()+']')
36             .attr('accessKey', key);
37     }
39     // set IDs if given
40     if(id){
41         $btn.attr('id', id);
42         $ico.attr('id', id+'_ico');
43     }
45     // create the icon and add it to the button
46     if(icon.substr(0,1) !== '/'){
47         icon = DOKU_BASE + 'lib/images/toolbar/' + icon;
48     }
49     $ico.attr('src', icon);
50     $ico.attr('alt', '');
51     $ico.attr('width', 16);
52     $ico.attr('height', 16);
53     $btn.append($ico);
55     // we have to return a DOM object (for compatibility reasons)
56     return $btn[0];
59 /**
60  * Creates a picker window for inserting text
61  *
62  * The given list can be an associative array with text,icon pairs
63  * or a simple list of text. Style the picker window through the picker
64  * class or the picker buttons with the pickerbutton class. Picker
65  * windows are appended to the body and created invisible.
66  *
67  * @param  {string} id    the ID to assign to the picker
68  * @param  {Array}  props the properties for the picker
69  * @param  {string} edid  the ID of the textarea
70  * @return DOMobject    the created picker
71  * @author Andreas Gohr <andi@splitbrain.org>
72  */
73 function createPicker(id,props,edid){
74     // create the wrapping div
75     var $picker = jQuery(document.createElement('div'));
77     $picker.addClass('picker a11y');
78     if(props['class']){
79         $picker.addClass(props['class']);
80     }
82     $picker.attr('id', id).css('position', 'absolute');
84     function $makebutton(title) {
85         var $btn = jQuery(document.createElement('button'))
86             .addClass('pickerbutton').attr('title', title)
87             .attr('aria-controls', edid)
88             .on('click', bind(pickerInsert, title, edid))
89             .appendTo($picker);
90         return $btn;
91     }
93     jQuery.each(props.list, function (key, item) {
94         if (!props.list.hasOwnProperty(key)) {
95             return;
96         }
98         if(isNaN(key)){
99             // associative array -> treat as text => image pairs
100             if (item.substr(0,1) !== '/') {
101                 item = DOKU_BASE+'lib/images/'+props.icobase+'/'+item;
102             }
103             jQuery(document.createElement('img'))
104                 .attr('src', item)
105                 .attr('alt', '')
106                 .css('height', '16')
107                 .appendTo($makebutton(key));
108         }else if (typeof item == 'string'){
109             // a list of text -> treat as text picker
110             $makebutton(item).text(item);
111         }else{
112             // a list of lists -> treat it as subtoolbar
113             initToolbar($picker,edid,props.list);
114             return false; // all buttons handled already
115         }
117     });
118     jQuery('body').append($picker);
120     // we have to return a DOM object (for compatibility reasons)
121     return $picker[0];
125  * Called by picker buttons to insert Text and close the picker again
127  * @author Andreas Gohr <andi@splitbrain.org>
128  */
129 function pickerInsert(text,edid){
130     insertAtCarret(edid,text);
131     pickerClose();
135  * Add button action for signature button
137  * @param  {jQuery} $btn   Button element to add the action to
138  * @param  {Array}  props  Associative array of button properties
139  * @param  {string} edid   ID of the editor textarea
140  * @return {string} picker id for aria-controls attribute
141  * @author Gabriel Birke <birke@d-scribe.de>
142  */
143 function addBtnActionSignature($btn, props, edid) {
144     if(typeof SIG != 'undefined' && SIG != ''){
145         $btn.on('click', function (e) {
146             insertAtCarret(edid,SIG);
147             e.preventDefault();
148         });
149         return edid;
150     }
151     return '';
155  * Determine the current section level while editing
157  * @param {string} textboxId   ID of the text field
159  * @author Andreas Gohr <gohr@cosmocode.de>
160  */
161 function currentHeadlineLevel(textboxId){
162     var field = jQuery('#' + textboxId)[0],
163         s = false,
164         opts = [field.value.substr(0,DWgetSelection(field).start)];
165     if (field.form && field.form.prefix) {
166         // we need to look in prefix context
167         opts.push(field.form.prefix.value);
168     }
170     jQuery.each(opts, function (_, opt) {
171         // Check whether there is a headline in the given string
172         var str = "\n" + opt,
173             lasthl = str.lastIndexOf("\n==");
174         if (lasthl !== -1) {
175             s = str.substr(lasthl+1,6);
176             return false;
177         }
178     });
179     if (s === false) {
180         return 0;
181     }
182     return 7 - s.match(/^={2,6}/)[0].length;
187  * global var used for not saved yet warning
188  */
189 window.textChanged = false;
192  * global var which stores original editor content
193  */
194 window.doku_edit_text_content = '';
196  * Delete the draft before leaving the page
197  */
198 function deleteDraft() {
199     if (is_opera || window.keepDraft) {
200         return;
201     }
203     var $dwform = jQuery('#dw__editform');
205     if($dwform.length === 0) {
206         return;
207     }
209     // remove a possibly saved draft using ajax
210     jQuery.post(DOKU_BASE + 'lib/exe/ajax.php',
211         {
212             call: 'draftdel',
213             id: $dwform.find('input[name=id]').val(),
214             sectok: $dwform.find('input[name=sectok]').val()
215         }
216     );
220  * Activate "not saved" dialog, add draft deletion to page unload,
221  * add handlers to monitor changes
222  * Note: textChanged could be set by e.g. html_edit() as well
224  * Sets focus to the editbox as well
225  */
226 jQuery(function () {
227     var $editform = jQuery('#dw__editform');
228     if ($editform.length == 0) {
229         return;
230     }
232     var $edit_text = jQuery('#wiki__text');
233     if ($edit_text.length > 0) {
234         if($edit_text.attr('readOnly')) {
235             return;
236         }
238         // set focus and place cursor at the start
239         var sel = DWgetSelection($edit_text[0]);
240         sel.start = 0;
241         sel.end   = 0;
242         DWsetSelection(sel);
243         $edit_text.trigger('focus');
245         doku_edit_text_content = $edit_text.val();
246     }
248     var changeHandler = function() {
249         doku_hasTextBeenModified();
251         doku_summaryCheck();
252     };
254     $editform.change(changeHandler);
255     $editform.keydown(changeHandler);
257     window.onbeforeunload = function(){
258         if(window.textChanged) {
259             return LANG.notsavedyet;
260         }
261     };
262     window.onunload = deleteDraft;
264     // reset change memory var on submit
265     jQuery('#edbtn__save').on('click',
266         function() {
267             window.onbeforeunload = '';
268             textChanged = false;
269         }
270     );
271     jQuery('#edbtn__preview').on('click',
272         function() {
273             window.onbeforeunload = '';
274             textChanged = false;
275             window.keepDraft = true; // needed to keep draft on page unload
276         }
277     );
279     var $summary = jQuery('#edit__summary');
280     $summary.on('change keyup', doku_summaryCheck);
282     if (textChanged) doku_summaryCheck();
286  * Updates textChanged variable if content of the editor has been modified
287  */
288 function doku_hasTextBeenModified() {
289     if (!textChanged) {
290         var $edit_text = jQuery('#wiki__text');
292         if ($edit_text.length > 0) {
293             textChanged = doku_edit_text_content != $edit_text.val();
294         } else {
295             textChanged = true;
296         }
297     }
301  * Checks if a summary was entered - if not the style is changed
303  * @author Andreas Gohr <andi@splitbrain.org>
304  */
305 function doku_summaryCheck(){
306     var $sum = jQuery('#edit__summary'),
307         missing = $sum.val() === '';
308     $sum.toggleClass('missing', missing).toggleClass('edit', !missing);