Merge pull request #14465 from Piyush3079/Mod_Js_Server_Privileges
server_privileges and server_databases modularized
This commit is contained in:
commit
dfcca3c46e
3
.babelrc
3
.babelrc
@ -1,3 +1,4 @@
|
||||
{
|
||||
"presets": ["env"]
|
||||
"presets": ["env"],
|
||||
"plugins": ["syntax-dynamic-import"]
|
||||
}
|
||||
|
||||
@ -5,9 +5,12 @@
|
||||
"node": true,
|
||||
"es6": true
|
||||
},
|
||||
"parser": "babel-eslint",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"sourceType": "module",
|
||||
"allowImportExportEverywhere": true,
|
||||
"codeFrame": false,
|
||||
"ecmaFeatures": {
|
||||
"jsx": false
|
||||
}
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -55,3 +55,4 @@ composer.lock
|
||||
/vendor/
|
||||
# NPM
|
||||
/node_modules/
|
||||
yarn.lock
|
||||
|
||||
40
js/common_params.php
Normal file
40
js/common_params.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
* Exporting of common params defined in Header.php to make them available in
|
||||
* the global window object and then serialize these variables in the modules.
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
|
||||
if (!defined('TESTSUITE')) {
|
||||
chdir('..');
|
||||
|
||||
// Send correct type:
|
||||
header('Content-Type: text/javascript; charset=UTF-8');
|
||||
|
||||
// Cache output in client - the nocache query parameter makes sure that this
|
||||
// file is reloaded when config changes
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
|
||||
|
||||
// Avoid loading the full common.inc.php because this would add many
|
||||
// non-js-compatible stuff like DOCTYPE
|
||||
define('PMA_MINIMUM_COMMON', true);
|
||||
define('PMA_PATH_TO_BASEDIR', '../');
|
||||
require_once './libraries/common.inc.php';
|
||||
// Close session early as we won't write anything there
|
||||
session_write_close();
|
||||
}
|
||||
|
||||
// But this one is needed for Sanitize::escapeJsString()
|
||||
use PhpMyAdmin\Header;
|
||||
use PhpMyAdmin\Sanitize;
|
||||
|
||||
$header = new Header();
|
||||
|
||||
echo "var common_params = new Array();\n";
|
||||
foreach ($header->getJsParams() as $name => $value) {
|
||||
Sanitize::printJsValue("common_params['" . $name . "']", $value);
|
||||
}
|
||||
|
||||
?>
|
||||
@ -5105,3 +5105,63 @@ jQuery.fn.getPostData = function () {
|
||||
}
|
||||
return dataPost;
|
||||
};
|
||||
|
||||
/**
|
||||
* @todo REMOVE THESE FUNCTIONS AFTER COMPLETE CODE BEING MODULAR
|
||||
*
|
||||
* Copy of functions copied from different files to make them globally
|
||||
* available so that build does not break during modularisation
|
||||
*/
|
||||
/**
|
||||
* server_privilages.js
|
||||
*/
|
||||
/**
|
||||
* Validates the "add a user" form
|
||||
*
|
||||
* @return boolean whether the form is validated or not
|
||||
*/
|
||||
function checkAddUser (the_form) {
|
||||
if (the_form.elements.pred_hostname.value === 'userdefined' && the_form.elements.hostname.value === '') {
|
||||
alert(PMA_messages.strHostEmpty);
|
||||
the_form.elements.hostname.focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (the_form.elements.pred_username.value === 'userdefined' && the_form.elements.username.value === '') {
|
||||
alert(PMA_messages.strUserEmpty);
|
||||
the_form.elements.username.focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
return PMA_checkPassword($(the_form));
|
||||
} // end of the 'checkAddUser()' function
|
||||
|
||||
function checkPasswordStrength (value, meter_obj, meter_object_label, username) {
|
||||
// List of words we don't want to appear in the password
|
||||
var customDict = [
|
||||
'phpmyadmin',
|
||||
'mariadb',
|
||||
'mysql',
|
||||
'php',
|
||||
'my',
|
||||
'admin',
|
||||
];
|
||||
if (username !== null) {
|
||||
customDict.push(username);
|
||||
}
|
||||
var zxcvbn_obj = zxcvbn(value, customDict);
|
||||
var strength = zxcvbn_obj.score;
|
||||
strength = parseInt(strength);
|
||||
meter_obj.val(strength);
|
||||
switch (strength) {
|
||||
case 0: meter_object_label.html(PMA_messages.strExtrWeak);
|
||||
break;
|
||||
case 1: meter_object_label.html(PMA_messages.strVeryWeak);
|
||||
break;
|
||||
case 2: meter_object_label.html(PMA_messages.strWeak);
|
||||
break;
|
||||
case 3: meter_object_label.html(PMA_messages.strGood);
|
||||
break;
|
||||
case 4: meter_object_label.html(PMA_messages.strStrong);
|
||||
}
|
||||
}
|
||||
|
||||
225
js/messages.php
225
js/messages.php
@ -755,6 +755,26 @@ foreach ($js_messages as $name => $js_message) {
|
||||
Sanitize::printJsValue("PMA_messages['" . $name . "']", $js_message);
|
||||
}
|
||||
|
||||
/* for new js code */
|
||||
/* Calendar */
|
||||
echo "var globalVars = new Array();\n";
|
||||
echo "globalVars['themeCalendarImage'] = '" , $GLOBALS['pmaThemeImage']
|
||||
, 'b_calendar.png' , "';\n";
|
||||
|
||||
/* Image path */
|
||||
echo "globalVars['pmaThemeImage'] = '" , $GLOBALS['pmaThemeImage'] , "';\n";
|
||||
|
||||
echo "globalVars['mysql_doc_template'] = '" , PhpMyAdmin\Util::getMySQLDocuURL('%s')
|
||||
, "';\n";
|
||||
|
||||
//Max input vars allowed by PHP.
|
||||
$maxInputVars = ini_get('max_input_vars');
|
||||
echo "globalVars['maxInputVars'] = '"
|
||||
, (false === $maxInputVars || '' == $maxInputVars ? 'false' : (int)$maxInputVars)
|
||||
, ';' . "'\n";
|
||||
/* for new js code */
|
||||
|
||||
/* for old js code */
|
||||
/* Calendar */
|
||||
echo "var themeCalendarImage = '" , $GLOBALS['pmaThemeImage']
|
||||
, 'b_calendar.png' , "';\n";
|
||||
@ -770,7 +790,144 @@ $maxInputVars = ini_get('max_input_vars');
|
||||
echo 'var maxInputVars = '
|
||||
, (false === $maxInputVars || '' == $maxInputVars ? 'false' : (int)$maxInputVars)
|
||||
, ';' . "\n";
|
||||
/* for old js code */
|
||||
|
||||
/* for new js code */
|
||||
echo "datePicker = new Array();\n";
|
||||
echo "timePicker = new Array();\n";
|
||||
/* l10n: Display text for calendar close link */
|
||||
Sanitize::printJsValue("datePicker['closeText']", __('Done'));
|
||||
/* l10n: Display text for previous month link in calendar */
|
||||
Sanitize::printJsValue(
|
||||
"datePicker['prevText']",
|
||||
_pgettext('Previous month', 'Prev')
|
||||
);
|
||||
/* l10n: Display text for next month link in calendar */
|
||||
Sanitize::printJsValue(
|
||||
"datePicker['nextText']",
|
||||
_pgettext('Next month', 'Next')
|
||||
);
|
||||
/* l10n: Display text for current month link in calendar */
|
||||
Sanitize::printJsValue("datePicker['currentText']", __('Today'));
|
||||
Sanitize::printJsValue(
|
||||
"datePicker['monthNames']",
|
||||
array(
|
||||
__('January'),
|
||||
__('February'),
|
||||
__('March'),
|
||||
__('April'),
|
||||
__('May'),
|
||||
__('June'),
|
||||
__('July'),
|
||||
__('August'),
|
||||
__('September'),
|
||||
__('October'),
|
||||
__('November'),
|
||||
__('December')
|
||||
)
|
||||
);
|
||||
Sanitize::printJsValue(
|
||||
"datePicker['monthNamesShort']",
|
||||
array(
|
||||
/* l10n: Short month name */
|
||||
__('Jan'),
|
||||
/* l10n: Short month name */
|
||||
__('Feb'),
|
||||
/* l10n: Short month name */
|
||||
__('Mar'),
|
||||
/* l10n: Short month name */
|
||||
__('Apr'),
|
||||
/* l10n: Short month name */
|
||||
_pgettext('Short month name', 'May'),
|
||||
/* l10n: Short month name */
|
||||
__('Jun'),
|
||||
/* l10n: Short month name */
|
||||
__('Jul'),
|
||||
/* l10n: Short month name */
|
||||
__('Aug'),
|
||||
/* l10n: Short month name */
|
||||
__('Sep'),
|
||||
/* l10n: Short month name */
|
||||
__('Oct'),
|
||||
/* l10n: Short month name */
|
||||
__('Nov'),
|
||||
/* l10n: Short month name */
|
||||
__('Dec')
|
||||
)
|
||||
);
|
||||
Sanitize::printJsValue(
|
||||
"datePicker['dayNames']",
|
||||
array(
|
||||
__('Sunday'),
|
||||
__('Monday'),
|
||||
__('Tuesday'),
|
||||
__('Wednesday'),
|
||||
__('Thursday'),
|
||||
__('Friday'),
|
||||
__('Saturday')
|
||||
)
|
||||
);
|
||||
Sanitize::printJsValue(
|
||||
"datePicker['dayNamesShort']",
|
||||
array(
|
||||
/* l10n: Short week day name */
|
||||
__('Sun'),
|
||||
/* l10n: Short week day name */
|
||||
__('Mon'),
|
||||
/* l10n: Short week day name */
|
||||
__('Tue'),
|
||||
/* l10n: Short week day name */
|
||||
__('Wed'),
|
||||
/* l10n: Short week day name */
|
||||
__('Thu'),
|
||||
/* l10n: Short week day name */
|
||||
__('Fri'),
|
||||
/* l10n: Short week day name */
|
||||
__('Sat')
|
||||
)
|
||||
);
|
||||
Sanitize::printJsValue(
|
||||
"datePicker['dayNamesMin']",
|
||||
array(
|
||||
/* l10n: Minimal week day name */
|
||||
__('Su'),
|
||||
/* l10n: Minimal week day name */
|
||||
__('Mo'),
|
||||
/* l10n: Minimal week day name */
|
||||
__('Tu'),
|
||||
/* l10n: Minimal week day name */
|
||||
__('We'),
|
||||
/* l10n: Minimal week day name */
|
||||
__('Th'),
|
||||
/* l10n: Minimal week day name */
|
||||
__('Fr'),
|
||||
/* l10n: Minimal week day name */
|
||||
__('Sa')
|
||||
)
|
||||
);
|
||||
/* l10n: Column header for week of the year in calendar */
|
||||
Sanitize::printJsValue("datePicker['weekHeader']", __('Wk'));
|
||||
|
||||
Sanitize::printJsValue(
|
||||
"datePicker['showMonthAfterYear']",
|
||||
/* l10n: Month-year order for calendar, use either "calendar-month-year"
|
||||
* or "calendar-year-month".
|
||||
*/
|
||||
(__('calendar-month-year') == 'calendar-year-month')
|
||||
);
|
||||
/* l10n: Year suffix for calendar, "none" is empty. */
|
||||
$year_suffix = _pgettext('Year suffix', 'none');
|
||||
Sanitize::printJsValue(
|
||||
"datePicker['yearSuffix']",
|
||||
($year_suffix == 'none' ? '' : $year_suffix)
|
||||
);
|
||||
Sanitize::printJsValue("timePicker['timeText']", __('Time'));
|
||||
Sanitize::printJsValue("timePicker['hourText']", __('Hour'));
|
||||
Sanitize::printJsValue("timePicker['minuteText']", __('Minute'));
|
||||
Sanitize::printJsValue("timePicker['secondText']", __('Second'));
|
||||
/* for new js code */
|
||||
|
||||
/* for old js code */
|
||||
echo "if ($.datepicker) {\n";
|
||||
/* l10n: Display text for calendar close link */
|
||||
Sanitize::printJsValue("$.datepicker.regional['']['closeText']", __('Done'));
|
||||
@ -908,11 +1065,78 @@ Sanitize::printJsValue("$.timepicker.regional['']['timeText']", __('Time'));
|
||||
Sanitize::printJsValue("$.timepicker.regional['']['hourText']", __('Hour'));
|
||||
Sanitize::printJsValue("$.timepicker.regional['']['minuteText']", __('Minute'));
|
||||
Sanitize::printJsValue("$.timepicker.regional['']['secondText']", __('Second'));
|
||||
/* for old js code */
|
||||
?>
|
||||
$.extend($.timepicker._defaults, $.timepicker.regional['']);
|
||||
} /* if ($.timepicker) */
|
||||
|
||||
<?php
|
||||
/* for new js code */
|
||||
/* Form validation */
|
||||
/* Default validation functions */
|
||||
echo "validationMessage = {\n";
|
||||
Sanitize::printJsValueForFormValidation('required', __('This field is required'));
|
||||
Sanitize::printJsValueForFormValidation('remote', __('Please fix this field'));
|
||||
Sanitize::printJsValueForFormValidation('email', __('Please enter a valid email address'));
|
||||
Sanitize::printJsValueForFormValidation('url', __('Please enter a valid URL'));
|
||||
Sanitize::printJsValueForFormValidation('date', __('Please enter a valid date'));
|
||||
Sanitize::printJsValueForFormValidation(
|
||||
'dateISO',
|
||||
__('Please enter a valid date ( ISO )')
|
||||
);
|
||||
Sanitize::printJsValueForFormValidation('number', __('Please enter a valid number'));
|
||||
Sanitize::printJsValueForFormValidation(
|
||||
'creditcard',
|
||||
__('Please enter a valid credit card number')
|
||||
);
|
||||
Sanitize::printJsValueForFormValidation('digits', __('Please enter only digits'));
|
||||
Sanitize::printJsValueForFormValidation(
|
||||
'equalTo',
|
||||
__('Please enter the same value again')
|
||||
);
|
||||
echo "\n};\n";
|
||||
echo "validationFormat = {\n";
|
||||
Sanitize::printJsValueForFormValidation(
|
||||
'maxlength',
|
||||
__('Please enter no more than {0} characters')
|
||||
);
|
||||
Sanitize::printJsValueForFormValidation(
|
||||
'minlength',
|
||||
__('Please enter at least {0} characters')
|
||||
);
|
||||
Sanitize::printJsValueForFormValidation(
|
||||
'rangelength',
|
||||
__('Please enter a value between {0} and {1} characters long')
|
||||
);
|
||||
Sanitize::printJsValueForFormValidation(
|
||||
'range',
|
||||
__('Please enter a value between {0} and {1}')
|
||||
);
|
||||
Sanitize::printJsValueForFormValidation(
|
||||
'max',
|
||||
__('Please enter a value less than or equal to {0}')
|
||||
);
|
||||
Sanitize::printJsValueForFormValidation(
|
||||
'min',
|
||||
__('Please enter a value greater than or equal to {0}')
|
||||
);
|
||||
/* customed functions */
|
||||
Sanitize::printJsValueForFormValidation(
|
||||
'validationFunctionForDateTime',
|
||||
__('Please enter a valid date or time')
|
||||
);
|
||||
Sanitize::printJsValueForFormValidation(
|
||||
'validationFunctionForHex',
|
||||
__('Please enter a valid HEX input')
|
||||
);
|
||||
Sanitize::printJsValueForFormValidation(
|
||||
'validationFunctionForFuns',
|
||||
__('Error')
|
||||
);
|
||||
echo "\n};\n";
|
||||
/* for new js code */
|
||||
|
||||
/* for old js code */
|
||||
/* Form validation */
|
||||
|
||||
echo "function extendingValidatorMessages() {\n";
|
||||
@ -986,4 +1210,5 @@ Sanitize::printJsValueForFormValidation(
|
||||
);
|
||||
echo "\n});";
|
||||
echo "\n} /* if ($.validator) */";
|
||||
/* for old js code */
|
||||
?>
|
||||
|
||||
@ -9,57 +9,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Validates the "add a user" form
|
||||
*
|
||||
* @return boolean whether the form is validated or not
|
||||
*/
|
||||
function checkAddUser (the_form) {
|
||||
if (the_form.elements.pred_hostname.value === 'userdefined' && the_form.elements.hostname.value === '') {
|
||||
alert(PMA_messages.strHostEmpty);
|
||||
the_form.elements.hostname.focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (the_form.elements.pred_username.value === 'userdefined' && the_form.elements.username.value === '') {
|
||||
alert(PMA_messages.strUserEmpty);
|
||||
the_form.elements.username.focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
return PMA_checkPassword($(the_form));
|
||||
} // end of the 'checkAddUser()' function
|
||||
|
||||
function checkPasswordStrength (value, meter_obj, meter_object_label, username) {
|
||||
// List of words we don't want to appear in the password
|
||||
customDict = [
|
||||
'phpmyadmin',
|
||||
'mariadb',
|
||||
'mysql',
|
||||
'php',
|
||||
'my',
|
||||
'admin',
|
||||
];
|
||||
if (username !== null) {
|
||||
customDict.push(username);
|
||||
}
|
||||
var zxcvbn_obj = zxcvbn(value, customDict);
|
||||
var strength = zxcvbn_obj.score;
|
||||
strength = parseInt(strength);
|
||||
meter_obj.val(strength);
|
||||
switch (strength) {
|
||||
case 0: meter_obj_label.html(PMA_messages.strExtrWeak);
|
||||
break;
|
||||
case 1: meter_obj_label.html(PMA_messages.strVeryWeak);
|
||||
break;
|
||||
case 2: meter_obj_label.html(PMA_messages.strWeak);
|
||||
break;
|
||||
case 3: meter_obj_label.html(PMA_messages.strGood);
|
||||
break;
|
||||
case 4: meter_obj_label.html(PMA_messages.strStrong);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX scripts for server_privileges page.
|
||||
*
|
||||
@ -75,7 +24,6 @@ function checkPasswordStrength (value, meter_obj, meter_object_label, username)
|
||||
* @name document.ready
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Unbind all event handlers before tearing down a page
|
||||
*/
|
||||
|
||||
757
js/src/ajax.js
Normal file
757
js/src/ajax.js
Normal file
@ -0,0 +1,757 @@
|
||||
import { PMA_ajaxShowMessage } from './utils/show_ajax_messages';
|
||||
import { PMA_Messages as PMA_messages } from './variables/export_variables';
|
||||
import { PMA_commonParams } from './variables/common_params';
|
||||
import { jQuery as $ } from './utils/JqueryExtended';
|
||||
import { PMA_getImage } from './functions/get_image';
|
||||
|
||||
/**
|
||||
* This object handles ajax requests for pages. It also
|
||||
* handles the reloading of the main menu and scripts.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @todo this function is to be removed when complete code is modularised
|
||||
*/
|
||||
function checkNewCode (script) {
|
||||
var check = script.split('.js');
|
||||
// console.log(check);
|
||||
if (check.length === 2) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export let AJAX = {
|
||||
/**
|
||||
* @var bool test variable for checking this object
|
||||
*/
|
||||
test: false,
|
||||
/**
|
||||
* @var bool active Whether we are busy
|
||||
*/
|
||||
active: false,
|
||||
/**
|
||||
* @var object source The object whose event initialized the request
|
||||
*/
|
||||
source: null,
|
||||
/**
|
||||
* @var object xhr A reference to the ajax request that is currently running
|
||||
*/
|
||||
xhr: null,
|
||||
/**
|
||||
* @var object lockedTargets, list of locked targets
|
||||
*/
|
||||
lockedTargets: {},
|
||||
/**
|
||||
* @var function Callback to execute after a successful request
|
||||
* Used by PMA_commonFunctions from common.js
|
||||
*/
|
||||
_callback: function () {},
|
||||
/**
|
||||
* @var bool _debug Makes noise in your Firebug console
|
||||
*/
|
||||
_debug: false,
|
||||
/**
|
||||
* @var object $msgbox A reference to a jQuery object that links to a message
|
||||
* box that is generated by PMA_ajaxShowMessage()
|
||||
*/
|
||||
$msgbox: null,
|
||||
/**
|
||||
* Given the filename of a script, returns a hash to be
|
||||
* used to refer to all the events registered for the file
|
||||
*
|
||||
* @param key string key The filename for which to get the event name
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
|
||||
hash: function (key) {
|
||||
/* http://burtleburtle.net/bob/hash/doobs.html#one */
|
||||
key += '';
|
||||
var len = key.length;
|
||||
var hash = 0;
|
||||
var i = 0;
|
||||
for (; i < len; ++i) {
|
||||
hash += key.charCodeAt(i);
|
||||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6);
|
||||
}
|
||||
hash += (hash << 3);
|
||||
hash ^= (hash >> 11);
|
||||
hash += (hash << 15);
|
||||
return Math.abs(hash);
|
||||
},
|
||||
/**
|
||||
* Registers an onload event for a file
|
||||
*
|
||||
* @param file string file The filename for which to register the event
|
||||
* @param func function func The function to execute when the page is ready
|
||||
*
|
||||
* @return self For chaining
|
||||
*/
|
||||
registerOnload: function (file, func) {
|
||||
var eventName = 'onload_' + this.hash(file);
|
||||
$(document).on(eventName, func);
|
||||
if (this._debug) {
|
||||
console.log(
|
||||
// no need to translate
|
||||
'Registered event ' + eventName + ' for file ' + file
|
||||
);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
/**
|
||||
* Registers a teardown event for a file. This is useful to execute functions
|
||||
* that unbind events for page elements that are about to be removed.
|
||||
*
|
||||
* @param string file The filename for which to register the event
|
||||
* @param function func The function to execute when
|
||||
* the page is about to be torn down
|
||||
*
|
||||
* @return self For chaining
|
||||
*/
|
||||
registerTeardown: function (file, func) {
|
||||
var eventName = 'teardown_' + this.hash(file);
|
||||
$(document).on(eventName, func);
|
||||
if (this._debug) {
|
||||
console.log(
|
||||
// no need to translate
|
||||
'Registered event ' + eventName + ' for file ' + file
|
||||
);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
/**
|
||||
* Called when a page has finished loading, once for every
|
||||
* file that registered to the onload event of that file.
|
||||
*
|
||||
* @param string file The filename for which to fire the event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
fireOnload: function (file) {
|
||||
var eventName = 'onload_' + this.hash(file);
|
||||
$(document).trigger(eventName);
|
||||
if (this._debug) {
|
||||
console.log(
|
||||
// no need to translate
|
||||
'Fired event ' + eventName + ' for file ' + file
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Called just before a page is torn down, once for every
|
||||
* file that registered to the teardown event of that file.
|
||||
*
|
||||
* @param string file The filename for which to fire the event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
fireTeardown: function (file) {
|
||||
var eventName = 'teardown_' + this.hash(file);
|
||||
$(document).triggerHandler(eventName);
|
||||
if (this._debug) {
|
||||
console.log(
|
||||
// no need to translate
|
||||
'Fired event ' + eventName + ' for file ' + file
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* function to handle lock page mechanism
|
||||
*
|
||||
* @param event the event object
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
lockPageHandler: function (event) {
|
||||
var newHash = null;
|
||||
var oldHash = null;
|
||||
var lockId;
|
||||
// CodeMirror lock
|
||||
if (event.data.value === 3) {
|
||||
newHash = event.data.content;
|
||||
oldHash = true;
|
||||
lockId = 'cm';
|
||||
} else {
|
||||
// Don't lock on enter.
|
||||
if (0 === event.charCode) {
|
||||
return;
|
||||
}
|
||||
|
||||
lockId = $(this).data('lock-id');
|
||||
if (typeof lockId === 'undefined') {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* @todo Fix Code mirror does not give correct full value (query)
|
||||
* in textarea, it returns only the change in content.
|
||||
*/
|
||||
if (event.data.value === 1) {
|
||||
newHash = AJAX.hash($(this).val());
|
||||
} else {
|
||||
newHash = AJAX.hash($(this).is(':checked'));
|
||||
}
|
||||
oldHash = $(this).data('val-hash');
|
||||
}
|
||||
// Set lock if old value !== new value
|
||||
// otherwise release lock
|
||||
if (oldHash !== newHash) {
|
||||
AJAX.lockedTargets[lockId] = true;
|
||||
} else {
|
||||
delete AJAX.lockedTargets[lockId];
|
||||
}
|
||||
// Show lock icon if locked targets is not empty.
|
||||
// otherwise remove lock icon
|
||||
if (!$.isEmptyObject(AJAX.lockedTargets)) {
|
||||
$('#lock_page_icon').html(PMA_getImage('s_lock', PMA_messages.strLockToolTip).toString());
|
||||
} else {
|
||||
$('#lock_page_icon').html('');
|
||||
}
|
||||
},
|
||||
/**
|
||||
* resets the lock
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
resetLock: function () {
|
||||
AJAX.lockedTargets = {};
|
||||
$('#lock_page_icon').html('');
|
||||
},
|
||||
handleMenu: {
|
||||
replace: function (content) {
|
||||
$('#floating_menubar').html(content)
|
||||
// Remove duplicate wrapper
|
||||
// TODO: don't send it in the response
|
||||
.children().first().remove();
|
||||
$('#topmenu').menuResizer(PMA_mainMenuResizerCallback);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Event handler for clicks on links and form submissions
|
||||
*
|
||||
* @param object e Event data
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
requestHandler: function (event) {
|
||||
// In some cases we don't want to handle the request here and either
|
||||
// leave the browser deal with it natively (e.g: file download)
|
||||
// or leave an existing ajax event handler present elsewhere deal with it
|
||||
var href = $(this).attr('href');
|
||||
if (typeof event !== 'undefined' && (event.shiftKey || event.ctrlKey)) {
|
||||
return true;
|
||||
} else if ($(this).attr('target')) {
|
||||
return true;
|
||||
} else if ($(this).hasClass('ajax') || $(this).hasClass('disableAjax')) {
|
||||
// reset the lockedTargets object, as specified AJAX operation has finished
|
||||
AJAX.resetLock();
|
||||
return true;
|
||||
} else if (href && href.match(/^#/)) {
|
||||
return true;
|
||||
} else if (href && href.match(/^mailto/)) {
|
||||
return true;
|
||||
} else if ($(this).hasClass('ui-datepicker-next') ||
|
||||
$(this).hasClass('ui-datepicker-prev')
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if (typeof event !== 'undefined') {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
|
||||
// triggers a confirm dialog if:
|
||||
// the user has performed some operations on loaded page
|
||||
// the user clicks on some link, (won't trigger for buttons)
|
||||
// the click event is not triggered by script
|
||||
|
||||
if (typeof event !== 'undefined' && event.type === 'click' &&
|
||||
event.isTrigger !== true &&
|
||||
!$.isEmptyObject(AJAX.lockedTargets)
|
||||
) {
|
||||
if (confirm(PMA_messages.strConfirmNavigation) === false) {
|
||||
return false;
|
||||
} else {
|
||||
if (isStorageSupported('localStorage')) {
|
||||
window.localStorage.removeItem('auto_saved_sql');
|
||||
} else {
|
||||
Cookies.set('auto_saved_sql', '');
|
||||
}
|
||||
}
|
||||
}
|
||||
AJAX.resetLock();
|
||||
var isLink = !! href || false;
|
||||
var previousLinkAborted = false;
|
||||
if (AJAX.active === true) {
|
||||
// Cancel the old request if abortable, when the user requests
|
||||
// something else. Otherwise silently bail out, as there is already
|
||||
// a request well in progress.
|
||||
if (AJAX.xhr) {
|
||||
// In case of a link request, attempt aborting
|
||||
AJAX.xhr.abort();
|
||||
if (AJAX.xhr.status === 0 && AJAX.xhr.statusText === 'abort') {
|
||||
// If aborted
|
||||
AJAX.$msgbox = PMA_ajaxShowMessage(PMA_messages.strAbortedRequest);
|
||||
AJAX.active = false;
|
||||
AJAX.xhr = null;
|
||||
previousLinkAborted = true;
|
||||
} else {
|
||||
// If can't abort
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// In case submitting a form, don't attempt aborting
|
||||
return false;
|
||||
}
|
||||
}
|
||||
AJAX.source = $(this);
|
||||
|
||||
$('html, body').animate({ scrollTop: 0 }, 'fast');
|
||||
|
||||
var url = isLink ? href : $(this).attr('action');
|
||||
var argsep = PMA_commonParams.get('arg_separator');
|
||||
var params = 'ajax_request=true' + argsep + 'ajax_page_request=true';
|
||||
var dataPost = AJAX.source.getPostData();
|
||||
if (! isLink) {
|
||||
params += argsep + $(this).serialize();
|
||||
} else if (dataPost) {
|
||||
params += argsep + dataPost;
|
||||
isLink = false;
|
||||
}
|
||||
if (! (history && history.pushState)) {
|
||||
// Add a list of menu hashes that we have in the cache to the request
|
||||
params += PMA_MicroHistory.menus.getRequestParam();
|
||||
}
|
||||
|
||||
if (AJAX._debug) {
|
||||
console.log('Loading: ' + url); // no need to translate
|
||||
}
|
||||
|
||||
if (isLink) {
|
||||
AJAX.active = true;
|
||||
AJAX.$msgbox = PMA_ajaxShowMessage();
|
||||
// Save reference for the new link request
|
||||
AJAX.xhr = $.get(url, params, AJAX.responseHandler);
|
||||
if (history && history.pushState) {
|
||||
var state = {
|
||||
url : href
|
||||
};
|
||||
if (previousLinkAborted) {
|
||||
// hack: there is already an aborted entry on stack
|
||||
// so just modify the aborted one
|
||||
history.replaceState(state, null, href);
|
||||
} else {
|
||||
history.pushState(state, null, href);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* Manually fire the onsubmit event for the form, if any.
|
||||
* The event was saved in the jQuery data object by an onload
|
||||
* handler defined below. Workaround for bug #3583316
|
||||
*/
|
||||
var onsubmit = $(this).data('onsubmit');
|
||||
// Submit the request if there is no onsubmit handler
|
||||
// or if it returns a value that evaluates to true
|
||||
if (typeof onsubmit !== 'function' || onsubmit.apply(this, [event])) {
|
||||
AJAX.active = true;
|
||||
AJAX.$msgbox = PMA_ajaxShowMessage();
|
||||
$.post(url, params, AJAX.responseHandler);
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Called after the request that was initiated by this.requestHandler()
|
||||
* has completed successfully or with a caught error. For completely
|
||||
* failed requests or requests with uncaught errors, see the .ajaxError
|
||||
* handler at the bottom of this file.
|
||||
*
|
||||
* To refer to self use 'AJAX', instead of 'this' as this function
|
||||
* is called in the jQuery context.
|
||||
*
|
||||
* @param object e Event data
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
responseHandler: function (data) {
|
||||
if (typeof data === 'undefined' || data === null) {
|
||||
return;
|
||||
}
|
||||
if (typeof data.success !== 'undefined' && data.success) {
|
||||
$('html, body').animate({ scrollTop: 0 }, 'fast');
|
||||
PMA_ajaxRemoveMessage(AJAX.$msgbox);
|
||||
|
||||
if (data._redirect) {
|
||||
PMA_ajaxShowMessage(data._redirect, false);
|
||||
AJAX.active = false;
|
||||
AJAX.xhr = null;
|
||||
return;
|
||||
}
|
||||
|
||||
AJAX.scriptHandler.reset(function () {
|
||||
if (data._reloadNavigation) {
|
||||
PMA_reloadNavigation();
|
||||
}
|
||||
|
||||
if (data._title) {
|
||||
$('title').replaceWith(data._title);
|
||||
}
|
||||
if (data._menu) {
|
||||
if (history && history.pushState) {
|
||||
var state = {
|
||||
url : data._selflink,
|
||||
menu : data._menu
|
||||
};
|
||||
history.replaceState(state, null);
|
||||
AJAX.handleMenu.replace(data._menu);
|
||||
} else {
|
||||
PMA_MicroHistory.menus.replace(data._menu);
|
||||
PMA_MicroHistory.menus.add(data._menuHash, data._menu);
|
||||
}
|
||||
} else if (data._menuHash) {
|
||||
if (! (history && history.pushState)) {
|
||||
PMA_MicroHistory.menus.replace(PMA_MicroHistory.menus.get(data._menuHash));
|
||||
}
|
||||
}
|
||||
if (data._disableNaviSettings) {
|
||||
PMA_disableNaviSettings();
|
||||
} else {
|
||||
PMA_ensureNaviSettings(data._selflink);
|
||||
}
|
||||
|
||||
// Remove all containers that may have
|
||||
// been added outside of #page_content
|
||||
$('body').children()
|
||||
.not('#pma_navigation')
|
||||
.not('#floating_menubar')
|
||||
.not('#page_nav_icons')
|
||||
.not('#page_content')
|
||||
.not('#selflink')
|
||||
.not('#pma_header')
|
||||
.not('#pma_footer')
|
||||
.not('#pma_demo')
|
||||
.not('#pma_console_container')
|
||||
.not('#prefs_autoload')
|
||||
.remove();
|
||||
// Replace #page_content with new content
|
||||
if (data.message && data.message.length > 0) {
|
||||
$('#page_content').replaceWith(
|
||||
'<div id=\'page_content\'>' + data.message + '</div>'
|
||||
);
|
||||
PMA_highlightSQL($('#page_content'));
|
||||
checkNumberOfFields();
|
||||
}
|
||||
|
||||
if (data._selflink) {
|
||||
var source = data._selflink.split('?')[0];
|
||||
// Check for faulty links
|
||||
var $selflink_replace = {
|
||||
'import.php': 'tbl_sql.php',
|
||||
'tbl_chart.php': 'sql.php',
|
||||
'tbl_gis_visualization.php': 'sql.php'
|
||||
};
|
||||
if ($selflink_replace[source]) {
|
||||
var replacement = $selflink_replace[source];
|
||||
data._selflink = data._selflink.replace(source, replacement);
|
||||
}
|
||||
$('#selflink').find('> a').attr('href', data._selflink);
|
||||
}
|
||||
if (data._params) {
|
||||
PMA_commonParams.setAll(data._params);
|
||||
}
|
||||
if (data._scripts) {
|
||||
AJAX.scriptHandler.load(data._scripts);
|
||||
}
|
||||
if (data._selflink && data._scripts && data._menuHash && data._params) {
|
||||
if (! (history && history.pushState)) {
|
||||
PMA_MicroHistory.add(
|
||||
data._selflink,
|
||||
data._scripts,
|
||||
data._menuHash,
|
||||
data._params,
|
||||
AJAX.source.attr('rel')
|
||||
);
|
||||
}
|
||||
}
|
||||
if (data._displayMessage) {
|
||||
$('#page_content').prepend(data._displayMessage);
|
||||
PMA_highlightSQL($('#page_content'));
|
||||
}
|
||||
|
||||
$('#pma_errors').remove();
|
||||
|
||||
var msg = '';
|
||||
if (data._errSubmitMsg) {
|
||||
msg = data._errSubmitMsg;
|
||||
}
|
||||
if (data._errors) {
|
||||
$('<div/>', { id : 'pma_errors', class : 'clearfloat' })
|
||||
.insertAfter('#selflink')
|
||||
.append(data._errors);
|
||||
// bind for php error reporting forms (bottom)
|
||||
$('#pma_ignore_errors_bottom').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
PMA_ignorePhpErrors();
|
||||
});
|
||||
$('#pma_ignore_all_errors_bottom').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
PMA_ignorePhpErrors(false);
|
||||
});
|
||||
// In case of 'sendErrorReport'='always'
|
||||
// submit the hidden error reporting form.
|
||||
if (data._sendErrorAlways === '1' &&
|
||||
data._stopErrorReportLoop !== '1'
|
||||
) {
|
||||
$('#pma_report_errors_form').submit();
|
||||
PMA_ajaxShowMessage(PMA_messages.phpErrorsBeingSubmitted, false);
|
||||
$('html, body').animate({ scrollTop:$(document).height() }, 'slow');
|
||||
} else if (data._promptPhpErrors) {
|
||||
// otherwise just prompt user if it is set so.
|
||||
msg = msg + PMA_messages.phpErrorsFound;
|
||||
// scroll to bottom where all the errors are displayed.
|
||||
$('html, body').animate({ scrollTop:$(document).height() }, 'slow');
|
||||
}
|
||||
}
|
||||
PMA_ajaxShowMessage(msg, false);
|
||||
// bind for php error reporting forms (popup)
|
||||
$('#pma_ignore_errors_popup').on('click', function () {
|
||||
PMA_ignorePhpErrors();
|
||||
});
|
||||
$('#pma_ignore_all_errors_popup').on('click', function () {
|
||||
PMA_ignorePhpErrors(false);
|
||||
});
|
||||
|
||||
if (typeof AJAX._callback === 'function') {
|
||||
AJAX._callback.call();
|
||||
}
|
||||
AJAX._callback = function () {};
|
||||
});
|
||||
} else {
|
||||
PMA_ajaxShowMessage(data.error, false);
|
||||
AJAX.active = false;
|
||||
AJAX.xhr = null;
|
||||
PMA_handleRedirectAndReload(data);
|
||||
if (data.fieldWithError) {
|
||||
$(':input.error').removeClass('error');
|
||||
$('#' + data.fieldWithError).addClass('error');
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* This object is in charge of downloading scripts,
|
||||
* keeping track of what's downloaded and firing
|
||||
* the onload event for them when the page is ready.
|
||||
*/
|
||||
scriptHandler: {
|
||||
/**
|
||||
* @var array _scripts The list of files already downloaded
|
||||
*/
|
||||
_scripts: [],
|
||||
/**
|
||||
* @var string _scriptsVersion version of phpMyAdmin from which the
|
||||
* scripts have been loaded
|
||||
*/
|
||||
_scriptsVersion: null,
|
||||
/**
|
||||
* @var array _scriptsToBeLoaded The list of files that
|
||||
* need to be downloaded
|
||||
*/
|
||||
_scriptsToBeLoaded: [],
|
||||
/**
|
||||
* @var array _scriptsToBeFired The list of files for which
|
||||
* to fire the onload and unload events
|
||||
*/
|
||||
_scriptsToBeFired: [],
|
||||
_scriptsCompleted: false,
|
||||
/**
|
||||
* Records that a file has been downloaded
|
||||
*
|
||||
* @param string file The filename
|
||||
* @param string fire Whether this file will be registering
|
||||
* onload/teardown events
|
||||
*
|
||||
* @return self For chaining
|
||||
*/
|
||||
add: function (file, fire, callback) {
|
||||
var self = this;
|
||||
this._scripts.push(file);
|
||||
if (fire) {
|
||||
// Record whether to fire any events for the file
|
||||
// This is necessary to correctly tear down the initial page
|
||||
this._scriptsToBeFired.push(file);
|
||||
}
|
||||
/**
|
||||
* @todo This condition is to be removed once all the files are modularised
|
||||
*/
|
||||
if (checkNewCode(file)) {
|
||||
var fileImports = ['server_privileges', 'server_databases'];
|
||||
if ($.inArray(file, fileImports) !== -1) {
|
||||
// Dynamic import to load the files dynamically
|
||||
// This is used for the purpose of code splitting
|
||||
import(`./${file}`)
|
||||
.then((module) => {
|
||||
/**
|
||||
* setTimeout is used so that scripts run only when content is
|
||||
* available.
|
||||
*/
|
||||
setTimeout(function () {
|
||||
/**
|
||||
* @var i The name of the module exported in corresponding file
|
||||
*/
|
||||
for (var i in module) {
|
||||
// If the export has onload in its name, register onload for that export
|
||||
if (i.indexOf('onload') !== -1) {
|
||||
AJAX.registerOnload(`${file}`, module[i]);
|
||||
} else if (i.indexOf('teardown') !== -1) {
|
||||
// If the export has teardown in its name, register teardown for that export
|
||||
AJAX.registerTeardown(file, module[i]);
|
||||
}
|
||||
}
|
||||
// Firinf onload for the files being dynamically imported.
|
||||
AJAX.fireOnload(file);
|
||||
}, 250);
|
||||
// AJAX.fireTeardown('server_databases_new.js');
|
||||
})
|
||||
// Error of Dynamica Imoprts need to be handled with Tracekit gracefully
|
||||
.catch(e => console.log(e));
|
||||
}
|
||||
}
|
||||
return this;
|
||||
},
|
||||
/**
|
||||
* Download a list of js files in one request
|
||||
*
|
||||
* @param array files An array of filenames and flags
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
load: function (files, callback) {
|
||||
var self = this;
|
||||
var i;
|
||||
// Clear loaded scripts if they are from another version of phpMyAdmin.
|
||||
// Depends on common params being set before loading scripts in responseHandler
|
||||
if (self._scriptsVersion === null) {
|
||||
self._scriptsVersion = PMA_commonParams.get('PMA_VERSION');
|
||||
} else if (self._scriptsVersion !== PMA_commonParams.get('PMA_VERSION')) {
|
||||
self._scripts = [];
|
||||
self._scriptsVersion = PMA_commonParams.get('PMA_VERSION');
|
||||
}
|
||||
self._scriptsCompleted = false;
|
||||
self._scriptsToBeFired = [];
|
||||
// We need to first complete list of files to load
|
||||
// as next loop will directly fire requests to load them
|
||||
// and that triggers removal of them from
|
||||
// self._scriptsToBeLoaded
|
||||
for (i in files) {
|
||||
self._scriptsToBeLoaded.push(files[i].name);
|
||||
if (files[i].fire) {
|
||||
self._scriptsToBeFired.push(files[i].name);
|
||||
}
|
||||
}
|
||||
for (i in files) {
|
||||
var script = files[i].name;
|
||||
// Only for scripts that we don't already have
|
||||
if ($.inArray(script, self._scripts) === -1) {
|
||||
this.add(script, 0, callback);
|
||||
/**
|
||||
* @todo To be removed once complete code is modularised
|
||||
* Only for appending js files in the header if not already present
|
||||
*/
|
||||
if (!checkNewCode(script)) {
|
||||
this.appendScript(script, callback);
|
||||
}
|
||||
}
|
||||
self.done(script, callback);
|
||||
}
|
||||
// Trigger callback if there is nothing else to load
|
||||
self.done(null, callback);
|
||||
},
|
||||
/**
|
||||
* Called whenever all files are loaded
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
done: function (script, callback) {
|
||||
if (typeof ErrorReport !== 'undefined') {
|
||||
ErrorReport.wrap_global_functions();
|
||||
}
|
||||
if ($.inArray(script, this._scriptsToBeFired)) {
|
||||
AJAX.fireOnload(script);
|
||||
}
|
||||
if ($.inArray(script, this._scriptsToBeLoaded)) {
|
||||
this._scriptsToBeLoaded.splice($.inArray(script, this._scriptsToBeLoaded), 1);
|
||||
}
|
||||
if (script === null) {
|
||||
this._scriptsCompleted = true;
|
||||
}
|
||||
/* We need to wait for last signal (with null) or last script load */
|
||||
AJAX.active = (this._scriptsToBeLoaded.length > 0) || ! this._scriptsCompleted;
|
||||
/* Run callback on last script */
|
||||
if (! AJAX.active && $.isFunction(callback)) {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Appends a script element to the head to load the scripts
|
||||
*
|
||||
* @return void
|
||||
* this is to be removed in modularised code
|
||||
* no appending of scripts is needed
|
||||
*
|
||||
* @todo This method will be of no use in modular code
|
||||
*/
|
||||
appendScript: function (name, callback) {
|
||||
var head = document.head || document.getElementsByTagName('head')[0];
|
||||
var script = document.createElement('script');
|
||||
var self = this;
|
||||
|
||||
script.type = 'text/javascript';
|
||||
script.src = 'js/' + name + '?' + 'v=' + encodeURIComponent(PMA_commonParams.get('PMA_VERSION'));
|
||||
script.async = false;
|
||||
|
||||
script.onload = function () {
|
||||
self.done(name, callback);
|
||||
};
|
||||
head.appendChild(script);
|
||||
},
|
||||
/**
|
||||
* Fires all the teardown event handlers for the current page
|
||||
* and rebinds all forms and links to the request handler
|
||||
*
|
||||
* @param function callback The callback to call after resetting
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
reset: function (callback) {
|
||||
for (var i in this._scriptsToBeFired) {
|
||||
AJAX.fireTeardown(this._scriptsToBeFired[i]);
|
||||
}
|
||||
this._scriptsToBeFired = [];
|
||||
/**
|
||||
* Re-attach a generic event handler to clicks
|
||||
* on pages and submissions of forms
|
||||
*/
|
||||
$(document).off('click', 'a').on('click', 'a', AJAX.requestHandler);
|
||||
$(document).off('submit', 'form').on('submit', 'form', AJAX.requestHandler);
|
||||
if (! (history && history.pushState)) {
|
||||
PMA_MicroHistory.update();
|
||||
}
|
||||
callback();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Attach a generic event handler to clicks
|
||||
* on pages and submissions of forms
|
||||
*/
|
||||
$(document).on('click', 'a', AJAX.requestHandler);
|
||||
$(document).on('submit', 'form', AJAX.requestHandler);
|
||||
|
||||
/**
|
||||
* @todo this is to be removed when complete code is modularised
|
||||
* Exporsing module to window for use with non modular code
|
||||
*/
|
||||
window.AJAX = AJAX;
|
||||
365
js/src/consts/doclinks.js
Normal file
365
js/src/consts/doclinks.js
Normal file
@ -0,0 +1,365 @@
|
||||
/**
|
||||
* Definition of links to MySQL documentation.
|
||||
*/
|
||||
|
||||
export const mysql_doc_keyword = {
|
||||
/* Multi word */
|
||||
'CHARACTER SET': Array('charset'),
|
||||
'SHOW AUTHORS': Array('show-authors'),
|
||||
'SHOW BINARY LOGS': Array('show-binary-logs'),
|
||||
'SHOW BINLOG EVENTS': Array('show-binlog-events'),
|
||||
'SHOW CHARACTER SET': Array('show-character-set'),
|
||||
'SHOW COLLATION': Array('show-collation'),
|
||||
'SHOW COLUMNS': Array('show-columns'),
|
||||
'SHOW CONTRIBUTORS': Array('show-contributors'),
|
||||
'SHOW CREATE DATABASE': Array('show-create-database'),
|
||||
'SHOW CREATE EVENT': Array('show-create-event'),
|
||||
'SHOW CREATE FUNCTION': Array('show-create-function'),
|
||||
'SHOW CREATE PROCEDURE': Array('show-create-procedure'),
|
||||
'SHOW CREATE TABLE': Array('show-create-table'),
|
||||
'SHOW CREATE TRIGGER': Array('show-create-trigger'),
|
||||
'SHOW CREATE VIEW': Array('show-create-view'),
|
||||
'SHOW DATABASES': Array('show-databases'),
|
||||
'SHOW ENGINE': Array('show-engine'),
|
||||
'SHOW ENGINES': Array('show-engines'),
|
||||
'SHOW ERRORS': Array('show-errors'),
|
||||
'SHOW EVENTS': Array('show-events'),
|
||||
'SHOW FUNCTION CODE': Array('show-function-code'),
|
||||
'SHOW FUNCTION STATUS': Array('show-function-status'),
|
||||
'SHOW GRANTS': Array('show-grants'),
|
||||
'SHOW INDEX': Array('show-index'),
|
||||
'SHOW MASTER STATUS': Array('show-master-status'),
|
||||
'SHOW OPEN TABLES': Array('show-open-tables'),
|
||||
'SHOW PLUGINS': Array('show-plugins'),
|
||||
'SHOW PRIVILEGES': Array('show-privileges'),
|
||||
'SHOW PROCEDURE CODE': Array('show-procedure-code'),
|
||||
'SHOW PROCEDURE STATUS': Array('show-procedure-status'),
|
||||
'SHOW PROCESSLIST': Array('show-processlist'),
|
||||
'SHOW PROFILE': Array('show-profile'),
|
||||
'SHOW PROFILES': Array('show-profiles'),
|
||||
'SHOW RELAYLOG EVENTS': Array('show-relaylog-events'),
|
||||
'SHOW SLAVE HOSTS': Array('show-slave-hosts'),
|
||||
'SHOW SLAVE STATUS': Array('show-slave-status'),
|
||||
'SHOW STATUS': Array('show-status'),
|
||||
'SHOW TABLE STATUS': Array('show-table-status'),
|
||||
'SHOW TABLES': Array('show-tables'),
|
||||
'SHOW TRIGGERS': Array('show-triggers'),
|
||||
'SHOW VARIABLES': Array('show-variables'),
|
||||
'SHOW WARNINGS': Array('show-warnings'),
|
||||
'LOAD DATA INFILE': Array('load-data'),
|
||||
'LOAD XML': Array('load-xml'),
|
||||
'LOCK TABLES': Array('lock-tables'),
|
||||
'UNLOCK TABLES': Array('lock-tables'),
|
||||
'ALTER DATABASE': Array('alter-database'),
|
||||
'ALTER EVENT': Array('alter-event'),
|
||||
'ALTER LOGFILE GROUP': Array('alter-logfile-group'),
|
||||
'ALTER FUNCTION': Array('alter-function'),
|
||||
'ALTER PROCEDURE': Array('alter-procedure'),
|
||||
'ALTER SERVER': Array('alter-server'),
|
||||
'ALTER TABLE': Array('alter-table'),
|
||||
'ALTER TABLESPACE': Array('alter-tablespace'),
|
||||
'ALTER VIEW': Array('alter-view'),
|
||||
'CREATE DATABASE': Array('create-database'),
|
||||
'CREATE EVENT': Array('create-event'),
|
||||
'CREATE FUNCTION': Array('create-function'),
|
||||
'CREATE INDEX': Array('create-index'),
|
||||
'CREATE LOGFILE GROUP': Array('create-logfile-group'),
|
||||
'CREATE PROCEDURE': Array('create-procedure'),
|
||||
'CREATE SERVER': Array('create-server'),
|
||||
'CREATE TABLE': Array('create-table'),
|
||||
'CREATE TABLESPACE': Array('create-tablespace'),
|
||||
'CREATE TRIGGER': Array('create-trigger'),
|
||||
'CREATE VIEW': Array('create-view'),
|
||||
'DROP DATABASE': Array('drop-database'),
|
||||
'DROP EVENT': Array('drop-event'),
|
||||
'DROP FUNCTION': Array('drop-function'),
|
||||
'DROP INDEX': Array('drop-index'),
|
||||
'DROP LOGFILE GROUP': Array('drop-logfile-group'),
|
||||
'DROP PROCEDURE': Array('drop-procedure'),
|
||||
'DROP SERVER': Array('drop-server'),
|
||||
'DROP TABLE': Array('drop-table'),
|
||||
'DROP TABLESPACE': Array('drop-tablespace'),
|
||||
'DROP TRIGGER': Array('drop-trigger'),
|
||||
'DROP VIEW': Array('drop-view'),
|
||||
'RENAME TABLE': Array('rename-table'),
|
||||
'TRUNCATE TABLE': Array('truncate-table'),
|
||||
|
||||
/* Statements */
|
||||
'SELECT': Array('select'),
|
||||
'SET': Array('set'),
|
||||
'EXPLAIN': Array('explain'),
|
||||
'DESCRIBE': Array('describe'),
|
||||
'DELETE': Array('delete'),
|
||||
'SHOW': Array('show'),
|
||||
'UPDATE': Array('update'),
|
||||
'INSERT': Array('insert'),
|
||||
'REPLACE': Array('replace'),
|
||||
'CALL': Array('call'),
|
||||
'DO': Array('do'),
|
||||
'HANDLER': Array('handler'),
|
||||
'COLLATE': Array('charset-collations'),
|
||||
|
||||
/* Functions */
|
||||
'ABS': Array('mathematical-functions', 'function_abs'),
|
||||
'ACOS': Array('mathematical-functions', 'function_acos'),
|
||||
'ADDDATE': Array('date-and-time-functions', 'function_adddate'),
|
||||
'ADDTIME': Array('date-and-time-functions', 'function_addtime'),
|
||||
'AES_DECRYPT': Array('encryption-functions', 'function_aes_decrypt'),
|
||||
'AES_ENCRYPT': Array('encryption-functions', 'function_aes_encrypt'),
|
||||
'AND': Array('logical-operators', 'operator_and'),
|
||||
'ASCII': Array('string-functions', 'function_ascii'),
|
||||
'ASIN': Array('mathematical-functions', 'function_asin'),
|
||||
'ATAN2': Array('mathematical-functions', 'function_atan2'),
|
||||
'ATAN': Array('mathematical-functions', 'function_atan'),
|
||||
'AVG': Array('group-by-functions', 'function_avg'),
|
||||
'BENCHMARK': Array('information-functions', 'function_benchmark'),
|
||||
'BIN': Array('string-functions', 'function_bin'),
|
||||
'BINARY': Array('cast-functions', 'operator_binary'),
|
||||
'BIT_AND': Array('group-by-functions', 'function_bit_and'),
|
||||
'BIT_COUNT': Array('bit-functions', 'function_bit_count'),
|
||||
'BIT_LENGTH': Array('string-functions', 'function_bit_length'),
|
||||
'BIT_OR': Array('group-by-functions', 'function_bit_or'),
|
||||
'BIT_XOR': Array('group-by-functions', 'function_bit_xor'),
|
||||
'CASE': Array('control-flow-functions', 'operator_case'),
|
||||
'CAST': Array('cast-functions', 'function_cast'),
|
||||
'CEIL': Array('mathematical-functions', 'function_ceil'),
|
||||
'CEILING': Array('mathematical-functions', 'function_ceiling'),
|
||||
'CHAR_LENGTH': Array('string-functions', 'function_char_length'),
|
||||
'CHAR': Array('string-functions', 'function_char'),
|
||||
'CHARACTER_LENGTH': Array('string-functions', 'function_character_length'),
|
||||
'CHARSET': Array('information-functions', 'function_charset'),
|
||||
'COALESCE': Array('comparison-operators', 'function_coalesce'),
|
||||
'COERCIBILITY': Array('information-functions', 'function_coercibility'),
|
||||
'COLLATION': Array('information-functions', 'function_collation'),
|
||||
'COMPRESS': Array('encryption-functions', 'function_compress'),
|
||||
'CONCAT_WS': Array('string-functions', 'function_concat_ws'),
|
||||
'CONCAT': Array('string-functions', 'function_concat'),
|
||||
'CONNECTION_ID': Array('information-functions', 'function_connection_id'),
|
||||
'CONV': Array('mathematical-functions', 'function_conv'),
|
||||
'CONVERT_TZ': Array('date-and-time-functions', 'function_convert_tz'),
|
||||
'Convert': Array('cast-functions', 'function_convert'),
|
||||
'COS': Array('mathematical-functions', 'function_cos'),
|
||||
'COT': Array('mathematical-functions', 'function_cot'),
|
||||
'COUNT': Array('group-by-functions', 'function_count'),
|
||||
'CRC32': Array('mathematical-functions', 'function_crc32'),
|
||||
'CURDATE': Array('date-and-time-functions', 'function_curdate'),
|
||||
'CURRENT_DATE': Array('date-and-time-functions', 'function_current_date'),
|
||||
'CURRENT_TIME': Array('date-and-time-functions', 'function_current_time'),
|
||||
'CURRENT_TIMESTAMP': Array('date-and-time-functions', 'function_current_timestamp'),
|
||||
'CURRENT_USER': Array('information-functions', 'function_current_user'),
|
||||
'CURTIME': Array('date-and-time-functions', 'function_curtime'),
|
||||
'DATABASE': Array('information-functions', 'function_database'),
|
||||
'DATE_ADD': Array('date-and-time-functions', 'function_date_add'),
|
||||
'DATE_FORMAT': Array('date-and-time-functions', 'function_date_format'),
|
||||
'DATE_SUB': Array('date-and-time-functions', 'function_date_sub'),
|
||||
'DATE': Array('date-and-time-functions', 'function_date'),
|
||||
'DATEDIFF': Array('date-and-time-functions', 'function_datediff'),
|
||||
'DAY': Array('date-and-time-functions', 'function_day'),
|
||||
'DAYNAME': Array('date-and-time-functions', 'function_dayname'),
|
||||
'DAYOFMONTH': Array('date-and-time-functions', 'function_dayofmonth'),
|
||||
'DAYOFWEEK': Array('date-and-time-functions', 'function_dayofweek'),
|
||||
'DAYOFYEAR': Array('date-and-time-functions', 'function_dayofyear'),
|
||||
'DECLARE': Array('declare', 'declare'),
|
||||
'DECODE': Array('encryption-functions', 'function_decode'),
|
||||
'DEFAULT': Array('miscellaneous-functions', 'function_default'),
|
||||
'DEGREES': Array('mathematical-functions', 'function_degrees'),
|
||||
'DES_DECRYPT': Array('encryption-functions', 'function_des_decrypt'),
|
||||
'DES_ENCRYPT': Array('encryption-functions', 'function_des_encrypt'),
|
||||
'DIV': Array('arithmetic-functions', 'operator_div'),
|
||||
'ELT': Array('string-functions', 'function_elt'),
|
||||
'ENCODE': Array('encryption-functions', 'function_encode'),
|
||||
'ENCRYPT': Array('encryption-functions', 'function_encrypt'),
|
||||
'EXP': Array('mathematical-functions', 'function_exp'),
|
||||
'EXPORT_SET': Array('string-functions', 'function_export_set'),
|
||||
'EXTRACT': Array('date-and-time-functions', 'function_extract'),
|
||||
'ExtractValue': Array('xml-functions', 'function_extractvalue'),
|
||||
'FIELD': Array('string-functions', 'function_field'),
|
||||
'FIND_IN_SET': Array('string-functions', 'function_find_in_set'),
|
||||
'FLOOR': Array('mathematical-functions', 'function_floor'),
|
||||
'FORMAT': Array('string-functions', 'function_format'),
|
||||
'FOUND_ROWS': Array('information-functions', 'function_found_rows'),
|
||||
'FROM_DAYS': Array('date-and-time-functions', 'function_from_days'),
|
||||
'FROM_UNIXTIME': Array('date-and-time-functions', 'function_from_unixtime'),
|
||||
'GET_FORMAT': Array('date-and-time-functions', 'function_get_format'),
|
||||
'GET_LOCK': Array('miscellaneous-functions', 'function_get_lock'),
|
||||
'GREATEST': Array('comparison-operators', 'function_greatest'),
|
||||
'GROUP_CONCAT': Array('group-by-functions', 'function_group_concat'),
|
||||
'HEX': Array('string-functions', 'function_hex'),
|
||||
'HOUR': Array('date-and-time-functions', 'function_hour'),
|
||||
'IF': Array('control-flow-functions', 'function_if'),
|
||||
'IFNULL': Array('control-flow-functions', 'function_ifnull'),
|
||||
'IN': Array('comparison-operators', 'function_in'),
|
||||
'INET_ATON': Array('miscellaneous-functions', 'function_inet_aton'),
|
||||
'INET_NTOA': Array('miscellaneous-functions', 'function_inet_ntoa'),
|
||||
'INSTR': Array('string-functions', 'function_instr'),
|
||||
'INTERVAL': Array('comparison-operators', 'function_interval'),
|
||||
'IS_FREE_LOCK': Array('miscellaneous-functions', 'function_is_free_lock'),
|
||||
'IS_USED_LOCK': Array('miscellaneous-functions', 'function_is_used_lock'),
|
||||
'IS': Array('comparison-operators', 'operator_is'),
|
||||
'ISNULL': Array('comparison-operators', 'function_isnull'),
|
||||
'LAST_DAY': Array('date-and-time-functions', 'function_last_day'),
|
||||
'LAST_INSERT_ID': Array('information-functions', 'function_last_insert_id'),
|
||||
'LCASE': Array('string-functions', 'function_lcase'),
|
||||
'LEAST': Array('comparison-operators', 'function_least'),
|
||||
'LEFT': Array('string-functions', 'function_left'),
|
||||
'LENGTH': Array('string-functions', 'function_length'),
|
||||
'LIKE': Array('string-comparison-functions', 'operator_like'),
|
||||
'LN': Array('mathematical-functions', 'function_ln'),
|
||||
'LOAD_FILE': Array('string-functions', 'function_load_file'),
|
||||
'LOCALTIME': Array('date-and-time-functions', 'function_localtime'),
|
||||
'LOCALTIMESTAMP': Array('date-and-time-functions', 'function_localtimestamp'),
|
||||
'LOCATE': Array('string-functions', 'function_locate'),
|
||||
'LOG10': Array('mathematical-functions', 'function_log10'),
|
||||
'LOG2': Array('mathematical-functions', 'function_log2'),
|
||||
'LOG': Array('mathematical-functions', 'function_log'),
|
||||
'LOWER': Array('string-functions', 'function_lower'),
|
||||
'LPAD': Array('string-functions', 'function_lpad'),
|
||||
'LTRIM': Array('string-functions', 'function_ltrim'),
|
||||
'MAKE_SET': Array('string-functions', 'function_make_set'),
|
||||
'MAKEDATE': Array('date-and-time-functions', 'function_makedate'),
|
||||
'MAKETIME': Array('date-and-time-functions', 'function_maketime'),
|
||||
'MASTER_POS_WAIT': Array('miscellaneous-functions', 'function_master_pos_wait'),
|
||||
'MATCH': Array('fulltext-search', 'function_match'),
|
||||
'MAX': Array('group-by-functions', 'function_max'),
|
||||
'MD5': Array('encryption-functions', 'function_md5'),
|
||||
'MICROSECOND': Array('date-and-time-functions', 'function_microsecond'),
|
||||
'MID': Array('string-functions', 'function_mid'),
|
||||
'MIN': Array('group-by-functions', 'function_min'),
|
||||
'MINUTE': Array('date-and-time-functions', 'function_minute'),
|
||||
'MOD': Array('mathematical-functions', 'function_mod'),
|
||||
'MONTH': Array('date-and-time-functions', 'function_month'),
|
||||
'MONTHNAME': Array('date-and-time-functions', 'function_monthname'),
|
||||
'NAME_CONST': Array('miscellaneous-functions', 'function_name_const'),
|
||||
'NOT': Array('logical-operators', 'operator_not'),
|
||||
'NOW': Array('date-and-time-functions', 'function_now'),
|
||||
'NULLIF': Array('control-flow-functions', 'function_nullif'),
|
||||
'OCT': Array('mathematical-functions', 'function_oct'),
|
||||
'OCTET_LENGTH': Array('string-functions', 'function_octet_length'),
|
||||
'OLD_PASSWORD': Array('encryption-functions', 'function_old_password'),
|
||||
'OR': Array('logical-operators', 'operator_or'),
|
||||
'ORD': Array('string-functions', 'function_ord'),
|
||||
'PASSWORD': Array('encryption-functions', 'function_password'),
|
||||
'PERIOD_ADD': Array('date-and-time-functions', 'function_period_add'),
|
||||
'PERIOD_DIFF': Array('date-and-time-functions', 'function_period_diff'),
|
||||
'PI': Array('mathematical-functions', 'function_pi'),
|
||||
'POSITION': Array('string-functions', 'function_position'),
|
||||
'POW': Array('mathematical-functions', 'function_pow'),
|
||||
'POWER': Array('mathematical-functions', 'function_power'),
|
||||
'QUARTER': Array('date-and-time-functions', 'function_quarter'),
|
||||
'QUOTE': Array('string-functions', 'function_quote'),
|
||||
'RADIANS': Array('mathematical-functions', 'function_radians'),
|
||||
'RAND': Array('mathematical-functions', 'function_rand'),
|
||||
'REGEXP': Array('regexp', 'operator_regexp'),
|
||||
'RELEASE_LOCK': Array('miscellaneous-functions', 'function_release_lock'),
|
||||
'REPEAT': Array('string-functions', 'function_repeat'),
|
||||
'REVERSE': Array('string-functions', 'function_reverse'),
|
||||
'RIGHT': Array('string-functions', 'function_right'),
|
||||
'RLIKE': Array('regexp', 'operator_rlike'),
|
||||
'ROUND': Array('mathematical-functions', 'function_round'),
|
||||
'ROW_COUNT': Array('information-functions', 'function_row_count'),
|
||||
'RPAD': Array('string-functions', 'function_rpad'),
|
||||
'RTRIM': Array('string-functions', 'function_rtrim'),
|
||||
'SCHEMA': Array('information-functions', 'function_schema'),
|
||||
'SEC_TO_TIME': Array('date-and-time-functions', 'function_sec_to_time'),
|
||||
'SECOND': Array('date-and-time-functions', 'function_second'),
|
||||
'SESSION_USER': Array('information-functions', 'function_session_user'),
|
||||
'SHA': Array('encryption-functions', 'function_sha1'),
|
||||
'SHA1': Array('encryption-functions', 'function_sha1'),
|
||||
'SIGN': Array('mathematical-functions', 'function_sign'),
|
||||
'SIN': Array('mathematical-functions', 'function_sin'),
|
||||
'SLEEP': Array('miscellaneous-functions', 'function_sleep'),
|
||||
'SOUNDEX': Array('string-functions', 'function_soundex'),
|
||||
'SPACE': Array('string-functions', 'function_space'),
|
||||
'SQRT': Array('mathematical-functions', 'function_sqrt'),
|
||||
'STD': Array('group-by-functions', 'function_std'),
|
||||
'STDDEV_POP': Array('group-by-functions', 'function_stddev_pop'),
|
||||
'STDDEV_SAMP': Array('group-by-functions', 'function_stddev_samp'),
|
||||
'STDDEV': Array('group-by-functions', 'function_stddev'),
|
||||
'STR_TO_DATE': Array('date-and-time-functions', 'function_str_to_date'),
|
||||
'STRCMP': Array('string-comparison-functions', 'function_strcmp'),
|
||||
'SUBDATE': Array('date-and-time-functions', 'function_subdate'),
|
||||
'SUBSTR': Array('string-functions', 'function_substr'),
|
||||
'SUBSTRING_INDEX': Array('string-functions', 'function_substring_index'),
|
||||
'SUBSTRING': Array('string-functions', 'function_substring'),
|
||||
'SUBTIME': Array('date-and-time-functions', 'function_subtime'),
|
||||
'SUM': Array('group-by-functions', 'function_sum'),
|
||||
'SYSDATE': Array('date-and-time-functions', 'function_sysdate'),
|
||||
'SYSTEM_USER': Array('information-functions', 'function_system_user'),
|
||||
'TAN': Array('mathematical-functions', 'function_tan'),
|
||||
'TIME_FORMAT': Array('date-and-time-functions', 'function_time_format'),
|
||||
'TIME_TO_SEC': Array('date-and-time-functions', 'function_time_to_sec'),
|
||||
'TIME': Array('date-and-time-functions', 'function_time'),
|
||||
'TIMEDIFF': Array('date-and-time-functions', 'function_timediff'),
|
||||
'TIMESTAMP': Array('date-and-time-functions', 'function_timestamp'),
|
||||
'TIMESTAMPADD': Array('date-and-time-functions', 'function_timestampadd'),
|
||||
'TIMESTAMPDIFF': Array('date-and-time-functions', 'function_timestampdiff'),
|
||||
'TO_DAYS': Array('date-and-time-functions', 'function_to_days'),
|
||||
'TRIM': Array('string-functions', 'function_trim'),
|
||||
'TRUNCATE': Array('mathematical-functions', 'function_truncate'),
|
||||
'UCASE': Array('string-functions', 'function_ucase'),
|
||||
'UNCOMPRESS': Array('encryption-functions', 'function_uncompress'),
|
||||
'UNCOMPRESSED_LENGTH': Array('encryption-functions', 'function_uncompressed_length'),
|
||||
'UNHEX': Array('string-functions', 'function_unhex'),
|
||||
'UNIX_TIMESTAMP': Array('date-and-time-functions', 'function_unix_timestamp'),
|
||||
'UpdateXML': Array('xml-functions', 'function_updatexml'),
|
||||
'UPPER': Array('string-functions', 'function_upper'),
|
||||
'USER': Array('information-functions', 'function_user'),
|
||||
'UTC_DATE': Array('date-and-time-functions', 'function_utc_date'),
|
||||
'UTC_TIME': Array('date-and-time-functions', 'function_utc_time'),
|
||||
'UTC_TIMESTAMP': Array('date-and-time-functions', 'function_utc_timestamp'),
|
||||
'UUID_SHORT': Array('miscellaneous-functions', 'function_uuid_short'),
|
||||
'UUID': Array('miscellaneous-functions', 'function_uuid'),
|
||||
'VALUES': Array('miscellaneous-functions', 'function_values'),
|
||||
'VAR_POP': Array('group-by-functions', 'function_var_pop'),
|
||||
'VAR_SAMP': Array('group-by-functions', 'function_var_samp'),
|
||||
'VARIANCE': Array('group-by-functions', 'function_variance'),
|
||||
'VERSION': Array('information-functions', 'function_version'),
|
||||
'WEEK': Array('date-and-time-functions', 'function_week'),
|
||||
'WEEKDAY': Array('date-and-time-functions', 'function_weekday'),
|
||||
'WEEKOFYEAR': Array('date-and-time-functions', 'function_weekofyear'),
|
||||
'XOR': Array('logical-operators', 'operator_xor'),
|
||||
'YEAR': Array('date-and-time-functions', 'function_year'),
|
||||
'YEARWEEK': Array('date-and-time-functions', 'function_yearweek'),
|
||||
'SOUNDS_LIKE': Array('string-functions', 'operator_sounds-like'),
|
||||
'IS_NOT_NULL': Array('comparison-operators', 'operator_is-not-null'),
|
||||
'IS_NOT': Array('comparison-operators', 'operator_is-not'),
|
||||
'IS_NULL': Array('comparison-operators', 'operator_is-null'),
|
||||
'NOT_LIKE': Array('string-comparison-functions', 'operator_not-like'),
|
||||
'NOT_REGEXP': Array('regexp', 'operator_not-regexp'),
|
||||
'COUNT_DISTINCT': Array('group-by-functions', 'function_count-distinct'),
|
||||
'NOT_IN': Array('comparison-operators', 'function_not-in')
|
||||
};
|
||||
|
||||
export const mysql_doc_builtin = {
|
||||
'TINYINT': Array('numeric-types'),
|
||||
'SMALLINT': Array('numeric-types'),
|
||||
'MEDIUMINT': Array('numeric-types'),
|
||||
'INT': Array('numeric-types'),
|
||||
'BIGINT': Array('numeric-types'),
|
||||
'DECIMAL': Array('numeric-types'),
|
||||
'FLOAT': Array('numeric-types'),
|
||||
'DOUBLE': Array('numeric-types'),
|
||||
'REAL': Array('numeric-types'),
|
||||
'BIT': Array('numeric-types'),
|
||||
'BOOLEAN': Array('numeric-types'),
|
||||
'SERIAL': Array('numeric-types'),
|
||||
'DATE': Array('date-and-time-types'),
|
||||
'DATETIME': Array('date-and-time-types'),
|
||||
'TIMESTAMP': Array('date-and-time-types'),
|
||||
'TIME': Array('date-and-time-types'),
|
||||
'YEAR': Array('date-and-time-types'),
|
||||
'CHAR': Array('string-types'),
|
||||
'VARCHAR': Array('string-types'),
|
||||
'TINYTEXT': Array('string-types'),
|
||||
'TEXT': Array('string-types'),
|
||||
'MEDIUMTEXT': Array('string-types'),
|
||||
'LONGTEXT': Array('string-types'),
|
||||
'BINARY': Array('string-types'),
|
||||
'VARBINARY': Array('string-types'),
|
||||
'TINYBLOB': Array('string-types'),
|
||||
'MEDIUMBLOB': Array('string-types'),
|
||||
'BLOB': Array('string-types'),
|
||||
'LONGBLOB': Array('string-types'),
|
||||
'ENUM': Array('string-types'),
|
||||
'SET': Array('string-types')
|
||||
};
|
||||
14
js/src/consts/files.js
Normal file
14
js/src/consts/files.js
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* List of JS files need to be loaded at the time of initial page load.
|
||||
* Eg. For server_privileges.php, server_privileges.js is required
|
||||
*/
|
||||
|
||||
/**
|
||||
* @type {Object} files
|
||||
*/
|
||||
const files = {
|
||||
server_privileges: ['server_privileges'],
|
||||
server_databases: ['server_databases']
|
||||
};
|
||||
|
||||
export default files;
|
||||
78
js/src/functions/get_image.js
Normal file
78
js/src/functions/get_image.js
Normal file
@ -0,0 +1,78 @@
|
||||
import { escapeHtml } from '../utils/Sanitise';
|
||||
/**
|
||||
* Returns an HTML IMG tag for a particular image from a theme,
|
||||
* which may be an actual file or an icon from a sprite
|
||||
*
|
||||
* @param string image The name of the file to get
|
||||
* @param string alternate Used to set 'alt' and 'title' attributes of the image
|
||||
* @param object attributes An associative array of other attributes
|
||||
*
|
||||
* @return Object The requested image, this object has two methods:
|
||||
* .toString() - Returns the IMG tag for the requested image
|
||||
* .attr(name) - Returns a particular attribute of the IMG
|
||||
* tag given it's name
|
||||
* .attr(name, value) - Sets a particular attribute of the IMG
|
||||
* tag to the given value
|
||||
*/
|
||||
export function PMA_getImage (image, alternate, attributes) {
|
||||
// custom image object, it will eventually be returned by this functions
|
||||
var retval = {
|
||||
data: {
|
||||
// this is private
|
||||
alt: '',
|
||||
title: '',
|
||||
src: 'themes/dot.gif',
|
||||
},
|
||||
attr: function (name, value) {
|
||||
if (value === undefined) {
|
||||
if (this.data[name] === undefined) {
|
||||
return '';
|
||||
} else {
|
||||
return this.data[name];
|
||||
}
|
||||
} else {
|
||||
this.data[name] = value;
|
||||
}
|
||||
},
|
||||
toString: function () {
|
||||
var retval = '<' + 'img';
|
||||
for (var i in this.data) {
|
||||
retval += ' ' + i + '="' + this.data[i] + '"';
|
||||
}
|
||||
retval += ' /' + '>';
|
||||
return retval;
|
||||
}
|
||||
};
|
||||
// initialise missing parameters
|
||||
if (attributes === undefined) {
|
||||
attributes = {};
|
||||
}
|
||||
if (alternate === undefined) {
|
||||
alternate = '';
|
||||
}
|
||||
// set alt
|
||||
if (attributes.alt !== undefined) {
|
||||
retval.attr('alt', escapeHtml(attributes.alt));
|
||||
} else {
|
||||
retval.attr('alt', escapeHtml(alternate));
|
||||
}
|
||||
// set title
|
||||
if (attributes.title !== undefined) {
|
||||
retval.attr('title', escapeHtml(attributes.title));
|
||||
} else {
|
||||
retval.attr('title', escapeHtml(alternate));
|
||||
}
|
||||
// set css classes
|
||||
retval.attr('class', 'icon ic_' + image);
|
||||
// set all other attrubutes
|
||||
for (var i in attributes) {
|
||||
if (i === 'src') {
|
||||
// do not allow to override the 'src' attribute
|
||||
continue;
|
||||
}
|
||||
|
||||
retval.attr(i, attributes[i]);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
159
js/src/functions/navigation.js
Normal file
159
js/src/functions/navigation.js
Normal file
@ -0,0 +1,159 @@
|
||||
/**
|
||||
* Expand the navigation and highlight the current database or table/view
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
import { PMA_commonParams } from '../variables/common_params';
|
||||
export function PMA_showCurrentNavigation () {
|
||||
var db = PMA_commonParams.get('db');
|
||||
var table = PMA_commonParams.get('table');
|
||||
|
||||
$('#pma_navigation_tree').find('li.selected').removeClass('selected');
|
||||
if (db) {
|
||||
var $dbItem = findLoadedItem($('#pma_navigation_tree').find('> div'), db, 'database', !table);
|
||||
if ($('#navi_db_select').length && $('option:selected', $('#navi_db_select')).length) {
|
||||
if (!PMA_selectCurrentDb()) {
|
||||
return;
|
||||
}
|
||||
// If loaded database in navigation is not same as current one
|
||||
if ($('#pma_navigation_tree_content').find('span.loaded_db:first').text() !== $('#navi_db_select').val()) {
|
||||
loadChildNodes(false, $('option:selected', $('#navi_db_select')), function (data) {
|
||||
handleTableOrDb(table, $('#pma_navigation_tree_content'));
|
||||
var $children = $('#pma_navigation_tree_content').children('div.list_container');
|
||||
$children.promise().done(navTreeStateUpdate);
|
||||
});
|
||||
} else {
|
||||
handleTableOrDb(table, $('#pma_navigation_tree_content'));
|
||||
}
|
||||
} else if ($dbItem) {
|
||||
var $expander = $dbItem.children('div:first').children('a.expander');
|
||||
// if not loaded or loaded but collapsed
|
||||
if (!$expander.hasClass('loaded') || $expander.find('img').is('.ic_b_plus')) {
|
||||
expandTreeNode($expander, function () {
|
||||
handleTableOrDb(table, $dbItem);
|
||||
});
|
||||
} else {
|
||||
handleTableOrDb(table, $dbItem);
|
||||
}
|
||||
}
|
||||
} else if ($('#navi_db_select').length && $('#navi_db_select').val()) {
|
||||
$('#navi_db_select').val('').hide().trigger('change');
|
||||
}
|
||||
PMA_showFullName($('#pma_navigation_tree'));
|
||||
|
||||
function handleTableOrDb (table, $dbItem) {
|
||||
if (table) {
|
||||
loadAndHighlightTableOrView($dbItem, table);
|
||||
} else {
|
||||
var $container = $dbItem.children('div.list_container');
|
||||
var $tableContainer = $container.children('ul').children('li.tableContainer');
|
||||
if ($tableContainer.length > 0) {
|
||||
var $expander = $tableContainer.children('div:first').children('a.expander');
|
||||
$tableContainer.addClass('selected');
|
||||
expandTreeNode($expander, function () {
|
||||
scrollToView($dbItem, true);
|
||||
});
|
||||
} else {
|
||||
scrollToView($dbItem, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function findLoadedItem ($container, name, clazz, doSelect) {
|
||||
var ret = false;
|
||||
$container.children('ul').children('li').each(function () {
|
||||
var $li = $(this);
|
||||
// this is a navigation group, recurse
|
||||
if ($li.is('.navGroup')) {
|
||||
var $container = $li.children('div.list_container');
|
||||
var $childRet = findLoadedItem($container, name, clazz, doSelect);
|
||||
if ($childRet) {
|
||||
ret = $childRet;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// this is a real navigation item
|
||||
// name and class matches
|
||||
if ((clazz && $li.is('.' + clazz) || !clazz) && $li.children('a').text() === name) {
|
||||
if (doSelect) {
|
||||
$li.addClass('selected');
|
||||
}
|
||||
// taverse up and expand and parent navigation groups
|
||||
$li.parents('.navGroup').each(function () {
|
||||
var $cont = $(this).children('div.list_container');
|
||||
if (!$cont.is(':visible')) {
|
||||
$(this).children('div:first').children('a.expander').click();
|
||||
}
|
||||
});
|
||||
ret = $li;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
function loadAndHighlightTableOrView ($dbItem, itemName) {
|
||||
var $container = $dbItem.children('div.list_container');
|
||||
var $expander;
|
||||
var $whichItem = isItemInContainer($container, itemName, 'li.table, li.view');
|
||||
// If item already there in some container
|
||||
if ($whichItem) {
|
||||
// get the relevant container while may also be a subcontainer
|
||||
var $relatedContainer = $whichItem.closest('li.subContainer').length ? $whichItem.closest('li.subContainer') : $dbItem;
|
||||
$whichItem = findLoadedItem($relatedContainer.children('div.list_container'), itemName, null, true);
|
||||
// Show directly
|
||||
showTableOrView($whichItem, $relatedContainer.children('div:first').children('a.expander'));
|
||||
// else if item not there, try loading once
|
||||
} else {
|
||||
var $sub_containers = $dbItem.find('.subContainer');
|
||||
// If there are subContainers i.e. tableContainer or viewContainer
|
||||
if ($sub_containers.length > 0) {
|
||||
var $containers = [];
|
||||
$sub_containers.each(function (index) {
|
||||
$containers[index] = $(this);
|
||||
$expander = $containers[index].children('div:first').children('a.expander');
|
||||
if (!$expander.hasClass('loaded')) {
|
||||
loadAndShowTableOrView($expander, $containers[index], itemName);
|
||||
}
|
||||
});
|
||||
// else if no subContainers
|
||||
} else {
|
||||
$expander = $dbItem.children('div:first').children('a.expander');
|
||||
if (!$expander.hasClass('loaded')) {
|
||||
loadAndShowTableOrView($expander, $dbItem, itemName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loadAndShowTableOrView ($expander, $relatedContainer, itemName) {
|
||||
loadChildNodes(true, $expander, function (data) {
|
||||
var $whichItem = findLoadedItem($relatedContainer.children('div.list_container'), itemName, null, true);
|
||||
if ($whichItem) {
|
||||
showTableOrView($whichItem, $expander);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function showTableOrView ($whichItem, $expander) {
|
||||
expandTreeNode($expander, function (data) {
|
||||
if ($whichItem) {
|
||||
scrollToView($whichItem, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function isItemInContainer ($container, name, clazz) {
|
||||
var $whichItem = null;
|
||||
$items = $container.find(clazz);
|
||||
var found = false;
|
||||
$items.each(function () {
|
||||
if ($(this).children('a').text() === name) {
|
||||
$whichItem = $(this);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return $whichItem;
|
||||
}
|
||||
}
|
||||
86
js/src/index.js
Normal file
86
js/src/index.js
Normal file
@ -0,0 +1,86 @@
|
||||
import { AJAX } from './ajax';
|
||||
import './variables/import_variables';
|
||||
import { jQuery as $ } from './utils/JqueryExtended';
|
||||
import files from './consts/files';
|
||||
|
||||
/**
|
||||
* Page load event handler
|
||||
*/
|
||||
$(function () {
|
||||
var menuContent = $('<div></div>')
|
||||
.append($('#serverinfo').clone())
|
||||
.append($('#topmenucontainer').clone())
|
||||
.html();
|
||||
if (history && history.pushState) {
|
||||
// set initial state reload
|
||||
var initState = ('state' in window.history && window.history.state !== null);
|
||||
var initURL = $('#selflink').find('> a').attr('href') || location.href;
|
||||
var state = {
|
||||
url : initURL,
|
||||
menu : menuContent
|
||||
};
|
||||
history.replaceState(state, null);
|
||||
|
||||
$(window).on('popstate', function (event) {
|
||||
var initPop = (! initState && location.href === initURL);
|
||||
initState = true;
|
||||
// check if popstate fired on first page itself
|
||||
if (initPop) {
|
||||
return;
|
||||
}
|
||||
var state = event.originalEvent.state;
|
||||
if (state && state.menu) {
|
||||
AJAX.$msgbox = PMA_ajaxShowMessage();
|
||||
var params = 'ajax_request=true' + PMA_commonParams.get('arg_separator') + 'ajax_page_request=true';
|
||||
var url = state.url || location.href;
|
||||
$.get(url, params, AJAX.responseHandler);
|
||||
// TODO: Check if sometimes menu is not retrieved from server,
|
||||
// Not sure but it seems menu was missing only for printview which
|
||||
// been removed lately, so if it's right some dead menu checks/fallbacks
|
||||
// may need to be removed from this file and Header.php
|
||||
// AJAX.handleMenu.replace(event.originalEvent.state.menu);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Fallback to microhistory mechanism
|
||||
AJAX.scriptHandler
|
||||
.load([{ 'name' : 'microhistory.js', 'fire' : 1 }], function () {
|
||||
// The cache primer is set by the footer class
|
||||
if (PMA_MicroHistory.primer.url) {
|
||||
PMA_MicroHistory.menus.add(
|
||||
PMA_MicroHistory.primer.menuHash,
|
||||
menuContent
|
||||
);
|
||||
}
|
||||
$(function () {
|
||||
// Queue up this event twice to make sure that we get a copy
|
||||
// of the page after all other onload events have been fired
|
||||
if (PMA_MicroHistory.primer.url) {
|
||||
PMA_MicroHistory.add(
|
||||
PMA_MicroHistory.primer.url,
|
||||
PMA_MicroHistory.primer.scripts,
|
||||
PMA_MicroHistory.primer.menuHash
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* This block of code is for importing javascript files needed
|
||||
* for the first time loading of the page.
|
||||
*/
|
||||
let firstPage = window.location.pathname.replace('/', '').replace('.php', '');
|
||||
let indexStart = window.location.search.indexOf('target') + 7;
|
||||
let indexEnd = window.location.search.indexOf('.php');
|
||||
let indexPage = window.location.search.slice(indexStart, indexEnd);
|
||||
if (typeof files[firstPage] !== 'undefined' && firstPage.toLocaleLowerCase() !== 'index') {
|
||||
for (let i in files[firstPage]) {
|
||||
AJAX.scriptHandler.add(files[firstPage][i], 1);
|
||||
}
|
||||
} else if (typeof files[indexPage] !== 'undefined' && firstPage.toLocaleLowerCase() === 'index') {
|
||||
for (let i in files[indexPage]) {
|
||||
AJAX.scriptHandler.add(files[indexPage][i], 1);
|
||||
}
|
||||
}
|
||||
151
js/src/server_databases.js
Normal file
151
js/src/server_databases.js
Normal file
@ -0,0 +1,151 @@
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
* @fileoverview functions used on the server databases list page
|
||||
* @name Server Databases
|
||||
*
|
||||
* @requires jQuery
|
||||
* @requires jQueryUI
|
||||
* @required js/functions.js
|
||||
*/
|
||||
import { PMA_sprintf } from './utils/sprintf';
|
||||
import './variables/import_variables';
|
||||
import { PMA_ajaxShowMessage } from './utils/show_ajax_messages';
|
||||
import { escapeHtml } from './utils/Sanitise';
|
||||
import { PMA_Messages as PMA_messages } from './variables/export_variables';
|
||||
import { jQuery as $ } from './utils/JqueryExtended';
|
||||
import { AJAX } from './ajax';
|
||||
import { PMA_commonParams } from './variables/common_params';
|
||||
|
||||
/**
|
||||
* Unbind all event handlers before tearing down a page
|
||||
*/
|
||||
export function teardown1 () {
|
||||
$(document).off('submit', '#dbStatsForm');
|
||||
$(document).off('submit', '#create_database_form.ajax');
|
||||
}
|
||||
|
||||
export function onload1 () {
|
||||
/**
|
||||
* Attach Event Handler for 'Drop Databases'
|
||||
*/
|
||||
$(document).on('submit', '#dbStatsForm', function (event) {
|
||||
// debugger;
|
||||
event.preventDefault();
|
||||
|
||||
var $form = $(this);
|
||||
|
||||
/**
|
||||
* @var selected_dbs Array containing the names of the checked databases
|
||||
*/
|
||||
var selected_dbs = [];
|
||||
// loop over all checked checkboxes, except the .checkall_box checkbox
|
||||
$form.find('input:checkbox:checked:not(.checkall_box)').each(function () {
|
||||
$(this).closest('tr').addClass('removeMe');
|
||||
selected_dbs[selected_dbs.length] = 'DROP DATABASE `' + escapeHtml($(this).val()) + '`;';
|
||||
});
|
||||
if (! selected_dbs.length) {
|
||||
PMA_ajaxShowMessage(
|
||||
$('<div class="notice" />').text(
|
||||
PMA_messages.strNoDatabasesSelected
|
||||
),
|
||||
2000
|
||||
);
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* @var question String containing the question to be asked for confirmation
|
||||
*/
|
||||
var question = PMA_messages.strDropDatabaseStrongWarning + ' ' +
|
||||
PMA_sprintf(PMA_messages.strDoYouReally, selected_dbs.join('<br />'));
|
||||
|
||||
var argsep = PMA_commonParams.get('arg_separator');
|
||||
$(this).PMA_confirm(
|
||||
question,
|
||||
$form.prop('action') + '?' + $(this).serialize() +
|
||||
argsep + 'drop_selected_dbs=1' + argsep + 'is_js_confirmed=1' + argsep + 'ajax_request=true',
|
||||
function (url) {
|
||||
PMA_ajaxShowMessage(PMA_messages.strProcessingRequest, false);
|
||||
|
||||
var params = getJSConfirmCommonParam(this);
|
||||
|
||||
$.post(url, params, function (data) {
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
PMA_ajaxShowMessage(data.message);
|
||||
|
||||
var $rowsToRemove = $form.find('tr.removeMe');
|
||||
var $databasesCount = $('#filter-rows-count');
|
||||
var newCount = parseInt($databasesCount.text(), 10) - $rowsToRemove.length;
|
||||
$databasesCount.text(newCount);
|
||||
|
||||
$rowsToRemove.remove();
|
||||
$form.find('tbody').PMA_sort_table('.name');
|
||||
if ($form.find('tbody').find('tr').length === 0) {
|
||||
// user just dropped the last db on this page
|
||||
PMA_commonActions.refreshMain();
|
||||
}
|
||||
PMA_reloadNavigation();
|
||||
} else {
|
||||
$form.find('tr.removeMe').removeClass('removeMe');
|
||||
PMA_ajaxShowMessage(data.error, false);
|
||||
}
|
||||
}); // end $.post()
|
||||
}
|
||||
); // end $.PMA_confirm()
|
||||
}); // end of Drop Database action
|
||||
|
||||
/**
|
||||
* Attach Ajax event handlers for 'Create Database'.
|
||||
*/
|
||||
$(document).on('submit', '#create_database_form.ajax', function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
var $form = $(this);
|
||||
|
||||
// TODO Remove this section when all browsers support HTML5 "required" property
|
||||
var newDbNameInput = $form.find('input[name=new_db]');
|
||||
if (newDbNameInput.val() === '') {
|
||||
newDbNameInput.focus();
|
||||
alert(PMA_messages.strFormEmpty);
|
||||
return;
|
||||
}
|
||||
// end remove
|
||||
|
||||
PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
|
||||
PMA_prepareForAjaxRequest($form);
|
||||
|
||||
$.post($form.attr('action'), $form.serialize(), function (data) {
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
PMA_ajaxShowMessage(data.message);
|
||||
|
||||
var $databases_count_object = $('#filter-rows-count');
|
||||
var databases_count = parseInt($databases_count_object.text(), 10) + 1;
|
||||
$databases_count_object.text(databases_count);
|
||||
PMA_reloadNavigation();
|
||||
|
||||
// make ajax request to load db structure page - taken from ajax.js
|
||||
var dbStruct_url = data.url_query;
|
||||
dbStruct_url = dbStruct_url.replace(/amp;/ig, '');
|
||||
var params = 'ajax_request=true' + PMA_commonParams.get('arg_separator') + 'ajax_page_request=true';
|
||||
if (! (history && history.pushState)) {
|
||||
params += PMA_MicroHistory.menus.getRequestParam();
|
||||
}
|
||||
$.get(dbStruct_url, params, AJAX.responseHandler);
|
||||
} else {
|
||||
PMA_ajaxShowMessage(data.error, false);
|
||||
}
|
||||
}); // end $.post()
|
||||
}); // end $(document).on()
|
||||
|
||||
/* Don't show filter if number of databases are very few */
|
||||
var databasesCount = $('#filter-rows-count').html();
|
||||
if (databasesCount <= 10) {
|
||||
$('#tableFilter').hide();
|
||||
}
|
||||
|
||||
var tableRows = $('.server_databases');
|
||||
$.each(tableRows, function (index, item) {
|
||||
$(this).click(function () {
|
||||
PMA_commonActions.setDb($(this).attr('data'));
|
||||
});
|
||||
});
|
||||
}
|
||||
436
js/src/server_privileges.js
Normal file
436
js/src/server_privileges.js
Normal file
@ -0,0 +1,436 @@
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
* @fileoverview functions used in server privilege pages
|
||||
* @name Server Privileges
|
||||
*
|
||||
* @requires jQuery
|
||||
* @requires jQueryUI
|
||||
* @requires js/functions.js
|
||||
*
|
||||
*/
|
||||
import { PMA_sprintf } from './utils/sprintf';
|
||||
import { checkPasswordStrength, displayPasswordGenerateButton } from './utils/password';
|
||||
// import { AJAX } from './ajax';
|
||||
import { PMA_Messages as PMA_messages } from './variables/export_variables';
|
||||
import { PMA_ajaxShowMessage, PMA_ajaxRemoveMessage } from './utils/show_ajax_messages';
|
||||
import { PMA_commonParams } from './variables/common_params';
|
||||
import { jQuery as $ } from './utils/JqueryExtended';
|
||||
|
||||
/**
|
||||
* AJAX scripts for server_privileges page.
|
||||
*
|
||||
* Actions ajaxified here:
|
||||
* Add user
|
||||
* Revoke a user
|
||||
* Edit privileges
|
||||
* Export privileges
|
||||
* Paginate table of users
|
||||
* Flush privileges
|
||||
*
|
||||
* @memberOf jQuery
|
||||
* @name document.ready
|
||||
*/
|
||||
|
||||
/**
|
||||
* Unbind all event handlers before tearing down a page
|
||||
*/
|
||||
export function teardown1 () {
|
||||
$('#fieldset_add_user_login').off('change', 'input[name=\'username\']');
|
||||
$(document).off('click', '#fieldset_delete_user_footer #buttonGo.ajax');
|
||||
$(document).off('click', 'a.edit_user_group_anchor.ajax');
|
||||
$(document).off('click', 'button.mult_submit[value=export]');
|
||||
$(document).off('click', 'a.export_user_anchor.ajax');
|
||||
$(document).off('click', '#initials_table a.ajax');
|
||||
$('#checkbox_drop_users_db').off('click');
|
||||
$(document).off('click', '.checkall_box');
|
||||
$(document).off('change', '#checkbox_SSL_priv');
|
||||
$(document).off('change', 'input[name="ssl_type"]');
|
||||
$(document).off('change', '#select_authentication_plugin');
|
||||
}
|
||||
|
||||
export function onload1 () {
|
||||
/**
|
||||
* Display a warning if there is already a user by the name entered as the username.
|
||||
*/
|
||||
$('#fieldset_add_user_login').on('change', 'input[name=\'username\']', function () {
|
||||
var username = $(this).val();
|
||||
var $warning = $('#user_exists_warning');
|
||||
if ($('#select_pred_username').val() === 'userdefined' && username !== '') {
|
||||
var href = $('form[name=\'usersForm\']').attr('action');
|
||||
var params = {
|
||||
'ajax_request' : true,
|
||||
'server' : PMA_commonParams.get('server'),
|
||||
'validate_username' : true,
|
||||
'username' : username
|
||||
};
|
||||
$.get(href, params, function (data) {
|
||||
if (data.user_exists) {
|
||||
$warning.show();
|
||||
} else {
|
||||
$warning.hide();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$warning.hide();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Indicating password strength
|
||||
*/
|
||||
var meter_obj;
|
||||
var meter_obj_label;
|
||||
var username;
|
||||
$(document).on('keyup', '#text_pma_pw', function () {
|
||||
meter_obj = $('#password_strength_meter');
|
||||
meter_obj_label = $('#password_strength');
|
||||
username = $('input[name="username"]');
|
||||
username = username.val();
|
||||
checkPasswordStrength($(this).val(), meter_obj, meter_obj_label, username);
|
||||
});
|
||||
|
||||
$(document).on('keyup', '#text_pma_change_pw', function () {
|
||||
meter_obj = $('#change_password_strength_meter');
|
||||
meter_obj_label = $('#change_password_strength');
|
||||
checkPasswordStrength($(this).val(), meter_obj, meter_obj_label, PMA_commonParams.get('user'));
|
||||
});
|
||||
|
||||
/**
|
||||
* Display a notice if sha256_password is selected
|
||||
*/
|
||||
$(document).on('change', '#select_authentication_plugin', function () {
|
||||
var selected_plugin = $(this).val();
|
||||
if (selected_plugin === 'sha256_password') {
|
||||
$('#ssl_reqd_warning').show();
|
||||
} else {
|
||||
$('#ssl_reqd_warning').hide();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* AJAX handler for 'Revoke User'
|
||||
*
|
||||
* @see PMA_ajaxShowMessage()
|
||||
* @memberOf jQuery
|
||||
* @name revoke_user_click
|
||||
*/
|
||||
$(document).on('click', '#fieldset_delete_user_footer #buttonGo.ajax', function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
var $thisButton = $(this);
|
||||
var $form = $('#usersForm');
|
||||
|
||||
$thisButton.PMA_confirm(PMA_messages.strDropUserWarning, $form.attr('action'), function (url) {
|
||||
var $drop_users_db_checkbox = $('#checkbox_drop_users_db');
|
||||
if ($drop_users_db_checkbox.is(':checked')) {
|
||||
var is_confirmed = confirm(PMA_messages.strDropDatabaseStrongWarning + '\n' + PMA_sprintf(PMA_messages.strDoYouReally, 'DROP DATABASE'));
|
||||
if (! is_confirmed) {
|
||||
// Uncheck the drop users database checkbox
|
||||
$drop_users_db_checkbox.prop('checked', false);
|
||||
}
|
||||
}
|
||||
|
||||
PMA_ajaxShowMessage(PMA_messages.strRemovingSelectedUsers);
|
||||
|
||||
var argsep = PMA_commonParams.get('arg_separator');
|
||||
$.post(url, $form.serialize() + argsep + 'delete=' + $thisButton.val() + argsep + 'ajax_request=true', function (data) {
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
PMA_ajaxShowMessage(data.message);
|
||||
// Refresh navigation, if we droppped some databases with the name
|
||||
// that is the same as the username of the deleted user
|
||||
if ($('#checkbox_drop_users_db:checked').length) {
|
||||
PMA_reloadNavigation();
|
||||
}
|
||||
// Remove the revoked user from the users list
|
||||
$form.find('input:checkbox:checked').parents('tr').slideUp('medium', function () {
|
||||
var this_user_initial = $(this).find('input:checkbox').val().charAt(0).toUpperCase();
|
||||
$(this).remove();
|
||||
|
||||
// If this is the last user with this_user_initial, remove the link from #initials_table
|
||||
if ($('#tableuserrights').find('input:checkbox[value^="' + this_user_initial + '"], input:checkbox[value^="' + this_user_initial.toLowerCase() + '"]').length === 0) {
|
||||
$('#initials_table').find('td > a:contains(' + this_user_initial + ')').parent('td').html(this_user_initial);
|
||||
}
|
||||
|
||||
// Re-check the classes of each row
|
||||
$form
|
||||
.find('tbody').find('tr:odd')
|
||||
.removeClass('even').addClass('odd')
|
||||
.end()
|
||||
.find('tr:even')
|
||||
.removeClass('odd').addClass('even');
|
||||
|
||||
// update the checkall checkbox
|
||||
$(checkboxes_sel).trigger('change');
|
||||
});
|
||||
} else {
|
||||
PMA_ajaxShowMessage(data.error, false);
|
||||
}
|
||||
}); // end $.post()
|
||||
});
|
||||
}); // end Revoke User
|
||||
|
||||
$(document).on('click', 'a.edit_user_group_anchor.ajax', function (event) {
|
||||
event.preventDefault();
|
||||
$(this).parents('tr').addClass('current_row');
|
||||
var $msg = PMA_ajaxShowMessage();
|
||||
$.get(
|
||||
$(this).attr('href'),
|
||||
{
|
||||
'ajax_request': true,
|
||||
'edit_user_group_dialog': true
|
||||
},
|
||||
function (data) {
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
PMA_ajaxRemoveMessage($msg);
|
||||
var buttonOptions = {};
|
||||
buttonOptions[PMA_messages.strGo] = function () {
|
||||
var usrGroup = $('#changeUserGroupDialog')
|
||||
.find('select[name="userGroup"]')
|
||||
.val();
|
||||
var $message = PMA_ajaxShowMessage();
|
||||
var argsep = PMA_commonParams.get('arg_separator');
|
||||
$.post(
|
||||
'server_privileges.php',
|
||||
$('#changeUserGroupDialog').find('form').serialize() + argsep + 'ajax_request=1',
|
||||
function (data) {
|
||||
PMA_ajaxRemoveMessage($message);
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
$('#usersForm')
|
||||
.find('.current_row')
|
||||
.removeClass('current_row')
|
||||
.find('.usrGroup')
|
||||
.text(usrGroup);
|
||||
} else {
|
||||
PMA_ajaxShowMessage(data.error, false);
|
||||
$('#usersForm')
|
||||
.find('.current_row')
|
||||
.removeClass('current_row');
|
||||
}
|
||||
}
|
||||
);
|
||||
$(this).dialog('close');
|
||||
};
|
||||
buttonOptions[PMA_messages.strClose] = function () {
|
||||
$(this).dialog('close');
|
||||
};
|
||||
var $dialog = $('<div/>')
|
||||
.attr('id', 'changeUserGroupDialog')
|
||||
.append(data.message)
|
||||
.dialog({
|
||||
width: 500,
|
||||
minWidth: 300,
|
||||
modal: true,
|
||||
buttons: buttonOptions,
|
||||
title: $('legend', $(data.message)).text(),
|
||||
close: function () {
|
||||
$(this).remove();
|
||||
}
|
||||
});
|
||||
$dialog.find('legend').remove();
|
||||
} else {
|
||||
PMA_ajaxShowMessage(data.error, false);
|
||||
$('#usersForm')
|
||||
.find('.current_row')
|
||||
.removeClass('current_row');
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* AJAX handler for 'Export Privileges'
|
||||
*
|
||||
* @see PMA_ajaxShowMessage()
|
||||
* @memberOf jQuery
|
||||
* @name export_user_click
|
||||
*/
|
||||
$(document).on('click', 'button.mult_submit[value=export]', function (event) {
|
||||
event.preventDefault();
|
||||
// can't export if no users checked
|
||||
if ($(this.form).find('input:checked').length === 0) {
|
||||
PMA_ajaxShowMessage(PMA_messages.strNoAccountSelected, 2000, 'success');
|
||||
return;
|
||||
}
|
||||
var $msgbox = PMA_ajaxShowMessage();
|
||||
var button_options = {};
|
||||
button_options[PMA_messages.strClose] = function () {
|
||||
$(this).dialog('close');
|
||||
};
|
||||
var argsep = PMA_commonParams.get('arg_separator');
|
||||
$.post(
|
||||
$(this.form).prop('action'),
|
||||
$(this.form).serialize() + argsep + 'submit_mult=export' + argsep + 'ajax_request=true',
|
||||
function (data) {
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
var $ajaxDialog = $('<div />')
|
||||
.append(data.message)
|
||||
.dialog({
|
||||
title: data.title,
|
||||
width: 500,
|
||||
buttons: button_options,
|
||||
close: function () {
|
||||
$(this).remove();
|
||||
}
|
||||
});
|
||||
PMA_ajaxRemoveMessage($msgbox);
|
||||
// Attach syntax highlighted editor to export dialog
|
||||
PMA_getSQLEditor($ajaxDialog.find('textarea'));
|
||||
} else {
|
||||
PMA_ajaxShowMessage(data.error, false);
|
||||
}
|
||||
}
|
||||
); // end $.post
|
||||
});
|
||||
// if exporting non-ajax, highlight anyways
|
||||
PMA_getSQLEditor($('textarea.export'));
|
||||
|
||||
$(document).on('click', 'a.export_user_anchor.ajax', function (event) {
|
||||
event.preventDefault();
|
||||
var $msgbox = PMA_ajaxShowMessage();
|
||||
/**
|
||||
* @var button_options Object containing options for jQueryUI dialog buttons
|
||||
*/
|
||||
var button_options = {};
|
||||
button_options[PMA_messages.strClose] = function () {
|
||||
$(this).dialog('close');
|
||||
};
|
||||
$.get($(this).attr('href'), { 'ajax_request': true }, function (data) {
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
var $ajaxDialog = $('<div />')
|
||||
.append(data.message)
|
||||
.dialog({
|
||||
title: data.title,
|
||||
width: 500,
|
||||
buttons: button_options,
|
||||
close: function () {
|
||||
$(this).remove();
|
||||
}
|
||||
});
|
||||
PMA_ajaxRemoveMessage($msgbox);
|
||||
// Attach syntax highlighted editor to export dialog
|
||||
PMA_getSQLEditor($ajaxDialog.find('textarea'));
|
||||
} else {
|
||||
PMA_ajaxShowMessage(data.error, false);
|
||||
}
|
||||
}); // end $.get
|
||||
}); // end export privileges
|
||||
|
||||
/**
|
||||
* AJAX handler to Paginate the Users Table
|
||||
*
|
||||
* @see PMA_ajaxShowMessage()
|
||||
* @name paginate_users_table_click
|
||||
* @memberOf jQuery
|
||||
*/
|
||||
$(document).on('click', '#initials_table a.ajax', function (event) {
|
||||
event.preventDefault();
|
||||
var $msgbox = PMA_ajaxShowMessage();
|
||||
$.get($(this).attr('href'), { 'ajax_request' : true }, function (data) {
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
PMA_ajaxRemoveMessage($msgbox);
|
||||
// This form is not on screen when first entering Privileges
|
||||
// if there are more than 50 users
|
||||
$('div.notice').remove();
|
||||
$('#usersForm').hide('medium').remove();
|
||||
$('#fieldset_add_user').hide('medium').remove();
|
||||
$('#initials_table')
|
||||
.prop('id', 'initials_table_old')
|
||||
.after(data.message).show('medium')
|
||||
.siblings('h2').not(':first').remove();
|
||||
// prevent double initials table
|
||||
$('#initials_table_old').remove();
|
||||
} else {
|
||||
PMA_ajaxShowMessage(data.error, false);
|
||||
}
|
||||
}); // end $.get
|
||||
}); // end of the paginate users table
|
||||
|
||||
$(document).on('change', 'input[name="ssl_type"]', function (e) {
|
||||
var $div = $('#specified_div');
|
||||
if ($('#ssl_type_SPECIFIED').is(':checked')) {
|
||||
$div.find('input').prop('disabled', false);
|
||||
} else {
|
||||
$div.find('input').prop('disabled', true);
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('change', '#checkbox_SSL_priv', function (e) {
|
||||
var $div = $('#require_ssl_div');
|
||||
if ($(this).is(':checked')) {
|
||||
$div.find('input').prop('disabled', false);
|
||||
$('#ssl_type_SPECIFIED').trigger('change');
|
||||
} else {
|
||||
$div.find('input').prop('disabled', true);
|
||||
}
|
||||
});
|
||||
|
||||
$('#checkbox_SSL_priv').trigger('change');
|
||||
|
||||
/*
|
||||
* Create submenu for simpler interface
|
||||
*/
|
||||
var addOrUpdateSubmenu = function () {
|
||||
var $topmenu2 = $('#topmenu2');
|
||||
var $edit_user_dialog = $('#edit_user_dialog');
|
||||
var submenu_label;
|
||||
var submenu_link;
|
||||
var link_number;
|
||||
|
||||
// if submenu exists yet, remove it first
|
||||
if ($topmenu2.length > 0) {
|
||||
$topmenu2.remove();
|
||||
}
|
||||
|
||||
// construct a submenu from the existing fieldsets
|
||||
$topmenu2 = $('<ul/>').prop('id', 'topmenu2');
|
||||
|
||||
$('#edit_user_dialog .submenu-item').each(function () {
|
||||
submenu_label = $(this).find('legend[data-submenu-label]').data('submenu-label');
|
||||
|
||||
submenu_link = $('<a/>')
|
||||
.prop('href', '#')
|
||||
.html(submenu_label);
|
||||
|
||||
$('<li/>')
|
||||
.append(submenu_link)
|
||||
.appendTo($topmenu2);
|
||||
});
|
||||
|
||||
// click handlers for submenu
|
||||
$topmenu2.find('a').click(function (e) {
|
||||
e.preventDefault();
|
||||
// if already active, ignore click
|
||||
if ($(this).hasClass('tabactive')) {
|
||||
return;
|
||||
}
|
||||
$topmenu2.find('a').removeClass('tabactive');
|
||||
$(this).addClass('tabactive');
|
||||
|
||||
// which section to show now?
|
||||
link_number = $topmenu2.find('a').index($(this));
|
||||
// hide all sections but the one to show
|
||||
$('#edit_user_dialog .submenu-item').hide().eq(link_number).show();
|
||||
});
|
||||
|
||||
// make first menu item active
|
||||
// TODO: support URL hash history
|
||||
$topmenu2.find('> :first-child a').addClass('tabactive');
|
||||
$edit_user_dialog.prepend($topmenu2);
|
||||
|
||||
// hide all sections but the first
|
||||
$('#edit_user_dialog .submenu-item').hide().eq(0).show();
|
||||
|
||||
// scroll to the top
|
||||
$('html, body').animate({ scrollTop: 0 }, 'fast');
|
||||
};
|
||||
|
||||
$('input.autofocus').focus();
|
||||
$(checkboxes_sel).trigger('change');
|
||||
displayPasswordGenerateButton();
|
||||
if ($('#edit_user_dialog').length > 0) {
|
||||
addOrUpdateSubmenu();
|
||||
}
|
||||
|
||||
var windowwidth = $(window).width();
|
||||
$('.jsresponsive').css('max-width', (windowwidth - 35) + 'px');
|
||||
}
|
||||
253
js/src/utils/JqueryExtended.js
Normal file
253
js/src/utils/JqueryExtended.js
Normal file
@ -0,0 +1,253 @@
|
||||
import $ from 'jquery';
|
||||
import 'jquery-migrate';
|
||||
import 'jquery-ui-bundle';
|
||||
import 'jquery-ui-timepicker-addon';
|
||||
import 'jquery-mousewheel';
|
||||
import 'jquery.event.drag';
|
||||
import 'jquery-validation';
|
||||
import { methods } from './menu_resizer';
|
||||
// TODO: To use this import for replacing variables used in this file for
|
||||
// extending various strings for localization.
|
||||
// import { GlobalVariables, timePicker, validations } from '../variables/export_variables';
|
||||
import { PMA_Messages as PMA_messages } from '../variables/export_variables';
|
||||
|
||||
/**
|
||||
* Make sure that ajax requests will not be cached
|
||||
* by appending a random variable to their parameters
|
||||
*/
|
||||
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
|
||||
var nocache = new Date().getTime() + '' + Math.floor(Math.random() * 1000000);
|
||||
if (typeof options.data === 'string') {
|
||||
options.data += '&_nocache=' + nocache + '&token=' + encodeURIComponent(PMA_commonParams.get('token'));
|
||||
} else if (typeof options.data === 'object') {
|
||||
options.data = $.extend(originalOptions.data, { '_nocache' : nocache, 'token': PMA_commonParams.get('token') });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Comes from menu_resizer.js
|
||||
*/
|
||||
$.fn.menuResizer = function (method) {
|
||||
if (methods[method]) {
|
||||
return methods[method].call(this);
|
||||
} else if (typeof method === 'function') {
|
||||
return methods.init.apply(this, [method]);
|
||||
} else {
|
||||
$.error('Method ' + method + ' does not exist on jQuery.menuResizer');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* comes from makegrid.js
|
||||
*/
|
||||
$.fn.noSelect = function (p) { // no select plugin by Paulo P.Marinas
|
||||
var prevent = (p === null) ? true : p;
|
||||
var is_msie = navigator.userAgent.indexOf('MSIE') > -1 || !!window.navigator.userAgent.match(/Trident.*rv\:11\./);
|
||||
var is_firefox = navigator.userAgent.indexOf('Firefox') > -1;
|
||||
var is_safari = navigator.userAgent.indexOf('Safari') > -1;
|
||||
var is_opera = navigator.userAgent.indexOf('Presto') > -1;
|
||||
if (prevent) {
|
||||
return this.each(function () {
|
||||
if (is_msie || is_safari) {
|
||||
$(this).on('selectstart', false);
|
||||
} else if (is_firefox) {
|
||||
$(this).css('MozUserSelect', 'none');
|
||||
$('body').trigger('focus');
|
||||
} else if (is_opera) {
|
||||
$(this).on('mousedown', false);
|
||||
} else {
|
||||
$(this).attr('unselectable', 'on');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return this.each(function () {
|
||||
if (is_msie || is_safari) {
|
||||
$(this).off('selectstart');
|
||||
} else if (is_firefox) {
|
||||
$(this).css('MozUserSelect', 'inherit');
|
||||
} else if (is_opera) {
|
||||
$(this).off('mousedown');
|
||||
} else {
|
||||
$(this).removeAttr('unselectable');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* comes from functions.js
|
||||
*/
|
||||
/**
|
||||
* jQuery plugin to correctly filter input fields by value, needed
|
||||
* because some nasty values may break selector syntax
|
||||
*/
|
||||
$.fn.filterByValue = function (value) {
|
||||
return this.filter(function () {
|
||||
return $(this).val() === value;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* jQuery function that uses jQueryUI's dialogs to confirm with user. Does not
|
||||
* return a jQuery object yet and hence cannot be chained
|
||||
*
|
||||
* @param string question
|
||||
* @param string url URL to be passed to the callbackFn to make
|
||||
* an Ajax call to
|
||||
* @param function callbackFn callback to execute after user clicks on OK
|
||||
* @param function openCallback optional callback to run when dialog is shown
|
||||
*/
|
||||
|
||||
$.fn.PMA_confirm = function (question, url, callbackFn, openCallback) {
|
||||
var confirmState = PMA_commonParams.get('confirm');
|
||||
if (! confirmState) {
|
||||
// user does not want to confirm
|
||||
if ($.isFunction(callbackFn)) {
|
||||
callbackFn.call(this, url);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (PMA_messages.strDoYouReally === '') {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var button_options Object that stores the options passed to jQueryUI
|
||||
* dialog
|
||||
*/
|
||||
var button_options = [
|
||||
{
|
||||
text: PMA_messages.strOK,
|
||||
'class': 'submitOK',
|
||||
click: function () {
|
||||
$(this).dialog('close');
|
||||
if ($.isFunction(callbackFn)) {
|
||||
callbackFn.call(this, url);
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
text: PMA_messages.strCancel,
|
||||
'class': 'submitCancel',
|
||||
click: function () {
|
||||
$(this).dialog('close');
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$('<div/>', { 'id': 'confirm_dialog', 'title': PMA_messages.strConfirm })
|
||||
.prepend(question)
|
||||
.dialog({
|
||||
buttons: button_options,
|
||||
close: function () {
|
||||
$(this).remove();
|
||||
},
|
||||
open: openCallback,
|
||||
modal: true
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* jQuery function to sort a table's body after a new row has been appended to it.
|
||||
*
|
||||
* @param string text_selector string to select the sortKey's text
|
||||
*
|
||||
* @return jQuery Object for chaining purposes
|
||||
*/
|
||||
$.fn.PMA_sort_table = function (text_selector) {
|
||||
return this.each(function () {
|
||||
/**
|
||||
* @var table_body Object referring to the table's <tbody> element
|
||||
*/
|
||||
var table_body = $(this);
|
||||
/**
|
||||
* @var rows Object referring to the collection of rows in {@link table_body}
|
||||
*/
|
||||
var rows = $(this).find('tr').get();
|
||||
|
||||
// get the text of the field that we will sort by
|
||||
$.each(rows, function (index, row) {
|
||||
row.sortKey = $.trim($(row).find(text_selector).text().toLowerCase());
|
||||
});
|
||||
|
||||
// get the sorted order
|
||||
rows.sort(function (a, b) {
|
||||
if (a.sortKey < b.sortKey) {
|
||||
return -1;
|
||||
}
|
||||
if (a.sortKey > b.sortKey) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
// pull out each row from the table and then append it according to it's order
|
||||
$.each(rows, function (index, row) {
|
||||
$(table_body).append(row);
|
||||
row.sortKey = null;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Return POST data as stored by Util::linkOrButton
|
||||
*/
|
||||
$.fn.getPostData = function () {
|
||||
var dataPost = this.attr('data-post');
|
||||
// Strip possible leading ?
|
||||
if (dataPost !== undefined && dataPost.substring(0,1) === '?') {
|
||||
dataPost = dataPost.substr(1);
|
||||
}
|
||||
return dataPost;
|
||||
};
|
||||
|
||||
/**
|
||||
* Replacing default datepicker strings for localization
|
||||
*/
|
||||
if ($.datepicker) {
|
||||
// Creating copy of datepicker strings object
|
||||
var datePicker = Object.assign(window.datePicker);
|
||||
// Deleting datepicker variable from window as it is of no use now
|
||||
delete window.datePicker;
|
||||
|
||||
for (let key in datePicker) {
|
||||
$.datepicker.regional[''][key] = datePicker[key];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replacing default timepicker strings for localozation
|
||||
*/
|
||||
if ($.timePicker) {
|
||||
// Creating copy of timepicker strings object
|
||||
var timePicker = Object.assign(window.timePicker);
|
||||
// Deleting timepicker variable from window as it is of no use now
|
||||
delete window.timePicker;
|
||||
|
||||
for (let key in timePicker) {
|
||||
$.timepicker.regional[''][key] = timePicker[key];
|
||||
}
|
||||
}
|
||||
|
||||
export function extendingValidatorMessages () {
|
||||
// Creating copy of validationMessage strings object
|
||||
var validateMessage = Object.assign(window.validationMessage);
|
||||
// Deleting validationMessage variable from window as it is of no use now
|
||||
delete window.validationMessage;
|
||||
// Replacing default validation messages forr localization
|
||||
$.extend($.validator.messages, validateMessage);
|
||||
|
||||
// Creating copy of validationFormat strings object
|
||||
var validateFormat = Object.assign(window.validationFormat);
|
||||
// Deleting validationFormat variable from window as it is of no use now
|
||||
delete window.validationFormat;
|
||||
for (let i in validateFormat) {
|
||||
validateFormat[i] = $.validator.format(validateFormat[i]);
|
||||
}
|
||||
// Replacing default validation messages forr localization
|
||||
$.extend($.validator.messages, validateFormat);
|
||||
}
|
||||
|
||||
window.jQ = $;
|
||||
|
||||
export const jQuery = $;
|
||||
35
js/src/utils/Sanitise.js
Normal file
35
js/src/utils/Sanitise.js
Normal file
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* HTML escaping
|
||||
*/
|
||||
|
||||
export function escapeHtml (unsafe) {
|
||||
if (typeof(unsafe) !== 'undefined') {
|
||||
return unsafe
|
||||
.toString()
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function escapeJsString (unsafe) {
|
||||
if (typeof(unsafe) !== 'undefined') {
|
||||
return unsafe
|
||||
.toString()
|
||||
.replace('\x00', '')
|
||||
.replace('\\', '\\\\')
|
||||
.replace('\'', '\\\'')
|
||||
.replace(''', '\\\'')
|
||||
.replace('"', '\"')
|
||||
.replace('"', '\"')
|
||||
.replace('\n', '\n')
|
||||
.replace('\r', '\r')
|
||||
.replace(/<\/script/gi, '</\' + \'script');
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
209
js/src/utils/menu_resizer.js
Normal file
209
js/src/utils/menu_resizer.js
Normal file
@ -0,0 +1,209 @@
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
* Handles the resizing of a menu according to the available screen width
|
||||
*
|
||||
* Uses themes/original/css/resizable-menu.css.php
|
||||
*
|
||||
* To initialise:
|
||||
* $('#myMenu').menuResizer(function () {
|
||||
* // This function will be called to find out how much
|
||||
* // available horizontal space there is for the menu
|
||||
* return $('body').width() - 5; // Some extra margin for good measure
|
||||
* });
|
||||
*
|
||||
* To trigger a resize operation:
|
||||
* $('#myMenu').menuResizer('resize'); // Bind this to $(window).resize()
|
||||
*
|
||||
* To restore the menu to a state like before it was initialized:
|
||||
* $('#myMenu').menuResizer('destroy');
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
function MenuResizer ($container, widthCalculator) {
|
||||
var self = this;
|
||||
self.$container = $container;
|
||||
self.widthCalculator = widthCalculator;
|
||||
var windowWidth = $(window).width();
|
||||
|
||||
if (windowWidth < 768) {
|
||||
$('#pma_navigation_resizer').css({ 'width': '0px' });
|
||||
}
|
||||
// Sets the image for the left and right scroll indicator
|
||||
$('.scrollindicator--left').html($(PMA_getImage('b_left').toString()));
|
||||
$('.scrollindicator--right').html($(PMA_getImage('b_right').toString()));
|
||||
|
||||
// Set the width of the navigation bar without scroll indicator
|
||||
$('.navigationbar').css({ 'width': widthCalculator.call($container) - 60 });
|
||||
|
||||
// Scroll the navigation bar on click
|
||||
$('.scrollindicator--right').on('click', function () {
|
||||
$('.navigationbar').scrollLeft($('.navigationbar').scrollLeft() + 70);
|
||||
});
|
||||
$('.scrollindicator--left').on('click', function () {
|
||||
$('.navigationbar').scrollLeft($('.navigationbar').scrollLeft() - 70);
|
||||
});
|
||||
|
||||
// create submenu container
|
||||
var link = $('<a />', { href: '#', 'class': 'tab nowrap' })
|
||||
.text(PMA_messages.strMore)
|
||||
.on('click', false); // same as event.preventDefault()
|
||||
var img = $container.find('li img');
|
||||
if (img.length) {
|
||||
$(PMA_getImage('b_more').toString()).prependTo(link);
|
||||
}
|
||||
var $submenu = $('<li />', { 'class': 'submenu' })
|
||||
.append(link)
|
||||
.append($('<ul />'))
|
||||
.on('mouseenter', function () {
|
||||
if ($(this).find('ul .tabactive').length === 0) {
|
||||
$(this)
|
||||
.addClass('submenuhover')
|
||||
.find('> a')
|
||||
.addClass('tabactive');
|
||||
}
|
||||
})
|
||||
.on('mouseleave', function () {
|
||||
if ($(this).find('ul .tabactive').length === 0) {
|
||||
$(this)
|
||||
.removeClass('submenuhover')
|
||||
.find('> a')
|
||||
.removeClass('tabactive');
|
||||
}
|
||||
});
|
||||
$container.children('.clearfloat').remove();
|
||||
$container.append($submenu).append('<div class=\'clearfloat\'></div>');
|
||||
setTimeout(function () {
|
||||
self.resize();
|
||||
}, 4);
|
||||
}
|
||||
MenuResizer.prototype.resize = function () {
|
||||
var wmax = this.widthCalculator.call(this.$container);
|
||||
var windowWidth = $(window).width();
|
||||
var $submenu = this.$container.find('.submenu:last');
|
||||
var submenu_w = $submenu.outerWidth(true);
|
||||
var $submenu_ul = $submenu.find('ul');
|
||||
var $li = this.$container.find('> li');
|
||||
var $li2 = $submenu_ul.find('li');
|
||||
var more_shown = $li2.length > 0;
|
||||
// Calculate the total width used by all the shown tabs
|
||||
var total_len = more_shown ? submenu_w : 0;
|
||||
var l = $li.length - 1;
|
||||
var i;
|
||||
for (i = 0; i < l; i++) {
|
||||
total_len += $($li[i]).outerWidth(true);
|
||||
}
|
||||
|
||||
var hasVScroll = document.body.scrollHeight > document.body.clientHeight;
|
||||
if (hasVScroll) {
|
||||
windowWidth += 15;
|
||||
}
|
||||
var navigationwidth = wmax;
|
||||
if (windowWidth < 768) {
|
||||
wmax = 2000;
|
||||
}
|
||||
|
||||
// Now hide menu elements that don't fit into the menubar
|
||||
var hidden = false; // Whether we have hidden any tabs
|
||||
while (total_len >= wmax && --l >= 0) { // Process the tabs backwards
|
||||
hidden = true;
|
||||
var el = $($li[l]);
|
||||
var el_width = el.outerWidth(true);
|
||||
el.data('width', el_width);
|
||||
if (! more_shown) {
|
||||
total_len -= el_width;
|
||||
el.prependTo($submenu_ul);
|
||||
total_len += submenu_w;
|
||||
more_shown = true;
|
||||
} else {
|
||||
total_len -= el_width;
|
||||
el.prependTo($submenu_ul);
|
||||
}
|
||||
}
|
||||
// If we didn't hide any tabs, then there might be some space to show some
|
||||
if (! hidden) {
|
||||
// Show menu elements that do fit into the menubar
|
||||
for (i = 0, l = $li2.length; i < l; i++) {
|
||||
total_len += $($li2[i]).data('width');
|
||||
// item fits or (it is the last item
|
||||
// and it would fit if More got removed)
|
||||
if (total_len < wmax ||
|
||||
(i === $li2.length - 1 && total_len - submenu_w < wmax)
|
||||
) {
|
||||
$($li2[i]).insertBefore($submenu);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Show/hide the "More" tab as needed
|
||||
if (windowWidth < 768) {
|
||||
$('.navigationbar').css({ 'width': windowWidth - 80 - $('#pma_navigation').width() });
|
||||
$submenu.removeClass('shown');
|
||||
$('.navigationbar').css({ 'overflow': 'hidden' });
|
||||
} else {
|
||||
$('.navigationbar').css({ 'width': 'auto' });
|
||||
$('.navigationbar').css({ 'overflow': 'visible' });
|
||||
if ($submenu_ul.find('li').length > 0) {
|
||||
$submenu.addClass('shown');
|
||||
} else {
|
||||
$submenu.removeClass('shown');
|
||||
}
|
||||
}
|
||||
if (this.$container.find('> li').length === 1) {
|
||||
// If there is only the "More" tab left, then we need
|
||||
// to align the submenu to the left edge of the tab
|
||||
$submenu_ul.removeClass().addClass('only');
|
||||
} else {
|
||||
// Otherwise we align the submenu to the right edge of the tab
|
||||
$submenu_ul.removeClass().addClass('notonly');
|
||||
}
|
||||
if ($submenu.find('.tabactive').length) {
|
||||
$submenu
|
||||
.addClass('active')
|
||||
.find('> a')
|
||||
.removeClass('tab')
|
||||
.addClass('tabactive');
|
||||
} else {
|
||||
$submenu
|
||||
.removeClass('active')
|
||||
.find('> a')
|
||||
.addClass('tab')
|
||||
.removeClass('tabactive');
|
||||
}
|
||||
};
|
||||
MenuResizer.prototype.destroy = function () {
|
||||
var $submenu = this.$container.find('li.submenu').removeData();
|
||||
$submenu.find('li').appendTo(this.$container);
|
||||
$submenu.remove();
|
||||
};
|
||||
|
||||
/** Public API */
|
||||
export var methods = {
|
||||
init: function (widthCalculator) {
|
||||
return this.each(function () {
|
||||
var $this = $(this);
|
||||
if (! $this.data('menuResizer')) {
|
||||
$this.data(
|
||||
'menuResizer',
|
||||
new MenuResizer($this, widthCalculator)
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
resize: function () {
|
||||
return this.each(function () {
|
||||
var self = $(this).data('menuResizer');
|
||||
if (self) {
|
||||
self.resize();
|
||||
}
|
||||
});
|
||||
},
|
||||
destroy: function () {
|
||||
return this.each(function () {
|
||||
var self = $(this).data('menuResizer');
|
||||
if (self) {
|
||||
self.destroy();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
179
js/src/utils/password.js
Normal file
179
js/src/utils/password.js
Normal file
@ -0,0 +1,179 @@
|
||||
import { PMA_Messages as PMA_messages } from '../variables/export_variables';
|
||||
import zxcvbn from 'zxcvbn';
|
||||
|
||||
/**
|
||||
* Generate a new password and copy it to the password input areas
|
||||
*
|
||||
* @param passwd_form object the form that holds the password fields
|
||||
*
|
||||
* @return boolean always true
|
||||
*/
|
||||
export function suggestPassword (passwd_form) {
|
||||
// restrict the password to just letters and numbers to avoid problems:
|
||||
// "editors and viewers regard the password as multiple words and
|
||||
// things like double click no longer work"
|
||||
var pwchars = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWYXZ';
|
||||
var passwordlength = 16; // do we want that to be dynamic? no, keep it simple :)
|
||||
var passwd = passwd_form.generated_pw;
|
||||
var randomWords = new Int32Array(passwordlength);
|
||||
|
||||
passwd.value = '';
|
||||
|
||||
// First we're going to try to use a built-in CSPRNG
|
||||
if (window.crypto && window.crypto.getRandomValues) {
|
||||
window.crypto.getRandomValues(randomWords);
|
||||
} else if (window.msCrypto && window.msCrypto.getRandomValues) {
|
||||
// Because of course IE calls it msCrypto instead of being standard
|
||||
window.msCrypto.getRandomValues(randomWords);
|
||||
} else {
|
||||
// Fallback to Math.random
|
||||
for (let i = 0; i < passwordlength; i++) {
|
||||
randomWords[i] = Math.floor(Math.random() * pwchars.length);
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < passwordlength; i++) {
|
||||
passwd.value += pwchars.charAt(Math.abs(randomWords[i]) % pwchars.length);
|
||||
}
|
||||
|
||||
var $jquery_passwd_form = $(passwd_form);
|
||||
|
||||
passwd_form.elements.pma_pw.value = passwd.value;
|
||||
passwd_form.elements.pma_pw2.value = passwd.value;
|
||||
var meter_obj = $jquery_passwd_form.find('meter[name="pw_meter"]').first();
|
||||
var meter_obj_label = $jquery_passwd_form.find('span[name="pw_strength"]').first();
|
||||
checkPasswordStrength(passwd.value, meter_obj, meter_obj_label);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* for PhpMyAdmin\Display\ChangePassword
|
||||
* libraries/user_password.php
|
||||
*
|
||||
*/
|
||||
export function displayPasswordGenerateButton () {
|
||||
var generatePwdRow = $('<tr />').addClass('vmiddle');
|
||||
$('<td />').html(PMA_messages.strGeneratePassword).appendTo(generatePwdRow);
|
||||
var pwdCell = $('<td />').appendTo(generatePwdRow);
|
||||
var pwdButton = $('<input />')
|
||||
.attr({ type: 'button', id: 'button_generate_password', value: PMA_messages.strGenerate })
|
||||
.addClass('button')
|
||||
.on('click', function () {
|
||||
suggestPassword(this.form);
|
||||
});
|
||||
var pwdTextbox = $('<input />')
|
||||
.attr({ type: 'text', name: 'generated_pw', id: 'generated_pw' });
|
||||
pwdCell.append(pwdButton).append(pwdTextbox);
|
||||
|
||||
$('#tr_element_before_generate_password').parent().append(generatePwdRow);
|
||||
|
||||
var generatePwdDiv = $('<div />').addClass('item');
|
||||
$('<label />').attr({ for: 'button_generate_password' })
|
||||
.html(PMA_messages.strGeneratePassword + ':')
|
||||
.appendTo(generatePwdDiv);
|
||||
var optionsSpan = $('<span/>').addClass('options')
|
||||
.appendTo(generatePwdDiv);
|
||||
pwdButton.clone(true).appendTo(optionsSpan);
|
||||
pwdTextbox.clone(true).appendTo(generatePwdDiv);
|
||||
$('#div_element_before_generate_password').parent().append(generatePwdDiv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the "add a user" form
|
||||
*
|
||||
* @return {boolean} whether the form is validated or not
|
||||
*/
|
||||
export function checkAddUser (the_form) {
|
||||
if (the_form.elements.pred_hostname.value === 'userdefined' && the_form.elements.hostname.value === '') {
|
||||
alert(PMA_messages.strHostEmpty);
|
||||
the_form.elements.hostname.focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (the_form.elements.pred_username.value === 'userdefined' && the_form.elements.username.value === '') {
|
||||
alert(PMA_messages.strUserEmpty);
|
||||
the_form.elements.username.focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
return PMA_checkPassword($(the_form));
|
||||
} // end of the 'checkAddUser()' function
|
||||
|
||||
/**
|
||||
* Function to check the password strength
|
||||
*
|
||||
* @param {string} value Passworrd string
|
||||
* @param {object} meter_obj jQuery object to show strength in meter
|
||||
* @param {object} meter_object_label jQuery object to show text of password strnegth
|
||||
* @param {string} username Username string
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
export function checkPasswordStrength (value, meter_obj, meter_object_label, username) {
|
||||
// List of words we don't want to appear in the password
|
||||
var customDict = [
|
||||
'phpmyadmin',
|
||||
'mariadb',
|
||||
'mysql',
|
||||
'php',
|
||||
'my',
|
||||
'admin',
|
||||
];
|
||||
if (username !== null) {
|
||||
customDict.push(username);
|
||||
}
|
||||
var zxcvbn_obj = zxcvbn(value, customDict);
|
||||
var strength = zxcvbn_obj.score;
|
||||
strength = parseInt(strength);
|
||||
meter_obj.val(strength);
|
||||
switch (strength) {
|
||||
case 0: meter_object_label.html(PMA_messages.strExtrWeak);
|
||||
break;
|
||||
case 1: meter_object_label.html(PMA_messages.strVeryWeak);
|
||||
break;
|
||||
case 2: meter_object_label.html(PMA_messages.strWeak);
|
||||
break;
|
||||
case 3: meter_object_label.html(PMA_messages.strGood);
|
||||
break;
|
||||
case 4: meter_object_label.html(PMA_messages.strStrong);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the password field in a form
|
||||
*
|
||||
* @see PMA_messages.strPasswordEmpty
|
||||
* @see PMA_messages.strPasswordNotSame
|
||||
* @param object $the_form The form to be validated
|
||||
* @return bool
|
||||
*/
|
||||
function PMA_checkPassword ($the_form) {
|
||||
// Did the user select 'no password'?
|
||||
if ($the_form.find('#nopass_1').is(':checked')) {
|
||||
return true;
|
||||
} else {
|
||||
var $pred = $the_form.find('#select_pred_password');
|
||||
if ($pred.length && ($pred.val() === 'none' || $pred.val() === 'keep')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var $password = $the_form.find('input[name=pma_pw]');
|
||||
var $password_repeat = $the_form.find('input[name=pma_pw2]');
|
||||
var alert_msg = false;
|
||||
|
||||
if ($password.val() === '') {
|
||||
alert_msg = PMA_messages.strPasswordEmpty;
|
||||
} else if ($password.val() !== $password_repeat.val()) {
|
||||
alert_msg = PMA_messages.strPasswordNotSame;
|
||||
}
|
||||
|
||||
if (alert_msg) {
|
||||
alert(alert_msg);
|
||||
$password.val('');
|
||||
$password_repeat.val('');
|
||||
$password.focus();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
190
js/src/utils/show_ajax_messages.js
Normal file
190
js/src/utils/show_ajax_messages.js
Normal file
@ -0,0 +1,190 @@
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
|
||||
/**
|
||||
* Functions for adding and removing ajax messages
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module imports
|
||||
*/
|
||||
import { PMA_Messages as PMA_messages } from '../variables/export_variables';
|
||||
|
||||
/**
|
||||
* @var int ajax_message_count Number of AJAX messages shown since page load
|
||||
*/
|
||||
let ajax_message_count = 0;
|
||||
|
||||
/**
|
||||
* Create a jQuery UI tooltip
|
||||
*
|
||||
* @param $elements jQuery object representing the elements
|
||||
* @param item the item
|
||||
* (see https://api.jqueryui.com/tooltip/#option-items)
|
||||
* @param myContent content of the tooltip
|
||||
* @param additionalOptions to override the default options
|
||||
*
|
||||
*/
|
||||
export function PMA_tooltip ($elements, item, myContent, additionalOptions) {
|
||||
if ($('#no_hint').length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
content: myContent,
|
||||
items: item,
|
||||
tooltipClass: 'tooltip',
|
||||
track: true,
|
||||
show: false,
|
||||
hide: false
|
||||
};
|
||||
|
||||
$elements.tooltip($.extend(true, defaultOptions, additionalOptions));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a message on the top of the page for an Ajax request
|
||||
*
|
||||
* Sample usage:
|
||||
*
|
||||
* 1) var $msg = PMA_ajaxShowMessage();
|
||||
* This will show a message that reads "Loading...". Such a message will not
|
||||
* disappear automatically and cannot be dismissed by the user. To remove this
|
||||
* message either the PMA_ajaxRemoveMessage($msg) function must be called or
|
||||
* another message must be show with PMA_ajaxShowMessage() function.
|
||||
*
|
||||
* 2) var $msg = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
|
||||
* This is a special case. The behaviour is same as above,
|
||||
* just with a different message
|
||||
*
|
||||
* 3) var $msg = PMA_ajaxShowMessage('The operation was successful');
|
||||
* This will show a message that will disappear automatically and it can also
|
||||
* be dismissed by the user.
|
||||
*
|
||||
* 4) var $msg = PMA_ajaxShowMessage('Some error', false);
|
||||
* This will show a message that will not disappear automatically, but it
|
||||
* can be dismissed by the user after he has finished reading it.
|
||||
*
|
||||
* @param string message string containing the message to be shown.
|
||||
* optional, defaults to 'Loading...'
|
||||
* @param mixed timeout number of milliseconds for the message to be visible
|
||||
* optional, defaults to 5000. If set to 'false', the
|
||||
* notification will never disappear
|
||||
* @param string type string to dictate the type of message shown.
|
||||
* optional, defaults to normal notification.
|
||||
* If set to 'error', the notification will show message
|
||||
* with red background.
|
||||
* If set to 'success', the notification will show with
|
||||
* a green background.
|
||||
* @return jQuery object jQuery Element that holds the message div
|
||||
* this object can be passed to PMA_ajaxRemoveMessage()
|
||||
* to remove the notification
|
||||
*/
|
||||
|
||||
export const PMA_ajaxShowMessage = (message, timeout, type) => {
|
||||
/**
|
||||
* @var self_closing Whether the notification will automatically disappear
|
||||
*/
|
||||
var self_closing = true;
|
||||
/**
|
||||
* @var dismissable Whether the user will be able to remove
|
||||
* the notification by clicking on it
|
||||
*/
|
||||
var dismissable = true;
|
||||
// Handle the case when a empty data.message is passed.
|
||||
// We don't want the empty message
|
||||
if (message === '') {
|
||||
return true;
|
||||
} else if (! message) {
|
||||
// If the message is undefined, show the default
|
||||
message = PMA_messages.strLoading;
|
||||
dismissable = false;
|
||||
self_closing = false;
|
||||
} else if (message === PMA_messages.strProcessingRequest) {
|
||||
// This is another case where the message should not disappear
|
||||
dismissable = false;
|
||||
self_closing = false;
|
||||
}
|
||||
// Figure out whether (or after how long) to remove the notification
|
||||
if (timeout === undefined) {
|
||||
timeout = 5000;
|
||||
} else if (timeout === false) {
|
||||
self_closing = false;
|
||||
}
|
||||
// Determine type of message, add styling as required
|
||||
if (type === 'error') {
|
||||
message = '<div class="error">' + message + '</div>';
|
||||
} else if (type === 'success') {
|
||||
message = '<div class="success">' + message + '</div>';
|
||||
}
|
||||
// Create a parent element for the AJAX messages, if necessary
|
||||
if ($('#loading_parent').length === 0) {
|
||||
$('<div id="loading_parent"></div>')
|
||||
.prependTo('#page_content');
|
||||
}
|
||||
// Update message count to create distinct message elements every time
|
||||
ajax_message_count++;
|
||||
// Remove all old messages, if any
|
||||
$('span.ajax_notification[id^=ajax_message_num]').remove();
|
||||
/**
|
||||
* @var $retval a jQuery object containing the reference
|
||||
* to the created AJAX message
|
||||
*/
|
||||
var $retval = $(
|
||||
'<span class="ajax_notification" id="ajax_message_num_' +
|
||||
ajax_message_count +
|
||||
'"></span>'
|
||||
)
|
||||
.hide()
|
||||
.appendTo('#loading_parent')
|
||||
.html(message)
|
||||
.show();
|
||||
// If the notification is self-closing we should create a callback to remove it
|
||||
if (self_closing) {
|
||||
$retval
|
||||
.delay(timeout)
|
||||
.fadeOut('medium', function () {
|
||||
if ($(this).is(':data(tooltip)')) {
|
||||
$(this).tooltip('destroy');
|
||||
}
|
||||
// Remove the notification
|
||||
$(this).remove();
|
||||
});
|
||||
}
|
||||
// If the notification is dismissable we need to add the relevant class to it
|
||||
// and add a tooltip so that the users know that it can be removed
|
||||
if (dismissable) {
|
||||
$retval.addClass('dismissable').css('cursor', 'pointer');
|
||||
/**
|
||||
* Add a tooltip to the notification to let the user know that (s)he
|
||||
* can dismiss the ajax notification by clicking on it.
|
||||
*/
|
||||
PMA_tooltip(
|
||||
$retval,
|
||||
'span',
|
||||
PMA_messages.strDismiss
|
||||
);
|
||||
}
|
||||
PMA_highlightSQL($retval);
|
||||
|
||||
return $retval;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the message shown for an Ajax operation when it's completed
|
||||
*
|
||||
* @param jQuery object jQuery Element that holds the notification
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
export function PMA_ajaxRemoveMessage ($this_msgbox) {
|
||||
if ($this_msgbox !== undefined && $this_msgbox instanceof jQuery) {
|
||||
$this_msgbox
|
||||
.stop(true, true)
|
||||
.fadeOut('medium');
|
||||
if ($this_msgbox.is(':data(tooltip)')) {
|
||||
$this_msgbox.tooltip('destroy');
|
||||
} else {
|
||||
$this_msgbox.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
18
js/src/utils/sprintf.js
Normal file
18
js/src/utils/sprintf.js
Normal file
@ -0,0 +1,18 @@
|
||||
import sprintf from 'sprintf-js';
|
||||
|
||||
/**
|
||||
* @param string string message to display
|
||||
*
|
||||
* @return string A concated string of aguments passed
|
||||
*/
|
||||
|
||||
export function PMA_sprintf () {
|
||||
/**
|
||||
* This package can be implemented in two ways
|
||||
*
|
||||
* 1) sprintf.sprintf("A %s is %s", "string", "string");
|
||||
*
|
||||
* 2) sprintf.vsprintf("A %s is %s", ["string", "string"]);
|
||||
*/
|
||||
return sprintf.sprintf(...arguments);
|
||||
}
|
||||
99
js/src/variables/common_params.js
Normal file
99
js/src/variables/common_params.js
Normal file
@ -0,0 +1,99 @@
|
||||
import { PMA_sprintf } from '../utils/sprintf';
|
||||
import { PMA_showCurrentNavigation } from '../functions/navigation';
|
||||
/**
|
||||
* Holds common parameters such as server, db, table, etc
|
||||
*
|
||||
* The content for this is normally loaded from Header.php or
|
||||
* Response.php and executed by ajax.js
|
||||
*/
|
||||
export const PMA_commonParams = (function () {
|
||||
/**
|
||||
* @var hash params An associative array of key value pairs
|
||||
* @access private
|
||||
*/
|
||||
var params = {};
|
||||
// The returned object is the public part of the module
|
||||
return {
|
||||
/**
|
||||
* Saves all the key value pair that
|
||||
* are provided in the input array
|
||||
*
|
||||
* @param obj hash The input array
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
setAll: function (obj) {
|
||||
// var reload = false;
|
||||
var updateNavigation = false;
|
||||
for (var i in obj) {
|
||||
if (params[i] !== undefined && params[i] !== obj[i]) {
|
||||
if (i === 'db' || i === 'table') {
|
||||
updateNavigation = true;
|
||||
}
|
||||
// reload = true;
|
||||
}
|
||||
params[i] = obj[i];
|
||||
}
|
||||
if (updateNavigation &&
|
||||
$('#pma_navigation_tree').hasClass('synced')
|
||||
) {
|
||||
PMA_showCurrentNavigation();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Retrieves a value given its key
|
||||
* Returns empty string for undefined values
|
||||
*
|
||||
* @param name string The key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
get: function (name) {
|
||||
return params[name];
|
||||
},
|
||||
/**
|
||||
* Saves a single key value pair
|
||||
*
|
||||
* @param name string The key
|
||||
* @param value string The value
|
||||
*
|
||||
* @return self For chainability
|
||||
*/
|
||||
set: function (name, value) {
|
||||
var updateNavigation = false;
|
||||
if (name === 'db' || name === 'table' &&
|
||||
params[name] !== value
|
||||
) {
|
||||
updateNavigation = true;
|
||||
}
|
||||
params[name] = value;
|
||||
if (updateNavigation &&
|
||||
$('#pma_navigation_tree').hasClass('synced')
|
||||
) {
|
||||
PMA_showCurrentNavigation();
|
||||
}
|
||||
return this;
|
||||
},
|
||||
/**
|
||||
* Returns the url query string using the saved parameters
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
getUrlQuery: function () {
|
||||
var common = this.get('common_query');
|
||||
var separator = '?';
|
||||
var argsep = PMA_commonParams.get('arg_separator');
|
||||
if (common.length > 0) {
|
||||
separator = argsep;
|
||||
}
|
||||
return PMA_sprintf(
|
||||
'%s%sserver=%s' + argsep + 'db=%s' + argsep + 'table=%s',
|
||||
this.get('common_query'),
|
||||
separator,
|
||||
encodeURIComponent(this.get('server')),
|
||||
encodeURIComponent(this.get('db')),
|
||||
encodeURIComponent(this.get('table'))
|
||||
);
|
||||
}
|
||||
};
|
||||
}());
|
||||
10
js/src/variables/export_variables.js
Normal file
10
js/src/variables/export_variables.js
Normal file
@ -0,0 +1,10 @@
|
||||
import { Variables } from './global_variables';
|
||||
|
||||
export const PMA_Messages = Variables.getMessages();
|
||||
|
||||
export const timePicker = Variables.getTimePickerVars();
|
||||
|
||||
export const GlobalVariables = Variables.getGlobalVars();
|
||||
|
||||
export const validations = Variables.getValidatorMessages();
|
||||
|
||||
@ -2,23 +2,23 @@
|
||||
|
||||
/**
|
||||
* Takes parameters defined in messages.php file like messages, validations,
|
||||
* jquery-ui-timepicker edits using global functions
|
||||
* jquery-ui-timepicker edits
|
||||
*/
|
||||
|
||||
export const PMA_messages = (function () {
|
||||
export const Variables = (function () {
|
||||
/**
|
||||
* @var obj params An associate array having key value pairs
|
||||
* of messages to show in js files.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
let messages = new Array();
|
||||
let pmaMessages = new Array();
|
||||
/**
|
||||
* @var obj params Associative array having global configurations
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
let globalVars = new Array();
|
||||
let globalVariables = new Array();
|
||||
/**
|
||||
* @var obj params Associative array having timepicker edits
|
||||
*
|
||||
@ -37,7 +37,7 @@ export const PMA_messages = (function () {
|
||||
* @return array
|
||||
*/
|
||||
getMessages: () => {
|
||||
return messages;
|
||||
return pmaMessages;
|
||||
},
|
||||
/**
|
||||
* Retrieves the globalVars array
|
||||
@ -45,7 +45,7 @@ export const PMA_messages = (function () {
|
||||
* @return array
|
||||
*/
|
||||
getGlobalVars: () => {
|
||||
return globalVars;
|
||||
return globalVariables;
|
||||
},
|
||||
/**
|
||||
* Retrieves the timePickerVars array
|
||||
@ -72,7 +72,7 @@ export const PMA_messages = (function () {
|
||||
*/
|
||||
setAllMessages: (obj) => {
|
||||
for (var i in obj) {
|
||||
messages[i] = obj[i];
|
||||
pmaMessages[i] = obj[i];
|
||||
}
|
||||
},
|
||||
/**
|
||||
@ -84,7 +84,7 @@ export const PMA_messages = (function () {
|
||||
*/
|
||||
setGlobalVars: (obj) => {
|
||||
for (var i in obj) {
|
||||
globalVars[i] = obj[i];
|
||||
globalVariables[i] = obj[i];
|
||||
}
|
||||
},
|
||||
/**
|
||||
20
js/src/variables/import_variables.js
Normal file
20
js/src/variables/import_variables.js
Normal file
@ -0,0 +1,20 @@
|
||||
import { Variables } from './global_variables';
|
||||
import { PMA_commonParams } from './common_params';
|
||||
|
||||
var jqueryValidations = {
|
||||
validationFormat: window.validateFormat,
|
||||
validationMessage: window.validationMessage
|
||||
};
|
||||
Variables.setAllMessages(window.PMA_messages);
|
||||
Variables.setTimePickerVars({
|
||||
datePicker: window.datePicker,
|
||||
timePicker: window.timePicker
|
||||
});
|
||||
Variables.setValidatorMessages(jqueryValidations);
|
||||
Variables.setGlobalVars(window.globalVars);
|
||||
|
||||
/**
|
||||
* This statement to be placed in the file going to be
|
||||
* executed firstly like functions.js
|
||||
*/
|
||||
PMA_commonParams.setAll(window.common_params);
|
||||
@ -84,7 +84,7 @@ class ServerDatabasesController extends Controller
|
||||
|
||||
$header = $this->response->getHeader();
|
||||
$scripts = $header->getScripts();
|
||||
$scripts->addFile('server_databases.js');
|
||||
$scripts->addFile('server_databases');
|
||||
|
||||
$this->_setSortDetails();
|
||||
$this->_dbstats = empty($_REQUEST['dbstats']) ? false : true;
|
||||
|
||||
@ -164,13 +164,10 @@ class Header
|
||||
private function _addDefaultScripts(): void
|
||||
{
|
||||
// Localised strings
|
||||
|
||||
$this->_scripts->addFile('vendor/jquery/jquery.min.js');
|
||||
$this->_scripts->addFile('vendor/jquery/jquery-migrate.js');
|
||||
$this->_scripts->addFile('whitelist.php');
|
||||
$this->_scripts->addFile('vendor/sprintf.js');
|
||||
$this->_scripts->addFile('ajax.js');
|
||||
$this->_scripts->addFile('keyhandler.js');
|
||||
$this->_scripts->addFile('vendor/jquery/jquery-ui.min.js');
|
||||
$this->_scripts->addFile('vendor/js.cookie.js');
|
||||
$this->_scripts->addFile('vendor/jquery/jquery.mousewheel.js');
|
||||
@ -185,7 +182,9 @@ class Header
|
||||
// the user preferences have not been merged at this point
|
||||
|
||||
$this->_scripts->addFile('messages.php', array('l' => $GLOBALS['lang']));
|
||||
|
||||
$this->_scripts->addFile('common_params.php', array('l' => $GLOBALS['lang']));
|
||||
$this->_scripts->addFile('index_new.js');
|
||||
$this->_scripts->addFile('keyhandler.js');
|
||||
// Cross-framing protection
|
||||
if ($GLOBALS['cfg']['AllowThirdPartyFraming'] === false) {
|
||||
$this->_scripts->addFile('cross_framing_protection.js');
|
||||
|
||||
@ -65,7 +65,7 @@ class Scripts
|
||||
}
|
||||
$result .= '<script data-cfasync="false" type="text/javascript" src="' . $src . 'js/dist/'
|
||||
. $value['filename'] . '?' . Header::getVersionParameter() . '"></script>' . "\n";
|
||||
} else {
|
||||
} else if (strpos($value['filename'], ".js") !== false) {
|
||||
$result .= '<script data-cfasync="false" type="text/javascript" src="js/'
|
||||
. $value['filename'] . '?' . Header::getVersionParameter() . '"></script>' . "\n";
|
||||
}
|
||||
@ -137,6 +137,7 @@ class Scripts
|
||||
|| strpos($filename, 'messages.php') !== false
|
||||
|| strpos($filename, 'ajax.js') !== false
|
||||
|| strpos($filename, 'cross_framing_protection.js') !== false
|
||||
|| strpos($filename, 'index_new.js') !== false
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
@ -186,7 +187,6 @@ class Scripts
|
||||
public function getDisplay()
|
||||
{
|
||||
$retval = '';
|
||||
|
||||
if (count($this->_files) > 0) {
|
||||
$retval .= $this->_includeFiles(
|
||||
$this->_files
|
||||
@ -195,18 +195,20 @@ class Scripts
|
||||
|
||||
$code = 'AJAX.scriptHandler';
|
||||
foreach ($this->_files as $file) {
|
||||
$code .= sprintf(
|
||||
'.add("%s",%d)',
|
||||
Sanitize::escapeJsString($file['filename']),
|
||||
$file['has_onload'] ? 1 : 0
|
||||
);
|
||||
if (strpos($file['filename'], ".js") !== false) {
|
||||
$code .= sprintf(
|
||||
'.add("%s",%d)',
|
||||
Sanitize::escapeJsString($file['filename']),
|
||||
$file['has_onload'] ? 1 : 0
|
||||
);
|
||||
}
|
||||
}
|
||||
$code .= ';';
|
||||
$this->addCode($code);
|
||||
|
||||
$code = '$(function() {';
|
||||
foreach ($this->_files as $file) {
|
||||
if ($file['has_onload']) {
|
||||
if ($file['has_onload'] && strpos($file['filename'], ".js") !== false) {
|
||||
$code .= 'AJAX.fireOnload("';
|
||||
$code .= Sanitize::escapeJsString($file['filename']);
|
||||
$code .= '");';
|
||||
|
||||
@ -14,20 +14,24 @@
|
||||
"dependencies": {
|
||||
"codemirror": "5.37.0",
|
||||
"jquery": "3.3.1",
|
||||
"jquery-migrate": "3.0.1",
|
||||
"jquery-migrate": "3.0.0",
|
||||
"jquery-mousewheel": "3.1.13",
|
||||
"jquery-ui": "1.12.1",
|
||||
"jquery-ui": "^1.12.1",
|
||||
"jquery-ui-bundle": "^1.12.1-migrate",
|
||||
"jquery-ui-timepicker-addon": "1.6.3",
|
||||
"jquery-validation": "1.17.0",
|
||||
"jquery.event.drag": "2.2.2",
|
||||
"js-cookie": "2.2.0",
|
||||
"sprintf-js": "^1.1.1",
|
||||
"tracekit": "0.4.5",
|
||||
"updated-jqplot": "1.0.9",
|
||||
"zxcvbn": "4.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "6.26.0",
|
||||
"babel-eslint": "8.2.6",
|
||||
"babel-loader": "^7.1.4",
|
||||
"babel-plugin-syntax-dynamic-import": "^6.18.0",
|
||||
"babel-preset-env": "^1.7.0",
|
||||
"cross-env": "^5.1.5",
|
||||
"del-cli": "^1.1.0",
|
||||
|
||||
@ -35,8 +35,7 @@ $cfgRelation = $relation->getRelationsParam();
|
||||
$response = Response::getInstance();
|
||||
$header = $response->getHeader();
|
||||
$scripts = $header->getScripts();
|
||||
$scripts->addFile('server_privileges.js');
|
||||
$scripts->addFile('vendor/zxcvbn.js');
|
||||
$scripts->addFile('server_privileges');
|
||||
|
||||
$template = new Template();
|
||||
$serverPrivileges = new Privileges($template);
|
||||
|
||||
@ -25,9 +25,8 @@ require_once 'libraries/replication.inc.php';
|
||||
$response = Response::getInstance();
|
||||
$header = $response->getHeader();
|
||||
$scripts = $header->getScripts();
|
||||
$scripts->addFile('server_privileges.js');
|
||||
$scripts->addFile('server_privileges');
|
||||
$scripts->addFile('replication.js');
|
||||
$scripts->addFile('vendor/zxcvbn.js');
|
||||
|
||||
$template = new Template();
|
||||
|
||||
|
||||
@ -40,10 +40,10 @@ var plugins = [
|
||||
export default [{
|
||||
mode: MODE,
|
||||
entry: {
|
||||
db_search_new: './js/src/db_search.js'
|
||||
index_new: './js/src/index.js'
|
||||
},
|
||||
output: {
|
||||
filename: 'db_search_new.js',
|
||||
filename: '[name].js',
|
||||
path: path.resolve(__dirname, 'js/dist'),
|
||||
publicPath: PUBLIC_PATH
|
||||
},
|
||||
|
||||
Loading…
Reference in New Issue
Block a user