PageRenderTime 54ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/phpMyAdmin/js/functions.js

https://gitlab.com/Evorx/uni
JavaScript | 4109 lines | 3226 code | 209 blank | 674 comment | 555 complexity | 1e78695f2b6be61a252a53e7e7049f0f MD5 | raw file
Possible License(s): GPL-2.0, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. /* vim: set expandtab sw=4 ts=4 sts=4: */
  2. /**
  3. * general function, usually for data manipulation pages
  4. *
  5. */
  6. /**
  7. * @var $table_clone reference to the action links on the tbl_structure page
  8. */
  9. var $table_clone = false;
  10. /**
  11. * @var sql_box_locked lock for the sqlbox textarea in the querybox/querywindow
  12. */
  13. var sql_box_locked = false;
  14. /**
  15. * @var array holds elements which content should only selected once
  16. */
  17. var only_once_elements = [];
  18. /**
  19. * @var int ajax_message_count Number of AJAX messages shown since page load
  20. */
  21. var ajax_message_count = 0;
  22. /**
  23. * @var codemirror_editor object containing CodeMirror editor of the query editor in SQL tab
  24. */
  25. var codemirror_editor = false;
  26. /**
  27. * @var codemirror_editor object containing CodeMirror editor of the inline query editor
  28. */
  29. var codemirror_inline_editor = false;
  30. /**
  31. * @var chart_activeTimeouts object active timeouts that refresh the charts. When disabling a realtime chart, this can be used to stop the continuous ajax requests
  32. */
  33. var chart_activeTimeouts = {};
  34. /**
  35. * Make sure that ajax requests will not be cached
  36. * by appending a random variable to their parameters
  37. */
  38. $.ajaxPrefilter(function (options, originalOptions, jqXHR) {
  39. var nocache = new Date().getTime() + "" + Math.floor(Math.random() * 1000000);
  40. if (typeof options.data == "string") {
  41. options.data += "&_nocache=" + nocache;
  42. } else if (typeof options.data == "object") {
  43. options.data = $.extend(originalOptions.data, {'_nocache' : nocache});
  44. }
  45. });
  46. /**
  47. * Add a hidden field to the form to indicate that this will be an
  48. * Ajax request (only if this hidden field does not exist)
  49. *
  50. * @param object the form
  51. */
  52. function PMA_prepareForAjaxRequest($form)
  53. {
  54. if (! $form.find('input:hidden').is('#ajax_request_hidden')) {
  55. $form.append('<input type="hidden" id="ajax_request_hidden" name="ajax_request" value="true" />');
  56. }
  57. }
  58. /**
  59. * Generate a new password and copy it to the password input areas
  60. *
  61. * @param object the form that holds the password fields
  62. *
  63. * @return boolean always true
  64. */
  65. function suggestPassword(passwd_form)
  66. {
  67. // restrict the password to just letters and numbers to avoid problems:
  68. // "editors and viewers regard the password as multiple words and
  69. // things like double click no longer work"
  70. var pwchars = "abcdefhjmnpqrstuvwxyz23456789ABCDEFGHJKLMNPQRSTUVWYXZ";
  71. var passwordlength = 16; // do we want that to be dynamic? no, keep it simple :)
  72. var passwd = passwd_form.generated_pw;
  73. passwd.value = '';
  74. for (var i = 0; i < passwordlength; i++) {
  75. passwd.value += pwchars.charAt(Math.floor(Math.random() * pwchars.length));
  76. }
  77. passwd_form.text_pma_pw.value = passwd.value;
  78. passwd_form.text_pma_pw2.value = passwd.value;
  79. return true;
  80. }
  81. /**
  82. * Version string to integer conversion.
  83. */
  84. function parseVersionString(str)
  85. {
  86. if (typeof(str) != 'string') { return false; }
  87. var add = 0;
  88. // Parse possible alpha/beta/rc/
  89. var state = str.split('-');
  90. if (state.length >= 2) {
  91. if (state[1].substr(0, 2) == 'rc') {
  92. add = - 20 - parseInt(state[1].substr(2), 10);
  93. } else if (state[1].substr(0, 4) == 'beta') {
  94. add = - 40 - parseInt(state[1].substr(4), 10);
  95. } else if (state[1].substr(0, 5) == 'alpha') {
  96. add = - 60 - parseInt(state[1].substr(5), 10);
  97. } else if (state[1].substr(0, 3) == 'dev') {
  98. /* We don't handle dev, it's git snapshot */
  99. add = 0;
  100. }
  101. }
  102. // Parse version
  103. var x = str.split('.');
  104. // Use 0 for non existing parts
  105. var maj = parseInt(x[0], 10) || 0;
  106. var min = parseInt(x[1], 10) || 0;
  107. var pat = parseInt(x[2], 10) || 0;
  108. var hotfix = parseInt(x[3], 10) || 0;
  109. return maj * 100000000 + min * 1000000 + pat * 10000 + hotfix * 100 + add;
  110. }
  111. /**
  112. * Indicates current available version on main page.
  113. */
  114. function PMA_current_version(data)
  115. {
  116. if (data && data.version && data.date) {
  117. var current = parseVersionString(pmaversion);
  118. var latest = parseVersionString(data.version);
  119. var version_information_message = '<span>'
  120. + PMA_messages.strLatestAvailable
  121. + ' ' + escapeHtml(data.version)
  122. + '</span>';
  123. if (latest > current) {
  124. var message = $.sprintf(
  125. PMA_messages.strNewerVersion,
  126. escapeHtml(data.version),
  127. escapeHtml(data.date)
  128. );
  129. var htmlClass = 'notice';
  130. if (Math.floor(latest / 10000) === Math.floor(current / 10000)) {
  131. /* Security update */
  132. htmlClass = 'error';
  133. }
  134. $('#maincontainer').after('<div class="' + htmlClass + '">' + message + '</div>');
  135. }
  136. if (latest === current) {
  137. version_information_message = ' (' + PMA_messages.strUpToDate + ')';
  138. }
  139. $('#li_pma_version span').remove();
  140. $('#li_pma_version').append(version_information_message);
  141. }
  142. }
  143. /**
  144. * Loads Git revision data from ajax for index.php
  145. */
  146. function PMA_display_git_revision()
  147. {
  148. $('#is_git_revision').remove();
  149. $('#li_pma_version_git').remove();
  150. $.get(
  151. "index.php",
  152. {
  153. "server": PMA_commonParams.get('server'),
  154. "token": PMA_commonParams.get('token'),
  155. "git_revision": true,
  156. "ajax_request": true
  157. },
  158. function (data) {
  159. if (data.success === true) {
  160. $(data.message).insertAfter('#li_pma_version');
  161. }
  162. }
  163. );
  164. }
  165. /**
  166. * for libraries/display_change_password.lib.php
  167. * libraries/user_password.php
  168. *
  169. */
  170. function displayPasswordGenerateButton()
  171. {
  172. $('#tr_element_before_generate_password').parent().append('<tr class="vmiddle"><td>' + PMA_messages.strGeneratePassword + '</td><td><input type="button" class="button" id="button_generate_password" value="' + PMA_messages.strGenerate + '" onclick="suggestPassword(this.form)" /><input type="text" name="generated_pw" id="generated_pw" /></td></tr>');
  173. $('#div_element_before_generate_password').parent().append('<div class="item"><label for="button_generate_password">' + PMA_messages.strGeneratePassword + ':</label><span class="options"><input type="button" class="button" id="button_generate_password" value="' + PMA_messages.strGenerate + '" onclick="suggestPassword(this.form)" /></span><input type="text" name="generated_pw" id="generated_pw" /></div>');
  174. }
  175. /*
  176. * Adds a date/time picker to an element
  177. *
  178. * @param object $this_element a jQuery object pointing to the element
  179. */
  180. function PMA_addDatepicker($this_element, options)
  181. {
  182. var showTimeOption = false;
  183. if ($this_element.is('.datetimefield')) {
  184. showTimeOption = true;
  185. }
  186. var defaultOptions = {
  187. showOn: 'button',
  188. buttonImage: themeCalendarImage, // defined in js/messages.php
  189. buttonImageOnly: true,
  190. stepMinutes: 1,
  191. stepHours: 1,
  192. showSecond: true,
  193. showMillisec: true,
  194. showMicrosec: true,
  195. showTimepicker: showTimeOption,
  196. showButtonPanel: false,
  197. dateFormat: 'yy-mm-dd', // yy means year with four digits
  198. timeFormat: 'HH:mm:ss.lc',
  199. constrainInput: false,
  200. altFieldTimeOnly: false,
  201. showAnim: '',
  202. beforeShow: function (input, inst) {
  203. // Remember that we came from the datepicker; this is used
  204. // in tbl_change.js by verificationsAfterFieldChange()
  205. $this_element.data('comes_from', 'datepicker');
  206. // Fix wrong timepicker z-index, doesn't work without timeout
  207. setTimeout(function () {
  208. $('#ui-timepicker-div').css('z-index', $('#ui-datepicker-div').css('z-index'));
  209. }, 0);
  210. },
  211. onClose: function (dateText, dp_inst) {
  212. // The value is no more from the date picker
  213. $this_element.data('comes_from', '');
  214. }
  215. };
  216. if (showTimeOption || (typeof(options) != 'undefined' && options.showTimepicker)) {
  217. $this_element.datetimepicker($.extend(defaultOptions, options));
  218. } else {
  219. $this_element.datepicker($.extend(defaultOptions, options));
  220. }
  221. }
  222. /**
  223. * selects the content of a given object, f.e. a textarea
  224. *
  225. * @param object element element of which the content will be selected
  226. * @param var lock variable which holds the lock for this element
  227. * or true, if no lock exists
  228. * @param boolean only_once if true this is only done once
  229. * f.e. only on first focus
  230. */
  231. function selectContent(element, lock, only_once)
  232. {
  233. if (only_once && only_once_elements[element.name]) {
  234. return;
  235. }
  236. only_once_elements[element.name] = true;
  237. if (lock) {
  238. return;
  239. }
  240. element.select();
  241. }
  242. /**
  243. * Displays a confirmation box before submitting a "DROP/DELETE/ALTER" query.
  244. * This function is called while clicking links
  245. *
  246. * @param object the link
  247. * @param object the sql query to submit
  248. *
  249. * @return boolean whether to run the query or not
  250. */
  251. function confirmLink(theLink, theSqlQuery)
  252. {
  253. // Confirmation is not required in the configuration file
  254. // or browser is Opera (crappy js implementation)
  255. if (PMA_messages.strDoYouReally === '' || typeof(window.opera) != 'undefined') {
  256. return true;
  257. }
  258. var is_confirmed = confirm($.sprintf(PMA_messages.strDoYouReally, theSqlQuery));
  259. if (is_confirmed) {
  260. if ($(theLink).hasClass('formLinkSubmit')) {
  261. var name = 'is_js_confirmed';
  262. if ($(theLink).attr('href').indexOf('usesubform') != -1) {
  263. name = 'subform[' + $(theLink).attr('href').substr('#').match(/usesubform\[(\d+)\]/i)[1] + '][is_js_confirmed]';
  264. }
  265. $(theLink).parents('form').append('<input type="hidden" name="' + name + '" value="1" />');
  266. } else if (typeof(theLink.href) != 'undefined') {
  267. theLink.href += '&is_js_confirmed=1';
  268. } else if (typeof(theLink.form) != 'undefined') {
  269. theLink.form.action += '?is_js_confirmed=1';
  270. }
  271. }
  272. return is_confirmed;
  273. } // end of the 'confirmLink()' function
  274. /**
  275. * Displays an error message if a "DROP DATABASE" statement is submitted
  276. * while it isn't allowed, else confirms a "DROP/DELETE/ALTER" query before
  277. * sumitting it if required.
  278. * This function is called by the 'checkSqlQuery()' js function.
  279. *
  280. * @param object the form
  281. * @param object the sql query textarea
  282. *
  283. * @return boolean whether to run the query or not
  284. *
  285. * @see checkSqlQuery()
  286. */
  287. function confirmQuery(theForm1, sqlQuery1)
  288. {
  289. // Confirmation is not required in the configuration file
  290. if (PMA_messages.strDoYouReally === '') {
  291. return true;
  292. }
  293. // "DROP DATABASE" statement isn't allowed
  294. if (PMA_messages.strNoDropDatabases !== '') {
  295. var drop_re = new RegExp('(^|;)\\s*DROP\\s+(IF EXISTS\\s+)?DATABASE\\s', 'i');
  296. if (drop_re.test(sqlQuery1.value)) {
  297. alert(PMA_messages.strNoDropDatabases);
  298. theForm1.reset();
  299. sqlQuery1.focus();
  300. return false;
  301. } // end if
  302. } // end if
  303. // Confirms a "DROP/DELETE/ALTER/TRUNCATE" statement
  304. //
  305. // TODO: find a way (if possible) to use the parser-analyser
  306. // for this kind of verification
  307. // For now, I just added a ^ to check for the statement at
  308. // beginning of expression
  309. var do_confirm_re_0 = new RegExp('^\\s*DROP\\s+(IF EXISTS\\s+)?(TABLE|DATABASE|PROCEDURE)\\s', 'i');
  310. var do_confirm_re_1 = new RegExp('^\\s*ALTER\\s+TABLE\\s+((`[^`]+`)|([A-Za-z0-9_$]+))\\s+DROP\\s', 'i');
  311. var do_confirm_re_2 = new RegExp('^\\s*DELETE\\s+FROM\\s', 'i');
  312. var do_confirm_re_3 = new RegExp('^\\s*TRUNCATE\\s', 'i');
  313. if (do_confirm_re_0.test(sqlQuery1.value) ||
  314. do_confirm_re_1.test(sqlQuery1.value) ||
  315. do_confirm_re_2.test(sqlQuery1.value) ||
  316. do_confirm_re_3.test(sqlQuery1.value)) {
  317. var message;
  318. if (sqlQuery1.value.length > 100) {
  319. message = sqlQuery1.value.substr(0, 100) + '\n ...';
  320. } else {
  321. message = sqlQuery1.value;
  322. }
  323. var is_confirmed = confirm($.sprintf(PMA_messages.strDoYouReally, message));
  324. // statement is confirmed -> update the
  325. // "is_js_confirmed" form field so the confirm test won't be
  326. // run on the server side and allows to submit the form
  327. if (is_confirmed) {
  328. theForm1.elements['is_js_confirmed'].value = 1;
  329. return true;
  330. }
  331. // statement is rejected -> do not submit the form
  332. else {
  333. window.focus();
  334. sqlQuery1.focus();
  335. return false;
  336. } // end if (handle confirm box result)
  337. } // end if (display confirm box)
  338. return true;
  339. } // end of the 'confirmQuery()' function
  340. /**
  341. * Displays an error message if the user submitted the sql query form with no
  342. * sql query, else checks for "DROP/DELETE/ALTER" statements
  343. *
  344. * @param object the form
  345. *
  346. * @return boolean always false
  347. *
  348. * @see confirmQuery()
  349. */
  350. function checkSqlQuery(theForm)
  351. {
  352. // get the textarea element containing the query
  353. if (codemirror_editor) {
  354. codemirror_editor.save();
  355. var sqlQuery = codemirror_editor.display.input;
  356. sqlQuery.value = codemirror_editor.getValue();
  357. } else {
  358. var sqlQuery = theForm.elements['sql_query'];
  359. }
  360. var isEmpty = 1;
  361. var space_re = new RegExp('\\s+');
  362. if (typeof(theForm.elements['sql_file']) != 'undefined' &&
  363. theForm.elements['sql_file'].value.replace(space_re, '') !== '') {
  364. return true;
  365. }
  366. if (typeof(theForm.elements['sql_localfile']) != 'undefined' &&
  367. theForm.elements['sql_localfile'].value.replace(space_re, '') !== '') {
  368. return true;
  369. }
  370. if (isEmpty && typeof(theForm.elements['id_bookmark']) != 'undefined' &&
  371. (theForm.elements['id_bookmark'].value !== null || theForm.elements['id_bookmark'].value !== '') &&
  372. theForm.elements['id_bookmark'].selectedIndex !== 0) {
  373. return true;
  374. }
  375. // Checks for "DROP/DELETE/ALTER" statements
  376. if (sqlQuery.value.replace(space_re, '') !== '') {
  377. if (confirmQuery(theForm, sqlQuery)) {
  378. return true;
  379. } else {
  380. return false;
  381. }
  382. }
  383. theForm.reset();
  384. isEmpty = 1;
  385. if (isEmpty) {
  386. sqlQuery.select();
  387. alert(PMA_messages.strFormEmpty);
  388. sqlQuery.focus();
  389. return false;
  390. }
  391. return true;
  392. } // end of the 'checkSqlQuery()' function
  393. /**
  394. * Check if a form's element is empty.
  395. * An element containing only spaces is also considered empty
  396. *
  397. * @param object the form
  398. * @param string the name of the form field to put the focus on
  399. *
  400. * @return boolean whether the form field is empty or not
  401. */
  402. function emptyCheckTheField(theForm, theFieldName)
  403. {
  404. var theField = theForm.elements[theFieldName];
  405. var space_re = new RegExp('\\s+');
  406. return (theField.value.replace(space_re, '') === '') ? 1 : 0;
  407. } // end of the 'emptyCheckTheField()' function
  408. /**
  409. * Check whether a form field is empty or not
  410. *
  411. * @param object the form
  412. * @param string the name of the form field to put the focus on
  413. *
  414. * @return boolean whether the form field is empty or not
  415. */
  416. function emptyFormElements(theForm, theFieldName)
  417. {
  418. var theField = theForm.elements[theFieldName];
  419. var isEmpty = emptyCheckTheField(theForm, theFieldName);
  420. return isEmpty;
  421. } // end of the 'emptyFormElements()' function
  422. /**
  423. * Ensures a value submitted in a form is numeric and is in a range
  424. *
  425. * @param object the form
  426. * @param string the name of the form field to check
  427. * @param integer the minimum authorized value
  428. * @param integer the maximum authorized value
  429. *
  430. * @return boolean whether a valid number has been submitted or not
  431. */
  432. function checkFormElementInRange(theForm, theFieldName, message, min, max)
  433. {
  434. var theField = theForm.elements[theFieldName];
  435. var val = parseInt(theField.value, 10);
  436. if (typeof(min) == 'undefined') {
  437. min = 0;
  438. }
  439. if (typeof(max) == 'undefined') {
  440. max = Number.MAX_VALUE;
  441. }
  442. // It's not a number
  443. if (isNaN(val)) {
  444. theField.select();
  445. alert(PMA_messages.strEnterValidNumber);
  446. theField.focus();
  447. return false;
  448. }
  449. // It's a number but it is not between min and max
  450. else if (val < min || val > max) {
  451. theField.select();
  452. alert($.sprintf(message, val));
  453. theField.focus();
  454. return false;
  455. }
  456. // It's a valid number
  457. else {
  458. theField.value = val;
  459. }
  460. return true;
  461. } // end of the 'checkFormElementInRange()' function
  462. function checkTableEditForm(theForm, fieldsCnt)
  463. {
  464. // TODO: avoid sending a message if user just wants to add a line
  465. // on the form but has not completed at least one field name
  466. var atLeastOneField = 0;
  467. var i, elm, elm2, elm3, val, id;
  468. for (i = 0; i < fieldsCnt; i++) {
  469. id = "#field_" + i + "_2";
  470. elm = $(id);
  471. val = elm.val();
  472. if (val == 'VARCHAR' || val == 'CHAR' || val == 'BIT' || val == 'VARBINARY' || val == 'BINARY') {
  473. elm2 = $("#field_" + i + "_3");
  474. val = parseInt(elm2.val(), 10);
  475. elm3 = $("#field_" + i + "_1");
  476. if (isNaN(val) && elm3.val() !== "") {
  477. elm2.select();
  478. alert(PMA_messages.strEnterValidLength);
  479. elm2.focus();
  480. return false;
  481. }
  482. }
  483. if (atLeastOneField === 0) {
  484. id = "field_" + i + "_1";
  485. if (!emptyCheckTheField(theForm, id)) {
  486. atLeastOneField = 1;
  487. }
  488. }
  489. }
  490. if (atLeastOneField === 0) {
  491. var theField = theForm.elements["field_0_1"];
  492. alert(PMA_messages.strFormEmpty);
  493. theField.focus();
  494. return false;
  495. }
  496. // at least this section is under jQuery
  497. if ($("input.textfield[name='table']").val() === "") {
  498. alert(PMA_messages.strFormEmpty);
  499. $("input.textfield[name='table']").focus();
  500. return false;
  501. }
  502. return true;
  503. } // enf of the 'checkTableEditForm()' function
  504. /**
  505. * Unbind all event handlers before tearing down a page
  506. */
  507. AJAX.registerTeardown('functions.js', function () {
  508. $('input:checkbox.checkall').die('click');
  509. });
  510. AJAX.registerOnload('functions.js', function () {
  511. /**
  512. * Row marking in horizontal mode (use "live" so that it works also for
  513. * next pages reached via AJAX); a tr may have the class noclick to remove
  514. * this behavior.
  515. */
  516. $('input:checkbox.checkall').live('click', function (e) {
  517. var $tr = $(this).closest('tr');
  518. // make the table unselectable (to prevent default highlighting when shift+click)
  519. //$tr.parents('table').noSelect();
  520. if (!e.shiftKey || last_clicked_row == -1) {
  521. // usual click
  522. // XXX: FF fires two click events for <label> (label and checkbox), so we need to handle this differently
  523. var $checkbox = $tr.find(':checkbox');
  524. if ($checkbox.length) {
  525. // checkbox in a row, add or remove class depending on checkbox state
  526. var checked = $checkbox.prop('checked');
  527. if (!$(e.target).is(':checkbox, label')) {
  528. checked = !checked;
  529. $checkbox.prop('checked', checked).trigger('change');
  530. }
  531. if (checked) {
  532. $tr.addClass('marked');
  533. } else {
  534. $tr.removeClass('marked');
  535. }
  536. last_click_checked = checked;
  537. } else {
  538. // normal data table, just toggle class
  539. $tr.toggleClass('marked');
  540. last_click_checked = false;
  541. }
  542. // remember the last clicked row
  543. last_clicked_row = last_click_checked ? $('tr.odd:not(.noclick), tr.even:not(.noclick)').index($tr) : -1;
  544. last_shift_clicked_row = -1;
  545. } else {
  546. // handle the shift click
  547. PMA_clearSelection();
  548. var start, end;
  549. // clear last shift click result
  550. if (last_shift_clicked_row >= 0) {
  551. if (last_shift_clicked_row >= last_clicked_row) {
  552. start = last_clicked_row;
  553. end = last_shift_clicked_row;
  554. } else {
  555. start = last_shift_clicked_row;
  556. end = last_clicked_row;
  557. }
  558. $tr.parent().find('tr.odd:not(.noclick), tr.even:not(.noclick)')
  559. .slice(start, end + 1)
  560. .removeClass('marked')
  561. .find(':checkbox')
  562. .prop('checked', false)
  563. .trigger('change');
  564. }
  565. // handle new shift click
  566. var curr_row = $('tr.odd:not(.noclick), tr.even:not(.noclick)').index($tr);
  567. if (curr_row >= last_clicked_row) {
  568. start = last_clicked_row;
  569. end = curr_row;
  570. } else {
  571. start = curr_row;
  572. end = last_clicked_row;
  573. }
  574. $tr.parent().find('tr.odd:not(.noclick), tr.even:not(.noclick)')
  575. .slice(start, end + 1)
  576. .addClass('marked')
  577. .find(':checkbox')
  578. .prop('checked', true)
  579. .trigger('change');
  580. // remember the last shift clicked row
  581. last_shift_clicked_row = curr_row;
  582. }
  583. });
  584. addDateTimePicker();
  585. /**
  586. * Add attribute to text boxes for iOS devices (based on bugID: 3508912)
  587. */
  588. if (navigator.userAgent.match(/(iphone|ipod|ipad)/i)) {
  589. $('input[type=text]').attr('autocapitalize', 'off').attr('autocorrect', 'off');
  590. }
  591. });
  592. /**
  593. * True if last click is to check a row.
  594. */
  595. var last_click_checked = false;
  596. /**
  597. * Zero-based index of last clicked row.
  598. * Used to handle the shift + click event in the code above.
  599. */
  600. var last_clicked_row = -1;
  601. /**
  602. * Zero-based index of last shift clicked row.
  603. */
  604. var last_shift_clicked_row = -1;
  605. /**
  606. * Row highlighting in horizontal mode (use "live"
  607. * so that it works also for pages reached via AJAX)
  608. */
  609. /*AJAX.registerOnload('functions.js', function () {
  610. $('tr.odd, tr.even').live('hover',function (event) {
  611. var $tr = $(this);
  612. $tr.toggleClass('hover',event.type=='mouseover');
  613. $tr.children().toggleClass('hover',event.type=='mouseover');
  614. });
  615. })*/
  616. /**
  617. * This array is used to remember mark status of rows in browse mode
  618. */
  619. var marked_row = [];
  620. /**
  621. * marks all rows and selects its first checkbox inside the given element
  622. * the given element is usaly a table or a div containing the table or tables
  623. *
  624. * @param container DOM element
  625. */
  626. function markAllRows(container_id)
  627. {
  628. $("#" + container_id).find("input:checkbox:enabled").prop('checked', true)
  629. .trigger("change")
  630. .parents("tr").addClass("marked");
  631. return true;
  632. }
  633. /**
  634. * marks all rows and selects its first checkbox inside the given element
  635. * the given element is usaly a table or a div containing the table or tables
  636. *
  637. * @param container DOM element
  638. */
  639. function unMarkAllRows(container_id)
  640. {
  641. $("#" + container_id).find("input:checkbox:enabled").prop('checked', false)
  642. .trigger("change")
  643. .parents("tr").removeClass("marked");
  644. return true;
  645. }
  646. /**
  647. * Checks/unchecks all checkbox in given conainer (f.e. a form, fieldset or div)
  648. *
  649. * @param string container_id the container id
  650. * @param boolean state new value for checkbox (true or false)
  651. * @return boolean always true
  652. */
  653. function setCheckboxes(container_id, state)
  654. {
  655. $("#" + container_id).find("input:checkbox").prop('checked', state);
  656. return true;
  657. } // end of the 'setCheckboxes()' function
  658. /**
  659. * Checks/unchecks all options of a <select> element
  660. *
  661. * @param string the form name
  662. * @param string the element name
  663. * @param boolean whether to check or to uncheck options
  664. *
  665. * @return boolean always true
  666. */
  667. function setSelectOptions(the_form, the_select, do_check)
  668. {
  669. $("form[name='" + the_form + "'] select[name='" + the_select + "']").find("option").prop('selected', do_check);
  670. return true;
  671. } // end of the 'setSelectOptions()' function
  672. /**
  673. * Sets current value for query box.
  674. */
  675. function setQuery(query)
  676. {
  677. if (codemirror_editor) {
  678. codemirror_editor.setValue(query);
  679. codemirror_editor.focus();
  680. } else {
  681. document.sqlform.sql_query.value = query;
  682. document.sqlform.sql_query.focus();
  683. }
  684. }
  685. /**
  686. * Create quick sql statements.
  687. *
  688. */
  689. function insertQuery(queryType)
  690. {
  691. if (queryType == "clear") {
  692. setQuery('');
  693. return;
  694. }
  695. var query = "";
  696. var myListBox = document.sqlform.dummy;
  697. var table = document.sqlform.table.value;
  698. if (myListBox.options.length > 0) {
  699. sql_box_locked = true;
  700. var chaineAj = "";
  701. var valDis = "";
  702. var editDis = "";
  703. var NbSelect = 0;
  704. for (var i = 0; i < myListBox.options.length; i++) {
  705. NbSelect++;
  706. if (NbSelect > 1) {
  707. chaineAj += ", ";
  708. valDis += ",";
  709. editDis += ",";
  710. }
  711. chaineAj += myListBox.options[i].value;
  712. valDis += "[value-" + NbSelect + "]";
  713. editDis += myListBox.options[i].value + "=[value-" + NbSelect + "]";
  714. }
  715. if (queryType == "selectall") {
  716. query = "SELECT * FROM `" + table + "` WHERE 1";
  717. } else if (queryType == "select") {
  718. query = "SELECT " + chaineAj + " FROM `" + table + "` WHERE 1";
  719. } else if (queryType == "insert") {
  720. query = "INSERT INTO `" + table + "`(" + chaineAj + ") VALUES (" + valDis + ")";
  721. } else if (queryType == "update") {
  722. query = "UPDATE `" + table + "` SET " + editDis + " WHERE 1";
  723. } else if (queryType == "delete") {
  724. query = "DELETE FROM `" + table + "` WHERE 1";
  725. }
  726. setQuery(query);
  727. sql_box_locked = false;
  728. }
  729. }
  730. /**
  731. * Inserts multiple fields.
  732. *
  733. */
  734. function insertValueQuery()
  735. {
  736. var myQuery = document.sqlform.sql_query;
  737. var myListBox = document.sqlform.dummy;
  738. if (myListBox.options.length > 0) {
  739. sql_box_locked = true;
  740. var chaineAj = "";
  741. var NbSelect = 0;
  742. for (var i = 0; i < myListBox.options.length; i++) {
  743. if (myListBox.options[i].selected) {
  744. NbSelect++;
  745. if (NbSelect > 1) {
  746. chaineAj += ", ";
  747. }
  748. chaineAj += myListBox.options[i].value;
  749. }
  750. }
  751. /* CodeMirror support */
  752. if (codemirror_editor) {
  753. codemirror_editor.replaceSelection(chaineAj);
  754. //IE support
  755. } else if (document.selection) {
  756. myQuery.focus();
  757. var sel = document.selection.createRange();
  758. sel.text = chaineAj;
  759. document.sqlform.insert.focus();
  760. }
  761. //MOZILLA/NETSCAPE support
  762. else if (document.sqlform.sql_query.selectionStart || document.sqlform.sql_query.selectionStart == "0") {
  763. var startPos = document.sqlform.sql_query.selectionStart;
  764. var endPos = document.sqlform.sql_query.selectionEnd;
  765. var chaineSql = document.sqlform.sql_query.value;
  766. myQuery.value = chaineSql.substring(0, startPos) + chaineAj + chaineSql.substring(endPos, chaineSql.length);
  767. } else {
  768. myQuery.value += chaineAj;
  769. }
  770. sql_box_locked = false;
  771. }
  772. }
  773. /**
  774. * Add a date/time picker to each element that needs it
  775. * (only when jquery-ui-timepicker-addon.js is loaded)
  776. */
  777. function addDateTimePicker() {
  778. if ($.timepicker !== undefined) {
  779. $('input.datefield, input.datetimefield').each(function () {
  780. no_decimals = $(this).parent().data('decimals');
  781. var showMillisec = false;
  782. var showMicrosec = false;
  783. var timeFormat = 'HH:mm:ss';
  784. // check for decimal places of seconds
  785. if (($(this).parent().data('decimals') > 0) && ($(this).parent().data('type').indexOf('time') != -1)){
  786. showMillisec = true;
  787. timeFormat = 'HH:mm:ss.lc';
  788. if ($(this).parent().data('decimals') > 3) {
  789. showMicrosec = true;
  790. }
  791. }
  792. PMA_addDatepicker($(this), {
  793. showMillisec: showMillisec,
  794. showMicrosec: showMicrosec,
  795. timeFormat: timeFormat,
  796. });
  797. })
  798. }
  799. }
  800. /**
  801. * Refresh/resize the WYSIWYG scratchboard
  802. */
  803. function refreshLayout()
  804. {
  805. var $elm = $('#pdflayout');
  806. var orientation = $('#orientation_opt').val();
  807. var paper = 'A4';
  808. if ($('#paper_opt').length == 1) {
  809. paper = $('#paper_opt').val();
  810. }
  811. var posa = 'y';
  812. var posb = 'x';
  813. if (orientation == 'P') {
  814. posa = 'x';
  815. posb = 'y';
  816. }
  817. $elm.css('width', pdfPaperSize(paper, posa) + 'px');
  818. $elm.css('height', pdfPaperSize(paper, posb) + 'px');
  819. }
  820. /**
  821. * Initializes positions of elements.
  822. */
  823. function TableDragInit() {
  824. $('.pdflayout_table').each(function () {
  825. var $this = $(this);
  826. var number = $this.data('number');
  827. var x = $('#c_table_' + number + '_x').val();
  828. var y = $('#c_table_' + number + '_y').val();
  829. $this.css('left', x + 'px');
  830. $this.css('top', y + 'px');
  831. /* Make elements draggable */
  832. $this.draggable({
  833. containment: "parent",
  834. drag: function (evt, ui) {
  835. var number = $this.data('number');
  836. $('#c_table_' + number + '_x').val(parseInt(ui.position.left, 10));
  837. $('#c_table_' + number + '_y').val(parseInt(ui.position.top, 10));
  838. }
  839. });
  840. });
  841. }
  842. /**
  843. * Resets drag and drop positions.
  844. */
  845. function resetDrag() {
  846. $('.pdflayout_table').each(function () {
  847. var $this = $(this);
  848. var x = $this.data('x');
  849. var y = $this.data('y');
  850. $this.css('left', x + 'px');
  851. $this.css('top', y + 'px');
  852. });
  853. }
  854. /**
  855. * User schema handlers.
  856. */
  857. $(function () {
  858. /* Move in scratchboard on manual change */
  859. $('.position-change').live('change', function () {
  860. var $this = $(this);
  861. var $elm = $('#table_' + $this.data('number'));
  862. $elm.css($this.data('axis'), $this.val() + 'px');
  863. });
  864. /* Refresh on paper size/orientation change */
  865. $('.paper-change').live('change', function () {
  866. var $elm = $('#pdflayout');
  867. if ($elm.css('visibility') == 'visible') {
  868. refreshLayout();
  869. TableDragInit();
  870. }
  871. });
  872. /* Show/hide the WYSIWYG scratchboard */
  873. $('#toggle-dragdrop').live('click', function () {
  874. var $elm = $('#pdflayout');
  875. if ($elm.css('visibility') == 'hidden') {
  876. refreshLayout();
  877. TableDragInit();
  878. $elm.css('visibility', 'visible');
  879. $elm.css('display', 'block');
  880. $('#showwysiwyg').val('1');
  881. } else {
  882. $elm.css('visibility', 'hidden');
  883. $elm.css('display', 'none');
  884. $('#showwysiwyg').val('0');
  885. }
  886. });
  887. /* Reset scratchboard */
  888. $('#reset-dragdrop').live('click', function () {
  889. resetDrag();
  890. });
  891. });
  892. /**
  893. * Returns paper sizes for a given format
  894. */
  895. function pdfPaperSize(format, axis)
  896. {
  897. switch (format.toUpperCase()) {
  898. case '4A0':
  899. if (axis == 'x') {
  900. return 4767.87;
  901. } else {
  902. return 6740.79;
  903. }
  904. break;
  905. case '2A0':
  906. if (axis == 'x') {
  907. return 3370.39;
  908. } else {
  909. return 4767.87;
  910. }
  911. break;
  912. case 'A0':
  913. if (axis == 'x') {
  914. return 2383.94;
  915. } else {
  916. return 3370.39;
  917. }
  918. break;
  919. case 'A1':
  920. if (axis == 'x') {
  921. return 1683.78;
  922. } else {
  923. return 2383.94;
  924. }
  925. break;
  926. case 'A2':
  927. if (axis == 'x') {
  928. return 1190.55;
  929. } else {
  930. return 1683.78;
  931. }
  932. break;
  933. case 'A3':
  934. if (axis == 'x') {
  935. return 841.89;
  936. } else {
  937. return 1190.55;
  938. }
  939. break;
  940. case 'A4':
  941. if (axis == 'x') {
  942. return 595.28;
  943. } else {
  944. return 841.89;
  945. }
  946. break;
  947. case 'A5':
  948. if (axis == 'x') {
  949. return 419.53;
  950. } else {
  951. return 595.28;
  952. }
  953. break;
  954. case 'A6':
  955. if (axis == 'x') {
  956. return 297.64;
  957. } else {
  958. return 419.53;
  959. }
  960. break;
  961. case 'A7':
  962. if (axis == 'x') {
  963. return 209.76;
  964. } else {
  965. return 297.64;
  966. }
  967. break;
  968. case 'A8':
  969. if (axis == 'x') {
  970. return 147.40;
  971. } else {
  972. return 209.76;
  973. }
  974. break;
  975. case 'A9':
  976. if (axis == 'x') {
  977. return 104.88;
  978. } else {
  979. return 147.40;
  980. }
  981. break;
  982. case 'A10':
  983. if (axis == 'x') {
  984. return 73.70;
  985. } else {
  986. return 104.88;
  987. }
  988. break;
  989. case 'B0':
  990. if (axis == 'x') {
  991. return 2834.65;
  992. } else {
  993. return 4008.19;
  994. }
  995. break;
  996. case 'B1':
  997. if (axis == 'x') {
  998. return 2004.09;
  999. } else {
  1000. return 2834.65;
  1001. }
  1002. break;
  1003. case 'B2':
  1004. if (axis == 'x') {
  1005. return 1417.32;
  1006. } else {
  1007. return 2004.09;
  1008. }
  1009. break;
  1010. case 'B3':
  1011. if (axis == 'x') {
  1012. return 1000.63;
  1013. } else {
  1014. return 1417.32;
  1015. }
  1016. break;
  1017. case 'B4':
  1018. if (axis == 'x') {
  1019. return 708.66;
  1020. } else {
  1021. return 1000.63;
  1022. }
  1023. break;
  1024. case 'B5':
  1025. if (axis == 'x') {
  1026. return 498.90;
  1027. } else {
  1028. return 708.66;
  1029. }
  1030. break;
  1031. case 'B6':
  1032. if (axis == 'x') {
  1033. return 354.33;
  1034. } else {
  1035. return 498.90;
  1036. }
  1037. break;
  1038. case 'B7':
  1039. if (axis == 'x') {
  1040. return 249.45;
  1041. } else {
  1042. return 354.33;
  1043. }
  1044. break;
  1045. case 'B8':
  1046. if (axis == 'x') {
  1047. return 175.75;
  1048. } else {
  1049. return 249.45;
  1050. }
  1051. break;
  1052. case 'B9':
  1053. if (axis == 'x') {
  1054. return 124.72;
  1055. } else {
  1056. return 175.75;
  1057. }
  1058. break;
  1059. case 'B10':
  1060. if (axis == 'x') {
  1061. return 87.87;
  1062. } else {
  1063. return 124.72;
  1064. }
  1065. break;
  1066. case 'C0':
  1067. if (axis == 'x') {
  1068. return 2599.37;
  1069. } else {
  1070. return 3676.54;
  1071. }
  1072. break;
  1073. case 'C1':
  1074. if (axis == 'x') {
  1075. return 1836.85;
  1076. } else {
  1077. return 2599.37;
  1078. }
  1079. break;
  1080. case 'C2':
  1081. if (axis == 'x') {
  1082. return 1298.27;
  1083. } else {
  1084. return 1836.85;
  1085. }
  1086. break;
  1087. case 'C3':
  1088. if (axis == 'x') {
  1089. return 918.43;
  1090. } else {
  1091. return 1298.27;
  1092. }
  1093. break;
  1094. case 'C4':
  1095. if (axis == 'x') {
  1096. return 649.13;
  1097. } else {
  1098. return 918.43;
  1099. }
  1100. break;
  1101. case 'C5':
  1102. if (axis == 'x') {
  1103. return 459.21;
  1104. } else {
  1105. return 649.13;
  1106. }
  1107. break;
  1108. case 'C6':
  1109. if (axis == 'x') {
  1110. return 323.15;
  1111. } else {
  1112. return 459.21;
  1113. }
  1114. break;
  1115. case 'C7':
  1116. if (axis == 'x') {
  1117. return 229.61;
  1118. } else {
  1119. return 323.15;
  1120. }
  1121. break;
  1122. case 'C8':
  1123. if (axis == 'x') {
  1124. return 161.57;
  1125. } else {
  1126. return 229.61;
  1127. }
  1128. break;
  1129. case 'C9':
  1130. if (axis == 'x') {
  1131. return 113.39;
  1132. } else {
  1133. return 161.57;
  1134. }
  1135. break;
  1136. case 'C10':
  1137. if (axis == 'x') {
  1138. return 79.37;
  1139. } else {
  1140. return 113.39;
  1141. }
  1142. break;
  1143. case 'RA0':
  1144. if (axis == 'x') {
  1145. return 2437.80;
  1146. } else {
  1147. return 3458.27;
  1148. }
  1149. break;
  1150. case 'RA1':
  1151. if (axis == 'x') {
  1152. return 1729.13;
  1153. } else {
  1154. return 2437.80;
  1155. }
  1156. break;
  1157. case 'RA2':
  1158. if (axis == 'x') {
  1159. return 1218.90;
  1160. } else {
  1161. return 1729.13;
  1162. }
  1163. break;
  1164. case 'RA3':
  1165. if (axis == 'x') {
  1166. return 864.57;
  1167. } else {
  1168. return 1218.90;
  1169. }
  1170. break;
  1171. case 'RA4':
  1172. if (axis == 'x') {
  1173. return 609.45;
  1174. } else {
  1175. return 864.57;
  1176. }
  1177. break;
  1178. case 'SRA0':
  1179. if (axis == 'x') {
  1180. return 2551.18;
  1181. } else {
  1182. return 3628.35;
  1183. }
  1184. break;
  1185. case 'SRA1':
  1186. if (axis == 'x') {
  1187. return 1814.17;
  1188. } else {
  1189. return 2551.18;
  1190. }
  1191. break;
  1192. case 'SRA2':
  1193. if (axis == 'x') {
  1194. return 1275.59;
  1195. } else {
  1196. return 1814.17;
  1197. }
  1198. break;
  1199. case 'SRA3':
  1200. if (axis == 'x') {
  1201. return 907.09;
  1202. } else {
  1203. return 1275.59;
  1204. }
  1205. break;
  1206. case 'SRA4':
  1207. if (axis == 'x') {
  1208. return 637.80;
  1209. } else {
  1210. return 907.09;
  1211. }
  1212. break;
  1213. case 'LETTER':
  1214. if (axis == 'x') {
  1215. return 612.00;
  1216. } else {
  1217. return 792.00;
  1218. }
  1219. break;
  1220. case 'LEGAL':
  1221. if (axis == 'x') {
  1222. return 612.00;
  1223. } else {
  1224. return 1008.00;
  1225. }
  1226. break;
  1227. case 'EXECUTIVE':
  1228. if (axis == 'x') {
  1229. return 521.86;
  1230. } else {
  1231. return 756.00;
  1232. }
  1233. break;
  1234. case 'FOLIO':
  1235. if (axis == 'x') {
  1236. return 612.00;
  1237. } else {
  1238. return 936.00;
  1239. }
  1240. break;
  1241. } // end switch
  1242. return 0;
  1243. }
  1244. /**
  1245. * Unbind all event handlers before tearing down a page
  1246. */
  1247. AJAX.registerTeardown('functions.js', function () {
  1248. $("a.inline_edit_sql").die('click');
  1249. $("input#sql_query_edit_save").die('click');
  1250. $("input#sql_query_edit_discard").die('click');
  1251. $('input.sqlbutton').unbind('click');
  1252. $("#export_type").unbind('change');
  1253. $('#sqlquery').unbind('keydown');
  1254. $('#sql_query_edit').unbind('keydown');
  1255. if (codemirror_inline_editor) {
  1256. // Copy the sql query to the text area to preserve it.
  1257. $('#sql_query_edit').text(codemirror_inline_editor.getValue());
  1258. $(codemirror_inline_editor.getWrapperElement()).unbind('keydown');
  1259. codemirror_inline_editor.toTextArea();
  1260. codemirror_inline_editor = false;
  1261. }
  1262. if (codemirror_editor) {
  1263. $(codemirror_editor.getWrapperElement()).unbind('keydown');
  1264. }
  1265. });
  1266. /**
  1267. * Jquery Coding for inline editing SQL_QUERY
  1268. */
  1269. AJAX.registerOnload('functions.js', function () {
  1270. // If we are coming back to the page by clicking forward button
  1271. // of the browser, bind the code mirror to inline query editor.
  1272. bindCodeMirrorToInlineEditor();
  1273. $("a.inline_edit_sql").live('click', function () {
  1274. if ($('#sql_query_edit').length) {
  1275. // An inline query editor is already open,
  1276. // we don't want another copy of it
  1277. return false;
  1278. }
  1279. var $form = $(this).prev('form');
  1280. var sql_query = $form.find("input[name='sql_query']").val();
  1281. var $inner_sql = $(this).parent().prev().find('code.sql');
  1282. var old_text = $inner_sql.html();
  1283. var new_content = "<textarea name=\"sql_query_edit\" id=\"sql_query_edit\">" + sql_query + "</textarea>\n";
  1284. new_content += "<input type=\"submit\" id=\"sql_query_edit_save\" class=\"button btnSave\" value=\"" + PMA_messages.strGo + "\"/>\n";
  1285. new_content += "<input type=\"button\" id=\"sql_query_edit_discard\" class=\"button btnDiscard\" value=\"" + PMA_messages.strCancel + "\"/>\n";
  1286. var $editor_area = $('div#inline_editor');
  1287. if ($editor_area.length === 0) {
  1288. $editor_area = $('<div id="inline_editor_outer"></div>');
  1289. $editor_area.insertBefore($inner_sql);
  1290. }
  1291. $editor_area.html(new_content);
  1292. $inner_sql.hide();
  1293. bindCodeMirrorToInlineEditor();
  1294. return false;
  1295. });
  1296. $("input#sql_query_edit_save").live('click', function () {
  1297. $(".success").hide();
  1298. //hide already existing success message
  1299. var sql_query;
  1300. if (codemirror_inline_editor) {
  1301. codemirror_inline_editor.save();
  1302. sql_query = codemirror_inline_editor.getValue();
  1303. } else {
  1304. sql_query = $(this).prev().val();
  1305. }
  1306. var $form = $("a.inline_edit_sql").prev('form');
  1307. var $fake_form = $('<form>', {action: 'import.php', method: 'post'})
  1308. .append($form.find("input[name=server], input[name=db], input[name=table], input[name=token]").clone())
  1309. .append($('<input/>', {type: 'hidden', name: 'show_query', value: 1}))
  1310. .append($('<input/>', {type: 'hidden', name: 'is_js_confirmed', value: 0}))
  1311. .append($('<input/>', {type: 'hidden', name: 'sql_query', value: sql_query}));
  1312. if (! checkSqlQuery($fake_form[0])) {
  1313. return false;
  1314. }
  1315. $fake_form.appendTo($('body')).submit();
  1316. });
  1317. $("input#sql_query_edit_discard").live('click', function () {
  1318. $('div#inline_editor_outer').siblings('code.sql').show();
  1319. $('div#inline_editor_outer').remove();
  1320. });
  1321. $('input.sqlbutton').click(function (evt) {
  1322. insertQuery(evt.target.id);
  1323. return false;
  1324. });
  1325. $("#export_type").change(function () {
  1326. if ($("#export_type").val() == 'svg') {
  1327. $("#show_grid_opt").prop("disabled", true);
  1328. $("#orientation_opt").prop("disabled", true);
  1329. $("#with_doc").prop("disabled", true);
  1330. $("#show_table_dim_opt").removeProp("disabled");
  1331. $("#all_tables_same_width").removeProp("disabled");
  1332. $("#paper_opt").removeProp("disabled");
  1333. $("#show_color_opt").removeProp("disabled");
  1334. //$(this).css("background-color","yellow");
  1335. } else if ($("#export_type").val() == 'dia') {
  1336. $("#show_grid_opt").prop("disabled", true);
  1337. $("#with_doc").prop("disabled", true);
  1338. $("#show_table_dim_opt").prop("disabled", true);
  1339. $("#all_tables_same_width").prop("disabled", true);
  1340. $("#paper_opt").removeProp("disabled");
  1341. $("#show_color_opt").removeProp("disabled");
  1342. $("#orientation_opt").removeProp("disabled");
  1343. } else if ($("#export_type").val() == 'eps') {
  1344. $("#show_grid_opt").prop("disabled", true);
  1345. $("#orientation_opt").removeProp("disabled");
  1346. $("#with_doc").prop("disabled", true);
  1347. $("#show_table_dim_opt").prop("disabled", true);
  1348. $("#all_tables_same_width").prop("disabled", true);
  1349. $("#paper_opt").prop("disabled", true);
  1350. $("#show_color_opt").prop("disabled", true);
  1351. } else if ($("#export_type").val() == 'pdf') {
  1352. $("#show_grid_opt").removeProp("disabled");
  1353. $("#orientation_opt").removeProp("disabled");
  1354. $("#with_doc").removeProp("disabled");
  1355. $("#show_table_dim_opt").removeProp("disabled");
  1356. $("#all_tables_same_width").removeProp("disabled");
  1357. $("#paper_opt").removeProp("disabled");
  1358. $("#show_color_opt").removeProp("disabled");
  1359. } else {
  1360. // nothing
  1361. }
  1362. });
  1363. if ($('#input_username')) {
  1364. if ($('#input_username').val() === '') {
  1365. $('#input_username').focus();
  1366. } else {
  1367. $('#input_password').focus();
  1368. }
  1369. }
  1370. });
  1371. /**
  1372. * Binds the CodeMirror to the text area used to inline edit a query.
  1373. */
  1374. function bindCodeMirrorToInlineEditor() {
  1375. var $inline_editor = $('#sql_query_edit');
  1376. if ($inline_editor.length > 0) {
  1377. if (typeof CodeMirror !== 'undefined') {
  1378. var height = $('#sql_query_edit').css('height');
  1379. codemirror_inline_editor = CodeMirror.fromTextArea($inline_editor[0], {
  1380. lineNumbers: true,
  1381. matchBrackets: true,
  1382. indentUnit: 4,
  1383. mode: "text/x-mysql",
  1384. lineWrapping: true
  1385. });
  1386. codemirror_inline_editor.getScrollerElement().style.height = height;
  1387. codemirror_inline_editor.refresh();
  1388. codemirror_inline_editor.focus();
  1389. $(codemirror_inline_editor.getWrapperElement()).bind(
  1390. 'keydown',
  1391. catchKeypressesFromSqlTextboxes
  1392. );
  1393. } else {
  1394. $inline_editor.focus().bind(
  1395. 'keydown',
  1396. catchKeypressesFromSqlTextboxes
  1397. );
  1398. }
  1399. }
  1400. }
  1401. function catchKeypressesFromSqlTextboxes(event) {
  1402. // ctrl-enter is 10 in chrome and ie, but 13 in ff
  1403. if (event.ctrlKey && (event.keyCode == 13 || event.keyCode == 10)) {
  1404. if ($('#sql_query_edit').length > 0) {
  1405. $("#sql_query_edit_save").trigger('click');
  1406. } else if ($('#sqlquery').length > 0) {
  1407. $("#button_submit_query").trigger('click');
  1408. }
  1409. }
  1410. }
  1411. /**
  1412. * Adds doc link to single highlighted SQL element
  1413. */
  1414. function PMA_doc_add($elm, params)
  1415. {
  1416. var url = $.sprintf(
  1417. mysql_doc_template,
  1418. params[0]
  1419. );
  1420. if (params.length > 1) {
  1421. url += '#' + params[1];
  1422. }
  1423. var content = $elm.text();
  1424. $elm.text('');
  1425. $elm.append('<a target="mysql_doc" class="cm-sql-doc" href="' + url + '">' + content + '</a>');
  1426. }
  1427. /**
  1428. * Generates doc links for keywords inside highlighted SQL
  1429. */
  1430. function PMA_doc_keyword(idx, elm)
  1431. {
  1432. var $elm = $(elm);
  1433. /* Skip already processed ones */
  1434. if ($elm.find('a').length > 0) {
  1435. return;
  1436. }
  1437. var keyword = $elm.text().toUpperCase();
  1438. var $next = $elm.next('.cm-keyword');
  1439. if ($next) {
  1440. var next_keyword = $next.text().toUpperCase();
  1441. var full = keyword + ' ' + next_keyword;
  1442. var $next2 = $next.next('.cm-keyword');
  1443. if ($next2) {
  1444. var next2_keyword = $next2.text().toUpperCase();
  1445. var full2 = full + ' ' + next2_keyword;
  1446. if (full2 in mysql_doc_keyword) {
  1447. PMA_doc_add($elm, mysql_doc_keyword[full2]);
  1448. PMA_doc_add($next, mysql_doc_keyword[full2]);
  1449. PMA_doc_add($next2, mysql_doc_keyword[full2]);
  1450. return;
  1451. }
  1452. }
  1453. if (full in mysql_doc_keyword) {
  1454. PMA_doc_add($elm, mysql_doc_keyword[full]);
  1455. PMA_doc_add($next, mysql_doc_keyword[full]);
  1456. return;
  1457. }
  1458. }
  1459. if (keyword in mysql_doc_keyword) {
  1460. PMA_doc_add($elm, mysql_doc_keyword[keyword]);
  1461. }
  1462. }
  1463. /**
  1464. * Generates doc links for builtins inside highlighted SQL
  1465. */
  1466. function PMA_doc_builtin(idx, elm)
  1467. {
  1468. var $elm = $(elm);
  1469. var builtin = $elm.text().toUpperCase();
  1470. if (builtin in mysql_doc_builtin) {
  1471. PMA_doc_add($elm, mysql_doc_builtin[builtin]);
  1472. }
  1473. }
  1474. /**
  1475. * Higlights SQL using CodeMirror.
  1476. */
  1477. function PMA_highlightSQL(base)
  1478. {
  1479. var $elm = base.find('code.sql');
  1480. $elm.each(function () {
  1481. var $sql = $(this);
  1482. var $pre = $sql.find('pre');
  1483. /* We only care about visible elements to avoid double processing */
  1484. if ($pre.is(":visible")) {
  1485. var $highlight = $('<div class="sql-highlight cm-s-default"></div>');
  1486. $sql.append($highlight);
  1487. if (typeof CodeMirror != 'undefined') {
  1488. CodeMirror.runMode($sql.text(), 'text/x-mysql', $highlight[0]);
  1489. $pre.hide();
  1490. $highlight.find('.cm-keyword').each(PMA_doc_keyword);
  1491. $highlight.find('.cm-builtin').each(PMA_doc_builtin);
  1492. }
  1493. }
  1494. });
  1495. }
  1496. /**
  1497. * Show a message on the top of the page for an Ajax request
  1498. *
  1499. * Sample usage:
  1500. *
  1501. * 1) var $msg = PMA_ajaxShowMessage();
  1502. * This will show a message that reads "Loading...". Such a message will not
  1503. * disappear automatically and cannot be dismissed by the user. To remove this
  1504. * message either the PMA_ajaxRemoveMessage($msg) function must be called or
  1505. * another message must be show with PMA_ajaxShowMessage() function.
  1506. *
  1507. * 2) var $msg = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
  1508. * This is a special case. The behaviour is same as above,
  1509. * just with a different message
  1510. *
  1511. * 3) var $msg = PMA_ajaxShowMessage('The operation was successful');
  1512. * This will show a message that will disappear automatically and it can also
  1513. * be dismissed by the user.
  1514. *
  1515. * 4) var $msg = PMA_ajaxShowMessage('Some error', false);
  1516. * This will show a message that will not disappear automatically, but it
  1517. * can be dismissed by the user after he has finished reading it.
  1518. *
  1519. * @param string message string containing the message to be shown.
  1520. * optional, defaults to 'Loading...'
  1521. * @param mixed timeout numb…

Large files files are truncated, but you can click here to view the full file