Merge pull request #14493 from Piyush3079/Mod_Js_Sql_Js

Add Modular code for sql query box (page) and codemirror related pages
This commit is contained in:
Deven Bansod 2018-08-14 09:52:04 -07:00 committed by GitHub
commit fc72f0d739
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
75 changed files with 7931 additions and 741 deletions

View File

@ -3,3 +3,4 @@ tmp/
vendor/
js/dist/
js/lib/
js/src/plugins/

30
.jsdoc.json Normal file
View File

@ -0,0 +1,30 @@
{
"tags": {
"allowUnknownTags": true,
"dictionaries": ["jsdoc", "closure"]
},
"recurseDepth": 10,
"source": {
"include": ["js/src/", "package.json"],
"includePattern": ".js$",
"exclude": ["js/src/plugins"],
"excludePattern": "(node_modules/|docs)"
},
"sourceType": "module",
"plugins": [
"plugins/markdown"
],
"templates": {
"cleverLinks": true,
"monospaceLinks": true,
"useLongnameInNav": false,
"showInheritedInNav": true
},
"opts": {
"destination": "./doc/js/",
"encoding": "utf8",
"private": true,
"recurse": true,
"template": "./node_modules/minami"
}
}

View File

@ -21,9 +21,8 @@ require_once 'libraries/common.inc.php';
$response = Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('db_search.js');
$scripts->addFile('sql.js');
$scripts->addFile('makegrid.js');
$scripts->addFile('db_search');
$scripts->addFile('sql');
require 'libraries/db_common.inc.php';

View File

@ -24,9 +24,7 @@ PageSettings::showGroup('Sql');
$response = Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('makegrid.js');
$scripts->addFile('vendor/jquery/jquery.uitablefilter.js');
$scripts->addFile('sql.js');
$scripts->addFile('sql');
require 'libraries/db_common.inc.php';

View File

