jumping cursor using Keyboard
[phpmyadmin/crack.git] / libraries / functions.js
blob544b75150f48c342c4f41e77fb360f38d8270c6e
1 /* $Id$ */
4 /**
5  * Displays an confirmation box beforme to submit a "DROP/DELETE/ALTER" query.
6  * This function is called while clicking links
7  *
8  * @param   object   the link
9  * @param   object   the sql query to submit
10  *
11  * @return  boolean  whether to run the query or not
12  */
13 function confirmLink(theLink, theSqlQuery)
15     // Confirmation is not required in the configuration file
16     // or browser is Opera (crappy js implementation)
17     if (confirmMsg == '' || typeof(window.opera) != 'undefined') {
18         return true;
19     }
21     var is_confirmed = confirm(confirmMsg + ' :\n' + theSqlQuery);
22     if (is_confirmed) {
23         theLink.href += '&is_js_confirmed=1';
24     }
26     return is_confirmed;
27 } // end of the 'confirmLink()' function
30 /**
31  * Displays an error message if a "DROP DATABASE" statement is submitted
32  * while it isn't allowed, else confirms a "DROP/DELETE/ALTER" query before
33  * sumitting it if required.
34  * This function is called by the 'checkSqlQuery()' js function.
35  *
36  * @param   object   the form
37  * @param   object   the sql query textarea
38  *
39  * @return  boolean  whether to run the query or not
40  *
41  * @see     checkSqlQuery()
42  */
43 function confirmQuery(theForm1, sqlQuery1)
45     // Confirmation is not required in the configuration file
46     if (confirmMsg == '') {
47         return true;
48     }
50     // The replace function (js1.2) isn't supported
51     else if (typeof(sqlQuery1.value.replace) == 'undefined') {
52         return true;
53     }
55     // js1.2+ -> validation with regular expressions
56     else {
57         // "DROP DATABASE" statement isn't allowed
58         if (noDropDbMsg != '') {
59             var drop_re = new RegExp('DROP\\s+(IF EXISTS\\s+)?DATABASE\\s', 'i');
60             if (drop_re.test(sqlQuery1.value)) {
61                 alert(noDropDbMsg);
62                 theForm1.reset();
63                 sqlQuery1.focus();
64                 return false;
65             } // end if
66         } // end if
68         // Confirms a "DROP/DELETE/ALTER" statement
69         //
70         // TODO: find a way (if possible) to use the parser-analyser
71         // for this kind of verification
72         // For now, I just added a ^ to check for the statement at
73         // beginning of expression
74         
75         //var do_confirm_re_0 = new RegExp('DROP\\s+(IF EXISTS\\s+)?(TABLE|DATABASE)\\s', 'i');
76         //var do_confirm_re_1 = new RegExp('ALTER\\s+TABLE\\s+((`[^`]+`)|([A-Za-z0-9_$]+))\\s+DROP\\s', 'i');
77         //var do_confirm_re_2 = new RegExp('DELETE\\s+FROM\\s', 'i');
78         var do_confirm_re_0 = new RegExp('^DROP\\s+(IF EXISTS\\s+)?(TABLE|DATABASE)\\s', 'i');
79         var do_confirm_re_1 = new RegExp('^ALTER\\s+TABLE\\s+((`[^`]+`)|([A-Za-z0-9_$]+))\\s+DROP\\s', 'i');
80         var do_confirm_re_2 = new RegExp('^DELETE\\s+FROM\\s', 'i');
81         if (do_confirm_re_0.test(sqlQuery1.value)
82             || do_confirm_re_1.test(sqlQuery1.value)
83             || do_confirm_re_2.test(sqlQuery1.value)) {
84             var message      = (sqlQuery1.value.length > 100)
85                              ? sqlQuery1.value.substr(0, 100) + '\n    ...'
86                              : sqlQuery1.value;
87             var is_confirmed = confirm(confirmMsg + ' :\n' + message);
88             // drop/delete/alter statement is confirmed -> update the
89             // "is_js_confirmed" form field so the confirm test won't be
90             // run on the server side and allows to submit the form
91             if (is_confirmed) {
92                 theForm1.elements['is_js_confirmed'].value = 1;
93                 return true;
94             }
95             // "DROP/DELETE/ALTER" statement is rejected -> do not submit
96             // the form
97             else {
98                 window.focus();
99                 sqlQuery1.focus();
100                 return false;
101             } // end if (handle confirm box result)
102         } // end if (display confirm box)
103     } // end confirmation stuff
105     return true;
106 } // end of the 'confirmQuery()' function
110  * Displays an error message if the user submitted the sql query form with no
111  * sql query, else checks for "DROP/DELETE/ALTER" statements
113  * @param   object   the form
115  * @return  boolean  always false
117  * @see     confirmQuery()
118  */
119 function checkSqlQuery(theForm)
121     var sqlQuery = theForm.elements['sql_query'];
122     var isEmpty  = 1;
124     // The replace function (js1.2) isn't supported -> basic tests
125     if (typeof(sqlQuery.value.replace) == 'undefined') {
126         isEmpty      = (sqlQuery.value == '') ? 1 : 0;
127         if (isEmpty && typeof(theForm.elements['sql_file']) != 'undefined') {
128             isEmpty  = (theForm.elements['sql_file'].value == '') ? 1 : 0;
129         }
130         if (isEmpty && typeof(theForm.elements['sql_localfile']) != 'undefined') {
131             isEmpty  = (theForm.elements['sql_localfile'].value == '') ? 1 : 0;
132         }
133         if (isEmpty && typeof(theForm.elements['id_bookmark']) != 'undefined') {
134             isEmpty  = (theForm.elements['id_bookmark'].value == null || theForm.elements['id_bookmark'].value == '');
135         }
136     }
137     // js1.2+ -> validation with regular expressions
138     else {
139         var space_re = new RegExp('\\s+');
140         isEmpty      = (sqlQuery.value.replace(space_re, '') == '') ? 1 : 0;
141         // Checks for "DROP/DELETE/ALTER" statements
142         if (!isEmpty && !confirmQuery(theForm, sqlQuery)) {
143             return false;
144         }
145         if (isEmpty && typeof(theForm.elements['sql_file']) != 'undefined') {
146             isEmpty  = (theForm.elements['sql_file'].value.replace(space_re, '') == '') ? 1 : 0;
147         }
148         if (isEmpty && typeof(theForm.elements['sql_localfile']) != 'undefined') {
149             isEmpty  = (theForm.elements['sql_localfile'].value.replace(space_re, '') == '') ? 1 : 0;
150         }
151         if (isEmpty && typeof(theForm.elements['id_bookmark']) != 'undefined') {
152             isEmpty  = (theForm.elements['id_bookmark'].value == null || theForm.elements['id_bookmark'].value == '');
153             isEmpty  = (theForm.elements['id_bookmark'].selectedIndex == 0);
154         }
155         if (isEmpty) {
156             theForm.reset();
157         }
158     }
160     if (isEmpty) {
161         sqlQuery.select();
162         alert(errorMsg0);
163         sqlQuery.focus();
164         return false;
165     }
167     return true;
168 } // end of the 'checkSqlQuery()' function
172  * Displays an error message if an element of a form hasn't been completed and
173  * should be
175  * @param   object   the form
176  * @param   string   the name of the form field to put the focus on
178  * @return  boolean  whether the form field is empty or not
179  */
180 function emptyFormElements(theForm, theFieldName)
182     var isEmpty  = 1;
183     var theField = theForm.elements[theFieldName];
184     // Whether the replace function (js1.2) is supported or not
185     var isRegExp = (typeof(theField.value.replace) != 'undefined');
187     if (!isRegExp) {
188         isEmpty      = (theField.value == '') ? 1 : 0;
189     } else {
190         var space_re = new RegExp('\\s+');
191         isEmpty      = (theField.value.replace(space_re, '') == '') ? 1 : 0;
192     }
193     if (isEmpty) {
194         theForm.reset();
195         theField.select();
196         alert(errorMsg0);
197         theField.focus();
198         return false;
199     }
201     return true;
202 } // end of the 'emptyFormElements()' function
206  * Ensures a value submitted in a form is numeric and is in a range
208  * @param   object   the form
209  * @param   string   the name of the form field to check
210  * @param   integer  the minimum authorized value
211  * @param   integer  the maximum authorized value
213  * @return  boolean  whether a valid number has been submitted or not
214  */
215 function checkFormElementInRange(theForm, theFieldName, min, max)
217     var theField         = theForm.elements[theFieldName];
218     var val              = parseInt(theField.value);
220     if (typeof(min) == 'undefined') {
221         min = 0;
222     }
223     if (typeof(max) == 'undefined') {
224         max = Number.MAX_VALUE;
225     }
227     // It's not a number
228     if (isNaN(val)) {
229         theField.select();
230         alert(errorMsg1);
231         theField.focus();
232         return false;
233     }
234     // It's a number but it is not between min and max
235     else if (val < min || val > max) {
236         theField.select();
237         alert(val + errorMsg2);
238         theField.focus();
239         return false;
240     }
241     // It's a valid number
242     else {
243         theField.value = val;
244     }
246     return true;
247 } // end of the 'checkFormElementInRange()' function
251  * Ensures the choice between 'transmit', 'zipped', 'gzipped' and 'bzipped'
252  * checkboxes is consistant
254  * @param   object   the form
255  * @param   string   a code for the action that causes this function to be run
257  * @return  boolean  always true
258  */
259 function checkTransmitDump(theForm, theAction)
261     var formElts = theForm.elements;
263     // 'zipped' option has been checked
264     if (theAction == 'zip' && formElts['zip'].checked) {
265         if (!formElts['asfile'].checked) {
266             theForm.elements['asfile'].checked = true;
267         }
268         if (typeof(formElts['gzip']) != 'undefined' && formElts['gzip'].checked) {
269             theForm.elements['gzip'].checked = false;
270         }
271         if (typeof(formElts['bzip']) != 'undefined' && formElts['bzip'].checked) {
272             theForm.elements['bzip'].checked = false;
273         }
274     }
275     // 'gzipped' option has been checked
276     else if (theAction == 'gzip' && formElts['gzip'].checked) {
277         if (!formElts['asfile'].checked) {
278             theForm.elements['asfile'].checked = true;
279         }
280         if (typeof(formElts['zip']) != 'undefined' && formElts['zip'].checked) {
281             theForm.elements['zip'].checked = false;
282         }
283         if (typeof(formElts['bzip']) != 'undefined' && formElts['bzip'].checked) {
284             theForm.elements['bzip'].checked = false;
285         }
286     }
287     // 'bzipped' option has been checked
288     else if (theAction == 'bzip' && formElts['bzip'].checked) {
289         if (!formElts['asfile'].checked) {
290             theForm.elements['asfile'].checked = true;
291         }
292         if (typeof(formElts['zip']) != 'undefined' && formElts['zip'].checked) {
293             theForm.elements['zip'].checked = false;
294         }
295         if (typeof(formElts['gzip']) != 'undefined' && formElts['gzip'].checked) {
296             theForm.elements['gzip'].checked = false;
297         }
298     }
299     // 'transmit' option has been unchecked
300     else if (theAction == 'transmit' && !formElts['asfile'].checked) {
301         if (typeof(formElts['zip']) != 'undefined' && formElts['zip'].checked) {
302             theForm.elements['zip'].checked = false;
303         }
304         if ((typeof(formElts['gzip']) != 'undefined' && formElts['gzip'].checked)) {
305             theForm.elements['gzip'].checked = false;
306         }
307         if ((typeof(formElts['bzip']) != 'undefined' && formElts['bzip'].checked)) {
308             theForm.elements['bzip'].checked = false;
309         }
310     }
312     return true;
313 } // end of the 'checkTransmitDump()' function
317  * This array is used to remember mark status of rows in browse mode
318  */
319 var marked_row = new Array;
323  * Sets/unsets the pointer and marker in browse mode
325  * @param   object    the table row
326  * @param   interger  the row number
327  * @param   string    the action calling this script (over, out or click)
328  * @param   string    the default background color
329  * @param   string    the color to use for mouseover
330  * @param   string    the color to use for marking a row
332  * @return  boolean  whether pointer is set or not
333  */
334 function setPointer(theRow, theRowNum, theAction, theDefaultColor, thePointerColor, theMarkColor)
336     var theCells = null;
338     // 1. Pointer and mark feature are disabled or the browser can't get the
339     //    row -> exits
340     if ((thePointerColor == '' && theMarkColor == '')
341         || typeof(theRow.style) == 'undefined') {
342         return false;
343     }
345     // 2. Gets the current row and exits if the browser can't get it
346     if (typeof(document.getElementsByTagName) != 'undefined') {
347         theCells = theRow.getElementsByTagName('td');
348     }
349     else if (typeof(theRow.cells) != 'undefined') {
350         theCells = theRow.cells;
351     }
352     else {
353         return false;
354     }
356     // 3. Gets the current color...
357     var rowCellsCnt  = theCells.length;
358     var domDetect    = null;
359     var currentColor = null;
360     var newColor     = null;
361     // 3.1 ... with DOM compatible browsers except Opera that does not return
362     //         valid values with "getAttribute"
363     if (typeof(window.opera) == 'undefined'
364         && typeof(theCells[0].getAttribute) != 'undefined') {
365         currentColor = theCells[0].getAttribute('bgcolor');
366         domDetect    = true;
367     }
368     // 3.2 ... with other browsers
369     else {
370         currentColor = theCells[0].style.backgroundColor;
371         domDetect    = false;
372     } // end 3
374     // 4. Defines the new color
375     // 4.1 Current color is the default one
376     if (currentColor == ''
377         || currentColor.toLowerCase() == theDefaultColor.toLowerCase()) {
378         if (theAction == 'over' && thePointerColor != '') {
379             newColor              = thePointerColor;
380         }
381         else if (theAction == 'click' && theMarkColor != '') {
382             newColor              = theMarkColor;
383             marked_row[theRowNum] = true;
384         }
385     }
386     // 4.1.2 Current color is the pointer one
387     else if (currentColor.toLowerCase() == thePointerColor.toLowerCase()
388              && (typeof(marked_row[theRowNum]) == 'undefined' || !marked_row[theRowNum])) {
389         if (theAction == 'out') {
390             newColor              = theDefaultColor;
391         }
392         else if (theAction == 'click' && theMarkColor != '') {
393             newColor              = theMarkColor;
394             marked_row[theRowNum] = true;
395         }
396     }
397     // 4.1.3 Current color is the marker one
398     else if (currentColor.toLowerCase() == theMarkColor.toLowerCase()) {
399         if (theAction == 'click') {
400             newColor              = (thePointerColor != '')
401                                   ? thePointerColor
402                                   : theDefaultColor;
403             marked_row[theRowNum] = (typeof(marked_row[theRowNum]) == 'undefined' || !marked_row[theRowNum])
404                                   ? true
405                                   : null;
406         }
407     } // end 4
409     // 5. Sets the new color...
410     if (newColor) {
411         var c = null;
412         // 5.1 ... with DOM compatible browsers except Opera
413         if (domDetect) {
414             for (c = 0; c < rowCellsCnt; c++) {
415                 theCells[c].setAttribute('bgcolor', newColor, 0);
416             } // end for
417         }
418         // 5.2 ... with other browsers
419         else {
420             for (c = 0; c < rowCellsCnt; c++) {
421                 theCells[c].style.backgroundColor = newColor;
422             }
423         }
424     } // end 5
426     return true;
427 } // end of the 'setPointer()' function
431  * Checks/unchecks all tables
433  * @param   string   the form name
434  * @param   boolean  whether to check or to uncheck the element
436  * @return  boolean  always true
437  */
438 function setCheckboxes(the_form, do_check)
440     var elts      = (typeof(document.forms[the_form].elements['selected_db[]']) != 'undefined')
441                   ? document.forms[the_form].elements['selected_db[]']
442                   : (typeof(document.forms[the_form].elements['selected_tbl[]']) != 'undefined')
443                   ? document.forms[the_form].elements['selected_tbl[]']
444                   : document.forms[the_form].elements['selected_fld[]'];
445     var elts_cnt  = (typeof(elts.length) != 'undefined')
446                   ? elts.length
447                   : 0;
449     if (elts_cnt) {
450         for (var i = 0; i < elts_cnt; i++) {
451             elts[i].checked = do_check;
452         } // end for
453     } else {
454         elts.checked        = do_check;
455     } // end if... else
457     return true;
458 } // end of the 'setCheckboxes()' function
462   * Checks/unchecks all options of a <select> element
463   *
464   * @param   string   the form name
465   * @param   string   the element name
466   * @param   boolean  whether to check or to uncheck the element
467   *
468   * @return  boolean  always true
469   */
470 function setSelectOptions(the_form, the_select, do_check)
472     var selectObject = document.forms[the_form].elements[the_select];
473     var selectCount  = selectObject.length;
475     for (var i = 0; i < selectCount; i++) {
476         selectObject.options[i].selected = do_check;
477     } // end for
479     return true;
480 } // end of the 'setSelectOptions()' function
483   * Allows moving around inputs/select by Ctrl+arrows
484   *
485   * @param   object   event data   
486   */
487 function onKeyDownArrowsHandler(e) {
488     e=e||window.event;
489     var o = (e.srcElement||e.target);
490     if (!o) return;
491     if (o.tagName != "INPUT" && o.tagName != "SELECT") return;
492     if (!e.ctrlKey) return;
493     if (!o.id) return;
495     var pos = o.id.split("_");
496     if (pos[0] != "field" || typeof pos[2] == "undefined") return;
498     var x = pos[2], y=pos[1];
500     switch(e.keyCode) {
501         case 38: y--; break; // up
502         case 40: y++; break; // down
503         case 37: x--; break; // left
504         case 39: x++; break; // right
505         default: return;
506     }
508     var id = "field_" + y + "_" + x;
509     var nO = document.getElementById(id);
510     if (!nO) return;
511     nO.focus();
512     if (nO.tagName != 'SELECT') {
513         nO.select();
514     }
515     e.returnValue = false;