@ -1808,121 +1808,6 @@ function getJSConfirmCommonParam (elem, params) {
return params;
}
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('functions.js', function () {
$(document).off('click', 'a.inline_edit_sql');
$(document).off('click', 'input#sql_query_edit_save');
$(document).off('click', 'input#sql_query_edit_discard');
$('input.sqlbutton').off('click');
if (codemirror_editor) {
codemirror_editor.off('blur');
} else {
$(document).off('blur', '#sqlquery');
}
$(document).off('change', '#parameterized');
$(document).off('click', 'input.sqlbutton');
$('#sqlquery').off('keydown');
$('#sql_query_edit').off('keydown');
if (codemirror_inline_editor) {
// Copy the sql query to the text area to preserve it.
$('#sql_query_edit').text(codemirror_inline_editor.getValue());
$(codemirror_inline_editor.getWrapperElement()).off('keydown');
codemirror_inline_editor.toTextArea();
codemirror_inline_editor = false;
}
if (codemirror_editor) {
$(codemirror_editor.getWrapperElement()).off('keydown');
}
});
/**
* Jquery Coding for inline editing SQL_QUERY
*/
AJAX.registerOnload('functions.js', function () {
// If we are coming back to the page by clicking forward button
// of the browser, bind the code mirror to inline query editor.
bindCodeMirrorToInlineEditor();
$(document).on('click', 'a.inline_edit_sql', function () {
if ($('#sql_query_edit').length) {
// An inline query editor is already open,
// we don't want another copy of it
return false;
}
var $form = $(this).prev('form');
var sql_query = $form.find('input[name=\'sql_query\']').val().trim();
var $inner_sql = $(this).parent().prev().find('code.sql');
var old_text = $inner_sql.html();
var new_content = '<textarea name="sql_query_edit" id="sql_query_edit">' + escapeHtml(sql_query) + '</textarea>\n';
new_content += getForeignKeyCheckboxLoader();
new_content += '<input type="submit" id="sql_query_edit_save" class="button btnSave" value="' + PMA_messages.strGo + '"/>\n';
new_content += '<input type="button" id="sql_query_edit_discard" class="button btnDiscard" value="' + PMA_messages.strCancel + '"/>\n';
var $editor_area = $('div#inline_editor');
if ($editor_area.length === 0) {
$editor_area = $('<div id="inline_editor_outer"></div>');
$editor_area.insertBefore($inner_sql);
}
$editor_area.html(new_content);
loadForeignKeyCheckbox();
$inner_sql.hide();
bindCodeMirrorToInlineEditor();
return false;
});
$(document).on('click', 'input#sql_query_edit_save', function () {
// hide already existing success message
var sql_query;
if (codemirror_inline_editor) {
codemirror_inline_editor.save();
sql_query = codemirror_inline_editor.getValue();
} else {
sql_query = $(this).parent().find('#sql_query_edit').val();
}
var fk_check = $(this).parent().find('#fk_checks').is(':checked');
var $form = $('a.inline_edit_sql').prev('form');
var $fake_form = $('<form>', { action: 'import.php', method: 'post' })
.append($form.find('input[name=server], input[name=db], input[name=table], input[name=token]').clone())
.append($('<input/>', { type: 'hidden', name: 'show_query', value: 1 }))
.append($('<input/>', { type: 'hidden', name: 'is_js_confirmed', value: 0 }))
.append($('<input/>', { type: 'hidden', name: 'sql_query', value: sql_query }))
.append($('<input/>', { type: 'hidden', name: 'fk_checks', value: fk_check ? 1 : 0 }));
if (! checkSqlQuery($fake_form[0])) {
return false;
}
$('.success').hide();
$fake_form.appendTo($('body')).submit();
});
$(document).on('click', 'input#sql_query_edit_discard', function () {
var $divEditor = $('div#inline_editor_outer');
$divEditor.siblings('code.sql').show();
$divEditor.remove();
});
$(document).on('click', 'input.sqlbutton', function (evt) {
insertQuery(evt.target.id);
PMA_handleSimulateQueryButton();
return false;
});
$(document).on('change', '#parameterized', updateQueryParameters);
var $inputUsername = $('#input_username');
if ($inputUsername) {
if ($inputUsername.val() === '') {
$inputUsername.trigger('focus');
} else {
$('#input_password').trigger('focus');
}
}
});
/**
* "inputRead" event handler for CodeMirror SQL query editors for autocompletion
*/
@ -4316,30 +4201,6 @@ function PMA_slidingMessage (msg, $obj) {
return true;
} // end PMA_slidingMessage()
/**
* Attach CodeMirror2 editor to SQL edit area.
*/
AJAX.registerOnload('functions.js', function () {
var $elm = $('#sqlquery');
if ($elm.length > 0) {
if (typeof CodeMirror !== 'undefined') {
codemirror_editor = PMA_getSQLEditor($elm);
codemirror_editor.focus();
codemirror_editor.on('blur', updateQueryParameters);
} else {
// without codemirror
$elm.focus().on('blur', updateQueryParameters);
}
}
PMA_highlightSQL($('body'));
});
AJAX.registerTeardown('functions.js', function () {
if (codemirror_editor) {
$('#sqlquery').text(codemirror_editor.getValue());
codemirror_editor.toTextArea();
codemirror_editor = false;
}
});
AJAX.registerOnload('functions.js', function () {
// initializes all lock-page elements lock-id and
// val-hash data property

View File

@ -8,13 +8,14 @@ import { PMA_ajaxShowMessage,
} from './utils/show_ajax_messages';
import { PMA_Messages as PMA_messages } from './variables/export_variables';
import CommonParams from './variables/common_params';
import { jQuery as $ } from './utils/JqueryExtended';
import { $ } from './utils/JqueryExtended';
import { PMA_getImage } from './functions/get_image';
import { PMA_ensureNaviSettings,
PMA_reloadNavigation,
PMA_disableNaviSettings
} from './functions/navigation';
import { isStorageSupported } from './functions/config';
import PMA_MicroHistory from './classes/MicroHistory';
/**
* This object handles ajax requests for pages. It also
* handles the reloading of the main menu and scripts.
@ -367,7 +368,6 @@ export let AJAX = {
if (typeof onsubmit !== 'function' || onsubmit.apply(this, [event])) {
AJAX.active = true;
AJAX.$msgbox = PMA_ajaxShowMessage();
$.post(url, params, AJAX.responseHandler);
}
}
@ -599,7 +599,7 @@ export let AJAX = {
var fileImports = ['server_privileges', 'server_databases', 'error_report', 'navigation', 'server_status_advisor',
'server_status_processes', 'server_status_variables', 'server_plugins', 'server_status_sorter', 'server_status_queries',
'server_status_monitor', 'server_variables', 'server_user_groups', 'replication', 'export', 'import', 'config',
'page_settings', 'shortcuts_handler'
'page_settings', 'shortcuts_handler', 'db_search', 'sql', 'functions', 'multi_column_sort'
];
if ($.inArray(file, fileImports) !== -1) {
// Dynamic import to load the files dynamically

View File

@ -1,7 +1,13 @@
import { $ } from '../utils/JqueryExtended';
import 'updated-jqplot';
import 'updated-jqplot/dist/plugins/jqplot.pieRenderer';
import 'updated-jqplot/dist/plugins/jqplot.highlighter';
import 'updated-jqplot/dist/plugins/jqplot.enhancedPieLegendRenderer';
/**
* Chart type enumerations
*/
var ChartType = {
export var ChartType = {
LINE : 'line',
SPLINE : 'spline',
AREA : 'area',
@ -15,7 +21,7 @@ var ChartType = {
/**
* Column type enumeration
*/
var ColumnType = {
export var ColumnType = {
STRING : 'string',
NUMBER : 'number',
BOOLEAN : 'boolean',
@ -153,7 +159,7 @@ ScatterChart.prototype.validateColumns = function (dataTable) {
/**
* The data table contains column information and data for the chart.
*/
var DataTable = function () {
export var DataTable = function () {
var columns = [];
var data = null;

View File

@ -0,0 +1,59 @@
import CommonParams from '../variables/common_params';
import { AJAX } from '../ajax';
/**
* 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 var PMA_commonActions = {
/**
* Saves the database name when it's changed
* and reloads the query window, if necessary
*
* @param {string} newDb newDb The name of the new database
*
* @return {void}
*/
setDb: function (newDb) {
if (newDb !== CommonParams.get('db')) {
CommonParams.setAll({ 'db': newDb, 'table': '' });
}
},
/**
* Opens a database in the main part of the page
*
* @param {string} newDb The name of the new database
*
* @return void
*/
openDb: function (newDb) {
CommonParams
.set('db', newDb)
.set('table', '');
this.refreshMain(
CommonParams.get('opendb_url')
);
},
/**
* Refreshes the main frame
*
* @param mixed url Undefined to refresh to the same page
* String to go to a different page, e.g: 'index.php'
*
* @return void
*/
refreshMain: function (url, callback) {
if (! url) {
url = $('#selflink').find('a').attr('href');
url = url.substring(0, url.indexOf('?'));
}
url += CommonParams.getUrlQuery();
$('<a />', { href: url })
.appendTo('body')
.trigger('click')
.remove();
AJAX._callback = callback;
}
};

View File

@ -1,9 +1,12 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Resizer object
* Careful: this object UI logics highly related with functions under PMA_console
* Resizing min-height is 32, if small than it, console will collapse
* @namespace ConsoleResizer
*/
export default class PMA_consoleResizer {
export default class ConsoleResizer {
constructor (instance) {
this._posY = 0;
this._height = 0;

View File

@ -1,7 +1,11 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
import CommonParams from '../../variables/common_params';
import { PMA_Messages as messages } from '../../variables/export_variables';
/**
* @namespace ConsoleBookmarks
* Console bookmarks card, and bookmarks items management object
*/
export default class PMA_consoleBookmarks {
export default class ConsoleBookmarks {
constructor (instance) {
this._bookmarks = [];
this.pmaConsole = null;
@ -15,7 +19,7 @@ export default class PMA_consoleBookmarks {
this.pmaConsole = instance;
this.initialize();
}
addBookmark (queryString, targetDb, label, isShared, id) {
addBookmark (queryString, targetDb, label, isShared) {
$('#pma_bookmarks').find('.add [name=shared]').prop('checked', false);
$('#pma_bookmarks').find('.add [name=label]').val('');
$('#pma_bookmarks').find('.add [name=targetdb]').val('');
@ -42,7 +46,7 @@ export default class PMA_consoleBookmarks {
refresh () {
$.get('import.php',
{ ajax_request: true,
server: PMA_commonParams.get('server'),
server: CommonParams.get('server'),
console_bookmark_refresh: 'refresh' },
function (data) {
if (data.console_message_bookmark) {
@ -71,7 +75,7 @@ export default class PMA_consoleBookmarks {
$('#pma_bookmarks').find('.card.add [name=submit]').click(function () {
if ($('#pma_bookmarks').find('.card.add [name=label]').val().length === 0
|| self.pmaConsole.pmaConsoleInput.getText('bookmark').length === 0) {
alert(PMA_messages.strFormEmpty);
alert(messages.strFormEmpty);
return;
}
$(this).prop('disabled', true);
@ -80,7 +84,7 @@ export default class PMA_consoleBookmarks {
ajax_request: true,
console_bookmark_add: 'true',
label: $('#pma_bookmarks').find('.card.add [name=label]').val(),
server: PMA_commonParams.get('server'),
server: CommonParams.get('server'),
db: $('#pma_bookmarks').find('.card.add [name=targetdb]').val(),
bookmark_query: self.pmaConsole.pmaConsoleInput.getText('bookmark'),
shared: $('#pma_bookmarks').find('.card.add [name=shared]').prop('checked') },

View File

@ -1,4 +1,17 @@
export default class PMA_consoleDebug {
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { PMA_Messages as messages } from '../../variables/export_variables';
import { PMA_sprintf } from '../../utils/sprintf';
import { escapeHtml } from '../../utils/Sanitise';
/**
* Console debug object
* @namespace ConsoleDebug
*/
export default class ConsoleDebug {
constructor (instance) {
this.pmaConsole = null;
this._config = {
@ -123,7 +136,7 @@ export default class PMA_consoleDebug {
$('<div class="message welcome">')
.text(
PMA_sprintf(
PMA_messages.strConsoleDebugArgsSummary,
messages.strConsoleDebugArgsSummary,
dbgStep.args.length
)
)
@ -186,12 +199,12 @@ export default class PMA_consoleDebug {
$('<div class="action_content">')
.append(
'<span class="action dbg_show_args">' +
PMA_messages.strConsoleDebugShowArgs +
messages.strConsoleDebugShowArgs +
'</span> '
)
.append(
'<span class="action dbg_hide_args">' +
PMA_messages.strConsoleDebugHideArgs +
messages.strConsoleDebugHideArgs +
'</span> '
)
);
@ -259,7 +272,7 @@ export default class PMA_consoleDebug {
.text((parseInt(i) + 1) + '.')
.append(
$('<span class="time">').text(
PMA_messages.strConsoleDebugTimeTaken +
messages.strConsoleDebugTimeTaken +
' ' + queryInfo[i].time + 's' +
' (' + ((queryInfo[i].time * 100) / totalTime).toFixed(3) + '%)'
)
@ -304,7 +317,7 @@ export default class PMA_consoleDebug {
}
if (debugJson === false) {
$('#debug_console').find('.debug>.welcome').text(
PMA_messages.strConsoleDebugError
messages.strConsoleDebugError
);
return;
}
@ -336,7 +349,7 @@ export default class PMA_consoleDebug {
$('#debug_console').find('.debug>.welcome').append(
$('<span class="debug_summary">').text(
PMA_sprintf(
PMA_messages.strConsoleDebugSummary,
messages.strConsoleDebugSummary,
totalUnique,
totalExec,
totalTime
@ -351,7 +364,7 @@ export default class PMA_consoleDebug {
// For sorting queries
function sortByTime (a, b) {
var order = ((PMA_console.config.Order === 'asc') ? 1 : -1);
var order = ((this.pmaConsole.config.Order === 'asc') ? 1 : -1);
if (Array.isArray(a) && Array.isArray(b)) {
// It is grouped
var timeA = 0;
@ -370,7 +383,7 @@ export default class PMA_consoleDebug {
}
function sortByCount (a, b) {
var order = ((PMA_console.config.Oorder === 'asc') ? 1 : -1);
var order = ((this.pmaConsole.config.Order === 'asc') ? 1 : -1);
return (a.length - b.length) * order;
}

View File

@ -1,7 +1,24 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
import CodeMirror from 'codemirror';
import 'codemirror/mode/sql/sql.js';
import 'codemirror/addon/runmode/runmode.js';
import 'codemirror/addon/hint/show-hint.js';
import 'codemirror/addon/hint/sql-hint.js';
import 'codemirror/addon/lint/lint.js';
import '../../plugins/codemirror/sql-lint';
import { codemirrorAutocompleteOnInputRead } from '../../utils/sql';
import CommonParams from '../../variables/common_params';
/**
* Console input object
* @namespace ConsoleInput
*/
export default class PMA_consoleInput {
export default class ConsoleInput {
/**
* @constructor
*
* @param {object} pmaConsoleInstance Instance of pma console
*/
constructor (pmaConsoleInstance) {
/**
* @var array, contains Codemirror objects or input jQuery objects
@ -23,9 +40,16 @@ export default class PMA_consoleInput {
* @access private
*/
this._historyPreserveCurrent = null;
/**
* @var object
* @access private
*/
this.pmaConsole = null;
/**
* Bindings for accessing the instance of the class using this
* insde the methods.
*/
this.setPmaConsole = this.setPmaConsole.bind(this);
this.initialize = this.initialize.bind(this);
this._historyNavigate = this._historyNavigate.bind(this);
@ -48,7 +72,7 @@ export default class PMA_consoleInput {
if (this._inputs !== null) {
return;
}
if (typeof CodeMirror !== 'undefined') {
if (CommonParams.get('CodemirrorEnable') === true) {
this._codemirror = true;
}
this._inputs = [];
@ -214,6 +238,7 @@ export default class PMA_consoleInput {
*
* @param string text
* @param string target
*
* @return void
*/
setText (text, target) {
@ -237,6 +262,13 @@ export default class PMA_consoleInput {
}
}
}
/**
* Used for getting the text of input
*
* @param {string} target
*
* @return {string}
*/
getText (target) {
if (this._codemirror) {
switch (target) {

View File

@ -1,7 +1,15 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
import CodeMirror from 'codemirror';
import PMA_commonParams from '../../variables/common_params';
/**
* Module import
*/
import { PMA_Messages as messages } from '../../variables/export_variables';
/**
* Console messages, and message items management object
* @namespace ConsoleMessages
*/
export default class PMA_consoleMessages {
export default class ConsoleMessages {
constructor (instance) {
this.pmaConsole = null;
this.clear = this.clear.bind(this);
@ -167,7 +175,7 @@ export default class PMA_consoleMessages {
$targetMessage.find('.action.requery').click(function () {
var query = $(this).parent().siblings('.query').text();
var $message = $(this).closest('.message');
if (confirm(PMA_messages.strConsoleRequeryConfirm + '\n' +
if (confirm(messages.strConsoleRequeryConfirm + '\n' +
(query.length < 100 ? query : query.slice(0, 100) + '...'))
) {
self.pmaConsole.execute(query, { db: $message.attr('targetdb'), table: $message.attr('targettable') });
@ -189,7 +197,7 @@ export default class PMA_consoleMessages {
});
$targetMessage.find('.action.delete_bookmark').click(function () {
var $message = $(this).closest('.message');
if (confirm(PMA_messages.strConsoleDeleteBookmarkConfirm + '\n' + $message.find('.bookmark_label').text())) {
if (confirm(messages.strConsoleDeleteBookmarkConfirm + '\n' + $message.find('.bookmark_label').text())) {
$.post('import.php',
{
server: PMA_commonParams.get('server'),

View File

@ -8,7 +8,7 @@ import CommonParams from '../variables/common_params';
import { PMA_ajaxShowMessage } from '../utils/show_ajax_messages';
import { PMA_getImage } from '../functions/get_image';
import TraceKit from 'tracekit';
import { jQuery as $ } from '../utils/JqueryExtended';
import { $ } from '../utils/JqueryExtended';
/**
* This Object uses the library TraceKit to generate the backtrace of the
@ -39,6 +39,7 @@ var ErrorReport = {
* @return void
*/
error_handler: function (exception) {
console.error(exception);
if (exception.name === null || typeof(exception.name) === 'undefined') {
exception.name = ErrorReport._extractExceptionName(exception);
}

View File

@ -0,0 +1,228 @@
import { PMA_ajaxShowMessage } from '../utils/show_ajax_messages';
import { AJAX } from '../ajax';
import { PMA_Messages as messages } from '../variables/export_variables';
import CommonParams from '../variables/common_params';
import SetUrlHash from './SetUrlHash';
/**
* An implementation of a client-side page cache.
* This object also uses the cache to provide a simple microhistory,
* that is the ability to use the back and forward buttons in the browser
*/
var MicroHistory = {
/**
* @var int The maximum number of pages to keep in the cache
*/
MAX: 6,
/**
* @var object A hash used to prime the cache with data about the initially
* loaded page. This is set in the footer, and then loaded
* by a double-queued event further down this file.
*/
primer: {},
/**
* @var array Stores the content of the cached pages
*/
pages: [],
/**
* @var int The index of the currently loaded page
* This is used to know at which point in the history we are
*/
current: 0,
/**
* Saves a new page in the cache
*
* @param string hash The hash part of the url that is being loaded
* @param array scripts A list of scripts that is required for the page
* @param string menu A hash that links to a menu stored
* in a dedicated menu cache
* @param array params A list of parameters used by CommonParams()
* @param string rel A relationship to the current page:
* 'samepage': Forces the response to be treated as
* the same page as the current one
* 'newpage': Forces the response to be treated as
* a new page
* undefined: Default behaviour, 'samepage' if the
* selflinks of the two pages are the same.
* 'newpage' otherwise
*
* @return void
*/
add: function (hash, scripts, menu, params, rel) {
if (this.pages.length > MicroHistory.MAX) {
// Trim the cache, to the maximum number of allowed entries
// This way we will have a cached menu for every page
for (var i = 0; i < this.pages.length - this.MAX; i++) {
delete this.pages[i];
}
}
while (this.current < this.pages.length) {
// trim the cache if we went back in the history
// and are now going forward again
this.pages.pop();
}
if (rel === 'newpage' ||
(
typeof rel === 'undefined' && (
typeof this.pages[this.current - 1] === 'undefined' ||
this.pages[this.current - 1].hash !== hash
)
)
) {
this.pages.push({
hash: hash,
content: $('#page_content').html(),
scripts: scripts,
selflink: $('#selflink').html(),
menu: menu,
params: params
});
SetUrlHash(this.current, hash);
this.current++;
}
},
/**
* Restores a page from the cache. This is called when the hash
* part of the url changes and it's structure appears to be valid
*
* @param string index Which page from the history to load
*
* @return void
*/
navigate: function (index) {
if (typeof this.pages[index] === 'undefined' ||
typeof this.pages[index].content === 'undefined' ||
typeof this.pages[index].menu === 'undefined' ||
! MicroHistory.menus.get(this.pages[index].menu)
) {
PMA_ajaxShowMessage(
'<div class="error">' + messages.strInvalidPage + '</div>',
false
);
} else {
AJAX.active = true;
var record = this.pages[index];
AJAX.scriptHandler.reset(function () {
$('#page_content').html(record.content);
$('#selflink').html(record.selflink);
MicroHistory.menus.replace(MicroHistory.menus.get(record.menu));
CommonParams.setAll(record.params);
AJAX.scriptHandler.load(record.scripts);
MicroHistory.current = ++index;
});
}
},
/**
* Resaves the content of the current page in the cache.
* Necessary in order not to show the user some outdated version of the page
*
* @return void
*/
update: function () {
var page = this.pages[this.current - 1];
if (page) {
page.content = $('#page_content').html();
}
},
/**
* @var object Dedicated menu cache
*/
menus: {
/**
* Returns the number of items in an associative array
*
* @return int
*/
size: function (obj) {
var size = 0;
var key;
for (key in obj) {
if (obj.hasOwnProperty(key)) {
size++;
}
}
return size;
},
/**
* @var hash Stores the content of the cached menus
*/
data: {},
/**
* Saves a new menu in the cache
*
* @param string hash The hash (trimmed md5) of the menu to be saved
* @param string content The HTML code of the menu to be saved
*
* @return void
*/
add: function (hash, content) {
if (this.size(this.data) > MicroHistory.MAX) {
// when the cache grows, we remove the oldest entry
var oldest;
var key;
var init = 0;
for (var i in this.data) {
if (this.data[i]) {
if (! init || this.data[i].timestamp.getTime() < oldest.getTime()) {
oldest = this.data[i].timestamp;
key = i;
init = 1;
}
}
}
delete this.data[key];
}
this.data[hash] = {
content: content,
timestamp: new Date()
};
},
/**
* Retrieves a menu given its hash
*
* @param string hash The hash of the menu to be retrieved
*
* @return string
*/
get: function (hash) {
if (this.data[hash]) {
return this.data[hash].content;
} else {
// This should never happen as long as the number of stored menus
// is larger or equal to the number of pages in the page cache
return '';
}
},
/**
* Prepares part of the parameter string used during page requests,
* this is necessary to tell the server which menus we have in the cache
*
* @return string
*/
getRequestParam: function () {
var param = '';
var menuHashes = [];
for (var i in this.data) {
menuHashes.push(i);
}
var menuHashesParam = menuHashes.join('-');
if (menuHashesParam) {
param = CommonParams.get('arg_separator') + 'menuHashes=' + menuHashesParam;
}
return param;
},
/**
* Replaces the menu with new content
*
* @return void
*/
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);
}
}
};
export default MicroHistory;

View File

@ -1,10 +1,10 @@
import { PMA_ajaxShowMessage } from '../../utils/show_ajax_messages';
import { PMA_highlightSQL } from '../../utils/sql';
import { PMA_Messages as PMA_messages } from '../../variables/export_variables';
import { PMA_Messages as messages } from '../../variables/export_variables';
import CommonParams from '../../variables/common_params';
import { PMA_getImage } from '../../functions/get_image';
import { escapeHtml } from '../../utils/Sanitise';
import { jQuery as $ } from '../../utils/JqueryExtended';
import { $ } from '../../utils/JqueryExtended';
// object to store process list state information
class ProcessList {
constructor () {
@ -129,10 +129,10 @@ class ProcessList {
*/
setRefreshLabel () {
var img = 'play';
var label = PMA_messages.strStartRefresh;
var label = messages.strStartRefresh;
if (this.autoRefresh) {
img = 'pause';
label = PMA_messages.strStopRefresh;
label = messages.strStopRefresh;
this.refresh();
}
$('a#toggleRefresh').html(PMA_getImage(img) + escapeHtml(label));

View File

@ -0,0 +1,117 @@
import MicroHistory from './MicroHistory';
import '../plugins/jquery/jquery.ba-hashchange-1.3';
/**
* URL hash management module.
* Allows direct bookmarking and microhistory.
*/
var SetUrlHash = (function (jQuery, window) {
/**
* Indictaes whether we have already completed
* the initialisation of the hash
*
* @access private
*/
var ready = false;
/**
* Stores a hash that needed to be set when we were not ready
*
* @access private
*/
var savedHash = '';
/**
* Flag to indicate if the change of hash was triggered
* by a user pressing the back/forward button or if
* the change was triggered internally
*
* @access private
*/
var userChange = true;
// Fix favicon disappearing in Firefox when setting location.hash
function resetFavicon () {
if (navigator.userAgent.indexOf('Firefox') > -1) {
// Move the link tags for the favicon to the bottom
// of the head element to force a reload of the favicon
$('head > link[href="favicon\\.ico"]').appendTo('head');
}
}
/**
* Sets the hash part of the URL
*
* @access public
*/
function setUrlHash (index, hash) {
/*
* Known problem:
* Setting hash leads to reload in webkit:
* http://www.quirksmode.org/bugreports/archives/2005/05/Safari_13_visual_anomaly_with_windowlocationhref.html
*
* so we expect that users are not running an ancient Safari version
*/
userChange = false;
if (ready) {
window.location.hash = 'PMAURL-' + index + ':' + hash;
resetFavicon();
} else {
savedHash = 'PMAURL-' + index + ':' + hash;
}
}
/**
* Start initialisation
*/
var urlhash = window.location.hash;
if (urlhash.substring(0, 8) === '#PMAURL-') {
// We have a valid hash, let's redirect the user
// to the page that it's pointing to
var colon_position = urlhash.indexOf(':');
var questionmark_position = urlhash.indexOf('?');
if (colon_position !== -1 && questionmark_position !== -1 && colon_position < questionmark_position) {
var hash_url = urlhash.substring(colon_position + 1, questionmark_position);
if (window.PMA_gotoWhitelist.indexOf(hash_url) !== -1) {
window.location = urlhash.substring(
colon_position + 1
);
}
}
} else {
// We don't have a valid hash, so we'll set it up
// when the page finishes loading
jQuery(function () {
/* Check if we should set URL */
if (savedHash !== '') {
window.location.hash = savedHash;
savedHash = '';
resetFavicon();
}
// Indicate that we're done initialising
ready = true;
});
}
/**
* Register an event handler for when the url hash changes
*/
jQuery(function () {
jQuery(window).hashchange(function () {
if (userChange === false) {
// Ignore internally triggered hash changes
userChange = true;
} else if (/^#PMAURL-\d+:/.test(window.location.hash)) {
// Change page if the hash changed was triggered by a user action
var index = window.location.hash.substring(
8, window.location.hash.indexOf(':')
);
MicroHistory.navigate(index);
}
});
});
/**
* Publicly exposes a reference to the otherwise private setUrlHash function
*/
return setUrlHash;
}(jQuery, window));
export default SetUrlHash;

View File

@ -3,13 +3,15 @@ import * as Config from './functions/config';
import { defaultValues } from './variables/get_config';
/**
* Functions used in configuration forms and on user preferences pages
* @package PhpMyAdmin
*
* Config
*/
/**
* Unbind all event handlers before tearing down a page
*/
export function teardown1 () {
function teardownConfig () {
$('.optbox input[id], .optbox select[id], .optbox textarea[id]').off('change').off('keyup');
$('.optbox input[type=button][name=submit_reset]').off('click');
$('div.tabs_contents').off();
@ -19,7 +21,7 @@ export function teardown1 () {
$('#prefs_autoload').find('a').off('click');
}
export function onload1 () {
function onloadConfigPrefsTab () {
var $topmenu_upt = $('#topmenu2.user_prefs_tabs');
$topmenu_upt.find('li.active a').attr('rel', 'samepage');
$topmenu_upt.find('li:not(.active) a').attr('rel', 'newpage');
@ -29,7 +31,7 @@ export function onload1 () {
// Form validation and field operations
//
export function onload2 () {
function onloadConfigValidations () {
Config.setupValidation();
}
@ -41,7 +43,7 @@ export function onload2 () {
// Tabbed forms
//
export function onload3 () {
function onloadConfigTabs () {
Config.setupConfigTabs();
Config.adjustPrefsNotification();
@ -72,7 +74,7 @@ export function onload3 () {
// Form reset buttons
//
export function onload4 () {
function onloadConfigResetDefault () {
$('.optbox input[type=button][name=submit_reset]').on('click', function () {
var fields = $(this).closest('fieldset').find('input, select, textarea');
for (var i = 0, imax = fields.length; i < imax; i++) {
@ -89,7 +91,7 @@ export function onload4 () {
// "Restore default" and "set value" buttons
//
export function onload5 () {
function onloadConfigRestore () {
Config.setupRestoreField();
}
@ -101,7 +103,7 @@ export function onload5 () {
// User preferences import/export
//
export function onload6 () {
function onloadPreferenceExport () {
Config.offerPrefsAutoimport();
var $radios = $('#import_local_storage, #export_local_storage');
if (!$radios.length) {
@ -113,15 +115,15 @@ export function onload6 () {
.prop('disabled', false)
.add('#export_text_file, #import_text_file')
.on('click', function () {
var enable_id = $(this).attr('id');
var disable_id;
if (enable_id.match(/local_storage$/)) {
disable_id = enable_id.replace(/local_storage$/, 'text_file');
var enableId = $(this).attr('id');
var disableId;
if (enableId.match(/local_storage$/)) {
disableId = enableId.replace(/local_storage$/, 'text_file');
} else {
disable_id = enable_id.replace(/text_file$/, 'local_storage');
disableId = enableId.replace(/text_file$/, 'local_storage');
}
$('#opts_' + disable_id).addClass('disabled').find('input').prop('disabled', true);
$('#opts_' + enable_id).removeClass('disabled').find('input').prop('disabled', false);
$('#opts_' + disableId).addClass('disabled').find('input').prop('disabled', true);
$('#opts_' + enableId).removeClass('disabled').find('input').prop('disabled', false);
});
// detect localStorage state
@ -135,9 +137,9 @@ export function onload6 () {
$('form.prefs-form').on('change', function () {
var $form = $(this);
var disabled = false;
if (!ls_supported) {
if (!lsSupported) {
disabled = $form.find('input[type=radio][value$=local_storage]').prop('checked');
} else if (!ls_exists && $form.attr('name') === 'prefs_import' &&
} else if (!lsExists && $form.attr('name') === 'prefs_import' &&
$('#import_local_storage')[0].checked
) {
disabled = true;
@ -168,3 +170,16 @@ export function onload6 () {
//
// END: User preferences import/export
// ------------------------------------------------------------------
/**
* Module export
*/
export {
teardownConfig,
onloadConfigPrefsTab,
onloadConfigResetDefault,
onloadConfigRestore,
onloadConfigTabs,
onloadConfigValidations,
onloadPreferenceExport
};

View File

@ -4,15 +4,15 @@
*
* @package phpMyAdmin-Console
*/
import PMA_consoleBookmarks from './classes/Console/PMA_consoleBookmarks';
import PMA_consoleDebug from './classes/Console/PMA_consoleDebug';
import PMA_consoleInput from './classes/Console/PMA_consoleInput';
import PMA_consoleMessages from './classes/Console/PMA_consoleMessages';
import PMA_consoleResizer from './classes/Console/PMA_ConsoleResizer';
import ConsoleBookmarks from './classes/Console/PMA_consoleBookmarks';
import ConsoleDebug from './classes/Console/PMA_consoleDebug';
import ConsoleInput from './classes/Console/PMA_consoleInput';
import ConsoleMessages from './classes/Console/PMA_consoleMessages';
import ConsoleResizer from './classes/Console/PMA_ConsoleResizer';
/**
* Console object
*/
var PMA_console = {
var Console = {
/**
* @var object, jQuery object, selector is '#pma_console>.content'
* @access private
@ -69,18 +69,18 @@ var PMA_console = {
return;
}
PMA_console.config = configGet('Console', false);
Console.config = configGet('Console', false);
PMA_console.isEnabled = true;
Console.isEnabled = true;
// Vars init
PMA_console.$consoleToolbar = $('#pma_console').find('>.toolbar');
PMA_console.$consoleContent = $('#pma_console').find('>.content');
PMA_console.$consoleAllContents = $('#pma_console').find('.content');
PMA_console.$consoleTemplates = $('#pma_console').find('>.templates');
Console.$consoleToolbar = $('#pma_console').find('>.toolbar');
Console.$consoleContent = $('#pma_console').find('>.content');
Console.$consoleAllContents = $('#pma_console').find('.content');
Console.$consoleTemplates = $('#pma_console').find('>.templates');
// Generate a from for post
PMA_console.$requestForm = $('<form method="post" action="import.php">' +
Console.$requestForm = $('<form method="post" action="import.php">' +
'<input name="is_js_confirmed" value="0">' +
'<textarea name="sql_query"></textarea>' +
'<input name="console_message_id" value="0">' +
@ -90,36 +90,37 @@ var PMA_console = {
'<input name="token" value="">' +
'</form>'
);
PMA_console.$requestForm.children('[name=token]').val(PMA_commonParams.get('token'));
PMA_console.$requestForm.on('submit', AJAX.requestHandler);
Console.$requestForm.children('[name=token]').val(PMA_commonParams.get('token'));
Console.$requestForm.on('submit', AJAX.requestHandler);
// Event binds shouldn't run again
if (PMA_console.isInitialized === false) {
if (Console.isInitialized === false) {
// Load config first
if (PMA_console.config.AlwaysExpand === true) {
if (Console.config.AlwaysExpand === true) {
$('#pma_console_options input[name=always_expand]').prop('checked', true);
}
if (PMA_console.config.StartHistory === true) {
if (Console.config.StartHistory === true) {
$('#pma_console_options').find('input[name=start_history]').prop('checked', true);
}
if (PMA_console.config.CurrentQuery === true) {
if (Console.config.CurrentQuery === true) {
$('#pma_console_options').find('input[name=current_query]').prop('checked', true);
}
if (PMA_console.config.EnterExecutes === true) {
if (Console.config.EnterExecutes === true) {
$('#pma_console_options').find('input[name=enter_executes]').prop('checked', true);
}
if (PMA_console.config.DarkTheme === true) {
if (Console.config.DarkTheme === true) {
$('#pma_console_options').find('input[name=dark_theme]').prop('checked', true);
$('#pma_console').find('>.content').addClass('console_dark_theme');
}
PMA_console.pmaConsoleResizer = new PMA_consoleResizer(PMA_console);
PMA_console.pmaConsoleInput = new PMA_consoleInput(PMA_console);
PMA_console.pmaConsoleMessages = new PMA_consoleMessages(PMA_console);
PMA_console.pmaConsoleBookmarks = new PMA_consoleBookmarks(PMA_console);
PMA_console.pmaConsoleDebug = new PMA_consoleDebug(PMA_console);
// Instances of helper classes
Console.pmaConsoleResizer = new ConsoleResizer(Console);
Console.pmaConsoleInput = new ConsoleInput(Console);
Console.pmaConsoleMessages = new ConsoleMessages(Console);
Console.pmaConsoleBookmarks = new ConsoleBookmarks(Console);
Console.pmaConsoleDebug = new ConsoleDebug(Console);
PMA_console.$consoleToolbar.children('.console_switch').click(PMA_console.toggle);
Console.$consoleToolbar.children('.console_switch').click(Console.toggle);
$('#pma_console').find('.toolbar').children().mousedown(function (event) {
event.preventDefault();
@ -127,42 +128,42 @@ var PMA_console = {
});
$('#pma_console').find('.button.clear').click(function () {
PMA_console.pmaConsoleMessages.clear();
Console.pmaConsoleMessages.clear();
});
$('#pma_console').find('.button.history').click(function () {
PMA_console.pmaConsoleMessages.showHistory();
Console.pmaConsoleMessages.showHistory();
});
$('#pma_console').find('.button.options').click(function () {
PMA_console.showCard('#pma_console_options');
Console.showCard('#pma_console_options');
});
$('#pma_console').find('.button.debug').click(function () {
PMA_console.showCard('#debug_console');
Console.showCard('#debug_console');
});
PMA_console.$consoleContent.click(function (event) {
Console.$consoleContent.click(function (event) {
if (event.target === this) {
PMA_console.pmaConsoleInput.focus();
Console.pmaConsoleInput.focus();
}
});
$('#pma_console').find('.mid_layer').click(function () {
PMA_console.hideCard($(this).parent().children('.card'));
Console.hideCard($(this).parent().children('.card'));
});
$('#debug_console').find('.switch_button').click(function () {
PMA_console.hideCard($(this).closest('.card'));
Console.hideCard($(this).closest('.card'));
});
$('#pma_bookmarks').find('.switch_button').click(function () {
PMA_console.hideCard($(this).closest('.card'));
Console.hideCard($(this).closest('.card'));
});
$('#pma_console_options').find('.switch_button').click(function () {
PMA_console.hideCard($(this).closest('.card'));
Console.hideCard($(this).closest('.card'));
});
$('#pma_console_options').find('input[type=checkbox]').change(function () {
PMA_console.updateConfig();
Console.updateConfig();
});
$('#pma_console_options').find('.button.default').click(function () {
@ -171,11 +172,11 @@ var PMA_console = {
$('#pma_console_options').find('input[name=current_query]').prop('checked', true);
$('#pma_console_options').find('input[name=enter_executes]').prop('checked', false);
$('#pma_console_options').find('input[name=dark_theme]').prop('checked', false);
PMA_console.updateConfig();
Console.updateConfig();
});
$('#pma_console_options').find('input[name=enter_executes]').change(function () {
PMA_console.pmaConsoleMessages.showInstructions(PMA_console.config.EnterExecutes);
Console.pmaConsoleMessages.showInstructions(Console.config.EnterExecutes);
});
$(document).ajaxComplete(function (event, xhr, ajaxOptions) {
@ -187,32 +188,32 @@ var PMA_console = {
}
try {
var data = JSON.parse(xhr.responseText);
PMA_console.ajaxCallback(data);
Console.ajaxCallback(data);
} catch (e) {
console.trace();
console.log('Failed to parse JSON: ' + e.message);
}
});
PMA_console.isInitialized = true;
Console.isInitialized = true;
}
// Change console mode from cookie
switch (PMA_console.config.Mode) {
switch (Console.config.Mode) {
case 'collapse':
PMA_console.collapse();
Console.collapse();
break;
/* jshint -W086 */// no break needed in default section
case 'info':
/* jshint +W086 */
PMA_console.info();
Console.info();
break;
case 'show':
PMA_console.show(true);
PMA_console.scrollBottom();
Console.show(true);
Console.scrollBottom();
break;
default:
PMA_console.setConfig('Mode', 'info');
Console.setConfig('Mode', 'info');
}
},
/**
@ -224,40 +225,40 @@ var PMA_console = {
if (typeof(queryString) !== 'string' || ! /[a-z]|[A-Z]/.test(queryString)) {
return;
}
PMA_console.$requestForm.children('textarea').val(queryString);
PMA_console.$requestForm.children('[name=server]').attr('value', PMA_commonParams.get('server'));
Console.$requestForm.children('textarea').val(queryString);
Console.$requestForm.children('[name=server]').attr('value', PMA_commonParams.get('server'));
if (options && options.db) {
PMA_console.$requestForm.children('[name=db]').val(options.db);
Console.$requestForm.children('[name=db]').val(options.db);
if (options.table) {
PMA_console.$requestForm.children('[name=table]').val(options.table);
Console.$requestForm.children('[name=table]').val(options.table);
} else {
PMA_console.$requestForm.children('[name=table]').val('');
Console.$requestForm.children('[name=table]').val('');
}
} else {
PMA_console.$requestForm.children('[name=db]').val(
Console.$requestForm.children('[name=db]').val(
(PMA_commonParams.get('db').length > 0 ? PMA_commonParams.get('db') : ''));
}
PMA_console.$requestForm.find('[name=profiling]').remove();
Console.$requestForm.find('[name=profiling]').remove();
if (options && options.profiling === true) {
PMA_console.$requestForm.append('<input name="profiling" value="on">');
Console.$requestForm.append('<input name="profiling" value="on">');
}
if (! confirmQuery(PMA_console.$requestForm[0], PMA_console.$requestForm.children('textarea')[0].value)) {
if (! confirmQuery(Console.$requestForm[0], Console.$requestForm.children('textarea')[0].value)) {
return;
}
PMA_console.$requestForm.children('[name=console_message_id]')
.val(PMA_console.pmaConsoleMessages.appendQuery({ sql_query: queryString }).message_id);
PMA_console.$requestForm.trigger('submit');
PMA_console.pmaConsoleInput.clear();
Console.$requestForm.children('[name=console_message_id]')
.val(Console.pmaConsoleMessages.appendQuery({ sql_query: queryString }).message_id);
Console.$requestForm.trigger('submit');
Console.pmaConsoleInput.clear();
PMA_reloadNavigation();
},
ajaxCallback: function (data) {
if (data && data.console_message_id) {
PMA_console.pmaConsoleMessages.updateQuery(data.console_message_id, data.success,
Console.pmaConsoleMessages.updateQuery(data.console_message_id, data.success,
(data._reloadQuerywindow ? data._reloadQuerywindow : false));
} else if (data && data._reloadQuerywindow) {
if (data._reloadQuerywindow.sql_query.length > 0) {
PMA_console.pmaConsoleMessages.appendQuery(data._reloadQuerywindow, 'successed')
.$message.addClass(PMA_console.config.CurrentQuery ? '' : 'hide');
Console.pmaConsoleMessages.appendQuery(data._reloadQuerywindow, 'successed')
.$message.addClass(Console.config.CurrentQuery ? '' : 'hide');
}
}
},
@ -267,18 +268,18 @@ var PMA_console = {
* @return void
*/
collapse: function () {
PMA_console.setConfig('Mode', 'collapse');
var pmaConsoleHeight = Math.max(92, PMA_console.config.Height);
Console.setConfig('Mode', 'collapse');
var pmaConsoleHeight = Math.max(92, Console.config.Height);
PMA_console.$consoleToolbar.addClass('collapsed');
PMA_console.$consoleAllContents.height(pmaConsoleHeight);
PMA_console.$consoleContent.stop();
PMA_console.$consoleContent.animate({ 'margin-bottom': -1 * PMA_console.$consoleContent.outerHeight() + 'px' },
Console.$consoleToolbar.addClass('collapsed');
Console.$consoleAllContents.height(pmaConsoleHeight);
Console.$consoleContent.stop();
Console.$consoleContent.animate({ 'margin-bottom': -1 * Console.$consoleContent.outerHeight() + 'px' },
'fast', 'easeOutQuart', function () {
PMA_console.$consoleContent.css({ display:'none' });
Console.$consoleContent.css({ display:'none' });
$(window).trigger('resize');
});
PMA_console.hideCard();
Console.hideCard();
},
/**
* Show console
@ -287,21 +288,21 @@ var PMA_console = {
* @return void
*/
show: function (inputFocus) {
PMA_console.setConfig('Mode', 'show');
Console.setConfig('Mode', 'show');
var pmaConsoleHeight = Math.max(92, PMA_console.config.Height);
pmaConsoleHeight = Math.min(PMA_console.config.Height, (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - 25);
PMA_console.$consoleContent.css({ display:'block' });
if (PMA_console.$consoleToolbar.hasClass('collapsed')) {
PMA_console.$consoleToolbar.removeClass('collapsed');
var pmaConsoleHeight = Math.max(92, Console.config.Height);
pmaConsoleHeight = Math.min(Console.config.Height, (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - 25);
Console.$consoleContent.css({ display:'block' });
if (Console.$consoleToolbar.hasClass('collapsed')) {
Console.$consoleToolbar.removeClass('collapsed');
}
PMA_console.$consoleAllContents.height(pmaConsoleHeight);
PMA_console.$consoleContent.stop();
PMA_console.$consoleContent.animate({ 'margin-bottom': 0 },
Console.$consoleAllContents.height(pmaConsoleHeight);
Console.$consoleContent.stop();
Console.$consoleContent.animate({ 'margin-bottom': 0 },
'fast', 'easeOutQuart', function () {
$(window).trigger('resize');
if (inputFocus) {
PMA_console.pmaConsoleInput.focus();
Console.pmaConsoleInput.focus();
}
});
},
@ -314,7 +315,7 @@ var PMA_console = {
*/
info: function () {
// Under construction
PMA_console.collapse();
Console.collapse();
},
/**
* Toggle console mode between collapse/show
@ -323,13 +324,13 @@ var PMA_console = {
* @return void
*/
toggle: function () {
switch (PMA_console.config.Mode) {
switch (Console.config.Mode) {
case 'collapse':
case 'info':
PMA_console.show(true);
Console.show(true);
break;
case 'show':
PMA_console.collapse();
Console.collapse();
break;
default:
PMA_consoleInitialize();
@ -341,7 +342,7 @@ var PMA_console = {
* @return void
*/
scrollBottom: function () {
PMA_console.$consoleContent.scrollTop(PMA_console.$consoleContent.prop('scrollHeight'));
Console.$consoleContent.scrollTop(Console.$consoleContent.prop('scrollHeight'));
},
/**
* Show card
@ -367,9 +368,9 @@ var PMA_console = {
}
$card.parent().children('.mid_layer').show().fadeTo(0, 0.15);
$card.addClass('show');
PMA_console.pmaConsoleInput.blur();
Console.pmaConsoleInput.blur();
if ($card.parents('.card').length > 0) {
PMA_console.showCard($card.parents('.card'));
Console.showCard($card.parents('.card'));
}
},
/**
@ -394,20 +395,20 @@ var PMA_console = {
* @return void
*/
updateConfig: function () {
PMA_console.setConfig('AlwaysExpand', $('#pma_console_options input[name=always_expand]').prop('checked'));
PMA_console.setConfig('StartHistory', $('#pma_console_options').find('input[name=start_history]').prop('checked'));
PMA_console.setConfig('CurrentQuery', $('#pma_console_options').find('input[name=current_query]').prop('checked'));
PMA_console.setConfig('EnterExecutes', $('#pma_console_options').find('input[name=enter_executes]').prop('checked'));
PMA_console.setConfig('DarkTheme', $('#pma_console_options').find('input[name=dark_theme]').prop('checked'));
Console.setConfig('AlwaysExpand', $('#pma_console_options input[name=always_expand]').prop('checked'));
Console.setConfig('StartHistory', $('#pma_console_options').find('input[name=start_history]').prop('checked'));
Console.setConfig('CurrentQuery', $('#pma_console_options').find('input[name=current_query]').prop('checked'));
Console.setConfig('EnterExecutes', $('#pma_console_options').find('input[name=enter_executes]').prop('checked'));
Console.setConfig('DarkTheme', $('#pma_console_options').find('input[name=dark_theme]').prop('checked'));
/* Setting the dark theme of the console*/
if (PMA_console.config.DarkTheme) {
if (Console.config.DarkTheme) {
$('#pma_console').find('>.content').addClass('console_dark_theme');
} else {
$('#pma_console').find('>.content').removeClass('console_dark_theme');
}
},
setConfig: function (key, value) {
PMA_console.config[key] = value;
Console.config[key] = value;
configSet('Console/' + key, value);
},
isSelect: function (queryString) {
@ -416,4 +417,4 @@ var PMA_console = {
}
};
export default PMA_console;
export default Console;

View File

@ -7,7 +7,7 @@
* @type {Object} files
*/
const files = {
global: ['error_report', 'config', 'navigation', 'page_settings', 'shortcuts_handler'],
global: ['error_report', 'config', 'navigation', 'page_settings', 'shortcuts_handler', 'functions'],
server_privileges: ['server_privileges'],
server_databases: ['server_databases'],
server_status_advisor: ['server_status_advisor'],
@ -21,7 +21,11 @@ const files = {
server_user_groups: ['server_user_groups'],
server_replication: ['server_privileges', 'replication'],
server_export: ['export'],
server_import: ['import']
server_import: ['import'],
db_search: ['db_search', 'sql'],
server_sql: ['multi_column_sort', 'sql'],
tbl_sql: ['sql'],
db_sql: ['sql']
};
export default files;

253
js/src/db_search.js Normal file
View File

@ -0,0 +1,253 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* JavaScript functions used on Database Search page
*
* @requires jQuery
* @requires js/functions.js
*
* @package PhpMyAdmin
*/
/**
* AJAX script for the Database Search page.
*
* Actions ajaxified here:
* Retrieve result of SQL query
*/
import { PMA_Messages as messages } from './variables/export_variables';
import { PMA_ajaxShowMessage, PMA_sprintf, PMA_ajaxRemoveMessage } from './utils/show_ajax_messages';
import PMA_commonParams from './variables/common_params';
import { PMA_makegrid } from './utils/makegrid';
/**
* Unbind all event handlers before tearing down a page
*/
export function teardownDbSearch () {
$('a.browse_results').off('click');
$('a.delete_results').off('click');
$('#buttonGo').off('click');
$('#togglesearchresultlink').off('click');
$('#togglequerybox').off('click');
$('#togglesearchformlink').off('click');
$(document).off('submit', '#db_search_form.ajax');
}
export function onloadDbSearch () {
/** Hide the table link in the initial search result */
let icon = PMA_getImage('s_tbl', '', { 'id': 'table-image' }).toString();
$('#table-info').prepend(icon).hide();
/** Hide the browse and deleted results in the new search criteria */
$('#buttonGo').click(function () {
$('#table-info').hide();
$('#browse-results').hide();
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
});
/**
* Prepare a div containing a link for toggle the search results
*/
$('#togglesearchresultsdiv')
/** don't show it until we have results on-screen */
.hide();
/**
* Changing the displayed text according to
* the hide/show criteria in search result forms
*/
$('#togglesearchresultlink')
.html(messages.strHideSearchResults)
.on('click', function () {
let $link = $(this);
$('#searchresults').slideToggle();
if ($link.text() === messages.strHideSearchResults) {
$link.text(messages.strShowSearchResults);
} else {
$link.text(messages.strHideSearchResults);
}
/** avoid default click action */
return false;
});
/**
* Prepare a div containing a link for toggle the search form,
* otherwise it's incorrectly displayed after a couple of clicks
*/
$('#togglesearchformdiv')
.hide(); // don't show it until we have results on-screen
/**
* Changing the displayed text according to
* the hide/show criteria in search form
*/
$('#togglequerybox')
.hide()
.on('click', function () {
let $link = $(this);
$('#sqlqueryform').slideToggle('medium');
if ($link.text() === messages.strHideQueryBox) {
$link.text(messages.strShowQueryBox);
} else {
$link.text(messages.strHideQueryBox);
}
/** avoid default click action */
return false;
});
/** don't show it until we have results on-screen */
/**
* Changing the displayed text according to
* the hide/show criteria in search criteria form
*/
$('#togglesearchformlink')
.html(messages.strShowSearchCriteria)
.on('click', function () {
let $link = $(this);
$('#db_search_form').slideToggle();
if ($link.text() === messages.strHideSearchCriteria) {
$link.text(messages.strShowSearchCriteria);
} else {
$link.text(messages.strHideSearchCriteria);
}
/** avoid default click action */
return false;
});
/*
* Ajax Event handler for retrieving the results from a table
*/
$(document).on('click', 'a.browse_results', function (e) {
e.preventDefault();
/** Hides the results shown by the delete criteria */
let $msg = PMA_ajaxShowMessage(messages.strBrowsing, false);
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
/** Load the browse results to the page */
$('#table-info').show();
let table_name = $(this).data('table-name');
$('#table-link').attr({ 'href' : $(this).attr('href') }).text(table_name);
let url = `${$(this).attr('href')}
#searchresults`;
let browse_sql = $(this).data('browse-sql');
let params = {
'ajax_request': true,
'is_js_confirmed': true,
'sql_query' : browse_sql
};
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success) {
$('#browse-results').html(data.message);
PMA_ajaxRemoveMessage($msg);
$('.table_results').each(function () {
PMA_makegrid(this);
});
$('#browse-results').show();
PMA_highlightSQL($('#browse-results'));
$('html, body')
.animate({
scrollTop: $('#browse-results').offset().top
}, 1000);
} else {
PMA_ajaxShowMessage(data.error, false);
}
});
});
/*
* Ajax Event handler for deleting the results from a table
*/
$(document).on('click', 'a.delete_results', function (e) {
e.preventDefault();
/** Hides the results shown by the browse criteria */
$('#table-info').hide();
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
/** Conformation message for deletion */
let msg = PMA_sprintf(
messages.strConfirmDeleteResults,
$(this).data('table-name')
);
if (confirm(msg)) {
let $msg = PMA_ajaxShowMessage(messages.strDeleting, false);
/** Load the deleted option to the page*/
$('#sqlqueryform').html('');
let params = {
'ajax_request': true,
'is_js_confirmed': true,
'sql_query': $(this).data('delete-sql')
};
let url = $(this).attr('href');
$.post(url, params, function (data) {
if (typeof data === 'undefined' || !data.success) {
PMA_ajaxShowMessage(data.error, false);
return;
}
$('#sqlqueryform').html(data.sql_query);
/** Refresh the search results after the deletion */
document.getElementById('buttonGo').click();
$('#togglequerybox').html(messages.strHideQueryBox);
/** Show the results of the deletion option */
$('#browse-results').hide();
$('#sqlqueryform').show();
$('#togglequerybox').show();
$('html, body')
.animate({
scrollTop: $('#browse-results').offset().top
}, 1000);
PMA_ajaxRemoveMessage($msg);
});
}
});
/**
* Ajax Event handler for retrieving the result of an SQL Query
*/
$(document).on('submit', '#db_search_form.ajax', function (event) {
event.preventDefault();
var $msgbox = PMA_ajaxShowMessage(messages.strSearching, false);
// jQuery object to reuse
var $form = $(this);
PMA_prepareForAjaxRequest($form);
var url = `${$form.serialize()}
${PMA_commonParams.get('arg_separator')}submit_search=${$('#buttonGo').val()}`;
$.post($form.attr('action'), url, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
// found results
$('#searchresults').html(data.message);
$('#togglesearchresultlink')
// always start with the Show message
.text(messages.strHideSearchResults);
$('#togglesearchresultsdiv')
// now it's time to show the div containing the link
.show();
$('#searchresults').show();
$('#db_search_form')
// workaround for Chrome problem (bug #3168569)
.slideToggle()
.hide();
$('#togglesearchformlink')
// always start with the Show message
.text(messages.strShowSearchCriteria);
$('#togglesearchformdiv')
// now it's time to show the div containing the link
.show();
} else {
// error message (zero rows)
$('#searchresults').html(data.error).show();
}
PMA_ajaxRemoveMessage($msgbox);
});
});
}

View File

@ -251,7 +251,7 @@ function onloadExportOptions () {
.parent()
.fadeTo('fast', 0.4);
Export.setupTableStructureOrData();
Export.setupTableStructureOrData();
}
/**

284
js/src/functions.js Normal file
View File

@ -0,0 +1,284 @@
import { AJAX } from './ajax';
import CommonParams from './variables/common_params';
import { PMA_Messages as PMA_messages } from './variables/export_variables';
// Sql based imports
import { PMA_getSQLEditor, bindCodeMirrorToInlineEditor } from './functions/Sql/SqlEditor';
import { sqlQueryOptions, updateQueryParameters, PMA_highlightSQL } from './utils/sql';
import { PMA_handleSimulateQueryButton, insertQuery, checkSqlQuery } from './functions/Sql/SqlQuery';
import { escapeHtml } from './utils/Sanitise';
import { getForeignKeyCheckboxLoader, loadForeignKeyCheckbox } from './functions/Sql/ForeignKey';
/**
* Here we register a function that will remove the onsubmit event from all
* forms that will be handled by the generic page loader. We then save this
* event handler in the "jQuery data", so that we can fire it up later in
* AJAX.requestHandler().
*
* See bug #3583316
*/
export function onload () {
// Registering the onload event for functions.js
// ensures that it will be fired for all pages
$('form').not('.ajax').not('.disableAjax').each(function () {
if ($(this).attr('onsubmit')) {
$(this).data('onsubmit', this.onsubmit).attr('onsubmit', '');
}
});
var $page_content = $('#page_content');
/**
* Workaround for passing submit button name,value on ajax form submit
* by appending hidden element with submit button name and value.
*/
$page_content.on('click', 'form input[type=submit]', function () {
var buttonName = $(this).attr('name');
if (typeof buttonName === 'undefined') {
return;
}
$(this).closest('form').append($('<input/>', {
'type' : 'hidden',
'name' : buttonName,
'value': $(this).val()
}));
});
/**
* Attach event listener to events when user modify visible
* Input,Textarea and select fields to make changes in forms
*/
$page_content.on(
'keyup change',
'form.lock-page textarea, ' +
'form.lock-page input[type="text"], ' +
'form.lock-page input[type="number"], ' +
'form.lock-page select',
{ value:1 },
AJAX.lockPageHandler
);
$page_content.on(
'change',
'form.lock-page input[type="checkbox"], ' +
'form.lock-page input[type="radio"]',
{ value:2 },
AJAX.lockPageHandler
);
/**
* Reset lock when lock-page form reset event is fired
* Note: reset does not bubble in all browser so attach to
* form directly.
*/
$('form.lock-page').on('reset', function (event) {
AJAX.resetLock();
});
}
/**
* Unbind all event handlers before tearing down a page
*/
export function teardown1 () {
$(document).off('click', 'a.themeselect');
$(document).off('change', '.autosubmit');
$('a.take_theme').off('click');
}
export function onload1 () {
/**
* Theme selector.
*/
$(document).on('click', 'a.themeselect', function (e) {
window.open(
e.target,
'themes',
'left=10,top=20,width=510,height=350,scrollbars=yes,status=yes,resizable=yes'
);
return false;
});
/**
* Automatic form submission on change.
*/
$(document).on('change', '.autosubmit', function (e) {
e.preventDefault();
debugger;
console.log($(this).closest('form').submit());
$(this).closest('form').submit();
debugger;
});
/**
* Theme changer.
*/
$('a.take_theme').on('click', function (e) {
var what = this.name;
if (window.opener && window.opener.document.forms.setTheme.elements.set_theme) {
window.opener.document.forms.setTheme.elements.set_theme.value = what;
window.opener.document.forms.setTheme.submit();
window.close();
return false;
}
return true;
});
}
/**
* Attach CodeMirror2 editor to SQL edit area.
*/
export function onloadSqlEditor () {
var $elm = $('#sqlquery');
if ($elm.length > 0) {
if (CommonParams.get('CodemirrorEnable') === true) {
sqlQueryOptions.codemirror_editor = PMA_getSQLEditor($elm);
sqlQueryOptions.codemirror_editor.focus();
sqlQueryOptions.codemirror_editor.on('blur', updateQueryParameters);
} else {
// without codemirror
$elm.focus().on('blur', updateQueryParameters);
}
}
PMA_highlightSQL($('body'));
}
export function teardownSqlEditor () {
if (sqlQueryOptions.codemirror_editor) {
$('#sqlquery').text(sqlQueryOptions.codemirror_editor.getValue());
sqlQueryOptions.codemirror_editor.toTextArea();
sqlQueryOptions.codemirror_editor = false;
}
}
/**
* Unbind all event handlers before tearing down a page
*/
export function teardownSqlInlineEditor () {
$(document).off('click', 'a.inline_edit_sql');
$(document).off('click', 'input#sql_query_edit_save');
$(document).off('click', 'input#sql_query_edit_discard');
$('input.sqlbutton').off('click');
if (sqlQueryOptions.codemirror_editor) {
sqlQueryOptions.codemirror_editor.off('blur');
} else {
$(document).off('blur', '#sqlquery');
}
$(document).off('change', '#parameterized');
$(document).off('click', 'input.sqlbutton');
$('#sqlquery').off('keydown');
$('#sql_query_edit').off('keydown');
if (sqlQueryOptions.codemirror_inline_editor) {
// Copy the sql query to the text area to preserve it.
$('#sql_query_edit').text(sqlQueryOptions.codemirror_inline_editor.getValue());
$(sqlQueryOptions.codemirror_inline_editor.getWrapperElement()).off('keydown');
sqlQueryOptions.codemirror_inline_editor.toTextArea();
sqlQueryOptions.codemirror_inline_editor = false;
}
if (sqlQueryOptions.codemirror_editor) {
$(sqlQueryOptions.codemirror_editor.getWrapperElement()).off('keydown');
}
}
/**
* Jquery Coding for inline editing SQL_QUERY
*/
export function onloadSqlInlineEditor () {
// If we are coming back to the page by clicking forward button
// of the browser, bind the code mirror to inline query editor.
bindCodeMirrorToInlineEditor();
$(document).on('click', 'a.inline_edit_sql', function () {
if ($('#sql_query_edit').length) {
// An inline query editor is already open,
// we don't want another copy of it
return false;
}
var $form = $(this).prev('form');
var sql_query = $form.find('input[name=\'sql_query\']').val().trim();
var $inner_sql = $(this).parent().prev().find('code.sql');
var old_text = $inner_sql.html();
var new_content = '<textarea name="sql_query_edit" id="sql_query_edit">' + escapeHtml(sql_query) + '</textarea>\n';
new_content += getForeignKeyCheckboxLoader();
new_content += '<input type="submit" id="sql_query_edit_save" class="button btnSave" value="' + PMA_messages.strGo + '"/>\n';
new_content += '<input type="button" id="sql_query_edit_discard" class="button btnDiscard" value="' + PMA_messages.strCancel + '"/>\n';
var $editor_area = $('div#inline_editor');
if ($editor_area.length === 0) {
$editor_area = $('<div id="inline_editor_outer"></div>');
$editor_area.insertBefore($inner_sql);
}
$editor_area.html(new_content);
loadForeignKeyCheckbox();
$inner_sql.hide();
bindCodeMirrorToInlineEditor();
return false;
});
$(document).on('click', 'input#sql_query_edit_save', function (e) {
// hide already existing success message
var sql_query;
if (sqlQueryOptions.codemirror_inline_editor) {
sqlQueryOptions.codemirror_inline_editor.save();
sql_query = sqlQueryOptions.codemirror_inline_editor.getValue();
} else {
sql_query = $(this).parent().find('#sql_query_edit').val();
}
var fk_check = $(this).parent().find('#fk_checks').is(':checked');
var $form = $('a.inline_edit_sql').prev('form');
var $fake_form = $('<form>', { action: 'import.php', method: 'post' })
.append($form.find('input[name=server], input[name=db], input[name=table], input[name=token]').clone())
.append($('<input/>', { type: 'hidden', name: 'show_query', value: 1 }))
.append($('<input/>', { type: 'hidden', name: 'is_js_confirmed', value: 0 }))
.append($('<input/>', { type: 'hidden', name: 'sql_query', value: sql_query }))
.append($('<input/>', { type: 'hidden', name: 'fk_checks', value: fk_check ? 1 : 0 }));
if (! checkSqlQuery($fake_form[0])) {
return false;
}
$('.success').hide();
$fake_form.appendTo($('body')).submit();
});
$(document).on('click', 'input#sql_query_edit_discard', function () {
var $divEditor = $('div#inline_editor_outer');
$divEditor.siblings('code.sql').show();
$divEditor.remove();
});
$(document).on('click', 'input.sqlbutton', function (evt) {
insertQuery(evt.target.id);
PMA_handleSimulateQueryButton();
return false;
});
$(document).on('change', '#parameterized', updateQueryParameters);
var $inputUsername = $('#input_username');
if ($inputUsername) {
if ($inputUsername.val() === '') {
$inputUsername.trigger('focus');
} else {
$('#input_password').trigger('focus');
}
}
}
/**
* Unbind all event handlers before tearing down a page
*/
export function teardownCtrlEnterFormSubmit () {
$(document).off('keydown', 'form input, form textarea, form select');
}
export function onloadCtrlEnterFormSubmit () {
/**
* Handle 'Ctrl/Alt + Enter' form submits
*/
$('form input, form textarea, form select').on('keydown', function (e) {
if ((e.ctrlKey && e.which === 13) || (e.altKey && e.which === 13)) {
var $form = $(this).closest('form');
if (! $form.find('input[type="submit"]') ||
! $form.find('input[type="submit"]').trigger('click')
) {
$form.submit();
}
}
});
}

View File

@ -0,0 +1,49 @@
import PMA_commonParams from '../variables/common_params';
function captureURL (url) {
var URL = {};
url = '' + url;
// Exclude the url part till HTTP
url = url.substr(url.search('sql.php'), url.length);
// The url part between ORDER BY and &session_max_rows needs to be replaced.
URL.head = url.substr(0, url.indexOf('ORDER+BY') + 9);
URL.tail = url.substr(url.indexOf('&session_max_rows'), url.length);
return URL;
}
/**
* This function is for navigating to the generated URL
*
* @param object target HTMLAnchor element
* @param object parent HTMLDom Object
*/
export function removeColumnFromMultiSort (target, parent) {
var URL = captureURL(target);
var begin = target.indexOf('ORDER+BY') + 8;
var end = target.indexOf(PMA_commonParams.get('arg_separator') + 'session_max_rows');
// get the names of the columns involved
var between_part = target.substr(begin, end - begin);
var columns = between_part.split('%2C+');
// If the given column is not part of the order clause exit from this function
var index = parent.find('small').length ? parent.find('small').text() : '';
if (index === '') {
return '';
}
// Remove the current clicked column
columns.splice(index - 1, 1);
// If all the columns have been removed dont submit a query with nothing
// After order by clause.
if (columns.length === 0) {
var head = URL.head;
head = head.slice(0,head.indexOf('ORDER+BY'));
URL.head = head;
// removing the last sort order should have priority over what
// is remembered via the RememberSorting directive
URL.tail += PMA_commonParams.get('arg_separator') + 'discard_remembered_sort=1';
}
URL.head = URL.head.substring(URL.head.indexOf('?') + 1);
var middle_part = columns.join('%2C+');
var params = URL.head + middle_part + URL.tail;
return params;
}

View File

@ -0,0 +1,46 @@
import { PMA_messages as PMA_messages } from '../variables//export_variables';
import { PMA_sprintf } from '../utils/sprintf';
import PMA_commonParams from '../variables/common_params';
/**
* Displays a confirmation box before submitting a "DROP/DELETE/ALTER" query.
* This function is called while clicking links
*
* @param theLink object the link
* @param theSqlQuery object the sql query to submit
*
* @return boolean whether to run the query or not
*/
export function confirmLink (theLink, theSqlQuery) {
// Confirmation is not required in the configuration file
// or browser is Opera (crappy js implementation)
if (PMA_messages.strDoYouReally === '' || typeof(window.opera) !== 'undefined') {
return true;
}
var is_confirmed = confirm(PMA_sprintf(PMA_messages.strDoYouReally, theSqlQuery));
if (is_confirmed) {
if (typeof(theLink.href) !== 'undefined') {
theLink.href += PMA_commonParams.get('arg_separator') + 'is_js_confirmed=1';
} else if (typeof(theLink.form) !== 'undefined') {
theLink.form.action += '?is_js_confirmed=1';
}
}
return is_confirmed;
} // end of the 'confirmLink()' function
export function getJSConfirmCommonParam (elem, params) {
var $elem = $(elem);
var sep = PMA_commonParams.get('arg_separator');
if (params) {
// Strip possible leading ?
if (params.substring(0,1) === '?') {
params = params.substr(1);
}
params += sep;
} else {
params = '';
}
params += 'is_js_confirmed=1' + sep + 'ajax_request=true' + sep + 'fk_checks=' + ($elem.find('#fk_checks').is(':checked') ? 1 : 0);
return params;
}

View File

@ -0,0 +1,16 @@
/**
* Return value of a cell in a table.
*/
export function PMA_getCellValue (td) {
var $td = $(td);
if ($td.is('.null')) {
return '';
} else if ((! $td.is('.to_be_saved')
|| $td.is('.set'))
&& $td.data('original_data')
) {
return $td.data('original_data');
} else {
return $td.text();
}
}

View File

@ -0,0 +1,41 @@
/**
* Get the field name for the current field. Required to construct the query
* for grid editing
*
* @param $table_results enclosing results table
* @param $this_field jQuery object that points to the current field's tr
*/
export function getFieldName ($table_results, $this_field) {
var this_field_index = $this_field.index();
// ltr or rtl direction does not impact how the DOM was generated
// check if the action column in the left exist
var left_action_exist = !$table_results.find('th:first').hasClass('draggable');
// number of column span for checkbox and Actions
var left_action_skip = left_action_exist ? $table_results.find('th:first').attr('colspan') - 1 : 0;
// If this column was sorted, the text of the a element contains something
// like <small>1</small> that is useful to indicate the order in case
// of a sort on multiple columns; however, we dont want this as part
// of the column name so we strip it ( .clone() to .end() )
var field_name = $table_results
.find('thead')
.find('th:eq(' + (this_field_index - left_action_skip) + ') a')
.clone() // clone the element
.children() // select all the children
.remove() // remove all of them
.end() // go back to the selected element
.text(); // grab the text
// happens when just one row (headings contain no a)
if (field_name === '') {
var $heading = $table_results.find('thead').find('th:eq(' + (this_field_index - left_action_skip) + ')').children('span');
// may contain column comment enclosed in a span - detach it temporarily to read the column name
var $tempColComment = $heading.children().detach();
field_name = $heading.text();
// re-attach the column comment
$heading.append($tempColComment);
}
field_name = $.trim(field_name);
return field_name;
}

View File

@ -0,0 +1,77 @@
var prevScrollX = 0;
/*
* Set position, left, top, width of sticky_columns div
*/
function setStickyColumnsPosition ($sticky_columns, $table_results, position, top, left, margin_left) {
$sticky_columns
.css('position', position)
.css('top', top)
.css('left', left ? left : 'auto')
.css('margin-left', margin_left ? margin_left : '0px')
.css('width', $table_results.width());
}
/*
* Initialize sticky columns
*/
export function initStickyColumns ($table_results) {
return $('<table class="sticky_columns"></table>')
.insertBefore($table_results)
.css('position', 'fixed')
.css('z-index', '99')
.css('width', $table_results.width())
.css('margin-left', $('#page_content').css('margin-left'))
.css('top', $('#floating_menubar').height())
.css('display', 'none');
}
/*
* Arrange/Rearrange columns in sticky header
*/
export function rearrangeStickyColumns ($sticky_columns, $table_results) {
var $originalHeader = $table_results.find('thead');
var $originalColumns = $originalHeader.find('tr:first').children();
var $clonedHeader = $originalHeader.clone();
// clone width per cell
$clonedHeader.find('tr:first').children().width(function (i,val) {
var width = $originalColumns.eq(i).width();
var is_firefox = navigator.userAgent.indexOf('Firefox') > -1;
if (! is_firefox) {
width += 1;
}
return width;
});
$sticky_columns.empty().append($clonedHeader);
}
/*
* Adjust sticky columns on horizontal/vertical scroll for all tables
*/
export function handleAllStickyColumns () {
$('.sticky_columns').each(function () {
handleStickyColumns($(this), $(this).next('.table_results'));
});
}
/*
* Adjust sticky columns on horizontal/vertical scroll
*/
export function handleStickyColumns ($sticky_columns, $table_results) {
var currentScrollX = $(window).scrollLeft();
var windowOffset = $(window).scrollTop();
var tableStartOffset = $table_results.offset().top;
var tableEndOffset = tableStartOffset + $table_results.height();
if (windowOffset >= tableStartOffset && windowOffset <= tableEndOffset) {
// for horizontal scrolling
if (prevScrollX !== currentScrollX) {
prevScrollX = currentScrollX;
setStickyColumnsPosition($sticky_columns, $table_results, 'absolute', $('#floating_menubar').height() + windowOffset - tableStartOffset);
// for vertical scrolling
} else {
setStickyColumnsPosition($sticky_columns, $table_results, 'fixed', $('#floating_menubar').height(), $('#pma_navigation').width() - currentScrollX, $('#page_content').css('margin-left'));
}
$sticky_columns.show();
} else {
$sticky_columns.hide();
}
}

47
js/src/functions/Print.js Normal file
View File

@ -0,0 +1,47 @@
import { PMA_Messages as PMA_messages } from '../variables/export_variables';
/**
* Produce print preview
*/
export function printPreview () {
$('#printcss').attr('media','all');
createPrintAndBackButtons();
}
/**
* Create print and back buttons in preview page
*/
function createPrintAndBackButtons () {
var back_button = $('<input/>',{
type: 'button',
value: PMA_messages.back,
id: 'back_button_print_view'
});
back_button.on('click', removePrintAndBackButton);
back_button.appendTo('#page_content');
var print_button = $('<input/>',{
type: 'button',
value: PMA_messages.print,
id: 'print_button_print_view'
});
print_button.on('click', printPage);
print_button.appendTo('#page_content');
}
/**
* Remove print and back buttons and revert to normal view
*/
function removePrintAndBackButton () {
$('#printcss').attr('media','print');
$('#back_button_print_view').remove();
$('#print_button_print_view').remove();
}
/**
* Print page
*/
function printPage () {
if (typeof(window.print) !== 'undefined') {
window.print();
}
}

View File

@ -0,0 +1,133 @@
import { PMA_Messages as PMA_messages } from '../../variables/export_variables';
export function getOsDetail (server_os, presetCharts) {
/* Add OS specific system info charts to the preset chart list */
switch (server_os) {
case 'WINNT':
$.extend(presetCharts, {
'cpu': {
title: PMA_messages.strSystemCPUUsage,
series: [{
label: PMA_messages.strAverageLoad
}],
nodes: [{
dataPoints: [{ type: 'cpu', name: 'loadavg' }]
}],
maxYLabel: 100
},
'memory': {
title: PMA_messages.strSystemMemory,
series: [{
label: PMA_messages.strTotalMemory,
fill: true
}, {
dataType: 'memory',
label: PMA_messages.strUsedMemory,
fill: true
}],
nodes: [{ dataPoints: [{ type: 'memory', name: 'MemTotal' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'MemUsed' }], valueDivisor: 1024 }
],
maxYLabel: 0
},
'swap': {
title: PMA_messages.strSystemSwap,
series: [{
label: PMA_messages.strTotalSwap,
fill: true
}, {
label: PMA_messages.strUsedSwap,
fill: true
}],
nodes: [{ dataPoints: [{ type: 'memory', name: 'SwapTotal' }] },
{ dataPoints: [{ type: 'memory', name: 'SwapUsed' }] }
],
maxYLabel: 0
}
});
break;
case 'Linux':
$.extend(presetCharts, {
'cpu': {
title: PMA_messages.strSystemCPUUsage,
series: [{
label: PMA_messages.strAverageLoad
}],
nodes: [{ dataPoints: [{ type: 'cpu', name: 'irrelevant' }], transformFn: 'cpu-linux' }],
maxYLabel: 0
},
'memory': {
title: PMA_messages.strSystemMemory,
series: [
{ label: PMA_messages.strBufferedMemory, fill: true },
{ label: PMA_messages.strUsedMemory, fill: true },
{ label: PMA_messages.strCachedMemory, fill: true },
{ label: PMA_messages.strFreeMemory, fill: true }
],
nodes: [
{ dataPoints: [{ type: 'memory', name: 'Buffers' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'MemUsed' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'Cached' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'MemFree' }], valueDivisor: 1024 }
],
maxYLabel: 0
},
'swap': {
title: PMA_messages.strSystemSwap,
series: [
{ label: PMA_messages.strCachedSwap, fill: true },
{ label: PMA_messages.strUsedSwap, fill: true },
{ label: PMA_messages.strFreeSwap, fill: true }
],
nodes: [
{ dataPoints: [{ type: 'memory', name: 'SwapCached' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'SwapUsed' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'SwapFree' }], valueDivisor: 1024 }
],
maxYLabel: 0
}
});
break;
case 'SunOS':
$.extend(presetCharts, {
'cpu': {
title: PMA_messages.strSystemCPUUsage,
series: [{
label: PMA_messages.strAverageLoad
}],
nodes: [{
dataPoints: [{ type: 'cpu', name: 'loadavg' }]
}],
maxYLabel: 0
},
'memory': {
title: PMA_messages.strSystemMemory,
series: [
{ label: PMA_messages.strUsedMemory, fill: true },
{ label: PMA_messages.strFreeMemory, fill: true }
],
nodes: [
{ dataPoints: [{ type: 'memory', name: 'MemUsed' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'MemFree' }], valueDivisor: 1024 }
],
maxYLabel: 0
},
'swap': {
title: PMA_messages.strSystemSwap,
series: [
{ label: PMA_messages.strUsedSwap, fill: true },
{ label: PMA_messages.strFreeSwap, fill: true }
],
nodes: [
{ dataPoints: [{ type: 'memory', name: 'SwapUsed' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'SwapFree' }], valueDivisor: 1024 }
],
maxYLabel: 0
}
});
break;
}
}

View File

@ -0,0 +1,42 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { $ } from '../../utils/JqueryExtended';
import '../../plugins/jquery/jquery.tablesorter';
// TODO: tablesorter shouldn't sort already sorted columns
/**
* @access public
*
* @param {string} tabid Table id for chart drawing
*
* @return {void}
*/
function initTableSorter (tabid) {
var $table;
var opts;
switch (tabid) {
case 'statustabs_queries':
$table = $('#serverstatusqueriesdetails');
opts = {
sortList: [[3, 1]],
headers: {
1: { sorter: 'fancyNumber' },
2: { sorter: 'fancyNumber' }
}
};
break;
}
$table.tablesorter(opts);
$table.find('tr:first th')
.append('<div class="sorticon"></div>')
.addClass('header');
}
/**
* Module export
*/
export {
initTableSorter
};

View File

@ -0,0 +1,49 @@
import { PMA_getImage } from '../get_image';
import PMA_commonParams from '../../variables/common_params';
import { PMA_Messages as PMA_messages } from '../../variables/export_variables';
/**
* Get checkbox for foreign key checks
*
* @return string
*/
export function getForeignKeyCheckboxLoader () {
var html = '';
html += '<div>';
html += '<div class="load-default-fk-check-value">';
html += PMA_getImage('ajax_clock_small');
html += '</div>';
html += '</div>';
return html;
}
export function loadForeignKeyCheckbox () {
// Load default foreign key check value
var params = {
'ajax_request': true,
'server': PMA_commonParams.get('server'),
'get_default_fk_check_value': true
};
$.get('sql.php', params, function (data) {
var html = '<input type="hidden" name="fk_checks" value="0" />' +
'<input type="checkbox" name="fk_checks" id="fk_checks"' +
(data.default_fk_check_value ? ' checked="checked"' : '') + ' />' +
'<label for="fk_checks">' + PMA_messages.strForeignKeyCheck + '</label>';
$('.load-default-fk-check-value').replaceWith(html);
});
}
function getJSConfirmCommonParam (elem, params) {
var $elem = $(elem);
var sep = PMA_commonParams.get('arg_separator');
if (params) {
// Strip possible leading ?
if (params.substring(0,1) === '?') {
params = params.substr(1);
}
params += sep;
} else {
params = '';
}
params += 'is_js_confirmed=1' + sep + 'ajax_request=true' + sep + 'fk_checks=' + ($elem.find('#fk_checks').is(':checked') ? 1 : 0);
return params;
}

View File

@ -0,0 +1,117 @@
import { sqlQueryOptions } from '../../utils/sql';
import CommonParams from '../../variables/common_params';
import { AJAX } from '../../ajax';
import { codemirrorAutocompleteOnInputRead } from '../../utils/sql';
import CodeMirror from 'codemirror';
import 'codemirror/mode/sql/sql.js';
import 'codemirror/addon/runmode/runmode.js';
import 'codemirror/addon/hint/show-hint.js';
import 'codemirror/addon/hint/sql-hint.js';
import 'codemirror/addon/lint/lint.js';
import '../../plugins/codemirror/sql-lint';
function catchKeypressesFromSqlInlineEdit (event) {
// ctrl-enter is 10 in chrome and ie, but 13 in ff
if ((event.ctrlKey || event.metaKey) && (event.keyCode === 13 || event.keyCode === 10)) {
$('#sql_query_edit_save').trigger('click');
}
}
/**
* Creates an SQL editor which supports auto completing etc.
*
* @param $textarea jQuery object wrapping the textarea to be made the editor
* @param options optional options for CodeMirror
* @param resize optional resizing ('vertical', 'horizontal', 'both')
* @param lintOptions additional options for lint
*/
export function PMA_getSQLEditor ($textarea, options, resize, lintOptions) {
if ($textarea.length > 0 && CommonParams.get('CodemirrorEnable') === true) {
// merge options for CodeMirror
var defaults = {
lineNumbers: true,
matchBrackets: true,
extraKeys: { 'Ctrl-Space': 'autocomplete' },
hintOptions: { 'completeSingle': false, 'completeOnSingleClick': true },
indentUnit: 4,
mode: 'text/x-mysql',
lineWrapping: true
};
if (CommonParams.get('LintEnable')) {
$.extend(defaults, {
gutters: ['CodeMirror-lint-markers'],
lint: {
'getAnnotations': CodeMirror.sqlLint,
'async': true,
'lintOptions': lintOptions
}
});
}
$.extend(true, defaults, options);
// create CodeMirror editor
var codemirrorEditor = CodeMirror.fromTextArea($textarea[0], defaults);
// allow resizing
if (! resize) {
resize = 'vertical';
}
var handles = '';
if (resize === 'vertical') {
handles = 's';
}
if (resize === 'both') {
handles = 'all';
}
if (resize === 'horizontal') {
handles = 'e, w';
}
$(codemirrorEditor.getWrapperElement())
.css('resize', resize)
.resizable({
handles: handles,
resize: function () {
codemirrorEditor.setSize($(this).width(), $(this).height());
}
});
// enable autocomplete
codemirrorEditor.on('inputRead', codemirrorAutocompleteOnInputRead);
// page locking
codemirrorEditor.on('change', function (e) {
e.data = {
value: 3,
content: codemirrorEditor.isClean(),
};
AJAX.lockPageHandler(e);
});
return codemirrorEditor;
}
return null;
}
/**
* Binds the CodeMirror to the text area used to inline edit a query.
*/
export function bindCodeMirrorToInlineEditor () {
var $inline_editor = $('#sql_query_edit');
if ($inline_editor.length > 0) {
if (CommonParams.get('CodemirrorEnable') === true) {
var height = $inline_editor.css('height');
sqlQueryOptions.codemirror_inline_editor = PMA_getSQLEditor($inline_editor);
sqlQueryOptions.codemirror_inline_editor.getWrapperElement().style.height = height;
sqlQueryOptions.codemirror_inline_editor.refresh();
sqlQueryOptions.codemirror_inline_editor.focus();
$(sqlQueryOptions.codemirror_inline_editor.getWrapperElement())
.on('keydown', catchKeypressesFromSqlInlineEdit);
} else {
$inline_editor
.focus()
.on('keydown', catchKeypressesFromSqlInlineEdit);
}
}
}

View File

@ -0,0 +1,57 @@
import { createProfilingChart } from '../chart';
/*
* Profiling Chart
*/
export function makeProfilingChart () {
if ($('#profilingchart').length === 0 ||
$('#profilingchart').html().length !== 0 ||
!$.jqplot || !$.jqplot.Highlighter || !$.jqplot.PieRenderer
) {
return;
}
var data = [];
$.each(JSON.parse($('#profilingChartData').html()), function (key, value) {
data.push([key, parseFloat(value)]);
});
// Remove chart and data divs contents
$('#profilingchart').html('').show();
$('#profilingChartData').html('');
createProfilingChart('profilingchart', data);
}
/*
* initialize profiling data tables
*/
export function initProfilingTables () {
if (!$.tablesorter) {
return;
}
$('#profiletable').tablesorter({
widgets: ['zebra'],
sortList: [[0, 0]],
textExtraction: function (node) {
if (node.children.length > 0) {
return node.children[0].innerHTML;
} else {
return node.innerHTML;
}
}
});
$('#profilesummarytable').tablesorter({
widgets: ['zebra'],
sortList: [[1, 1]],
textExtraction: function (node) {
if (node.children.length > 0) {
return node.children[0].innerHTML;
} else {
return node.innerHTML;
}
}
});
}

View File

@ -0,0 +1,371 @@
import { isStorageSupported } from '../config';
import Cookies from 'js-cookie';
import { sqlQueryOptions } from '../../utils/sql';
import { GlobalVariables, PMA_Messages as PMA_messages } from '../../variables/export_variables';
import { PMA_ajaxShowMessage } from '../../utils/show_ajax_messages';
import { PMA_sprintf } from '../../utils/sprintf';
/**
* Handles 'Simulate query' button on SQL query box.
*
* @return void
*/
export function PMA_handleSimulateQueryButton () {
var update_re = new RegExp('^\\s*UPDATE\\s+((`[^`]+`)|([A-Za-z0-9_$]+))\\s+SET\\s', 'i');
var delete_re = new RegExp('^\\s*DELETE\\s+FROM\\s', 'i');
var query = '';
if (sqlQueryOptions.codemirror_editor) {
query = sqlQueryOptions.codemirror_editor.getValue();
} else {
query = $('#sqlquery').val();
}
var $simulateDml = $('#simulate_dml');
if (update_re.test(query) || delete_re.test(query)) {
if (! $simulateDml.length) {
$('#button_submit_query')
.before('<input type="button" id="simulate_dml"' +
'tabindex="199" value="' +
PMA_messages.strSimulateDML +
'" />');
}
} else {
if ($simulateDml.length) {
$simulateDml.remove();
}
}
}
/**
* Sets current value for query box.
*/
export function setQuery (query) {
if (sqlQueryOptions.codemirror_editor) {
sqlQueryOptions.codemirror_editor.setValue(query);
sqlQueryOptions.codemirror_editor.focus();
} else if (document.sqlform) {
document.sqlform.sql_query.value = query;
document.sqlform.sql_query.focus();
}
}
/**
* Create quick sql statements.
*
*/
export function insertQuery (queryType) {
if (queryType === 'clear') {
setQuery('');
return;
} else if (queryType === 'format') {
if (sqlQueryOptions.codemirror_editor) {
$('#querymessage').html(PMA_messages.strFormatting +
'&nbsp;<img class="ajaxIcon" src="' +
GlobalVariables.pmaThemeImage + 'ajax_clock_small.gif" alt="">');
var href = 'db_sql_format.php';
var params = {
'ajax_request': true,
'sql': sqlQueryOptions.codemirror_editor.getValue()
};
$.ajax({
type: 'POST',
url: href,
data: params,
success: function (data) {
if (data.success) {
sqlQueryOptions.codemirror_editor.setValue(data.sql);
}
$('#querymessage').html('');
}
});
}
return;
} else if (queryType === 'saved') {
if (isStorageSupported('localStorage')
&& typeof window.localStorage.auto_saved_sql !== 'undefined'
) {
setQuery(window.localStorage.auto_saved_sql);
} else if (Cookies.get('auto_saved_sql')) {
setQuery(Cookies.get('auto_saved_sql'));
} else {
PMA_ajaxShowMessage(PMA_messages.strNoAutoSavedQuery);
}
return;
}
var query = '';
var myListBox = document.sqlform.dummy;
var table = document.sqlform.table.value;
if (myListBox.options.length > 0) {
sql_box_locked = true;
var columnsList = '';
var valDis = '';
var editDis = '';
var NbSelect = 0;
for (var i = 0; i < myListBox.options.length; i++) {
NbSelect++;
if (NbSelect > 1) {
columnsList += ', ';
valDis += ',';
editDis += ',';
}
columnsList += myListBox.options[i].value;
valDis += '[value-' + NbSelect + ']';
editDis += myListBox.options[i].value + '=[value-' + NbSelect + ']';
}
if (queryType === 'selectall') {
query = 'SELECT * FROM `' + table + '` WHERE 1';
} else if (queryType === 'select') {
query = 'SELECT ' + columnsList + ' FROM `' + table + '` WHERE 1';
} else if (queryType === 'insert') {
query = 'INSERT INTO `' + table + '`(' + columnsList + ') VALUES (' + valDis + ')';
} else if (queryType === 'update') {
query = 'UPDATE `' + table + '` SET ' + editDis + ' WHERE 1';
} else if (queryType === 'delete') {
query = 'DELETE FROM `' + table + '` WHERE 0';
}
setQuery(query);
sql_box_locked = false;
}
}
/**
* Confirms a "DROP/DELETE/ALTER" query before
* submitting it if required.
* This function is called by the 'checkSqlQuery()' js function.
*
* @param theForm1 object the form
* @param sqlQuery1 string the sql query string
*
* @return boolean whether to run the query or not
*
* @see checkSqlQuery()
*/
function confirmQuery (theForm1, sqlQuery1) {
// Confirmation is not required in the configuration file
if (PMA_messages.strDoYouReally === '') {
return true;
}
// Confirms a "DROP/DELETE/ALTER/TRUNCATE" statement
//
// TODO: find a way (if possible) to use the parser-analyser
// for this kind of verification
// For now, I just added a ^ to check for the statement at
// beginning of expression
var do_confirm_re_0 = new RegExp('^\\s*DROP\\s+(IF EXISTS\\s+)?(TABLE|PROCEDURE)\\s', 'i');
var do_confirm_re_1 = new RegExp('^\\s*ALTER\\s+TABLE\\s+((`[^`]+`)|([A-Za-z0-9_$]+))\\s+DROP\\s', 'i');
var do_confirm_re_2 = new RegExp('^\\s*DELETE\\s+FROM\\s', 'i');
var do_confirm_re_3 = new RegExp('^\\s*TRUNCATE\\s', 'i');
if (do_confirm_re_0.test(sqlQuery1) ||
do_confirm_re_1.test(sqlQuery1) ||
do_confirm_re_2.test(sqlQuery1) ||
do_confirm_re_3.test(sqlQuery1)) {
var message;
if (sqlQuery1.length > 100) {
message = sqlQuery1.substr(0, 100) + '\n ...';
} else {
message = sqlQuery1;
}
var is_confirmed = confirm(PMA_sprintf(PMA_messages.strDoYouReally, message));
// statement is confirmed -> update the
// "is_js_confirmed" form field so the confirm test won't be
// run on the server side and allows to submit the form
if (is_confirmed) {
theForm1.elements.is_js_confirmed.value = 1;
return true;
} else {
// statement is rejected -> do not submit the form
window.focus();
return false;
} // end if (handle confirm box result)
} // end if (display confirm box)
return true;
} // end of the 'confirmQuery()' function
/**
* Displays an error message if the user submitted the sql query form with no
* sql query, else checks for "DROP/DELETE/ALTER" statements
*
* @param theForm object the form
*
* @return boolean always false
*
* @see confirmQuery()
*/
export function checkSqlQuery (theForm) {
// get the textarea element containing the query
var sqlQuery;
if (sqlQueryOptions.codemirror_editor) {
sqlQueryOptions.codemirror_editor.save();
sqlQuery = sqlQueryOptions.codemirror_editor.getValue();
} else {
sqlQuery = theForm.elements.sql_query.value;
}
var space_re = new RegExp('\\s+');
if (typeof(theForm.elements.sql_file) !== 'undefined' &&
theForm.elements.sql_file.value.replace(space_re, '') !== '') {
return true;
}
if (typeof(theForm.elements.id_bookmark) !== 'undefined' &&
(theForm.elements.id_bookmark.value !== null || theForm.elements.id_bookmark.value !== '') &&
theForm.elements.id_bookmark.selectedIndex !== 0) {
return true;
}
var result = false;
// Checks for "DROP/DELETE/ALTER" statements
if (sqlQuery.replace(space_re, '') !== '') {
result = confirmQuery(theForm, sqlQuery);
} else {
alert(PMA_messages.strFormEmpty);
}
if (sqlQueryOptions.codemirror_editor) {
sqlQueryOptions.codemirror_editor.focus();
} else if (sqlQueryOptions.codemirror_inline_editor) {
sqlQueryOptions.codemirror_inline_editor.focus();
}
return result;
} // end of the 'checkSqlQuery()' function
export function checkSavedQuery () {
if (isStorageSupported('localStorage')
&& window.localStorage.auto_saved_sql !== undefined
) {
PMA_ajaxShowMessage(PMA_messages.strPreviousSaveQuery);
}
}
/**
* Set query to codemirror if show this query is
* checked and query for the db and table pair exists
*/
export function setShowThisQuery () {
var db = $('input[name="db"]').val();
var table = $('input[name="table"]').val();
if (isStorageSupported('localStorage')) {
if (window.localStorage.show_this_query_object !== undefined) {
var stored_db = JSON.parse(window.localStorage.show_this_query_object).db;
var stored_table = JSON.parse(window.localStorage.show_this_query_object).table;
var stored_query = JSON.parse(window.localStorage.show_this_query_object).query;
}
if (window.localStorage.show_this_query !== undefined
&& window.localStorage.show_this_query === '1') {
$('input[name="show_query"]').prop('checked', true);
if ((db === stored_db && table === stored_table) || (db === undefined && table === undefined)) {
if (sqlQueryOptions.codemirror_editor) {
sqlQueryOptions.codemirror_editor.setValue(stored_query);
} else if (document.sqlform) {
document.sqlform.sql_query.value = stored_query;
}
}
} else {
$('input[name="show_query"]').prop('checked', false);
}
}
}
/**
* Saves SQL query in local storage or cookie
*
* @param string database name
* @param string table name
* @param string SQL query
* @return void
*/
export function PMA_showThisQuery (db, table, query) {
var show_this_query_object = {
'db': db,
'table': table,
'query': query
};
if (isStorageSupported('localStorage')) {
window.localStorage.show_this_query = 1;
window.localStorage.show_this_query_object = JSON.stringify(show_this_query_object);
} else {
Cookies.set('show_this_quey', 1);
Cookies.set('show_this_query_object', JSON.stringify(show_this_query_object));
}
}
/**
* Saves SQL query in local storage or cookie
*
* @param string SQL query
* @return void
*/
export function PMA_autosaveSQL (query) {
if (isStorageSupported('localStorage')) {
window.localStorage.auto_saved_sql = query;
} else {
Cookies.set('auto_saved_sql', query);
}
}
/**
* Saves SQL query with sort in local storage or cookie
*
* @param string SQL query
* @return void
*/
export function PMA_autosaveSQLSort (query) {
if (query) {
if (isStorageSupported('localStorage')) {
window.localStorage.auto_saved_sql_sort = query;
} else {
Cookies.set('auto_saved_sql_sort', query);
}
}
}
/**
* Inserts multiple fields.
*
*/
export function insertValueQuery () {
var myQuery = document.sqlform.sql_query;
var myListBox = document.sqlform.dummy;
if (myListBox.options.length > 0) {
sql_box_locked = true;
var columnsList = '';
var NbSelect = 0;
for (var i = 0; i < myListBox.options.length; i++) {
if (myListBox.options[i].selected) {
NbSelect++;
if (NbSelect > 1) {
columnsList += ', ';
}
columnsList += myListBox.options[i].value;
}
}
/* CodeMirror support */
if (sqlQueryOptions.codemirror_editor) {
sqlQueryOptions.codemirror_editor.replaceSelection(columnsList);
sqlQueryOptions.codemirror_editor.focus();
// IE support
} else if (document.selection) {
myQuery.focus();
var sel = document.selection.createRange();
sel.text = columnsList;
// MOZILLA/NETSCAPE support
} else if (document.sqlform.sql_query.selectionStart || document.sqlform.sql_query.selectionStart === '0') {
var startPos = document.sqlform.sql_query.selectionStart;
var endPos = document.sqlform.sql_query.selectionEnd;
var SqlString = document.sqlform.sql_query.value;
myQuery.value = SqlString.substring(0, startPos) + columnsList + SqlString.substring(endPos, SqlString.length);
myQuery.focus();
} else {
myQuery.value += columnsList;
}
sql_box_locked = false;
}
}

View File

@ -0,0 +1,50 @@
/**
* Updates an element containing code.
*
* @param jQuery Object $base base element which contains the raw and the
* highlighted code.
*
* @param string htmlValue code in HTML format, displayed if code cannot be
* highlighted
*
* @param string rawValue raw code, used as a parameter for highlighter
*
* @return bool whether content was updated or not
*/
export function PMA_updateCode ($base, htmlValue, rawValue) {
var $code = $base.find('code');
if ($code.length === 0) {
return false;
}
// Determines the type of the content and appropriate CodeMirror mode.
var type = '';
var mode = '';
if ($code.hasClass('json')) {
type = 'json';
mode = 'application/json';
} else if ($code.hasClass('sql')) {
type = 'sql';
mode = 'text/x-mysql';
} else if ($code.hasClass('xml')) {
type = 'xml';
mode = 'application/xml';
} else {
return false;
}
// Element used to display unhighlighted code.
var $notHighlighted = $('<pre>' + htmlValue + '</pre>');
// Tries to highlight code using CodeMirror.
if (typeof CodeMirror !== 'undefined') {
var $highlighted = $('<div class="' + type + '-highlight cm-s-default"></div>');
CodeMirror.runMode(rawValue, mode, $highlighted[0]);
$notHighlighted.hide();
$code.html('').append($notHighlighted, $highlighted[0]);
} else {
$code.html('').append($notHighlighted);
}
return true;
}

View File

@ -2,11 +2,14 @@
* Creates a Profiling Chart. Used in sql.js
* and in server_status_monitor.js
*/
import { $ } from '../utils/JqueryExtended';
import JQPlotChartFactory from '../classes/Chart';
import { ChartType, ColumnType, DataTable } from '../classes/Chart';
export function PMA_createProfilingChart (target, data) {
export function createProfilingChart (target, data) {
// create the chart
var factory = new JQPlotChartFactory();
console.log(factory);
var chart = factory.createChart(ChartType.PIE, target);
// create the data table and add columns
@ -62,5 +65,6 @@ export function PMA_createProfilingChart (target, data) {
'#2e3436'
]
});
console.log(chart);
return chart;
}

View File

@ -26,7 +26,7 @@ export function isStorageSupported (type, warn) {
}
return false;
}
/** ******************** Common Functions for Srttings page ****************** */
/** ******************** Common Functions for Settings page ****************** */
/**
* Checks whether field has its default value
*
@ -126,6 +126,8 @@ export function setFieldValue (field, field_type, value) {
* Returns field type
*
* @param {Element} field
*
* @return {string}
*/
export function getFieldType (field) {
var $field = $(field);
@ -321,7 +323,8 @@ export function setupRestoreField () {
var field_sel;
if ($(this).hasClass('restore-default')) {
field_sel = href;
restoreField(field_sel.substr(1), defaultValues);
console.log(field_sel);
restoreField(field_sel.substr(1));
} else {
field_sel = href.match(/^[^=]+/)[0];
var value = href.match(/\=(.+)$/)[1];

View File

@ -4,7 +4,7 @@
* Module import
*/
import './variables/import_variables';
import { jQuery as $ } from './utils/JqueryExtended';
import { $ } from './utils/JqueryExtended';
import { AJAX } from './ajax';
import './variables/get_config';
import files from './consts/files';
@ -15,9 +15,6 @@ import { escapeHtml } from './utils/Sanitise';
import { PMA_ajaxShowMessage } from './utils/show_ajax_messages';
import PMA_commonParams from './variables/common_params';
// console.log(PMA_messages);
// console.log(PMA_ajaxShowMessage);
/**
* Page load event handler
*/
@ -116,7 +113,6 @@ $(document).ajaxError(function (event, request, settings) {
for (let i in files.global) {
AJAX.scriptHandler.add(files.global[i]);
}
/**
* This block of code is for importing javascript files needed
* for the first time loading of the page.
@ -133,10 +129,6 @@ if (typeof files[firstPage] !== 'undefined' && firstPage.toLocaleLowerCase() !==
for (let i in files[indexPage]) {
AJAX.scriptHandler.add(files[indexPage][i], 1);
}
} else if (typeof files[indexPage] !== 'undefined' && firstPage.toLocaleLowerCase() === 'index') {
for (let i in files[indexPage]) {
AJAX.scriptHandler.add(files[indexPage][i]);
}
}
$(function () {

View File

@ -0,0 +1,41 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
import PMA_commonParams from './variables/common_params';
import { PMA_ajaxShowMessage } from './utils/show_ajax_messages';
import { AJAX } from './ajax';
import { removeColumnFromMultiSort } from './functions/ColumnSorting';
/**
* @fileoverview Implements the shiftkey + click remove column
* from order by clause funcationality
* @name columndelete
*
* @requires jQuery
*/
export function onloadMultiColumnSort () {
$(document).on('click', 'th.draggable.column_heading.pointer.marker a', function (event) {
var url = $(this).parent().find('input').val();
var argsep = PMA_commonParams.get('arg_separator');
if (event.ctrlKey || event.altKey) {
event.preventDefault();
let params = removeColumnFromMultiSort(url, $(this).parent());
if (params) {
AJAX.source = $(this);
PMA_ajaxShowMessage();
params += argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
$.post('sql.php', params, AJAX.responseHandler);
}
} else if (event.shiftKey) {
event.preventDefault();
AJAX.source = $(this);
PMA_ajaxShowMessage();
let params = url.substring(url.indexOf('?') + 1);
params += argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
$.post('sql.php', params, AJAX.responseHandler);
}
});
}
export function teardownMultiColumnSort () {
$(document).off('click', 'th.draggable.column_heading.pointer.marker a');
}

View File

@ -0,0 +1,41 @@
import CodeMirror from 'codemirror';
import CommonParams from '../../variables/common_params';
CodeMirror.sqlLint = function (text, updateLinting, options, cm) {
// Skipping check if text box is empty.
if (text.trim() === '') {
updateLinting(cm, []);
return;
}
function handleResponse (response) {
var found = [];
for (var idx in response) {
found.push({
from: CodeMirror.Pos(
response[idx].fromLine, response[idx].fromColumn
),
to: CodeMirror.Pos(
response[idx].toLine, response[idx].toColumn
),
messageHTML: response[idx].message,
severity : response[idx].severity
});
}
updateLinting(cm, found);
}
$.ajax({
method: 'POST',
url: 'lint.php',
dataType: 'json',
data: {
sql_query: text,
server: CommonParams.get('server'),
options: options.lintOptions,
no_history: true,
},
success: handleResponse
});
};

View File

@ -0,0 +1,46 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* jqplot formatter for byte values
*
* @package phpMyAdmin
*/
(function ($) {
'use strict';
var formatByte = function (val, index) {
var units = [
PMA_messages.strB,
PMA_messages.strKiB,
PMA_messages.strMiB,
PMA_messages.strGiB,
PMA_messages.strTiB,
PMA_messages.strPiB,
PMA_messages.strEiB
];
while (val >= 1024 && index <= 6) {
val /= 1024;
index++;
}
var format = '%.1f';
if (Math.floor(val) === val) {
format = '%.0f';
}
return $.jqplot.sprintf(
format + ' ' + units[index], val
);
};
/**
* The index indicates what unit the incoming data will be in.
* 0 for bytes, 1 for kilobytes and so on...
*/
$.jqplot.byteFormatter = function (index) {
index = index || 0;
return function (format, val) {
if (typeof val === 'number') {
val = parseFloat(val) || 0;
return formatByte(val, index);
} else {
return String(val);
}
};
};
}(jQuery));

View File

@ -0,0 +1,390 @@
/*!
* jQuery hashchange event - v1.3 - 7/21/2010
* http://benalman.com/projects/jquery-hashchange-plugin/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
// Script: jQuery hashchange event
//
// *Version: 1.3, Last updated: 7/21/2010*
//
// Project Home - http://benalman.com/projects/jquery-hashchange-plugin/
// GitHub - http://github.com/cowboy/jquery-hashchange/
// Source - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.js
// (Minified) - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.min.js (0.8kb gzipped)
//
// About: License
//
// Copyright (c) 2010 "Cowboy" Ben Alman,
// Dual licensed under the MIT and GPL licenses.
// http://benalman.com/about/license/
//
// About: Examples
//
// These working examples, complete with fully commented code, illustrate a few
// ways in which this plugin can be used.
//
// hashchange event - http://benalman.com/code/projects/jquery-hashchange/examples/hashchange/
// document.domain - http://benalman.com/code/projects/jquery-hashchange/examples/document_domain/
//
// About: Support and Testing
//
// Information about what version or versions of jQuery this plugin has been
// tested with, what browsers it has been tested in, and where the unit tests
// reside (so you can test it yourself).
//
// jQuery Versions - 1.2.6, 1.3.2, 1.4.1, 1.4.2
// Browsers Tested - Internet Explorer 6-8, Firefox 2-4, Chrome 5-6, Safari 3.2-5,
// Opera 9.6-10.60, iPhone 3.1, Android 1.6-2.2, BlackBerry 4.6-5.
// Unit Tests - http://benalman.com/code/projects/jquery-hashchange/unit/
//
// About: Known issues
//
// While this jQuery hashchange event implementation is quite stable and
// robust, there are a few unfortunate browser bugs surrounding expected
// hashchange event-based behaviors, independent of any JavaScript
// window.onhashchange abstraction. See the following examples for more
// information:
//
// Chrome: Back Button - http://benalman.com/code/projects/jquery-hashchange/examples/bug-chrome-back-button/
// Firefox: Remote XMLHttpRequest - http://benalman.com/code/projects/jquery-hashchange/examples/bug-firefox-remote-xhr/
// WebKit: Back Button in an Iframe - http://benalman.com/code/projects/jquery-hashchange/examples/bug-webkit-hash-iframe/
// Safari: Back Button from a different domain - http://benalman.com/code/projects/jquery-hashchange/examples/bug-safari-back-from-diff-domain/
//
// Also note that should a browser natively support the window.onhashchange
// event, but not report that it does, the fallback polling loop will be used.
//
// About: Release History
//
// 1.3 - (7/21/2010) Reorganized IE6/7 Iframe code to make it more
// "removable" for mobile-only development. Added IE6/7 document.title
// support. Attempted to make Iframe as hidden as possible by using
// techniques from http://www.paciellogroup.com/blog/?p=604. Added
// support for the "shortcut" format $(window).hashchange( fn ) and
// $(window).hashchange() like jQuery provides for built-in events.
// Renamed jQuery.hashchangeDelay to <jQuery.fn.hashchange.delay> and
// lowered its default value to 50. Added <jQuery.fn.hashchange.domain>
// and <jQuery.fn.hashchange.src> properties plus document-domain.html
// file to address access denied issues when setting document.domain in
// IE6/7.
// 1.2 - (2/11/2010) Fixed a bug where coming back to a page using this plugin
// from a page on another domain would cause an error in Safari 4. Also,
// IE6/7 Iframe is now inserted after the body (this actually works),
// which prevents the page from scrolling when the event is first bound.
// Event can also now be bound before DOM ready, but it won't be usable
// before then in IE6/7.
// 1.1 - (1/21/2010) Incorporated document.documentMode test to fix IE8 bug
// where browser version is incorrectly reported as 8.0, despite
// inclusion of the X-UA-Compatible IE=EmulateIE7 meta tag.
// 1.0 - (1/9/2010) Initial Release. Broke out the jQuery BBQ event.special
// window.onhashchange functionality into a separate plugin for users
// who want just the basic event & back button support, without all the
// extra awesomeness that BBQ provides. This plugin will be included as
// part of jQuery BBQ, but also be available separately.
(function($,window,undefined){
'$:nomunge'; // Used by YUI compressor.
// Reused string.
var str_hashchange = 'hashchange',
// Method / object references.
doc = document,
fake_onhashchange,
special = $.event.special,
// Does the browser support window.onhashchange? Note that IE8 running in
// IE7 compatibility mode reports true for 'onhashchange' in window, even
// though the event isn't supported, so also test document.documentMode.
doc_mode = doc.documentMode,
supports_onhashchange = 'on' + str_hashchange in window && ( doc_mode === undefined || doc_mode > 7 );
// Get location.hash (or what you'd expect location.hash to be) sans any
// leading #. Thanks for making this necessary, Firefox!
function get_fragment( url ) {
url = url || location.href;
return '#' + url.replace( /^[^#]*#?(.*)$/, '$1' );
};
// Method: jQuery.fn.hashchange
//
// Bind a handler to the window.onhashchange event or trigger all bound
// window.onhashchange event handlers. This behavior is consistent with
// jQuery's built-in event handlers.
//
// Usage:
//
// > jQuery(window).hashchange( [ handler ] );
//
// Arguments:
//
// handler - (Function) Optional handler to be bound to the hashchange
// event. This is a "shortcut" for the more verbose form:
// jQuery(window).bind( 'hashchange', handler ). If handler is omitted,
// all bound window.onhashchange event handlers will be triggered. This
// is a shortcut for the more verbose
// jQuery(window).trigger( 'hashchange' ). These forms are described in
// the <hashchange event> section.
//
// Returns:
//
// (jQuery) The initial jQuery collection of elements.
// Allow the "shortcut" format $(elem).hashchange( fn ) for binding and
// $(elem).hashchange() for triggering, like jQuery does for built-in events.
$.fn[ str_hashchange ] = function( fn ) {
return fn ? this.bind( str_hashchange, fn ) : this.trigger( str_hashchange );
};
// Property: jQuery.fn.hashchange.delay
//
// The numeric interval (in milliseconds) at which the <hashchange event>
// polling loop executes. Defaults to 50.
// Property: jQuery.fn.hashchange.domain
//
// If you're setting document.domain in your JavaScript, and you want hash
// history to work in IE6/7, not only must this property be set, but you must
// also set document.domain BEFORE jQuery is loaded into the page. This
// property is only applicable if you are supporting IE6/7 (or IE8 operating
// in "IE7 compatibility" mode).
//
// In addition, the <jQuery.fn.hashchange.src> property must be set to the
// path of the included "document-domain.html" file, which can be renamed or
// modified if necessary (note that the document.domain specified must be the
// same in both your main JavaScript as well as in this file).
//
// Usage:
//
// jQuery.fn.hashchange.domain = document.domain;
// Property: jQuery.fn.hashchange.src
//
// If, for some reason, you need to specify an Iframe src file (for example,
// when setting document.domain as in <jQuery.fn.hashchange.domain>), you can
// do so using this property. Note that when using this property, history
// won't be recorded in IE6/7 until the Iframe src file loads. This property
// is only applicable if you are supporting IE6/7 (or IE8 operating in "IE7
// compatibility" mode).
//
// Usage:
//
// jQuery.fn.hashchange.src = 'path/to/file.html';
$.fn[ str_hashchange ].delay = 50;
/*
$.fn[ str_hashchange ].domain = null;
$.fn[ str_hashchange ].src = null;
*/
// Event: hashchange event
//
// Fired when location.hash changes. In browsers that support it, the native
// HTML5 window.onhashchange event is used, otherwise a polling loop is
// initialized, running every <jQuery.fn.hashchange.delay> milliseconds to
// see if the hash has changed. In IE6/7 (and IE8 operating in "IE7
// compatibility" mode), a hidden Iframe is created to allow the back button
// and hash-based history to work.
//
// Usage as described in <jQuery.fn.hashchange>:
//
// > // Bind an event handler.
// > jQuery(window).hashchange( function(e) {
// > var hash = location.hash;
// > ...
// > });
// >
// > // Manually trigger the event handler.
// > jQuery(window).hashchange();
//
// A more verbose usage that allows for event namespacing:
//
// > // Bind an event handler.
// > jQuery(window).bind( 'hashchange', function(e) {
// > var hash = location.hash;
// > ...
// > });
// >
// > // Manually trigger the event handler.
// > jQuery(window).trigger( 'hashchange' );
//
// Additional Notes:
//
// * The polling loop and Iframe are not created until at least one handler
// is actually bound to the 'hashchange' event.
// * If you need the bound handler(s) to execute immediately, in cases where
// a location.hash exists on page load, via bookmark or page refresh for
// example, use jQuery(window).hashchange() or the more verbose
// jQuery(window).trigger( 'hashchange' ).
// * The event can be bound before DOM ready, but since it won't be usable
// before then in IE6/7 (due to the necessary Iframe), recommended usage is
// to bind it inside a DOM ready handler.
// Override existing $.event.special.hashchange methods (allowing this plugin
// to be defined after jQuery BBQ in BBQ's source code).
special[ str_hashchange ] = $.extend( special[ str_hashchange ], {
// Called only when the first 'hashchange' event is bound to window.
setup: function() {
// If window.onhashchange is supported natively, there's nothing to do..
if ( supports_onhashchange ) { return false; }
// Otherwise, we need to create our own. And we don't want to call this
// until the user binds to the event, just in case they never do, since it
// will create a polling loop and possibly even a hidden Iframe.
$( fake_onhashchange.start );
},
// Called only when the last 'hashchange' event is unbound from window.
teardown: function() {
// If window.onhashchange is supported natively, there's nothing to do..
if ( supports_onhashchange ) { return false; }
// Otherwise, we need to stop ours (if possible).
$( fake_onhashchange.stop );
}
});
// fake_onhashchange does all the work of triggering the window.onhashchange
// event for browsers that don't natively support it, including creating a
// polling loop to watch for hash changes and in IE 6/7 creating a hidden
// Iframe to enable back and forward.
fake_onhashchange = (function(){
var self = {},
timeout_id,
// Remember the initial hash so it doesn't get triggered immediately.
last_hash = get_fragment(),
fn_retval = function(val){ return val; },
history_set = fn_retval,
history_get = fn_retval;
// Start the polling loop.
self.start = function() {
timeout_id || poll();
};
// Stop the polling loop.
self.stop = function() {
timeout_id && clearTimeout( timeout_id );
timeout_id = undefined;
};
// This polling loop checks every $.fn.hashchange.delay milliseconds to see
// if location.hash has changed, and triggers the 'hashchange' event on
// window when necessary.
function poll() {
var hash = get_fragment(),
history_hash = history_get( last_hash );
if ( hash !== last_hash ) {
history_set( last_hash = hash, history_hash );
$(window).trigger( str_hashchange );
} else if ( history_hash !== last_hash ) {
location.href = location.href.replace( /#.*/, '' ) + history_hash;
}
timeout_id = setTimeout( poll, $.fn[ str_hashchange ].delay );
};
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// vvvvvvvvvvvvvvvvvvv REMOVE IF NOT SUPPORTING IE6/7/8 vvvvvvvvvvvvvvvvvvv
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
(window.navigator.userAgent.indexOf("MSIE ") > -1 || !!window.navigator.userAgent.match(/Trident.*rv\:11\./)) && !supports_onhashchange && (function(){
// Not only do IE6/7 need the "magical" Iframe treatment, but so does IE8
// when running in "IE7 compatibility" mode.
var iframe,
iframe_src;
// When the event is bound and polling starts in IE 6/7, create a hidden
// Iframe for history handling.
self.start = function(){
if ( !iframe ) {
iframe_src = $.fn[ str_hashchange ].src;
iframe_src = iframe_src && iframe_src + get_fragment();
// Create hidden Iframe. Attempt to make Iframe as hidden as possible
// by using techniques from http://www.paciellogroup.com/blog/?p=604.
iframe = $('<iframe tabindex="-1" title="empty"/>').hide()
// When Iframe has completely loaded, initialize the history and
// start polling.
.one( 'load', function(){
iframe_src || history_set( get_fragment() );
poll();
})
// Load Iframe src if specified, otherwise nothing.
.attr( 'src', iframe_src || 'javascript:0' )
// Append Iframe after the end of the body to prevent unnecessary
// initial page scrolling (yes, this works).
.insertAfter( 'body' )[0].contentWindow;
// Whenever `document.title` changes, update the Iframe's title to
// prettify the back/next history menu entries. Since IE sometimes
// errors with "Unspecified error" the very first time this is set
// (yes, very useful) wrap this with a try/catch block.
doc.onpropertychange = function(){
try {
if ( event.propertyName === 'title' ) {
iframe.document.title = doc.title;
}
} catch(e) {}
};
}
};
// Override the "stop" method since an IE6/7 Iframe was created. Even
// if there are no longer any bound event handlers, the polling loop
// is still necessary for back/next to work at all!
self.stop = fn_retval;
// Get history by looking at the hidden Iframe's location.hash.
history_get = function() {
return get_fragment( iframe.location.href );
};
// Set a new history item by opening and then closing the Iframe
// document, *then* setting its location.hash. If document.domain has
// been set, update that as well.
history_set = function( hash, history_hash ) {
var iframe_doc = iframe.document,
domain = $.fn[ str_hashchange ].domain;
if ( hash !== history_hash ) {
// Update Iframe with any initial `document.title` that might be set.
iframe_doc.title = doc.title;
// Opening the Iframe's document after it has been closed is what
// actually adds a history entry.
iframe_doc.open();
// Set document.domain for the Iframe document as well, if necessary.
domain && iframe_doc.write( '<script>document.domain="' + domain + '"</script>' );
iframe_doc.close();
// Update the Iframe's hash, for great justice.
iframe.location.hash = hash;
}
};
})();
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// ^^^^^^^^^^^^^^^^^^^ REMOVE IF NOT SUPPORTING IE6/7/8 ^^^^^^^^^^^^^^^^^^^
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
return self;
})();
})(jQuery,window);

View File

@ -0,0 +1,272 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview A jquery plugin that allows drag&drop sorting in tables.
* Coded because JQuery UI sortable doesn't support tables. Also it has no animation
*
* @name Sortable Table JQuery plugin
*
* @requires jQuery
*
*/
/* Options:
$('table').sortableTable({
ignoreRect: { top, left, width, height } - relative coordinates on each element. If the user clicks
in this area, it is not seen as a drag&drop request. Useful for toolbars etc.
events: {
start: callback function when the user starts dragging
drop: callback function after an element has been dropped
}
})
*/
/* Commands:
$('table').sortableTable('init') - equivalent to $('table').sortableTable()
$('table').sortableTable('refresh') - if the table has been changed, refresh correctly assigns all events again
$('table').sortableTable('destroy') - removes all events from the table
*/
/* Setup:
Can be applied on any table, there is just one convention.
Each cell (<td>) has to contain one and only one element (preferably div or span)
which is the actually draggable element.
*/
(function($) {
jQuery.fn.sortableTable = function(method) {
var methods = {
init : function(options) {
var tb = new sortableTableInstance(this, options);
tb.init();
$(this).data('sortableTable',tb);
},
refresh : function( ) {
$(this).data('sortableTable').refresh();
},
destroy : function( ) {
$(this).data('sortableTable').destroy();
}
};
if ( methods[method] ) {
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.sortableTable' );
}
function sortableTableInstance(table, options) {
var down = false;
var $draggedEl, oldCell, previewMove, id;
if(!options) options = {};
/* Mouse handlers on the child elements */
var onMouseUp = function(e) {
dropAt(e.pageX, e.pageY);
}
var onMouseDown = function(e) {
$draggedEl = $(this).children();
if($draggedEl.length == 0) return;
if(options.ignoreRect && insideRect({x: e.pageX - $draggedEl.offset().left, y: e.pageY - $draggedEl.offset().top}, options.ignoreRect)) return;
down = true;
oldCell = this;
//move(e.pageX,e.pageY);
if(options.events && options.events.start)
options.events.start(this);
return false;
}
var globalMouseMove = function(e) {
if(down) {
move(e.pageX,e.pageY);
if(inside($(oldCell), e.pageX, e.pageY)) {
if(previewMove != null) {
moveTo(previewMove);
previewMove = null;
}
} else
$(table).find('td').each(function() {
if(inside($(this), e.pageX, e.pageY)) {
if($(previewMove).attr('class') != $(this).children().first().attr('class')) {
if(previewMove != null) moveTo(previewMove);
previewMove = $(this).children().first();
if(previewMove.length > 0)
moveTo($(previewMove), { pos: {
top: $(oldCell).offset().top - $(previewMove).parent().offset().top,
left: $(oldCell).offset().left - $(previewMove).parent().offset().left
} });
}
return false;
}
});
}
return false;
}
var globalMouseOut = function() {
if(down) {
down = false;
if(previewMove) moveTo(previewMove);
moveTo($draggedEl);
previewMove = null;
}
}
// Initialize sortable table
this.init = function() {
id = 1;
// Add some required css to each child element in the <td>s
$(table).find('td').children().each(function() {
// Remove any old occurences of our added draggable-num class
$(this).attr('class',$(this).attr('class').replace(/\s*draggable\-\d+/g,''));
$(this).addClass('draggable-' + (id++));
});
// Mouse events
$(table).find('td').bind('mouseup',onMouseUp);
$(table).find('td').bind('mousedown',onMouseDown);
$(document).mousemove(globalMouseMove);
$(document).bind('mouseleave', globalMouseOut);
}
// Call this when the table has been updated
this.refresh = function() {
this.destroy();
this.init();
}
this.destroy = function() {
// Add some required css to each child element in the <td>s
$(table).find('td').children().each(function() {
// Remove any old occurences of our added draggable-num class
$(this).attr('class',$(this).attr('class').replace(/\s*draggable\-\d+/g,''));
});
// Mouse events
$(table).find('td').unbind('mouseup',onMouseUp)
$(table).find('td').unbind('mousedown',onMouseDown);
$(document).unbind('mousemove',globalMouseMove);
$(document).unbind('mouseleave',globalMouseOut);
}
function switchElement(drag, dropTo) {
var dragPosDiff = {
left: $(drag).children().first().offset().left - $(dropTo).offset().left,
top: $(drag).children().first().offset().top - $(dropTo).offset().top
};
var dropPosDiff = null;
if($(dropTo).children().length > 0) {
dropPosDiff = {
left: $(dropTo).children().first().offset().left - $(drag).offset().left,
top: $(dropTo).children().first().offset().top - $(drag).offset().top
};
}
/* I love you append(). It moves the DOM Elements so gracefully <3 */
// Put the element in the way to old place
$(drag).append($(dropTo).children().first()).children()
.stop(true,true)
.bind('mouseup',onMouseUp);
if(dropPosDiff)
$(drag).append($(dropTo).children().first()).children()
.css('left',dropPosDiff.left + 'px')
.css('top',dropPosDiff.top + 'px');
// Put our dragged element into the space we just freed up
$(dropTo).append($(drag).children().first()).children()
.bind('mouseup',onMouseUp)
.css('left',dragPosDiff.left + 'px')
.css('top',dragPosDiff.top + 'px');
moveTo($(dropTo).children().first(), { duration: 100 });
moveTo($(drag).children().first(), { duration: 100 });
if(options.events && options.events.drop) {
// Drop event. The drag child element is moved into the drop element
// and vice versa. So the parameters are switched.
// Calculate row and column index
colIdx = $(dropTo).prevAll().length;
rowIdx = $(dropTo).parent().prevAll().length;
options.events.drop(drag,dropTo, { col: colIdx, row: rowIdx });
}
}
function move(x,y) {
$draggedEl.offset({
top: Math.min($(document).height(), Math.max(0, y - $draggedEl.height()/2)),
left: Math.min($(document).width(), Math.max(0, x - $draggedEl.width()/2))
});
}
function inside($el, x,y) {
var off = $el.offset();
return y >= off.top && x >= off.left && x < off.left + $el.width() && y < off.top + $el.height();
}
function insideRect(pos, r) {
return pos.y > r.top && pos.x > r.left && pos.y < r.top + r.height && pos.x < r.left + r.width;
}
function dropAt(x,y) {
if(!down) return;
down = false;
var switched = false;
$(table).find('td').each(function() {
if($(this).children().first().attr('class') != $(oldCell).children().first().attr('class') && inside($(this), x, y)) {
switchElement(oldCell, this);
switched = true;
return;
}
});
if(!switched) {
if(previewMove) moveTo(previewMove);
moveTo($draggedEl);
}
previewMove = null;
}
function moveTo(elem, opts) {
if(!opts) opts = {};
if(!opts.pos) opts.pos = { left: 0, top: 0 };
if(!opts.duration) opts.duration = 200;
$(elem).css('position','relative');
$(elem).animate({ top: opts.pos.top, left: opts.pos.left }, {
duration: opts.duration,
complete: function() {
if(opts.pos.left == 0 && opts.pos.top == 0) {
$(elem)
.css('position','')
.css('left','')
.css('top','');
}
}
});
}
}
}
})( jQuery );

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,117 @@
/*
* Copyright (c) 2008 Greg Weber greg at gregweber.info
* Dual licensed under the MIT and GPLv2 licenses just as jQuery is:
* http://jquery.org/license
*
* Multi-columns fork by natinusala
*
* documentation at http://gregweber.info/projects/uitablefilter
* https://github.com/natinusala/jquery-uitablefilter
*
* allows table rows to be filtered (made invisible)
* <code>
* t = $('table')
* $.uiTableFilter( t, phrase )
* </code>
* arguments:
* jQuery object containing table rows
* phrase to search for
* optional arguments:
* array of columns to limit search too (the column title in the table header)
* ifHidden - callback to execute if one or more elements was hidden
* tdElem - specific element within <td> to be considered for searching or to limit search to,
* default:whole <td>. useful if <td> has more than one elements inside but want to
* limit search within only some of elements or only visible elements. eg tdElem can be "td span"
*/
(function($) {
$.uiTableFilter = function(jq, phrase, column, ifHidden, tdElem){
if(!tdElem) tdElem = "td";
var new_hidden = false;
if( this.last_phrase === phrase ) return false;
var phrase_length = phrase.length;
var words = phrase.toLowerCase().split(" ");
// these function pointers may change
var matches = function(elem) { elem.show() }
var noMatch = function(elem) { elem.hide(); new_hidden = true }
var getText = function(elem) { return elem.text() }
if( column )
{
if (!$.isArray(column))
{
column = new Array(column);
}
var index = new Array();
jq.find("thead > tr:last > th").each(function(i)
{
for (var j = 0; j < column.length; j++)
{
if ($.trim($(this).text()) == column[j])
{
index[j] = i;
break;
}
}
});
getText = function(elem) {
var selector = "";
for (var i = 0; i < index.length; i++)
{
if (i != 0) {selector += ",";}
selector += tdElem + ":eq(" + index[i] + ")";
}
return $(elem.find((selector))).text();
}
}
// if added one letter to last time,
// just check newest word and only need to hide
if( (words.size > 1) && (phrase.substr(0, phrase_length - 1) ===
this.last_phrase) ) {
if( phrase[-1] === " " )
{ this.last_phrase = phrase; return false; }
var words = words[-1]; // just search for the newest word
// only hide visible rows
matches = function(elem) {;}
var elems = jq.find("tbody:first > tr:visible")
}
else {
new_hidden = true;
var elems = jq.find("tbody:first > tr")
}
elems.each(function(){
var elem = $(this);
$.uiTableFilter.has_words( getText(elem), words, false ) ?
matches(elem) : noMatch(elem);
});
this.last_phrase = phrase;
if( ifHidden && new_hidden ) ifHidden();
return jq;
};
// caching for speedup
$.uiTableFilter.last_phrase = ""
// not jQuery dependent
// "" [""] -> Boolean
// "" [""] Boolean -> Boolean
$.uiTableFilter.has_words = function( str, words, caseSensitive )
{
var text = caseSensitive ? str : str.toLowerCase();
for (var i=0; i < words.length; i++) {
if (text.indexOf(words[i]) === -1) return false;
}
return true;
}
}) (jQuery);

View File

@ -15,10 +15,12 @@ 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 { PMA_Messages as messages } from './variables/export_variables';
import { $ } from './utils/JqueryExtended';
import { AJAX } from './ajax';
import CommonParams from './variables/common_params';
import { PMA_reloadNavigation } from './functions/navigation';
import { getJSConfirmCommonParam } from './functions/Common';
/**
* @package PhpMyAdmin

View File

@ -1,5 +1,11 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { $ } from './utils/JqueryExtended';
import './plugins/jquery/jquery.tablesorter';
/**
* @package PhpMyAdmin
*

View File

@ -16,8 +16,8 @@ import { checkPasswordStrength, displayPasswordGenerateButton } from './utils/pa
import { PMA_Messages as messages } from './variables/export_variables';
import { PMA_ajaxShowMessage, PMA_ajaxRemoveMessage } from './utils/show_ajax_messages';
import CommonParams from './variables/common_params';
import { jQuery as $ } from './utils/JqueryExtended';
import { PMA_getSQLEditor } from './utils/sql';
import { $ } from './utils/JqueryExtended';
import { PMA_getSQLEditor } from './functions/Sql/SqlEditor';
/**
* @package PhpMyAdmin

View File

@ -1,4 +1,26 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
import { PMA_Messages as messages } from './variables/export_variables';
import { $ } from './utils/JqueryExtended';
import 'updated-jqplot';
import './plugins/jquery/jquery.sortableTable';
import 'updated-jqplot/dist/plugins/jqplot.pieRenderer.js';
import 'updated-jqplot/dist/plugins/jqplot.enhancedPieLegendRenderer.js';
import 'updated-jqplot/dist/plugins/jqplot.canvasTextRenderer.js';
import 'updated-jqplot/dist/plugins/jqplot.canvasAxisLabelRenderer.js';
import 'updated-jqplot/dist/plugins/jqplot.dateAxisRenderer.js';
import 'updated-jqplot/dist/plugins/jqplot.highlighter.js';
import 'updated-jqplot/dist/plugins/jqplot.cursor.js';
import './plugins/jqplot/jqplot.byteFormatter';
import { getOsDetail } from './functions/Server/ServerStatusMonitor';
import { isStorageSupported } from './functions/config';
import { createProfilingChart } from './functions/chart';
import CommonParams from './variables/common_params';
import { escapeHtml } from './utils/Sanitise';
import { PMA_getImage } from './functions/get_image';
var runtime = {};
var server_time_diff;
var server_os;
@ -160,9 +182,9 @@ export function onload3 () {
var presetCharts = {
// Query cache efficiency
'qce': {
title: PMA_messages.strQueryCacheEfficiency,
title: messages.strQueryCacheEfficiency,
series: [{
label: PMA_messages.strQueryCacheEfficiency
label: messages.strQueryCacheEfficiency
}],
nodes: [{
dataPoints: [{ type: 'statusvar', name: 'Qcache_hits' }, { type: 'statusvar', name: 'Com_select' }],
@ -172,9 +194,9 @@ export function onload3 () {
},
// Query cache usage
'qcu': {
title: PMA_messages.strQueryCacheUsage,
title: messages.strQueryCacheUsage,
series: [{
label: PMA_messages.strQueryCacheUsed
label: messages.strQueryCacheUsed
}],
nodes: [{
dataPoints: [{ type: 'statusvar', name: 'Qcache_free_memory' }, { type: 'servervar', name: 'query_cache_size' }],
@ -188,150 +210,21 @@ export function onload3 () {
var selectionTimeDiff = [];
var selectionStartX;
var selectionStartY;
var selectionEndX;
var selectionEndY;
// var selectionEndX;
// var selectionEndY;
var drawTimeSpan = false;
// chart tooltip
var tooltipBox;
// var tooltipBox;
/* Add OS specific system info charts to the preset chart list */
switch (server_os) {
case 'WINNT':
$.extend(presetCharts, {
'cpu': {
title: PMA_messages.strSystemCPUUsage,
series: [{
label: PMA_messages.strAverageLoad
}],
nodes: [{
dataPoints: [{ type: 'cpu', name: 'loadavg' }]
}],
maxYLabel: 100
},
'memory': {
title: PMA_messages.strSystemMemory,
series: [{
label: PMA_messages.strTotalMemory,
fill: true
}, {
dataType: 'memory',
label: PMA_messages.strUsedMemory,
fill: true
}],
nodes: [{ dataPoints: [{ type: 'memory', name: 'MemTotal' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'MemUsed' }], valueDivisor: 1024 }
],
maxYLabel: 0
},
'swap': {
title: PMA_messages.strSystemSwap,
series: [{
label: PMA_messages.strTotalSwap,
fill: true
}, {
label: PMA_messages.strUsedSwap,
fill: true
}],
nodes: [{ dataPoints: [{ type: 'memory', name: 'SwapTotal' }] },
{ dataPoints: [{ type: 'memory', name: 'SwapUsed' }] }
],
maxYLabel: 0
}
});
break;
case 'Linux':
$.extend(presetCharts, {
'cpu': {
title: PMA_messages.strSystemCPUUsage,
series: [{
label: PMA_messages.strAverageLoad
}],
nodes: [{ dataPoints: [{ type: 'cpu', name: 'irrelevant' }], transformFn: 'cpu-linux' }],
maxYLabel: 0
},
'memory': {
title: PMA_messages.strSystemMemory,
series: [
{ label: PMA_messages.strBufferedMemory, fill: true },
{ label: PMA_messages.strUsedMemory, fill: true },
{ label: PMA_messages.strCachedMemory, fill: true },
{ label: PMA_messages.strFreeMemory, fill: true }
],
nodes: [
{ dataPoints: [{ type: 'memory', name: 'Buffers' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'MemUsed' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'Cached' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'MemFree' }], valueDivisor: 1024 }
],
maxYLabel: 0
},
'swap': {
title: PMA_messages.strSystemSwap,
series: [
{ label: PMA_messages.strCachedSwap, fill: true },
{ label: PMA_messages.strUsedSwap, fill: true },
{ label: PMA_messages.strFreeSwap, fill: true }
],
nodes: [
{ dataPoints: [{ type: 'memory', name: 'SwapCached' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'SwapUsed' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'SwapFree' }], valueDivisor: 1024 }
],
maxYLabel: 0
}
});
break;
case 'SunOS':
$.extend(presetCharts, {
'cpu': {
title: PMA_messages.strSystemCPUUsage,
series: [{
label: PMA_messages.strAverageLoad
}],
nodes: [{
dataPoints: [{ type: 'cpu', name: 'loadavg' }]
}],
maxYLabel: 0
},
'memory': {
title: PMA_messages.strSystemMemory,
series: [
{ label: PMA_messages.strUsedMemory, fill: true },
{ label: PMA_messages.strFreeMemory, fill: true }
],
nodes: [
{ dataPoints: [{ type: 'memory', name: 'MemUsed' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'MemFree' }], valueDivisor: 1024 }
],
maxYLabel: 0
},
'swap': {
title: PMA_messages.strSystemSwap,
series: [
{ label: PMA_messages.strUsedSwap, fill: true },
{ label: PMA_messages.strFreeSwap, fill: true }
],
nodes: [
{ dataPoints: [{ type: 'memory', name: 'SwapUsed' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'SwapFree' }], valueDivisor: 1024 }
],
maxYLabel: 0
}
});
break;
}
getOsDetail(server_os, presetCharts);
// Default setting for the chart grid
var defaultChartGrid = {
'c0': {
title: PMA_messages.strQuestions,
title: messages.strQuestions,
series: [
{ label: PMA_messages.strQuestions }
{ label: messages.strQuestions }
],
nodes: [
{ dataPoints: [{ type: 'statusvar', name: 'Questions' }], display: 'differential' }
@ -339,10 +232,10 @@ export function onload3 () {
maxYLabel: 0
},
'c1': {
title: PMA_messages.strChartConnectionsTitle,
title: messages.strChartConnectionsTitle,
series: [
{ label: PMA_messages.strConnections },
{ label: PMA_messages.strProcesses }
{ label: messages.strConnections },
{ label: messages.strProcesses }
],
nodes: [
{ dataPoints: [{ type: 'statusvar', name: 'Connections' }], display: 'differential' },
@ -351,10 +244,10 @@ export function onload3 () {
maxYLabel: 0
},
'c2': {
title: PMA_messages.strTraffic,
title: messages.strTraffic,
series: [
{ label: PMA_messages.strBytesSent },
{ label: PMA_messages.strBytesReceived }
{ label: messages.strBytesSent },
{ label: messages.strBytesReceived }
],
nodes: [
{ dataPoints: [{ type: 'statusvar', name: 'Bytes_sent' }], display: 'differential', valueDivisor: 1024 },
@ -486,7 +379,7 @@ export function onload3 () {
event.preventDefault();
var dlgButtons = { };
dlgButtons[PMA_messages.strAddChart] = function () {
dlgButtons[messages.strAddChart] = function () {
var type = $('input[name="chartType"]:checked').val();
if (type === 'preset') {
@ -496,7 +389,7 @@ export function onload3 () {
// each time he adds a series
// So here we only warn if he didn't add a series yet
if (! newChart || ! newChart.nodes || newChart.nodes.length === 0) {
alert(PMA_messages.strAddOneSeriesWarning);
alert(messages.strAddOneSeriesWarning);
return;
}
}
@ -512,7 +405,7 @@ export function onload3 () {
$(this).dialog('close');
};
dlgButtons[PMA_messages.strClose] = function () {
dlgButtons[messages.strClose] = function () {
newChart = null;
$('span#clearSeriesLink').hide();
$('#seriesPreview').html('');
@ -553,7 +446,7 @@ export function onload3 () {
buttons: dlgButtons
});
$('#seriesPreview').html('<i>' + PMA_messages.strNone + '</i>');
$('#seriesPreview').html('<i>' + messages.strNone + '</i>');
return false;
});
@ -580,18 +473,18 @@ export function onload3 () {
$('a[href="#importMonitorConfig"]').on('click', function (event) {
event.preventDefault();
$('#emptyDialog').dialog({ title: PMA_messages.strImportDialogTitle });
$('#emptyDialog').html(PMA_messages.strImportDialogMessage + ':<br/><form>' +
$('#emptyDialog').dialog({ title: messages.strImportDialogTitle });
$('#emptyDialog').html(messages.strImportDialogMessage + ':<br/><form>' +
'<input type="file" name="file" id="import_file"> </form>');
var dlgBtns = {};
dlgBtns[PMA_messages.strImport] = function () {
dlgBtns[messages.strImport] = function () {
var input = $('#emptyDialog').find('#import_file')[0];
var reader = new FileReader();
reader.onerror = function (event) {
alert(PMA_messages.strFailedParsingConfig + '\n' + event.target.error.code);
alert(messages.strFailedParsingConfig + '\n' + event.target.error.code);
};
reader.onload = function (e) {
var data = e.target.result;
@ -600,14 +493,14 @@ export function onload3 () {
try {
json = JSON.parse(data);
} catch (err) {
alert(PMA_messages.strFailedParsingConfig);
alert(messages.strFailedParsingConfig);
$('#emptyDialog').dialog('close');
return;
}
// Basic check, is this a monitor config json?
if (!json || ! json.monitorCharts || ! json.monitorCharts) {
alert(PMA_messages.strFailedParsingConfig);
alert(messages.strFailedParsingConfig);
$('#emptyDialog').dialog('close');
return;
}
@ -618,8 +511,7 @@ export function onload3 () {
window.localStorage.monitorSettings = JSON.stringify(json.monitorSettings);
rebuildGrid();
} catch (err) {
console.log(err);
alert(PMA_messages.strFailedBuildingGrid);
alert(messages.strFailedBuildingGrid);
// If an exception is thrown, load default again
if (isStorageSupported('localStorage')) {
window.localStorage.removeItem('monitorCharts');
@ -633,7 +525,7 @@ export function onload3 () {
reader.readAsText(input.files[0]);
};
dlgBtns[PMA_messages.strCancel] = function () {
dlgBtns[messages.strCancel] = function () {
$(this).dialog('close');
};
@ -659,9 +551,9 @@ export function onload3 () {
event.preventDefault();
runtime.redrawCharts = ! runtime.redrawCharts;
if (! runtime.redrawCharts) {
$(this).html(PMA_getImage('play') + PMA_messages.strResumeMonitor);
$(this).html(PMA_getImage('play') + messages.strResumeMonitor);
} else {
$(this).html(PMA_getImage('pause') + PMA_messages.strPauseMonitor);
$(this).html(PMA_getImage('pause') + messages.strPauseMonitor);
if (! runtime.charts) {
initGrid();
$('a[href="#settingsPopup"]').show();
@ -686,7 +578,7 @@ export function onload3 () {
$.extend(vars, getvars);
}
$.get('server_status_monitor.php' + PMA_commonParams.get('common_query'), vars,
$.get('server_status_monitor.php' + CommonParams.get('common_query'), vars,
function (data) {
var logVars;
if (typeof data !== 'undefined' && data.success === true) {
@ -700,40 +592,40 @@ export function onload3 () {
if (logVars.general_log === 'ON') {
if (logVars.slow_query_log === 'ON') {
msg = PMA_messages.strBothLogOn;
msg = messages.strBothLogOn;
} else {
msg = PMA_messages.strGenLogOn;
msg = messages.strGenLogOn;
}
}
if (msg.length === 0 && logVars.slow_query_log === 'ON') {
msg = PMA_messages.strSlowLogOn;
msg = messages.strSlowLogOn;
}
if (msg.length === 0) {
icon = PMA_getImage('s_error');
msg = PMA_messages.strBothLogOff;
msg = messages.strBothLogOff;
}
str = '<b>' + PMA_messages.strCurrentSettings + '</b><br/><div class="smallIndent">';
str = '<b>' + messages.strCurrentSettings + '</b><br/><div class="smallIndent">';
str += icon + msg + '<br />';
if (logVars.log_output !== 'TABLE') {
str += PMA_getImage('s_error') + ' ' + PMA_messages.strLogOutNotTable + '<br />';
str += PMA_getImage('s_error') + ' ' + messages.strLogOutNotTable + '<br />';
} else {
str += PMA_getImage('s_success') + ' ' + PMA_messages.strLogOutIsTable + '<br />';
str += PMA_getImage('s_success') + ' ' + messages.strLogOutIsTable + '<br />';
}
if (logVars.slow_query_log === 'ON') {
if (logVars.long_query_time > 2) {
str += PMA_getImage('s_attention') + ' ';
str += PMA_sprintf(PMA_messages.strSmallerLongQueryTimeAdvice, logVars.long_query_time);
str += PMA_sprintf(messages.strSmallerLongQueryTimeAdvice, logVars.long_query_time);
str += '<br />';
}
if (logVars.long_query_time < 2) {
str += PMA_getImage('s_success') + ' ';
str += PMA_sprintf(PMA_messages.strLongQueryTimeSet, logVars.long_query_time);
str += PMA_sprintf(messages.strLongQueryTimeSet, logVars.long_query_time);
str += '<br />';
}
}
@ -741,9 +633,9 @@ export function onload3 () {
str += '</div>';
if (is_superuser) {
str += '<p></p><b>' + PMA_messages.strChangeSettings + '</b>';
str += '<p></p><b>' + messages.strChangeSettings + '</b>';
str += '<div class="smallIndent">';
str += PMA_messages.strSettingsAppliedGlobal + '<br/>';
str += messages.strSettingsAppliedGlobal + '<br/>';
var varValue = 'TABLE';
if (logVars.log_output === 'TABLE') {
@ -751,26 +643,26 @@ export function onload3 () {
}
str += '- <a class="set" href="#log_output-' + varValue + '">';
str += PMA_sprintf(PMA_messages.strSetLogOutput, varValue);
str += PMA_sprintf(messages.strSetLogOutput, varValue);
str += ' </a><br />';
if (logVars.general_log !== 'ON') {
str += '- <a class="set" href="#general_log-ON">';
str += PMA_sprintf(PMA_messages.strEnableVar, 'general_log');
str += PMA_sprintf(messages.strEnableVar, 'general_log');
str += ' </a><br />';
} else {
str += '- <a class="set" href="#general_log-OFF">';
str += PMA_sprintf(PMA_messages.strDisableVar, 'general_log');
str += PMA_sprintf(messages.strDisableVar, 'general_log');
str += ' </a><br />';
}
if (logVars.slow_query_log !== 'ON') {
str += '- <a class="set" href="#slow_query_log-ON">';
str += PMA_sprintf(PMA_messages.strEnableVar, 'slow_query_log');
str += PMA_sprintf(messages.strEnableVar, 'slow_query_log');
str += ' </a><br />';
} else {
str += '- <a class="set" href="#slow_query_log-OFF">';
str += PMA_sprintf(PMA_messages.strDisableVar, 'slow_query_log');
str += PMA_sprintf(messages.strDisableVar, 'slow_query_log');
str += ' </a><br />';
}
@ -780,10 +672,10 @@ export function onload3 () {
}
str += '- <a class="set" href="#long_query_time-' + varValue + '">';
str += PMA_sprintf(PMA_messages.setSetLongQueryTime, varValue);
str += PMA_sprintf(messages.setSetLongQueryTime, varValue);
str += ' </a><br />';
} else {
str += PMA_messages.strNoSuperUser + '<br/>';
str += messages.strNoSuperUser + '<br/>';
}
str += '</div>';
@ -812,7 +704,7 @@ export function onload3 () {
$('input[name="chartType"]').on('change', function () {
$('#chartVariableSettings').toggle(this.checked && this.value === 'variable');
var title = $('input[name="chartTitle"]').val();
if (title === PMA_messages.strChartTitle ||
if (title === messages.strChartTitle ||
title === $('label[for="' + $('input[name="chartTitle"]').data('lastRadio') + '"]').text()
) {
$('input[name="chartTitle"]')
@ -838,7 +730,7 @@ export function onload3 () {
$('a[href="#kibDivisor"]').on('click', function (event) {
event.preventDefault();
$('input[name="valueDivisor"]').val(1024);
$('input[name="valueUnit"]').val(PMA_messages.strKiB);
$('input[name="valueUnit"]').val(messages.strKiB);
$('span.unitInput').toggle(true);
$('input[name="useUnit"]').prop('checked', true);
return false;
@ -847,7 +739,7 @@ export function onload3 () {
$('a[href="#mibDivisor"]').on('click', function (event) {
event.preventDefault();
$('input[name="valueDivisor"]').val(1024 * 1024);
$('input[name="valueUnit"]').val(PMA_messages.strMiB);
$('input[name="valueUnit"]').val(messages.strMiB);
$('span.unitInput').toggle(true);
$('input[name="useUnit"]').prop('checked', true);
return false;
@ -855,7 +747,7 @@ export function onload3 () {
$('a[href="#submitClearSeries"]').on('click', function (event) {
event.preventDefault();
$('#seriesPreview').html('<i>' + PMA_messages.strNone + '</i>');
$('#seriesPreview').html('<i>' + messages.strNone + '</i>');
newChart = null;
$('#clearSeriesLink').hide();
});
@ -894,9 +786,9 @@ export function onload3 () {
serie.unit = $('input[name="valueUnit"]').val();
}
var str = serie.display === 'differential' ? ', ' + PMA_messages.strDifferential : '';
str += serie.valueDivisor ? (', ' + PMA_sprintf(PMA_messages.strDividedBy, serie.valueDivisor)) : '';
str += serie.unit ? (', ' + PMA_messages.strUnit + ': ' + serie.unit) : '';
var str = serie.display === 'differential' ? ', ' + messages.strDifferential : '';
str += serie.valueDivisor ? (', ' + PMA_sprintf(messages.strDividedBy, serie.valueDivisor)) : '';
str += serie.unit ? (', ' + messages.strUnit + ': ' + serie.unit) : '';
var newSeries = {
label: $('#variableInput').val().replace(/_/g, ' ')
@ -940,11 +832,11 @@ export function onload3 () {
&& typeof window.localStorage.monitorVersion !== 'undefined'
&& monitorProtocolVersion !== window.localStorage.monitorVersion
) {
$('#emptyDialog').dialog({ title: PMA_messages.strIncompatibleMonitorConfig });
$('#emptyDialog').html(PMA_messages.strIncompatibleMonitorConfigDescription);
$('#emptyDialog').dialog({ title: messages.strIncompatibleMonitorConfig });
$('#emptyDialog').html(messages.strIncompatibleMonitorConfigDescription);
var dlgBtns = {};
dlgBtns[PMA_messages.strClose] = function () {
dlgBtns[messages.strClose] = function () {
$(this).dialog('close');
};
@ -1092,25 +984,25 @@ export function onload3 () {
}
};
if (settings.title === PMA_messages.strSystemCPUUsage ||
settings.title === PMA_messages.strQueryCacheEfficiency
if (settings.title === messages.strSystemCPUUsage ||
settings.title === messages.strQueryCacheEfficiency
) {
settings.axes.yaxis.tickOptions = {
formatString: '%d %%'
};
} else if (settings.title === PMA_messages.strSystemMemory ||
settings.title === PMA_messages.strSystemSwap
} else if (settings.title === messages.strSystemMemory ||
settings.title === messages.strSystemSwap
) {
settings.stackSeries = true;
settings.axes.yaxis.tickOptions = {
formatter: $.jqplot.byteFormatter(2) // MiB
};
} else if (settings.title === PMA_messages.strTraffic) {
} else if (settings.title === messages.strTraffic) {
settings.axes.yaxis.tickOptions = {
formatter: $.jqplot.byteFormatter(1) // KiB
};
} else if (settings.title === PMA_messages.strQuestions ||
settings.title === PMA_messages.strConnections
} else if (settings.title === messages.strQuestions ||
settings.title === messages.strConnections
) {
settings.axes.yaxis.tickOptions = {
formatter: function (format, val) {
@ -1306,12 +1198,12 @@ export function onload3 () {
var dlgBtns = { };
dlgBtns[PMA_messages.strFromSlowLog] = function () {
dlgBtns[messages.strFromSlowLog] = function () {
loadLog('slow', min, max);
$(this).dialog('close');
};
dlgBtns[PMA_messages.strFromGeneralLog] = function () {
dlgBtns[messages.strFromGeneralLog] = function () {
loadLog('general', min, max);
$(this).dialog('close');
};
@ -1352,12 +1244,12 @@ export function onload3 () {
/* Called in regular intervals, this function updates the values of each chart in the grid */
function refreshChartGrid () {
/* Send to server */
runtime.refreshRequest = $.post('server_status_monitor.php' + PMA_commonParams.get('common_query'), {
runtime.refreshRequest = $.post('server_status_monitor.php' + CommonParams.get('common_query'), {
ajax_request: true,
chart_data: 1,
type: 'chartgrid',
requiredData: JSON.stringify(runtime.dataList),
server: PMA_commonParams.get('server')
server: CommonParams.get('server')
}, function (data) {
var chartData;
if (typeof data !== 'undefined' && data.success === true) {
@ -1448,8 +1340,8 @@ export function onload3 () {
elem.chart.series[j].data.splice(0, elem.chart.series[j].data.length - runtime.gridMaxPoints);
}
}
if (elem.title === PMA_messages.strSystemMemory ||
elem.title === PMA_messages.strSystemSwap
if (elem.title === messages.strSystemMemory ||
elem.title === messages.strSystemSwap
) {
total += value;
}
@ -1463,15 +1355,15 @@ export function onload3 () {
(runtime.xmax - tickInterval * 3), (runtime.xmax - tickInterval * 2),
(runtime.xmax - tickInterval), runtime.xmax];
if (elem.title !== PMA_messages.strSystemCPUUsage &&
elem.title !== PMA_messages.strQueryCacheEfficiency &&
elem.title !== PMA_messages.strSystemMemory &&
elem.title !== PMA_messages.strSystemSwap
if (elem.title !== messages.strSystemCPUUsage &&
elem.title !== messages.strQueryCacheEfficiency &&
elem.title !== messages.strSystemMemory &&
elem.title !== messages.strSystemSwap
) {
elem.chart.axes.yaxis.max = Math.ceil(elem.maxYLabel * 1.1);
elem.chart.axes.yaxis.tickInterval = Math.ceil(elem.maxYLabel * 1.1 / 5);
} else if (elem.title === PMA_messages.strSystemMemory ||
elem.title === PMA_messages.strSystemSwap
} else if (elem.title === messages.strSystemMemory ||
elem.title === messages.strSystemSwap
) {
elem.chart.axes.yaxis.max = Math.ceil(total * 1.1 / 100) * 100;
elem.chart.axes.yaxis.tickInterval = Math.ceil(total * 1.1 / 5);
@ -1571,13 +1463,13 @@ export function onload3 () {
opts.limitTypes = false;
}
$('#emptyDialog').dialog({ title: PMA_messages.strAnalysingLogsTitle });
$('#emptyDialog').html(PMA_messages.strAnalysingLogs +
$('#emptyDialog').dialog({ title: messages.strAnalysingLogsTitle });
$('#emptyDialog').html(messages.strAnalysingLogs +
' <img class="ajaxIcon" src="' + pmaThemeImage +
'ajax_clock_small.gif" alt="">');
var dlgBtns = {};
dlgBtns[PMA_messages.strCancelRequest] = function () {
dlgBtns[messages.strCancelRequest] = function () {
if (logRequest !== null) {
logRequest.abort();
}
@ -1592,7 +1484,7 @@ export function onload3 () {
});
logRequest = $.get('server_status_monitor.php' + PMA_commonParams.get('common_query'),
logRequest = $.get('server_status_monitor.php' + CommonParams.get('common_query'),
{ ajax_request: true,
log_data: 1,
type: opts.src,
@ -1611,10 +1503,10 @@ export function onload3 () {
}
if (logData.rows.length === 0) {
$('#emptyDialog').dialog({ title: PMA_messages.strNoDataFoundTitle });
$('#emptyDialog').html('<p>' + PMA_messages.strNoDataFound + '</p>');
$('#emptyDialog').dialog({ title: messages.strNoDataFoundTitle });
$('#emptyDialog').html('<p>' + messages.strNoDataFound + '</p>');
dlgBtns[PMA_messages.strClose] = function () {
dlgBtns[messages.strClose] = function () {
$(this).dialog('close');
};
@ -1625,8 +1517,8 @@ export function onload3 () {
runtime.logDataCols = buildLogTable(logData, opts.removeVariables);
/* Show some stats in the dialog */
$('#emptyDialog').dialog({ title: PMA_messages.strLoadingLogs });
$('#emptyDialog').html('<p>' + PMA_messages.strLogDataLoaded + '</p>');
$('#emptyDialog').dialog({ title: messages.strLoadingLogs });
$('#emptyDialog').html('<p>' + messages.strLogDataLoaded + '</p>');
$.each(logData.sum, function (key, value) {
key = key.charAt(0).toUpperCase() + key.slice(1).toLowerCase();
if (key === 'Total') {
@ -1639,15 +1531,15 @@ export function onload3 () {
if (logData.numRows > 12) {
$('#logTable').prepend(
'<fieldset id="logDataFilter">' +
' <legend>' + PMA_messages.strFiltersForLogTable + '</legend>' +
' <legend>' + messages.strFiltersForLogTable + '</legend>' +
' <div class="formelement">' +
' <label for="filterQueryText">' + PMA_messages.strFilterByWordRegexp + '</label>' +
' <label for="filterQueryText">' + messages.strFilterByWordRegexp + '</label>' +
' <input name="filterQueryText" type="text" id="filterQueryText" style="vertical-align: baseline;" />' +
' </div>' +
((logData.numRows > 250) ? ' <div class="formelement"><button name="startFilterQueryText" id="startFilterQueryText">' + PMA_messages.strFilter + '</button></div>' : '') +
((logData.numRows > 250) ? ' <div class="formelement"><button name="startFilterQueryText" id="startFilterQueryText">' + messages.strFilter + '</button></div>' : '') +
' <div class="formelement">' +
' <input type="checkbox" id="noWHEREData" name="noWHEREData" value="1" /> ' +
' <label for="noWHEREData"> ' + PMA_messages.strIgnoreWhereAndGroup + '</label>' +
' <label for="noWHEREData"> ' + messages.strIgnoreWhereAndGroup + '</label>' +
' </div' +
'</fieldset>'
);
@ -1663,7 +1555,7 @@ export function onload3 () {
}
}
dlgBtns[PMA_messages.strJumpToTable] = function () {
dlgBtns[messages.strJumpToTable] = function () {
$(this).dialog('close');
$(document).scrollTop($('#logTable').offset().top);
};
@ -1826,8 +1718,8 @@ export function onload3 () {
// Display some stats at the bottom of the table
$('#logTable').find('table tfoot tr')
.html('<th colspan="' + (runtime.logDataCols.length - 1) + '">' +
PMA_messages.strSumRows + ' ' + rowSum + '<span class="floatright">' +
PMA_messages.strTotal + '</span></th><th class="right">' + totalSum + '</th>');
messages.strSumRows + ' ' + rowSum + '<span class="floatright">' +
messages.strTotal + '</span></th><th class="right">' + totalSum + '</th>');
}
}
@ -1906,17 +1798,17 @@ export function onload3 () {
}
$table.append('<tfoot>' +
'<tr><th colspan="' + (cols.length - 1) + '">' + PMA_messages.strSumRows +
' ' + data.numRows + '<span class="floatright">' + PMA_messages.strTotal +
'<tr><th colspan="' + (cols.length - 1) + '">' + messages.strSumRows +
' ' + data.numRows + '<span class="floatright">' + messages.strTotal +
'</span></th><th class="right">' + data.sum.TOTAL + '</th></tr></tfoot>');
// Append a tooltip to the count column, if there exist one
if ($('#logTable').find('tr:first th:last').text().indexOf('#') > -1) {
$('#logTable').find('tr:first th:last').append('&nbsp;' + PMA_getImage('b_help', '', { 'class': 'qroupedQueryInfoIcon' }));
var tooltipContent = PMA_messages.strCountColumnExplanation;
var tooltipContent = messages.strCountColumnExplanation;
if (groupInserts) {
tooltipContent += '<p>' + PMA_messages.strMoreCountColumnExplanation + '</p>';
tooltipContent += '<p>' + messages.strMoreCountColumnExplanation + '</p>';
}
PMA_tooltip(
@ -1958,10 +1850,10 @@ export function onload3 () {
var profilingChart = null;
var dlgBtns = {};
dlgBtns[PMA_messages.strAnalyzeQuery] = function () {
dlgBtns[messages.strAnalyzeQuery] = function () {
loadQueryAnalysis(rowData);
};
dlgBtns[PMA_messages.strClose] = function () {
dlgBtns[messages.strClose] = function () {
$(this).dialog('close');
};
@ -1989,15 +1881,15 @@ export function onload3 () {
var db = rowData.db || '';
$('#queryAnalyzerDialog').find('div.placeHolder').html(
PMA_messages.strAnalyzing + ' <img class="ajaxIcon" src="' +
messages.strAnalyzing + ' <img class="ajaxIcon" src="' +
pmaThemeImage + 'ajax_clock_small.gif" alt="">');
$.post('server_status_monitor.php' + PMA_commonParams.get('common_query'), {
$.post('server_status_monitor.php' + CommonParams.get('common_query'), {
ajax_request: true,
query_analyzer: true,
query: codemirror_editor ? codemirror_editor.getValue() : $('#sqlquery').val(),
database: db,
server: PMA_commonParams.get('server')
server: CommonParams.get('server')
}, function (data) {
var i;
var l;
@ -2006,7 +1898,7 @@ export function onload3 () {
}
if (data.error) {
if (data.error.indexOf('1146') !== -1 || data.error.indexOf('1046') !== -1) {
data.error = PMA_messages.strServerLogError;
data.error = messages.strServerLogError;
}
$('#queryAnalyzerDialog').find('div.placeHolder').html('<div class="error">' + data.error + '</div>');
return;
@ -2016,7 +1908,7 @@ export function onload3 () {
$('#queryAnalyzerDialog').find('div.placeHolder')
.html('<table width="100%" border="0"><tr><td class="explain"></td><td class="chart"></td></tr></table>');
var explain = '<b>' + PMA_messages.strExplainOutput + '</b> ' + $('#explain_docu').html();
var explain = '<b>' + messages.strExplainOutput + '</b> ' + $('#explain_docu').html();
if (data.explain.length > 1) {
explain += ' (';
for (i = 0; i < data.explain.length; i++) {
@ -2047,7 +1939,7 @@ export function onload3 () {
explain += '</div>';
}
explain += '<p><b>' + PMA_messages.strAffectedRows + '</b> ' + data.affectedRows;
explain += '<p><b>' + messages.strAffectedRows + '</b> ' + data.affectedRows;
$('#queryAnalyzerDialog').find('div.placeHolder td.explain').append(explain);
@ -2059,7 +1951,7 @@ export function onload3 () {
if (data.profiling) {
var chartData = [];
var numberTable = '<table class="queryNums"><thead><tr><th>' + PMA_messages.strStatus + '</th><th>' + PMA_messages.strTime + '</th></tr></thead><tbody>';
var numberTable = '<table class="queryNums"><thead><tr><th>' + messages.strStatus + '</th><th>' + messages.strTime + '</th></tr></thead><tbody>';
var duration;
var otherTime = 0;
@ -2083,15 +1975,15 @@ export function onload3 () {
}
if (otherTime > 0) {
chartData.push([PMA_prettyProfilingNum(otherTime, 2) + ' ' + PMA_messages.strOther, otherTime]);
chartData.push([PMA_prettyProfilingNum(otherTime, 2) + ' ' + messages.strOther, otherTime]);
}
numberTable += '<tr><td><b>' + PMA_messages.strTotalTime + '</b></td><td>' + PMA_prettyProfilingNum(totalTime, 2) + '</td></tr>';
numberTable += '<tr><td><b>' + messages.strTotalTime + '</b></td><td>' + PMA_prettyProfilingNum(totalTime, 2) + '</td></tr>';
numberTable += '</tbody></table>';
$('#queryAnalyzerDialog').find('div.placeHolder td.chart').append(
'<b>' + PMA_messages.strProfilingResults + ' ' + $('#profiling_docu').html() + '</b> ' +
'(<a href="#showNums">' + PMA_messages.strTable + '</a>, <a href="#showChart">' + PMA_messages.strChart + '</a>)<br/>' +
'<b>' + messages.strProfilingResults + ' ' + $('#profiling_docu').html() + '</b> ' +
'(<a href="#showNums">' + messages.strTable + '</a>, <a href="#showChart">' + messages.strChart + '</a>)<br/>' +
numberTable + ' <div id="queryProfiling"></div>');
$('#queryAnalyzerDialog').find('div.placeHolder a[href="#showNums"]').on('click', function () {
@ -2106,7 +1998,7 @@ export function onload3 () {
return false;
});
profilingChart = PMA_createProfilingChart(
profilingChart = createProfilingChart(
'queryProfiling',
chartData
);
@ -2119,7 +2011,6 @@ export function onload3 () {
/* Saves the monitor to localstorage */
function saveMonitor () {
var gridCopy = {};
$.each(runtime.charts, function (key, elem) {
gridCopy[key] = {};
gridCopy[key].nodes = elem.nodes;
@ -2146,13 +2037,13 @@ export function onload4 () {
function serverResponseError () {
var btns = {};
btns[PMA_messages.strReloadPage] = function () {
btns[messages.strReloadPage] = function () {
window.location.reload();
};
$('#emptyDialog').dialog({ title: PMA_messages.strRefreshFailed });
$('#emptyDialog').dialog({ title: messages.strRefreshFailed });
$('#emptyDialog').html(
PMA_getImage('s_attention') +
PMA_messages.strInvalidResponseExplanation
messages.strInvalidResponseExplanation
);
$('#emptyDialog').dialog({ buttons: btns });
}

View File

@ -4,8 +4,8 @@
* Module import
*/
import { createProfilingChart } from './functions/chart';
import { jQuery as $ } from './utils/JqueryExtended';
import { initTableSorter } from './server_status_sorter';
import { $ } from './utils/JqueryExtended';
import { initTableSorter } from './functions/Server/SeverStatusSorter';
/**
* @package PhpMyAdmin

View File

@ -1,25 +1,11 @@
import { PMA_Messages as PMA_messages } from './variables/export_variables';
// TODO: tablesorter shouldn't sort already sorted columns
export function initTableSorter (tabid) {
var $table;
var opts;
switch (tabid) {
case 'statustabs_queries':
$table = $('#serverstatusqueriesdetails');
opts = {
sortList: [[3, 1]],
headers: {
// 1: { sorter: 'fancyNumber' },
// 2: { sorter: 'fancyNumber' }
}
};
break;
}
$table.tablesorter(opts);
$table.find('tr:first th')
.append('<div class="sorticon"></div>')
.addClass('header');
}
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { $ } from './utils/JqueryExtended';
import './plugins/jquery/jquery.tablesorter';
import { PMA_Messages as messages } from './variables/export_variables';
$(function () {
$.tablesorter.addParser({
@ -29,8 +15,8 @@ $(function () {
},
format: function (s) {
var num = $.tablesorter.formatFloat(
s.replace(PMA_messages.strThousandsSeparator, '')
.replace(PMA_messages.strDecimalSeparator, '.')
s.replace(messages.strThousandsSeparator, '')
.replace(messages.strDecimalSeparator, '.')
);
var factor = 1;

View File

@ -3,7 +3,7 @@
/**
* Module import
*/
import { PMA_Messages as PMA_messages } from './variables/export_variables';
import { PMA_Messages as messages } from './variables/export_variables';
import { PMA_sprintf } from './utils/sprintf';
import { escapeHtml } from './utils/Sanitise';
@ -25,6 +25,7 @@ function teardownServerUserGroups () {
*/
function onloadServerUserGroups () {
// update the checkall checkbox on Edit user group page
// console.log($('input.checkall:checkbox:enabled'));
$(checkboxes_sel).trigger('change');
$(document).on('click', 'a.deleteUserGroup.ajax', function (event) {
@ -32,22 +33,22 @@ function onloadServerUserGroups () {
var $link = $(this);
var groupName = $link.parents('tr').find('td:first').text();
var buttonOptions = {};
buttonOptions[PMA_messages.strGo] = function () {
buttonOptions[messages.strGo] = function () {
$(this).dialog('close');
$link.removeClass('ajax').trigger('click');
};
buttonOptions[PMA_messages.strClose] = function () {
buttonOptions[messages.strClose] = function () {
$(this).dialog('close');
};
$('<div/>')
.attr('id', 'confirmUserGroupDeleteDialog')
.append(PMA_sprintf(PMA_messages.strDropUserGroupWarning, escapeHtml(groupName)))
.append(PMA_sprintf(messages.strDropUserGroupWarning, escapeHtml(groupName)))
.dialog({
width: 300,
minWidth: 200,
modal: true,
buttons: buttonOptions,
title: PMA_messages.strConfirm,
title: messages.strConfirm,
close: function () {
$(this).remove();
}

View File

@ -3,6 +3,7 @@
/**
* Module import
*/
import { $ } from './utils/JqueryExtended';
import { editVariable } from './functions/Server/ServerVariables';
/**

868
js/src/sql.js Normal file
View File

@ -0,0 +1,868 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
import { $ } from './utils/JqueryExtended';
import './plugins/jquery/jquery.uitablefilter';
import { PMA_Messages as PMA_messages } from './variables/export_variables';
import PMA_commonParams from './variables/common_params';
import { PMA_commonActions } from './classes/CommonActions';
import PMA_MicroHistory from './classes/MicroHistory';
import { isStorageSupported } from './functions/config';
import { PMA_sprintf } from './utils/sprintf';
import { escapeHtml } from './utils/Sanitise';
import { PMA_ajaxShowMessage, PMA_ajaxRemoveMessage } from './utils/show_ajax_messages';
import { initStickyColumns, rearrangeStickyColumns, handleStickyColumns } from './functions/Grid/StickyColumns';
import { PMA_makegrid } from './utils/makegrid';
import { AJAX } from './ajax';
import { initProfilingTables, makeProfilingChart } from './functions/Sql/SqlProfiling';
import { PMA_highlightSQL } from './utils/sql';
import { sqlQueryOptions } from './utils/sql';
import Cookies from 'js-cookie';
import { printPreview } from './functions/Print';
import {
setShowThisQuery, PMA_autosaveSQL, PMA_autosaveSQLSort, PMA_showThisQuery,
checkSavedQuery, setQuery, checkSqlQuery, PMA_handleSimulateQueryButton, insertValueQuery
} from './functions/Sql/SqlQuery';
/**
* @fileoverview functions used wherever an sql query form is used
*
* @requires jQuery
* @requires js/functions.js
*
*/
var $data_a;
/**
* Unbind all event handlers before tearing down a page
*/
export function teardown1 () {
$(document).off('click', 'a.delete_row.ajax');
$(document).off('submit', '.bookmarkQueryForm');
$('input#bkm_label').off('keyup');
$(document).off('makegrid', '.sqlqueryresults');
$(document).off('stickycolumns', '.sqlqueryresults');
$('#togglequerybox').off('click');
$(document).off('click', '#button_submit_query');
$(document).off('change', '#id_bookmark');
$('input[name=\'bookmark_variable\']').off('keypress');
$(document).off('submit', '#sqlqueryform.ajax');
$(document).off('click', 'input[name=navig].ajax');
$(document).off('submit', 'form[name=\'displayOptionsForm\'].ajax');
$(document).off('mouseenter', 'th.column_heading.pointer');
$(document).off('mouseleave', 'th.column_heading.pointer');
$(document).off('click', 'th.column_heading.marker');
$(window).off('scroll');
$(document).off('keyup', '.filter_rows');
$(document).off('click', '#printView');
if (sqlQueryOptions.codemirror_editor) {
sqlQueryOptions.codemirror_editor.off('change');
} else {
$('#sqlquery').off('input propertychange');
}
$('body').off('click', '.navigation .showAllRows');
$('body').off('click', 'a.browse_foreign');
$('body').off('click', '#simulate_dml');
$('body').off('keyup', '#sqlqueryform');
$('body').off('click', 'form[name="resultsForm"].ajax button[name="submit_mult"], form[name="resultsForm"].ajax input[name="submit_mult"]');
}
/**
* @description <p>Ajax scripts for sql and browse pages</p>
*
* Actions ajaxified here:
* <ul>
* <li>Retrieve results of an SQL query</li>
* <li>Paginate the results table</li>
* <li>Sort the results table</li>
* <li>Change table according to display options</li>
* <li>Grid editing of data</li>
* <li>Saving a bookmark</li>
* </ul>
*
* @name document.ready
* @memberOf jQuery
*/
export function onload1 () {
if (sqlQueryOptions.codemirror_editor || document.sqlform) {
setShowThisQuery();
}
$(function () {
if (sqlQueryOptions.codemirror_editor) {
sqlQueryOptions.codemirror_editor.on('change', function () {
PMA_autosaveSQL(sqlQueryOptions.codemirror_editor.getValue());
});
} else {
$('#sqlquery').on('input propertychange', function () {
PMA_autosaveSQL($('#sqlquery').val());
});
// Save sql query with sort
if ($('#RememberSorting') !== undefined && $('#RememberSorting').is(':checked')) {
$('select[name="sql_query"]').on('change', function () {
PMA_autosaveSQLSort($('select[name="sql_query"]').val());
});
} else {
if (isStorageSupported('localStorage')
&& window.localStorage.auto_saved_sql_sort !== undefined
) {
window.localStorage.removeItem('auto_saved_sql_sort');
} else {
Cookies.set('auto_saved_sql_sort', '');
}
}
// If sql query with sort for current table is stored, change sort by key select value
var sortStoredQuery = (isStorageSupported('localStorage')
&& typeof window.localStorage.auto_saved_sql_sort !== 'undefined')
? window.localStorage.auto_saved_sql_sort :
Cookies.get('auto_saved_sql_sort');
if (typeof sortStoredQuery !== 'undefined'
&& sortStoredQuery !== $('select[name="sql_query"]').val()
&& $('select[name="sql_query"] option[value="' + sortStoredQuery + '"]').length !== 0
) {
$('select[name="sql_query"]').val(sortStoredQuery).trigger('change');
}
}
});
// Delete row from SQL results
$(document).on('click', 'a.delete_row.ajax', function (e) {
e.preventDefault();
var question = PMA_sprintf(PMA_messages.strDoYouReally, escapeHtml($(this).closest('td').find('div').text()));
var $link = $(this);
$link.PMA_confirm(question, $link.attr('href'), function (url) {
$msgbox = PMA_ajaxShowMessage();
var argsep = PMA_commonParams.get('arg_separator');
var params = 'ajax_request=1' + argsep + 'is_js_confirmed=1';
var postData = $link.getPostData();
if (postData) {
params += argsep + postData;
}
$.post(url, params, function (data) {
if (data.success) {
PMA_ajaxShowMessage(data.message);
$link.closest('tr').remove();
} else {
PMA_ajaxShowMessage(data.error, false);
}
});
});
});
// Ajaxification for 'Bookmark this SQL query'
$(document).on('submit', '.bookmarkQueryForm', function (e) {
e.preventDefault();
PMA_ajaxShowMessage();
var argsep = PMA_commonParams.get('arg_separator');
$.post($(this).attr('action'), 'ajax_request=1' + argsep + $(this).serialize(), function (data) {
if (data.success) {
PMA_ajaxShowMessage(data.message);
} else {
PMA_ajaxShowMessage(data.error, false);
}
});
});
/* Hides the bookmarkoptions checkboxes when the bookmark label is empty */
$('input#bkm_label').on('keyup', function () {
$('input#id_bkm_all_users, input#id_bkm_replace')
.parent()
.toggle($(this).val().length > 0);
}).trigger('keyup');
/**
* Attach Event Handler for 'Copy to clipbpard
*/
$(document).on('click', '#copyToClipBoard', function (event) {
event.preventDefault();
var textArea = document.createElement('textarea');
//
// *** This styling is an extra step which is likely not required. ***
//
// Why is it here? To ensure:
// 1. the element is able to have focus and selection.
// 2. if element was to flash render it has minimal visual impact.
// 3. less flakyness with selection and copying which **might** occur if
// the textarea element is not visible.
//
// The likelihood is the element won't even render, not even a flash,
// so some of these are just precautions. However in IE the element
// is visible whilst the popup box asking the user for permission for
// the web page to copy to the clipboard.
//
// Place in top-left corner of screen regardless of scroll position.
textArea.style.position = 'fixed';
textArea.style.top = 0;
textArea.style.left = 0;
// Ensure it has a small width and height. Setting to 1px / 1em
// doesn't work as this gives a negative w/h on some browsers.
textArea.style.width = '2em';
textArea.style.height = '2em';
// We don't need padding, reducing the size if it does flash render.
textArea.style.padding = 0;
// Clean up any borders.
textArea.style.border = 'none';
textArea.style.outline = 'none';
textArea.style.boxShadow = 'none';
// Avoid flash of white box if rendered for any reason.
textArea.style.background = 'transparent';
textArea.value = '';
$('#serverinfo a').each(function () {
textArea.value += $(this).text().split(':')[1].trim() + '/';
});
textArea.value += '\t\t' + window.location.href;
textArea.value += '\n';
$('.success').each(function () {
textArea.value += $(this).text() + '\n\n';
});
$('.sql pre').each(function () {
textArea.value += $(this).text() + '\n\n';
});
$('.table_results .column_heading a').each(function () {
// Don't copy ordering number text within <small> tag
textArea.value += $(this).clone().find('small').remove().end().text() + '\t';
});
textArea.value += '\n';
$('.table_results tbody tr').each(function () {
$(this).find('.data span').each(function () {
textArea.value += $(this).text() + '\t';
});
textArea.value += '\n';
});
document.body.appendChild(textArea);
textArea.select();
try {
document.execCommand('copy');
} catch (err) {
alert('Sorry! Unable to copy');
}
document.body.removeChild(textArea);
}); // end of Copy to Clipboard action
/**
* Attach Event Handler for 'Print' link
*/
$(document).on('click', '#printView', function (event) {
event.preventDefault();
// Take to preview mode
printPreview();
}); // end of 'Print' action
/**
* Attach the {@link makegrid} function to a custom event, which will be
* triggered manually everytime the table of results is reloaded
* @memberOf jQuery
*/
$(document).on('makegrid', '.sqlqueryresults', function () {
$('.table_results').each(function () {
PMA_makegrid(this);
});
});
/*
* Attach a custom event for sticky column headings which will be
* triggered manually everytime the table of results is reloaded
* @memberOf jQuery
*/
$(document).on('stickycolumns', '.sqlqueryresults', function () {
$('.sticky_columns').remove();
$('.table_results').each(function () {
var $table_results = $(this);
// add sticky columns div
var $stick_columns = initStickyColumns($table_results);
rearrangeStickyColumns($stick_columns, $table_results);
// adjust sticky columns on scroll
$(window).on('scroll', function () {
handleStickyColumns($stick_columns, $table_results);
});
});
});
/**
* Append the "Show/Hide query box" message to the query input form
*
* @memberOf jQuery
* @name appendToggleSpan
*/
// do not add this link more than once
if (! $('#sqlqueryform').find('a').is('#togglequerybox')) {
$('<a id="togglequerybox"></a>')
.html(PMA_messages.strHideQueryBox)
.appendTo('#sqlqueryform')
// initially hidden because at this point, nothing else
// appears under the link
.hide();
// Attach the toggling of the query box visibility to a click
$('#togglequerybox').bind('click', function () {
var $link = $(this);
$link.siblings().slideToggle('fast');
if ($link.text() === PMA_messages.strHideQueryBox) {
$link.text(PMA_messages.strShowQueryBox);
// cheap trick to add a spacer between the menu tabs
// and "Show query box"; feel free to improve!
$('#togglequerybox_spacer').remove();
$link.before('<br id="togglequerybox_spacer" />');
} else {
$link.text(PMA_messages.strHideQueryBox);
}
// avoid default click action
return false;
});
}
/**
* Event handler for sqlqueryform.ajax button_submit_query
*
* @memberOf jQuery
*/
$(document).on('click', '#button_submit_query', function (event) {
$('.success,.error').hide();
// hide already existing error or success message
var $form = $(this).closest('form');
// the Go button related to query submission was clicked,
// instead of the one related to Bookmarks, so empty the
// id_bookmark selector to avoid misinterpretation in
// import.php about what needs to be done
$form.find('select[name=id_bookmark]').val('');
// let normal event propagation happen
if (isStorageSupported('localStorage')) {
window.localStorage.removeItem('auto_saved_sql');
} else {
Cookies.set('auto_saved_sql', '');
}
var isShowQuery = $('input[name="show_query"').is(':checked');
if (isShowQuery) {
window.localStorage.show_this_query = '1';
var db = $('input[name="db"]').val();
var table = $('input[name="table"]').val();
var query;
if (sqlQueryOptions.codemirror_editor) {
query = sqlQueryOptions.codemirror_editor.getValue();
} else {
query = $('#sqlquery').val();
}
PMA_showThisQuery(db, table, query);
} else {
window.localStorage.show_this_query = '0';
}
});
/**
* Event handler to show appropiate number of variable boxes
* based on the bookmarked query
*/
$(document).on('change', '#id_bookmark', function (event) {
var varCount = $(this).find('option:selected').data('varcount');
if (typeof varCount === 'undefined') {
varCount = 0;
}
var $varDiv = $('#bookmark_variables');
$varDiv.empty();
for (var i = 1; i <= varCount; i++) {
$varDiv.append($('<label for="bookmark_variable_' + i + '">' + PMA_sprintf(PMA_messages.strBookmarkVariable, i) + '</label>'));
$varDiv.append($('<input type="text" size="10" name="bookmark_variable[' + i + ']" id="bookmark_variable_' + i + '"/>'));
}
if (varCount === 0) {
$varDiv.parent('.formelement').hide();
} else {
$varDiv.parent('.formelement').show();
}
});
/**
* Event handler for hitting enter on sqlqueryform bookmark_variable
* (the Variable textfield in Bookmarked SQL query section)
*
* @memberOf jQuery
*/
$('input[name=bookmark_variable]').on('keypress', function (event) {
// force the 'Enter Key' to implicitly click the #button_submit_bookmark
var keycode = (event.keyCode ? event.keyCode : (event.which ? event.which : event.charCode));
if (keycode === 13) { // keycode for enter key
// When you press enter in the sqlqueryform, which
// has 2 submit buttons, the default is to run the
// #button_submit_query, because of the tabindex
// attribute.
// This submits #button_submit_bookmark instead,
// because when you are in the Bookmarked SQL query
// section and hit enter, you expect it to do the
// same action as the Go button in that section.
$('#button_submit_bookmark').trigger('click');
return false;
} else {
return true;
}
});
/**
* Ajax Event handler for 'SQL Query Submit'
*
* @see PMA_ajaxShowMessage()
* @memberOf jQuery
* @name sqlqueryform_submit
*/
$(document).on('submit', '#sqlqueryform.ajax', function (event) {
event.preventDefault();
var $form = $(this);
if (sqlQueryOptions.codemirror_editor) {
$form[0].elements.sql_query.value = sqlQueryOptions.codemirror_editor.getValue();
}
if (! checkSqlQuery($form[0])) {
return false;
}
// remove any div containing a previous error message
$('div.error').remove();
var $msgbox = PMA_ajaxShowMessage();
var $sqlqueryresultsouter = $('#sqlqueryresultsouter');
PMA_prepareForAjaxRequest($form);
var argsep = PMA_commonParams.get('arg_separator');
$.post($form.attr('action'), $form.serialize() + argsep + 'ajax_page_request=true', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
// success happens if the query returns rows or not
// show a message that stays on screen
if (typeof data.action_bookmark !== 'undefined') {
// view only
if ('1' === data.action_bookmark) {
$('#sqlquery').text(data.sql_query);
// send to codemirror if possible
setQuery(data.sql_query);
}
// delete
if ('2' === data.action_bookmark) {
$('#id_bookmark option[value=\'' + data.id_bookmark + '\']').remove();
// if there are no bookmarked queries now (only the empty option),
// remove the bookmark section
if ($('#id_bookmark option').length === 1) {
$('#fieldsetBookmarkOptions').hide();
$('#fieldsetBookmarkOptionsFooter').hide();
}
}
}
$sqlqueryresultsouter
.show()
.html(data.message);
PMA_highlightSQL($sqlqueryresultsouter);
if (data._menu) {
if (history && history.pushState) {
history.replaceState({
menu : data._menu
},
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._params) {
PMA_commonParams.setAll(data._params);
}
if (typeof data.ajax_reload !== 'undefined') {
if (data.ajax_reload.reload) {
if (data.ajax_reload.table_name) {
PMA_commonParams.set('table', data.ajax_reload.table_name);
PMA_commonActions.refreshMain();
} else {
PMA_reloadNavigation();
}
}
} else if (typeof data.reload !== 'undefined') {
// this happens if a USE or DROP command was typed
PMA_commonActions.setDb(data.db);
var url;
if (data.db) {
if (data.table) {
url = 'table_sql.php';
} else {
url = 'db_sql.php';
}
} else {
url = 'server_sql.php';
}
PMA_commonActions.refreshMain(url, function () {
$('#sqlqueryresultsouter')
.show()
.html(data.message);
PMA_highlightSQL($('#sqlqueryresultsouter'));
});
}
$('.sqlqueryresults').trigger('makegrid').trigger('stickycolumns');
$('#togglequerybox').show();
PMA_init_slider();
if (typeof data.action_bookmark === 'undefined') {
if ($('#sqlqueryform input[name="retain_query_box"]').is(':checked') !== true) {
if ($('#togglequerybox').siblings(':visible').length > 0) {
$('#togglequerybox').trigger('click');
}
}
}
} else if (typeof data !== 'undefined' && data.success === false) {
// show an error message that stays on screen
$sqlqueryresultsouter
.show()
.html(data.error);
}
PMA_ajaxRemoveMessage($msgbox);
}); // end $.post()
}); // end SQL Query submit
/**
* Ajax Event handler for the display options
* @memberOf jQuery
* @name displayOptionsForm_submit
*/
$(document).on('submit', 'form[name=\'displayOptionsForm\'].ajax', function (event) {
event.preventDefault();
var $form = $(this);
var $msgbox = PMA_ajaxShowMessage();
var argsep = PMA_commonParams.get('arg_separator');
$.post($form.attr('action'), $form.serialize() + argsep + 'ajax_request=true', function (data) {
PMA_ajaxRemoveMessage($msgbox);
var $sqlqueryresults = $form.parents('.sqlqueryresults');
$sqlqueryresults
.html(data.message)
.trigger('makegrid')
.trigger('stickycolumns');
PMA_init_slider();
PMA_highlightSQL($sqlqueryresults);
}); // end $.post()
}); // end displayOptionsForm handler
// Filter row handling. --STARTS--
$(document).on('keyup', '.filter_rows', function () {
var unique_id = $(this).data('for');
var $target_table = $('.table_results[data-uniqueId=\'' + unique_id + '\']');
var $header_cells = $target_table.find('th[data-column]');
var target_columns = Array();
// To handle colspan=4, in case of edit,copy etc options.
var dummy_th = ($('.edit_row_anchor').length !== 0 ?
'<th class="hide dummy_th"></th><th class="hide dummy_th"></th><th class="hide dummy_th"></th>'
: '');
// Selecting columns that will be considered for filtering and searching.
$header_cells.each(function () {
target_columns.push($.trim($(this).text()));
});
var phrase = $(this).val();
// Set same value to both Filter rows fields.
$('.filter_rows[data-for=\'' + unique_id + '\']').not(this).val(phrase);
// Handle colspan.
$target_table.find('thead > tr').prepend(dummy_th);
$.uiTableFilter($target_table, phrase, target_columns);
$target_table.find('th.dummy_th').remove();
});
// Filter row handling. --ENDS--
// Prompt to confirm on Show All
$('body').on('click', '.navigation .showAllRows', function (e) {
e.preventDefault();
var $form = $(this).parents('form');
if (! $(this).is(':checked')) { // already showing all rows
submitShowAllForm();
} else {
$form.PMA_confirm(PMA_messages.strShowAllRowsWarning, $form.attr('action'), function (url) {
submitShowAllForm();
});
}
function submitShowAllForm () {
var argsep = PMA_commonParams.get('arg_separator');
var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
PMA_ajaxShowMessage();
AJAX.source = $form;
$.post($form.attr('action'), submitData, AJAX.responseHandler);
}
});
$('body').on('keyup', '#sqlqueryform', function () {
PMA_handleSimulateQueryButton();
});
/**
* Ajax event handler for 'Simulate DML'.
*/
$('body').on('click', '#simulate_dml', function () {
var $form = $('#sqlqueryform');
var query = '';
var delimiter = $('#id_sql_delimiter').val();
var db_name = $form.find('input[name="db"]').val();
if (sqlQueryOptions.codemirror_editor) {
query = sqlQueryOptions.codemirror_editor.getValue();
} else {
query = $('#sqlquery').val();
}
if (query.length === 0) {
alert(PMA_messages.strFormEmpty);
$('#sqlquery').focus();
return false;
}
var $msgbox = PMA_ajaxShowMessage();
$.ajax({
type: 'POST',
url: $form.attr('action'),
data: {
server: PMA_commonParams.get('server'),
db: db_name,
ajax_request: '1',
simulate_dml: '1',
sql_query: query,
sql_delimiter: delimiter
},
success: function (response) {
PMA_ajaxRemoveMessage($msgbox);
if (response.success) {
var dialog_content = '<div class="preview_sql">';
if (response.sql_data) {
var len = response.sql_data.length;
for (var i = 0; i < len; i++) {
dialog_content += '<strong>' + PMA_messages.strSQLQuery +
'</strong>' + response.sql_data[i].sql_query +
PMA_messages.strMatchedRows +
' <a href="' + response.sql_data[i].matched_rows_url +
'">' + response.sql_data[i].matched_rows + '</a><br>';
if (i < len - 1) {
dialog_content += '<hr>';
}
}
} else {
dialog_content += response.message;
}
dialog_content += '</div>';
var $dialog_content = $(dialog_content);
var button_options = {};
button_options[PMA_messages.strClose] = function () {
$(this).dialog('close');
};
var $response_dialog = $('<div />').append($dialog_content).dialog({
minWidth: 540,
maxHeight: 400,
modal: true,
buttons: button_options,
title: PMA_messages.strSimulateDML,
open: function () {
PMA_highlightSQL($(this));
},
close: function () {
$(this).remove();
}
});
} else {
PMA_ajaxShowMessage(response.error);
}
},
error: function (response) {
PMA_ajaxShowMessage(PMA_messages.strErrorProcessingRequest);
}
});
});
/**
* Handles multi submits of results browsing page such as edit, delete and export
*/
$('body').on('click', 'form[name="resultsForm"].ajax button[name="submit_mult"], form[name="resultsForm"].ajax input[name="submit_mult"]', function (e) {
e.preventDefault();
var $button = $(this);
var $form = $button.closest('form');
var argsep = PMA_commonParams.get('arg_separator');
var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'submit_mult=' + $button.val();
PMA_ajaxShowMessage();
AJAX.source = $form;
$.post($form.attr('action'), submitData, AJAX.responseHandler);
});
/**
* Handles double click table fields to insert into query
*/
$('#tablefields')
.on('dblclick', function () {
insertValueQuery();
});
/**
* Handle click on insert or arrow button to insert table fields in query
*/
$('#tablefieldsSubmitLinkMode,#tablefieldsSubmitNonLinkMode')
.on('click', function () {
insertValueQuery();
});
} // end $()
/**
* Starting from some th, change the class of all td under it.
* If isAddClass is specified, it will be used to determine whether to add or remove the class.
*/
function PMA_changeClassForColumn ($this_th, newclass, isAddClass) {
// index 0 is the th containing the big T
var th_index = $this_th.index();
var has_big_t = $this_th.closest('tr').children(':first').hasClass('column_action');
// .eq() is zero-based
if (has_big_t) {
th_index--;
}
var $table = $this_th.parents('.table_results');
if (! $table.length) {
$table = $this_th.parents('table').siblings('.table_results');
}
var $tds = $table.find('tbody tr').find('td.data:eq(' + th_index + ')');
if (isAddClass === undefined) {
$tds.toggleClass(newclass);
} else {
$tds.toggleClass(newclass, isAddClass);
}
}
/**
* Handles browse foreign values modal dialog
*
* @param object $this_a reference to the browse foreign value link
*/
function browseForeignDialog ($this_a) {
var formId = '#browse_foreign_form';
var showAllId = '#foreign_showAll';
var tableId = '#browse_foreign_table';
var filterId = '#input_foreign_filter';
var $dialog = null;
$.get($this_a.attr('href'), { 'ajax_request': true }, function (data) {
// Creates browse foreign value dialog
$dialog = $('<div>').append(data.message).dialog({
title: PMA_messages.strBrowseForeignValues,
width: Math.min($(window).width() - 100, 700),
maxHeight: $(window).height() - 100,
dialogClass: 'browse_foreign_modal',
close: function (ev, ui) {
// remove event handlers attached to elements related to dialog
$(tableId).off('click', 'td a.foreign_value');
$(formId).off('click', showAllId);
$(formId).off('submit');
// remove dialog itself
$(this).remove();
},
modal: true
});
}).done(function () {
var showAll = false;
$(tableId).on('click', 'td a.foreign_value', function (e) {
e.preventDefault();
var $input = $this_a.prev('input[type=text]');
// Check if input exists or get CEdit edit_box
if ($input.length === 0) {
$input = $this_a.closest('.edit_area').prev('.edit_box');
}
// Set selected value as input value
$input.val($(this).data('key'));
$dialog.dialog('close');
});
$(formId).on('click', showAllId, function () {
showAll = true;
});
$(formId).on('submit', function (e) {
e.preventDefault();
// if filter value is not equal to old value
// then reset page number to 1
if ($(filterId).val() !== $(filterId).data('old')) {
$(formId).find('select[name=pos]').val('0');
}
var postParams = $(this).serializeArray();
// if showAll button was clicked to submit form then
// add showAll button parameter to form
if (showAll) {
postParams.push({
name: $(showAllId).attr('name'),
value: $(showAllId).val()
});
}
// updates values in dialog
$.post($(this).attr('action') + '?ajax_request=1', postParams, function (data) {
var $obj = $('<div>').html(data.message);
$(formId).html($obj.find(formId).html());
$(tableId).html($obj.find(tableId).html());
});
showAll = false;
});
});
}
export function onload2 () {
$('body').on('click', 'a.browse_foreign', function (e) {
e.preventDefault();
browseForeignDialog($(this));
});
/**
* vertical column highlighting in horizontal mode when hovering over the column header
*/
$(document).on('mouseenter', 'th.column_heading.pointer', function (e) {
PMA_changeClassForColumn($(this), 'hover', true);
});
$(document).on('mouseleave', 'th.column_heading.pointer', function (e) {
PMA_changeClassForColumn($(this), 'hover', false);
});
/**
* vertical column marking in horizontal mode when clicking the column header
*/
$(document).on('click', 'th.column_heading.marker', function () {
PMA_changeClassForColumn($(this), 'marked');
});
/**
* create resizable table
*/
$('.sqlqueryresults').trigger('makegrid').trigger('stickycolumns');
/**
* Check if there is any saved query
*/
if (sqlQueryOptions.codemirror_editor || document.sqlform) {
checkSavedQuery();
}
}
export function onload4 () {
makeProfilingChart();
initProfilingTables();
}

147
js/src/utils/DateTime.js Normal file
View File

@ -0,0 +1,147 @@
import { PMA_Messages as PMA_messages } from '../variables/export_variables';
import { PMA_tooltip } from './show_ajax_messages';
/*
* Adds a date/time picker to an element
*
* @param object $this_element a jQuery object pointing to the element
*/
export function PMA_addDatepicker ($this_element, type, options) {
var showTimepicker = true;
if (type === 'date') {
showTimepicker = false;
}
var defaultOptions = {
showOn: 'button',
buttonImage: themeCalendarImage, // defined in js/messages.php
buttonImageOnly: true,
stepMinutes: 1,
stepHours: 1,
showSecond: true,
showMillisec: true,
showMicrosec: true,
showTimepicker: showTimepicker,
showButtonPanel: false,
dateFormat: 'yy-mm-dd', // yy means year with four digits
timeFormat: 'HH:mm:ss.lc',
constrainInput: false,
altFieldTimeOnly: false,
showAnim: '',
beforeShow: function (input, inst) {
// Remember that we came from the datepicker; this is used
// in tbl_change.js by verificationsAfterFieldChange()
$this_element.data('comes_from', 'datepicker');
if ($(input).closest('.cEdit').length > 0) {
setTimeout(function () {
inst.dpDiv.css({
top: 0,
left: 0,
position: 'relative'
});
}, 0);
}
setTimeout(function () {
// Fix wrong timepicker z-index, doesn't work without timeout
$('#ui-timepicker-div').css('z-index', $('#ui-datepicker-div').css('z-index'));
// Integrate tooltip text into dialog
var tooltip = $this_element.tooltip('instance');
if (typeof tooltip !== 'undefined') {
tooltip.disable();
var $note = $('<p class="note"></div>');
$note.text(tooltip.option('content'));
$('div.ui-datepicker').append($note);
}
}, 0);
},
onSelect: function () {
$this_element.data('datepicker').inline = true;
},
onClose: function (dateText, dp_inst) {
// The value is no more from the date picker
$this_element.data('comes_from', '');
if (typeof $this_element.data('datepicker') !== 'undefined') {
$this_element.data('datepicker').inline = false;
}
var tooltip = $this_element.tooltip('instance');
if (typeof tooltip !== 'undefined') {
tooltip.enable();
}
}
};
if (type === 'time') {
$this_element.timepicker($.extend(defaultOptions, options));
// Add a tip regarding entering MySQL allowed-values for TIME data-type
PMA_tooltip($this_element, 'input', PMA_messages.strMysqlAllowedValuesTipTime);
} else {
$this_element.datetimepicker($.extend(defaultOptions, options));
}
}
/**
* Add a date/time picker to each element that needs it
* (only when jquery-ui-timepicker-addon.js is loaded)
*/
function addDateTimePicker () {
if ($.timepicker !== undefined) {
$('input.timefield, input.datefield, input.datetimefield').each(function () {
var decimals = $(this).parent().attr('data-decimals');
var type = $(this).parent().attr('data-type');
var showMillisec = false;
var showMicrosec = false;
var timeFormat = 'HH:mm:ss';
var hourMax = 23;
// check for decimal places of seconds
if (decimals > 0 && type.indexOf('time') !== -1) {
if (decimals > 3) {
showMillisec = true;
showMicrosec = true;
timeFormat = 'HH:mm:ss.lc';
} else {
showMillisec = true;
timeFormat = 'HH:mm:ss.l';
}
}
if (type === 'time') {
hourMax = 99;
}
PMA_addDatepicker($(this), type, {
showMillisec: showMillisec,
showMicrosec: showMicrosec,
timeFormat: timeFormat,
hourMax: hourMax
});
// Add a tip regarding entering MySQL allowed-values
// for TIME and DATE data-type
if ($(this).hasClass('timefield')) {
PMA_tooltip($(this), 'input', PMA_messages.strMysqlAllowedValuesTipTime);
} else if ($(this).hasClass('datefield')) {
PMA_tooltip($(this), 'input', PMA_messages.strMysqlAllowedValuesTipDate);
}
});
}
}
/**
* Toggle the Datetimepicker UI if the date value entered
* by the user in the 'text box' is not going to be accepted
* by the Datetimepicker plugin (but is accepted by MySQL)
*/
export function toggleDatepickerIfInvalid ($td, $input_field) {
// Regex allowed by the Datetimepicker UI
var dtexpDate = new RegExp(['^([0-9]{4})',
'-(((01|03|05|07|08|10|12)-((0[1-9])|([1-2][0-9])|(3[0-1])))|((02|04|06|09|11)',
'-((0[1-9])|([1-2][0-9])|30)))$'].join(''));
var dtexpTime = new RegExp(['^(([0-1][0-9])|(2[0-3]))',
':((0[0-9])|([1-5][0-9]))',
':((0[0-9])|([1-5][0-9]))(\.[0-9]{1,6}){0,1}$'].join(''));
// If key-ed in Time or Date values are unsupported by the UI, close it
if ($td.attr('data-type') === 'date' && ! dtexpDate.test($input_field.val())) {
$input_field.datepicker('hide');
} else if ($td.attr('data-type') === 'time' && ! dtexpTime.test($input_field.val())) {
$input_field.datepicker('hide');
} else {
$input_field.datepicker('show');
}
}

View File

@ -15,7 +15,7 @@ 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) {
$.ajaxPrefilter(function (options, originalOptions) {
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'));
@ -250,4 +250,6 @@ export function extendingValidatorMessages () {
window.jQ = $;
export const jQuery = $;
export {
$
};

View File

@ -48,10 +48,35 @@ function escapeJsString (unsafe) {
}
}
/**
* decode a string URL_encoded
*
* @param string str
* @return string the URL-decoded string
*/
function PMA_urldecode (str) {
if (typeof str !== 'undefined') {
return decodeURIComponent(str.replace(/\+/g, '%20'));
}
}
/**
* endecode a string URL_decoded
*
* @param string str
* @return string the URL-encoded string
*/
function PMA_urlencode (str) {
if (typeof str !== 'undefined') {
return encodeURIComponent(str).replace(/\%20/g, '+');
}
}
/**
* Module export
*/
export {
escapeHtml,
escapeJsString
escapeJsString,
PMA_urlencode
};

2255
js/src/utils/makegrid.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,10 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { PMA_getImage } from '../functions/get_image';
import { PMA_Messages as messages } from '../variables/export_variables';
/**
* Handles the resizing of a menu according to the available screen width
*
@ -17,7 +23,13 @@
* To restore the menu to a state like before it was initialized:
* $('#myMenu').menuResizer('destroy');
*
* @package PhpMyAdmin
* @access private
*
* @param {Element} $container
*
* @param {function} widthCalculator
*
* @return {void}
*/
function MenuResizer ($container, widthCalculator) {
var self = this;
@ -45,7 +57,7 @@ function MenuResizer ($container, widthCalculator) {
// create submenu container
var link = $('<a />', { href: '#', 'class': 'tab nowrap' })
.text(PMA_messages.strMore)
.text(messages.strMore)
.on('click', false); // same as event.preventDefault()
var img = $container.find('li img');
if (img.length) {
@ -80,54 +92,54 @@ 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 submenuW = $submenu.outerWidth(true);
var $submenuUl = $submenu.find('ul');
var $li = this.$container.find('> li');
var $li2 = $submenu_ul.find('li');
var more_shown = $li2.length > 0;
var $li2 = $submenuUl.find('li');
var moreShown = $li2.length > 0;
// Calculate the total width used by all the shown tabs
var total_len = more_shown ? submenu_w : 0;
var totalLen = moreShown ? submenuW : 0;
var l = $li.length - 1;
var i;
for (i = 0; i < l; i++) {
total_len += $($li[i]).outerWidth(true);
totalLen += $($li[i]).outerWidth(true);
}
var hasVScroll = document.body.scrollHeight > document.body.clientHeight;
if (hasVScroll) {
windowWidth += 15;
}
var navigationwidth = wmax;
// 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
while (totalLen >= 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;
var elWidth = el.outerWidth(true);
el.data('width', elWidth);
if (! moreShown) {
totalLen -= elWidth;
el.prependTo($submenuUl);
totalLen += submenuW;
moreShown = true;
} else {
total_len -= el_width;
el.prependTo($submenu_ul);
totalLen -= elWidth;
el.prependTo($submenuUl);
}
}
// 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');
totalLen += $($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)
if (totalLen < wmax ||
(i === $li2.length - 1 && totalLen - submenuW < wmax)
) {
$($li2[i]).insertBefore($submenu);
} else {
@ -143,7 +155,7 @@ MenuResizer.prototype.resize = function () {
} else {
$('.navigationbar').css({ 'width': 'auto' });
$('.navigationbar').css({ 'overflow': 'visible' });
if ($submenu_ul.find('li').length > 0) {
if ($submenuUl.find('li').length > 0) {
$submenu.addClass('shown');
} else {
$submenu.removeClass('shown');
@ -152,10 +164,10 @@ MenuResizer.prototype.resize = function () {
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');
$submenuUl.removeClass().addClass('only');
} else {
// Otherwise we align the submenu to the right edge of the tab
$submenu_ul.removeClass().addClass('notonly');
$submenuUl.removeClass().addClass('notonly');
}
if ($submenu.find('.tabactive').length) {
$submenu

View File

@ -11,9 +11,9 @@ import { PMA_Messages as messages } from '../variables/export_variables';
import { PMA_highlightSQL } from './sql';
/**
* @var {int} ajax_message_count Number of AJAX messages shown since page load
* @var {int} ajaxMessageCount Number of AJAX messages shown since page load
*/
let ajax_message_count = 0;
let ajaxMessageCount = 0;
/**
* Create a jQuery UI tooltip
@ -129,7 +129,7 @@ const PMA_ajaxShowMessage = (message, timeout, type) => {
.prependTo('#page_content');
}
// Update message count to create distinct message elements every time
ajax_message_count++;
ajaxMessageCount++;
// Remove all old messages, if any
$('span.ajax_notification[id^=ajax_message_num]').remove();
/**
@ -138,7 +138,7 @@ const PMA_ajaxShowMessage = (message, timeout, type) => {
*/
var $retval = $(
'<span class="ajax_notification" id="ajax_message_num_' +
ajax_message_count +
ajaxMessageCount +
'"></span>'
)
.hide()
@ -186,7 +186,7 @@ const PMA_ajaxShowMessage = (message, timeout, type) => {
* @return nothing
*/
function PMA_ajaxRemoveMessage ($thisMsgbox) {
if ($thisMsgbox !== undefined && $thisMsgbox instanceof jQuery) {
if ($thisMsgbox !== undefined && $thisMsgbox instanceof $) {
$thisMsgbox
.stop(true, true)
.fadeOut('medium');

View File

@ -1,13 +1,13 @@
import CodeMirror from 'codemirror';
import '../../../node_modules/codemirror/mode/sql/sql.js';
import '../../../node_modules/codemirror/addon/runmode/runmode.js';
import '../../../node_modules/codemirror/addon/hint/show-hint.js';
import '../../../node_modules/codemirror/addon/hint/sql-hint.js';
import '../../../node_modules/codemirror/addon/lint/lint.js';
// import '../../../node_modules/codemirror/addon/lint/sql-lint.js';
import 'codemirror/mode/sql/sql.js';
import 'codemirror/addon/runmode/runmode.js';
import 'codemirror/addon/hint/show-hint.js';
import 'codemirror/addon/hint/sql-hint.js';
import 'codemirror/addon/lint/lint.js';
import '../plugins/codemirror/sql-lint';
import { mysql_doc_builtin, mysql_doc_keyword } from '../consts/doclinks';
window.cm = CodeMirror;
import CommonParams from '../variables/common_params';
import { GlobalVariables, PMA_Messages as PMA_messages } from '../variables/export_variables';
/**
* Adds doc link to single highlighted SQL element
@ -18,7 +18,7 @@ function PMA_doc_add ($elm, params) {
}
var url = PMA_sprintf(
decodeURIComponent(mysql_doc_template),
decodeURIComponent(GlobalVariables.mysql_doc_template),
params[0]
);
if (params.length > 1) {
@ -106,6 +106,12 @@ export function PMA_highlightSQL ($base) {
let sql_autocomplete_in_progress = false;
let sql_autocomplete = false;
var sql_autocomplete_default_table = '';
export var sqlQueryOptions = {
codemirror_editor: false,
codemirror_inline_editor: false
};
export function codemirrorAutocompleteOnInputRead (instance) {
if (!sql_autocomplete_in_progress
&& (!instance.options.hintOptions.tables || !sql_autocomplete)) {
@ -119,8 +125,8 @@ export function codemirrorAutocompleteOnInputRead (instance) {
var href = 'db_sql_autocomplete.php';
var params = {
'ajax_request': true,
'server': PMA_commonParams.get('server'),
'db': PMA_commonParams.get('db'),
'server': CommonParams.get('server'),
'db': CommonParams.get('db'),
'no_debug': true
};
@ -140,7 +146,7 @@ export function codemirrorAutocompleteOnInputRead (instance) {
success: function (data) {
if (data.success) {
var tables = JSON.parse(data.tables);
sql_autocomplete_default_table = PMA_commonParams.get('table');
sql_autocomplete_default_table = CommonParams.get('table');
sql_autocomplete = [];
for (var table in tables) {
if (tables.hasOwnProperty(table)) {
@ -197,76 +203,43 @@ export function codemirrorAutocompleteOnInputRead (instance) {
}
/**
* Creates an SQL editor which supports auto completing etc.
*
* @param $textarea jQuery object wrapping the textarea to be made the editor
* @param options optional options for CodeMirror
* @param resize optional resizing ('vertical', 'horizontal', 'both')
* @param lintOptions additional options for lint
* Updates the input fields for the parameters based on the query
*/
export function PMA_getSQLEditor ($textarea, options, resize, lintOptions) {
if ($textarea.length > 0 && typeof CodeMirror !== 'undefined') {
// merge options for CodeMirror
var defaults = {
lineNumbers: true,
matchBrackets: true,
extraKeys: { 'Ctrl-Space': 'autocomplete' },
hintOptions: { 'completeSingle': false, 'completeOnSingleClick': true },
indentUnit: 4,
mode: 'text/x-mysql',
lineWrapping: true
};
export function updateQueryParameters () {
if ($('#parameterized').is(':checked')) {
var query = sqlQueryOptions.codemirror_editor
? sqlQueryOptions.codemirror_editor.getValue()
: $('#sqlquery').val();
if (CodeMirror.sqlLint) {
$.extend(defaults, {
gutters: ['CodeMirror-lint-markers'],
lint: {
'getAnnotations': CodeMirror.sqlLint,
'async': true,
'lintOptions': lintOptions
var allParameters = query.match(/:[a-zA-Z0-9_]+/g);
var parameters = [];
// get unique parameters
if (allParameters) {
$.each(allParameters, function (i, parameter) {
if ($.inArray(parameter, parameters) === -1) {
parameters.push(parameter);
}
});
} else {
$('#parametersDiv').text(PMA_messages.strNoParam);
return;
}
$.extend(true, defaults, options);
var $temp = $('<div />');
$temp.append($('#parametersDiv').children());
$('#parametersDiv').empty();
// create CodeMirror editor
var codemirrorEditor = CodeMirror.fromTextArea($textarea[0], defaults);
// allow resizing
if (! resize) {
resize = 'vertical';
}
var handles = '';
if (resize === 'vertical') {
handles = 's';
}
if (resize === 'both') {
handles = 'all';
}
if (resize === 'horizontal') {
handles = 'e, w';
}
$(codemirrorEditor.getWrapperElement())
.css('resize', resize)
.resizable({
handles: handles,
resize: function () {
codemirrorEditor.setSize($(this).width(), $(this).height());
}
});
// enable autocomplete
codemirrorEditor.on('inputRead', codemirrorAutocompleteOnInputRead);
// page locking
codemirrorEditor.on('change', function (e) {
e.data = {
value: 3,
content: codemirrorEditor.isClean(),
};
AJAX.lockPageHandler(e);
$.each(parameters, function (i, parameter) {
var paramName = parameter.substring(1);
var $param = $temp.find('#paramSpan_' + paramName);
if (! $param.length) {
$param = $('<span class="parameter" id="paramSpan_' + paramName + '" />');
$('<label for="param_' + paramName + '" />').text(parameter).appendTo($param);
$('<input type="text" name="parameters[' + parameter + ']" id="param_' + paramName + '" />').appendTo($param);
}
$('#parametersDiv').append($param);
});
return codemirrorEditor;
} else {
$('#parametersDiv').empty();
}
return null;
}

View File

@ -46,6 +46,12 @@ Variables.setGlobalVars(window.globalVars);
/**
* Importing common parameters like db, table, url etc
*
* @argument {hash} window.common_params
* @argument {hash} window.commonParams
*/
CommonParams.setAll(window.common_params);
CommonParams.setAll(window.commonParams);
CommonParams.set('CodemirrorEnable', window.CodemirrorEnable);
CommonParams.set('LintEnable', window.LintEnable);
CommonParams.set('ConsoleEnterExecutes', window.ConsoleEnterExecutes);

View File

@ -49,7 +49,6 @@ class ServerPluginsController extends Controller
$header = $this->response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('vendor/jquery/jquery.tablesorter.js');
$scripts->addFile('server_plugins');
/**

View File

@ -182,7 +182,6 @@ 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('vendors~index_new.js');
$this->_scripts->addFile('index_new.js');
$this->_scripts->addFile('keyhandler.js');
@ -207,6 +206,7 @@ class Header
$this->_scripts->addFile('config');
$this->_scripts->addFile('doclinks.js');
$this->_scripts->addFile('functions.js');
$this->_scripts->addFile('functions');
$this->_scripts->addFile('navigation');
$this->_scripts->addFile('navigation.js');
$this->_scripts->addFile('indexes.js');
@ -220,6 +220,7 @@ class Header
$this->_scripts->addFile('shortcuts_handler');
}
$this->_scripts->addCode($this->getJsParamsCode());
$this->_scripts->addCodeNew($this->getJsParamsCode(true));
}
/**
@ -287,9 +288,11 @@ class Header
* Returns, as a string, a list of parameters
* used on the client side
*
* @param bool $flag to check for CommonParams for Modular Code
*
* @return string
*/
public function getJsParamsCode(): string
public function getJsParamsCode($flag = false): string
{
$params = $this->getJsParams();
foreach ($params as $key => $value) {
@ -299,7 +302,11 @@ class Header
$params[$key] = $key . ':"' . Sanitize::escapeJsString($value) . '"';
}
}
return 'PMA_commonParams.setAll({' . implode(',', $params) . '});';
if ($flag) {
return 'var commonParams = {' . implode(',', $params) . '};';
} else {
return 'PMA_commonParams.setAll({' . implode(',', $params) . '});';
}
}
/**
@ -434,6 +441,18 @@ class Header
);
}
}
$this->_scripts->addCodeNew(
'CodemirrorEnable='
. ($GLOBALS['cfg']['CodemirrorEnable'] ? 'true' : 'false')
);
$this->_scripts->addCodeNew(
'LintEnable='
. ($GLOBALS['cfg']['LintEnable'] ? 'true' : 'false')
);
$this->_scripts->addCodeNew(
'ConsoleEnterExecutes='
. ($GLOBALS['cfg']['ConsoleEnterExecutes'] ? 'true' : 'false')
);
$this->_scripts->addCode(
'ConsoleEnterExecutes='
. ($GLOBALS['cfg']['ConsoleEnterExecutes'] ? 'true' : 'false')

View File

@ -36,6 +36,13 @@ class Scripts
* @var array of strings
*/
private $_code;
/**
* An array of discrete javascript code snippets for top script
*
* @access private
* @var array of strings
*/
private $_codeNew;
/**
* Returns HTML code to include javascript file.
@ -157,6 +164,19 @@ class Scripts
$this->_code .= "$code\n";
}
/**
* Adds a temporary new code snippet to the code to be executed
* at the top of the script before other scripts
*
* @param string $code The JS code to be added
*
* @return void
*/
public function addCodeNew($code)
{
$this->_codeNew .= "$code\n";
}
/**
* Returns a list with filenames and a flag to indicate
* whether to register onload events for this file
@ -187,6 +207,13 @@ class Scripts
public function getDisplay()
{
$retval = '';
$retval .= '<script data-cfasync="false" type="text/javascript">';
$retval .= "// <![CDATA[\n";
$retval .= $this->_codeNew;
$retval .= '// ]]>';
$retval .= '</script>';
if (count($this->_files) > 0) {
$retval .= $this->_includeFiles(
$this->_files

View File

@ -278,7 +278,7 @@ class SqlQueryForm
. '<label>' . __('Columns') . '</label>'
. '<select id="tablefields" name="dummy" '
. 'size="' . ($GLOBALS['cfg']['TextareaRows'] - 2) . '" '
. 'multiple="multiple" ondblclick="insertValueQuery()">';
. 'multiple="multiple">';
foreach ($columns_list as $field) {
$html .= '<option value="'
. Util::backquote(htmlspecialchars($field['Field']))
@ -295,12 +295,11 @@ class SqlQueryForm
. '<div id="tablefieldinsertbuttoncontainer">';
if (Util::showIcons('ActionLinksMode')) {
$html .= '<input type="button" class="button" name="insert"'
. ' value="&lt;&lt;" onclick="insertValueQuery()"'
. ' value="&lt;&lt;" id="tablefieldsSubmitLinkMode"'
. ' title="' . __('Insert') . '" />';
} else {
$html .= '<input type="button" class="button" name="insert"'
. ' value="' . __('Insert') . '"'
. ' onclick="insertValueQuery()" />';
. ' value="' . __('Insert') . '" id="tablefieldsSubmitNonLinkMode" />';
}
$html .= '</div>' . "\n"
. '</div>' . "\n";

View File

@ -9,7 +9,8 @@
"dev:wds": "webpack-dev-server --progress",
"prod:build": "del js/lib js/dist && babel js/src/ -d js/lib --ignore .test.js && cross-env NODE_ENV=production webpack -p --env.production --progress",
"lint:check": "eslint js/src/*.js",
"lint:fix": "eslint js/src/*.js --fix"
"lint:fix": "eslint js/src/*.js --fix",
"generate-docs": "node_modules/.bin/jsdoc --configure .jsdoc.json --verbose"
},
"dependencies": {
"codemirror": "5.37.0",
@ -24,7 +25,7 @@
"js-cookie": "2.2.0",
"sprintf-js": "^1.1.1",
"tracekit": "0.4.5",
"updated-jqplot": "1.0.9",
"updated-jqplot": "1.0.9-2",
"zxcvbn": "4.4.2"
},
"devDependencies": {
@ -36,6 +37,8 @@
"cross-env": "^5.1.5",
"del-cli": "^1.1.0",
"eslint": "^4.9.0",
"jsdoc": "^3.5.5",
"minami": "^1.2.3",
"webpack": "^4.8.3",
"webpack-bundle-analyzer": "^2.13.1",
"webpack-cli": "^2.1.3",

View File

@ -24,9 +24,7 @@ PageSettings::showGroup('Sql');
$response = Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('makegrid.js');
$scripts->addFile('vendor/jquery/jquery.uitablefilter.js');
$scripts->addFile('sql.js');
$scripts->addFile('sql');
require_once 'libraries/server_common.inc.php';

View File

@ -73,20 +73,9 @@ if ($response->isAjax()) {
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('vendor/jquery/jquery.tablesorter.js');
$scripts->addFile('vendor/jquery/jquery.sortableTable.js');
// for charting
$scripts->addFile('vendor/jqplot/jquery.jqplot.js');
$scripts->addFile('vendor/jqplot/plugins/jqplot.pieRenderer.js');
$scripts->addFile('vendor/jqplot/plugins/jqplot.enhancedPieLegendRenderer.js');
$scripts->addFile('vendor/jqplot/plugins/jqplot.canvasTextRenderer.js');
$scripts->addFile('vendor/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js');
$scripts->addFile('vendor/jqplot/plugins/jqplot.dateAxisRenderer.js');
$scripts->addFile('vendor/jqplot/plugins/jqplot.highlighter.js');
$scripts->addFile('vendor/jqplot/plugins/jqplot.cursor.js');
$scripts->addFile('jqplot/plugins/jqplot.byteFormatter.js');
$scripts->addFile('server_status_monitor.js');
$scripts->addFile('server_status_sorter.js');
$scripts->addFile('server_status_monitor');
$scripts->addFile('server_status_sorter');
/**
* Output

View File

@ -23,13 +23,6 @@ $response = Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
// for charting
$scripts->addFile('chart.js');
$scripts->addFile('vendor/jqplot/jquery.jqplot.js');
$scripts->addFile('vendor/jqplot/plugins/jqplot.pieRenderer.js');
$scripts->addFile('vendor/jqplot/plugins/jqplot.highlighter.js');
$scripts->addFile('vendor/jqplot/plugins/jqplot.enhancedPieLegendRenderer.js');
$scripts->addFile('vendor/jquery/jquery.tablesorter.js');
$scripts->addFile('server_status_sorter');
$scripts->addFile('server_status_queries');

View File

@ -38,8 +38,7 @@ $response = Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('server_status_variables');
$scripts->addFile('vendor/jquery/jquery.tablesorter.js');
$scripts->addFile('server_status_sorter.js');
$scripts->addFile('server_status_sorter');
$response->addHTML('<div>');
$response->addHTML($serverStatusData->getMenuHtml());

View File

@ -24,9 +24,7 @@ PageSettings::showGroup('Sql');
$response = Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('makegrid.js');
$scripts->addFile('vendor/jquery/jquery.uitablefilter.js');
$scripts->addFile('sql.js');
$scripts->addFile('sql');
require 'libraries/tbl_common.inc.php';
$url_query .= '&amp;goto=tbl_sql.php&amp;back=tbl_sql.php';

View File

@ -117,6 +117,28 @@ class ScriptsTest extends PmaTestCase
);
}
/**
* test for addCodeNew
*
* @return void
*/
public function testAddCodeNew()
{
$this->object->addCodeNew('alert(\'CodeAdded\');');
$this->assertEquals(
'<script data-cfasync="false" type="text/javascript">// <![CDATA[' . "\n"
. 'alert(\'CodeAdded\');' . "\n"
. '// ]]></script>'
. '<script data-cfasync="false" type="text/javascript">// <![CDATA[' . "\n"
. 'AJAX.scriptHandler;' . "\n"
. '$(function() {});' . "\n"
. '// ]]></script>',
$this->object->getDisplay()
);
}
/**
* test for addCode
*
@ -128,11 +150,13 @@ class ScriptsTest extends PmaTestCase
$this->object->addCode('alert(\'CodeAdded\');');
$this->assertEquals(
'<script data-cfasync="false" type="text/javascript">// <![CDATA[
alert(\'CodeAdded\');
AJAX.scriptHandler;
$(function() {});
// ]]></script>',
'<script data-cfasync="false" type="text/javascript">// <![CDATA[' . "\n"
. '// ]]></script>'
. '<script data-cfasync="false" type="text/javascript">// <![CDATA[' . "\n"
. 'alert(\'CodeAdded\');' . "\n"
. 'AJAX.scriptHandler;' . "\n"
. '$(function() {});' . "\n"
. '// ]]></script>',
$this->object->getDisplay()
);
}

View File

@ -46,7 +46,10 @@ function WebpackConfig (env) {
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new webpack.NoEmitOnErrorsPlugin()
new webpack.NoEmitOnErrorsPlugin(),
new webpack.ProvidePlugin({
jQuery: 'jquery'
}),
];
if (MODE === 'development') {
plugins.push(new BundleAnalyzer());