mirror of
https://github.com/vrana/adminer.git
synced 2025-08-30 09:39:51 +02:00
Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
81e337bed1 | ||
|
18ddbf1d60 | ||
|
e4235d21e5 | ||
|
10dfc54bf4 | ||
|
af3c863be3 | ||
|
6cd5495c1b | ||
|
78ad8381ab | ||
|
87fc82f88e | ||
|
0519a0b985 | ||
|
f61cf1ba0c | ||
|
fc2e025603 | ||
|
659e72b692 | ||
|
123373ca82 | ||
|
e99f2d90cf | ||
|
bdabc5aa13 | ||
|
92f3e0ca00 | ||
|
aa1266e4f2 |
13
CHANGELOG.md
13
CHANGELOG.md
@@ -1,5 +1,18 @@
|
||||
# Changelog
|
||||
|
||||
## Adminer 4.11 (2024-10-30)
|
||||
- Support drag-n-drop moving on touch screens
|
||||
- Fix drag-n-drop moving of function parameters
|
||||
- Update project information in comments
|
||||
- Update CS and SK translations
|
||||
- Show help popup after a short delay
|
||||
- PostgreSQL: Show list of schemas in database, unify lists of sequences and user types
|
||||
- MariaDB: Fix several links to documentation pages
|
||||
- MySQL: Fix highlighting current table in menu on macOS
|
||||
- MS SQL: Prefix Unicode strings with 'N' so they are treated correctly
|
||||
- Fix printing error message while validating server URL
|
||||
- Small CSS tuning
|
||||
|
||||
## Adminer 4.10 (2024-10-22)
|
||||
|
||||
### UI changes and improvements
|
||||
|
@@ -182,8 +182,8 @@ foreach ($engines as $engine) {
|
||||
<p>
|
||||
<?php if (support("columns") || $TABLE == "") { ?>
|
||||
<?php echo lang('Table name'); ?>: <input name="name" data-maxlength="64" value="<?php echo h($row["name"]); ?>" autocapitalize="off">
|
||||
<?php if ($TABLE == "" && !$_POST) { echo script("focus(qs('#form')['name']);"); } ?>
|
||||
<?php echo ($engines ? "<select name='Engine'>" . optionlist(array("" => "(" . lang('engine') . ")") + $engines, $row["Engine"]) . "</select>" . on_help("getTarget(event).value", 1) . script("qsl('select').onchange = helpClose;") : ""); ?>
|
||||
<?php if ($TABLE == "" && !$_POST) { echo script("focus(gid('form')['name']);"); } ?>
|
||||
<?php echo ($engines ? "<select name='Engine'>" . optionlist(array("" => "(" . lang('engine') . ")") + $engines, $row["Engine"]) . "</select>" . help_script_command("value", true) : ""); ?>
|
||||
<?php echo ($collations && !preg_match("~sqlite|mssql~", $jush) ? html_select("Collation", array("" => "(" . lang('collation') . ")") + $collations, $row["Collation"]) : ""); ?>
|
||||
<input type="submit" value="<?php echo lang('Save'); ?>">
|
||||
<?php } ?>
|
||||
@@ -221,7 +221,7 @@ if (support("partitioning")) {
|
||||
print_fieldset("partition", lang('Partition by'), $row["partition_by"]);
|
||||
?>
|
||||
<p>
|
||||
<?php echo "<select name='partition_by'>" . optionlist(array("" => "") + $partition_by, $row["partition_by"]) . "</select>" . on_help("getTarget(event).value.replace(/./, 'PARTITION BY \$&')", 1) . script("qsl('select').onchange = partitionByChange;"); ?>
|
||||
<?php echo "<select name='partition_by'>" . optionlist(array("" => "") + $partition_by, $row["partition_by"]) . "</select>" . help_script_command("value.replace(/./, 'PARTITION BY \$&')", true) . script("qsl('select').onchange = partitionByChange;"); ?>
|
||||
(<input name="partition" value="<?php echo h($row["partition"]); ?>">)
|
||||
<?php echo lang('Partitions'); ?>: <input type="number" name="partitions" class="size<?php echo ($partition_table || !$row["partition_by"] ? " hidden" : ""); ?>" value="<?php echo h($row["partitions"]); ?>">
|
||||
<table cellspacing="0" id="partition-table"<?php echo ($partition_table ? "" : " class='hidden'"); ?>>
|
||||
|
@@ -66,7 +66,7 @@ echo ($_POST["add_x"] || strpos($name, "\n")
|
||||
'mariadb' => "supported-character-sets-and-collations/",
|
||||
'mssql' => "ms187963.aspx",
|
||||
)) : "");
|
||||
echo script("focus(qs('#name'));");
|
||||
echo script("focus(gid('name'));");
|
||||
?>
|
||||
<input type="submit" value="<?php echo lang('Save'); ?>">
|
||||
<?php
|
||||
|
@@ -47,7 +47,28 @@ if ($tables_views && !$error && !$_POST["search"]) {
|
||||
page_header(($_GET["ns"] == "" ? lang('Database') . ": " . h(DB) : lang('Schema') . ": " . h($_GET["ns"])), $error, true);
|
||||
|
||||
if ($adminer->homepage()) {
|
||||
if ($_GET["ns"] !== "") {
|
||||
if ($_GET["ns"] === "") {
|
||||
echo "<h3 id='schemas'>" . lang('Schemas') . "</h3>\n";
|
||||
$schemas = schemas();
|
||||
if (!$schemas) {
|
||||
echo "<p class='message'>" . lang('No schemas.') . "\n";
|
||||
} else {
|
||||
// TODO: Checkboxes for batch dropping of schemas.
|
||||
echo "<div class='scrollable'>\n",
|
||||
"<table class='nowrap'>\n",
|
||||
'<thead><tr class="wrap">',
|
||||
'<th>', lang('Schema'), "</th>",
|
||||
'</tr></thead>';
|
||||
|
||||
foreach ($schemas as $name) {
|
||||
echo "<tr", odd(), ">",
|
||||
"<th><a href='", h(ME), "ns=" . urlencode($name), "' title='", lang('Show schema'), "'>" . h($name) . "</a></th>",
|
||||
"</tr>";
|
||||
}
|
||||
|
||||
echo '</table></div>';
|
||||
}
|
||||
} else {
|
||||
echo "<h3 id='tables-views'>" . lang('Tables and views') . "</h3>\n";
|
||||
$tables_list = tables_list();
|
||||
if (!$tables_list) {
|
||||
@@ -73,7 +94,7 @@ if ($adminer->homepage()) {
|
||||
echo "<table cellspacing='0' class='nowrap checkable'>\n";
|
||||
echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});");
|
||||
echo '<thead><tr class="wrap">';
|
||||
echo '<td><input id="check-all" type="checkbox" class="jsonly">' . script("qs('#check-all').onclick = partial(formCheck, /^(tables|views)\[/);", "");
|
||||
echo '<td><input id="check-all" type="checkbox" class="jsonly">' . script("gid('check-all').onclick = partial(formCheck, /^(tables|views)\[/);", "");
|
||||
echo '<th>' . lang('Table');
|
||||
echo '<td>' . lang('Engine') . doc_link(array('sql' => 'storage-engines.html'));
|
||||
echo '<td>' . lang('Collation') . doc_link(array('sql' => 'charset-charsets.html', 'mariadb' => 'supported-character-sets-and-collations/'));
|
||||
@@ -126,17 +147,17 @@ if ($adminer->homepage()) {
|
||||
echo "</div>\n";
|
||||
if (!information_schema(DB)) {
|
||||
echo "<div class='footer'><div>\n";
|
||||
$vacuum = "<input type='submit' value='" . lang('Vacuum') . "'> " . on_help("'VACUUM'");
|
||||
$optimize = "<input type='submit' name='optimize' value='" . lang('Optimize') . "'> " . on_help($jush == "sql" ? "'OPTIMIZE TABLE'" : "'VACUUM OPTIMIZE'");
|
||||
$vacuum = "<input type='submit' value='" . lang('Vacuum') . "'> " . help_script("VACUUM");
|
||||
$optimize = "<input type='submit' name='optimize' value='" . lang('Optimize') . "'> " . help_script($jush == "sql" ? "OPTIMIZE TABLE" : "VACUUM OPTIMIZE");
|
||||
echo "<fieldset><legend>" . lang('Selected') . " <span id='selected'></span></legend><div>"
|
||||
. ($jush == "sqlite" ? $vacuum
|
||||
: ($jush == "pgsql" ? $vacuum . $optimize
|
||||
: ($jush == "sql" ? "<input type='submit' value='" . lang('Analyze') . "'> " . on_help("'ANALYZE TABLE'") . $optimize
|
||||
. "<input type='submit' name='check' value='" . lang('Check') . "'> " . on_help("'CHECK TABLE'")
|
||||
. "<input type='submit' name='repair' value='" . lang('Repair') . "'> " . on_help("'REPAIR TABLE'")
|
||||
: ($jush == "sql" ? "<input type='submit' value='" . lang('Analyze') . "'> " . help_script("ANALYZE TABLE") . $optimize
|
||||
. "<input type='submit' name='check' value='" . lang('Check') . "'> " . help_script("CHECK TABLE")
|
||||
. "<input type='submit' name='repair' value='" . lang('Repair') . "'> " . help_script("REPAIR TABLE")
|
||||
: "")))
|
||||
. "<input type='submit' name='truncate' value='" . lang('Truncate') . "'> " . on_help($jush == "sqlite" ? "'DELETE'" : "'TRUNCATE" . ($jush == "pgsql" ? "'" : " TABLE'")) . confirm()
|
||||
. "<input type='submit' name='drop' value='" . lang('Drop') . "'>" . on_help("'DROP TABLE'") . confirm() . "\n";
|
||||
. "<input type='submit' name='truncate' value='" . lang('Truncate') . "'> " . help_script($jush == "sqlite" ? "DELETE" : ("TRUNCATE" . ($jush == "pgsql" ? "" : " TABLE"))) . confirm()
|
||||
. "<input type='submit' name='drop' value='" . lang('Drop') . "'>" . help_script("DROP TABLE") . confirm() . "\n";
|
||||
$databases = (support("scheme") ? $adminer->schemas() : $adminer->databases());
|
||||
if (count($databases) != 1 && $jush != "sqlite") {
|
||||
$db = (isset($_POST["target"]) ? $_POST["target"] : (support("scheme") ? $_GET["ns"] : DB));
|
||||
@@ -186,12 +207,16 @@ if ($adminer->homepage()) {
|
||||
echo "<h3 id='sequences'>" . lang('Sequences') . "</h3>\n";
|
||||
$sequences = get_vals("SELECT sequence_name FROM information_schema.sequences WHERE sequence_schema = current_schema() ORDER BY sequence_name");
|
||||
if ($sequences) {
|
||||
echo "<table>\n";
|
||||
echo "<thead><tr><th>" . lang('Name') . "</thead>\n";
|
||||
echo "<table>\n",
|
||||
"<thead><tr><th>", lang('Name'), "</th><td></td></tr></thead>\n";
|
||||
|
||||
odd('');
|
||||
foreach ($sequences as $val) {
|
||||
echo "<tr" . odd() . "><th><a href='" . h(ME) . "sequence=" . urlencode($val) . "'>" . h($val) . "</a>\n";
|
||||
echo "<tr", odd(), ">",
|
||||
"<th>", h($val), "</th>",
|
||||
"<td><a href='", h(ME), "sequence=", urlencode($val), "'>", lang('Alter'), "</a></td>\n";
|
||||
}
|
||||
|
||||
echo "</table>\n";
|
||||
}
|
||||
echo "<p class='links'><a href='" . h(ME) . "sequence='>" . lang('Create sequence') . "</a>\n";
|
||||
@@ -201,12 +226,16 @@ if ($adminer->homepage()) {
|
||||
echo "<h3 id='user-types'>" . lang('User types') . "</h3>\n";
|
||||
$user_types = types();
|
||||
if ($user_types) {
|
||||
echo "<table>\n";
|
||||
echo "<thead><tr><th>" . lang('Name') . "</thead>\n";
|
||||
echo "<table>\n",
|
||||
"<thead><tr><th>", lang('Name'), "</th><td></td></tr></thead>\n";
|
||||
|
||||
odd('');
|
||||
foreach ($user_types as $val) {
|
||||
echo "<tr" . odd() . "><th><a href='" . h(ME) . "type=" . urlencode($val) . "'>" . h($val) . "</a>\n";
|
||||
echo "<tr", odd(), ">",
|
||||
"<th>", h($val), "</th>",
|
||||
"<td><a href='", h(ME), "type=", urlencode($val), "'>", lang('Alter'), "</a></td>\n";
|
||||
}
|
||||
|
||||
echo "</table>\n";
|
||||
}
|
||||
echo "<p class='links'><a href='" . h(ME) . "type='>" . lang('Create type') . "</a>\n";
|
||||
|
@@ -40,7 +40,8 @@ if (isset($_GET["mssql"])) {
|
||||
}
|
||||
|
||||
function quote($string) {
|
||||
return "'" . str_replace("'", "''", $string) . "'";
|
||||
$unicode = strlen($string) != strlen(utf8_decode($string));
|
||||
return ($unicode ? "N" : "") . "'" . str_replace("'", "''", $string) . "'";
|
||||
}
|
||||
|
||||
function select_db($database) {
|
||||
@@ -163,7 +164,8 @@ if (isset($_GET["mssql"])) {
|
||||
}
|
||||
|
||||
function quote($string) {
|
||||
return "'" . str_replace("'", "''", $string) . "'";
|
||||
$unicode = strlen($string) != strlen(utf8_decode($string));
|
||||
return ($unicode ? "N" : "") . "'" . str_replace("'", "''", $string) . "'";
|
||||
}
|
||||
|
||||
function select_db($database) {
|
||||
|
@@ -500,11 +500,14 @@ if (!defined("DRIVER")) {
|
||||
* @return array array($name => array("Name" => , "Engine" => , "Comment" => , "Oid" => , "Rows" => , "Collation" => , "Auto_increment" => , "Data_length" => , "Index_length" => , "Data_free" => )) or only inner array with $name
|
||||
*/
|
||||
function table_status($name = "", $fast = false) {
|
||||
$return = array();
|
||||
foreach (get_rows($fast && min_version(5)
|
||||
? "SELECT TABLE_NAME AS Name, ENGINE AS Engine, CREATE_OPTIONS AS Create_options, TABLE_COMMENT AS Comment FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() " . ($name != "" ? "AND TABLE_NAME = " . q($name) : "ORDER BY Name")
|
||||
: "SHOW TABLE STATUS" . ($name != "" ? " LIKE " . q(addcslashes($name, "%_\\")) : "")
|
||||
) as $row) {
|
||||
if ($fast && min_version(5)) {
|
||||
$query = "SELECT TABLE_NAME AS Name, ENGINE AS Engine, CREATE_OPTIONS AS Create_options, TABLE_COMMENT AS Comment FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() " . ($name != "" ? "AND TABLE_NAME = " . q($name) : "ORDER BY Name");
|
||||
} else {
|
||||
$query = "SHOW TABLE STATUS" . ($name != "" ? " LIKE " . q(addcslashes($name, "%_\\")) : "");
|
||||
}
|
||||
|
||||
$tables = [];
|
||||
foreach (get_rows($query) as $row) {
|
||||
if ($row["Engine"] == "InnoDB") {
|
||||
// ignore internal comment, unnecessary since MySQL 5.1.21
|
||||
$row["Comment"] = preg_replace('~(?:(.+); )?InnoDB free: .*~', '\1', $row["Comment"]);
|
||||
@@ -513,11 +516,15 @@ if (!defined("DRIVER")) {
|
||||
$row["Comment"] = "";
|
||||
}
|
||||
if ($name != "") {
|
||||
// MariaDB: Table name is returned as lowercase on macOS, so we fix it here.
|
||||
$row["Name"] = $name;
|
||||
return $row;
|
||||
}
|
||||
$return[$row["Name"]] = $row;
|
||||
|
||||
$tables[$row["Name"]] = $row;
|
||||
}
|
||||
return $return;
|
||||
|
||||
return $tables;
|
||||
}
|
||||
|
||||
/** Find out whether the identifier is view
|
||||
|
@@ -182,8 +182,8 @@ $prefixes = array();
|
||||
if (DB != "") {
|
||||
$checked = ($TABLE != "" ? "" : " checked");
|
||||
echo "<thead><tr>";
|
||||
echo "<th style='text-align: left;'><label class='block'><input type='checkbox' id='check-tables'$checked>" . lang('Tables') . "</label>" . script("qs('#check-tables').onclick = partial(formCheck, /^tables\\[/);", "");
|
||||
echo "<th style='text-align: right;'><label class='block'>" . lang('Data') . "<input type='checkbox' id='check-data'$checked></label>" . script("qs('#check-data').onclick = partial(formCheck, /^data\\[/);", "");
|
||||
echo "<th style='text-align: left;'><label class='block'><input type='checkbox' id='check-tables'$checked>" . lang('Tables') . "</label>" . script("gid('check-tables').onclick = partial(formCheck, /^tables\\[/);", "");
|
||||
echo "<th style='text-align: right;'><label class='block'>" . lang('Data') . "<input type='checkbox' id='check-data'$checked></label>" . script("gid('check-data').onclick = partial(formCheck, /^data\\[/);", "");
|
||||
echo "</thead>\n";
|
||||
|
||||
$views = "";
|
||||
@@ -208,7 +208,7 @@ if (DB != "") {
|
||||
} else {
|
||||
echo "<thead><tr><th style='text-align: left;'>";
|
||||
echo "<label class='block'><input type='checkbox' id='check-databases'" . ($TABLE == "" ? " checked" : "") . ">" . lang('Database') . "</label>";
|
||||
echo script("qs('#check-databases').onclick = partial(formCheck, /^databases\\[/);", "");
|
||||
echo script("gid('check-databases').onclick = partial(formCheck, /^databases\\[/);", "");
|
||||
echo "</thead>\n";
|
||||
$databases = $adminer->databases();
|
||||
if ($databases) {
|
||||
|
@@ -129,7 +129,7 @@ class Adminer {
|
||||
echo "<table cellspacing='0' class='layout'>\n";
|
||||
echo $this->loginFormField('driver', '<tr><th>' . lang('System') . '<td>', html_select("auth[driver]", $drivers, DRIVER, "loginDriver(this);") . "\n");
|
||||
echo $this->loginFormField('server', '<tr><th>' . lang('Server') . '<td>', '<input name="auth[server]" value="' . h(SERVER) . '" title="hostname[:port]" placeholder="localhost" autocapitalize="off">' . "\n");
|
||||
echo $this->loginFormField('username', '<tr><th>' . lang('Username') . '<td>', '<input name="auth[username]" id="username" value="' . h($_GET["username"]) . '" autocomplete="username" autocapitalize="off">' . script("focus(qs('#username')); qs('#username').form['auth[driver]'].onchange();"));
|
||||
echo $this->loginFormField('username', '<tr><th>' . lang('Username') . '<td>', '<input name="auth[username]" id="username" value="' . h($_GET["username"]) . '" autocomplete="username" autocapitalize="off">' . script("focus(gid('username')); gid('username').form['auth[driver]'].onchange();"));
|
||||
echo $this->loginFormField('password', '<tr><th>' . lang('Password') . '<td>', '<input type="password" name="auth[password]" autocomplete="current-password">' . "\n");
|
||||
echo $this->loginFormField('db', '<tr><th>' . lang('Database') . '<td>', '<input name="auth[db]" value="' . h($_GET["db"]) . '" autocapitalize="off">' . "\n");
|
||||
echo "</table>\n";
|
||||
@@ -424,8 +424,8 @@ class Adminer {
|
||||
echo "<select name='columns[$i][fun]'>",
|
||||
optionlist([-1 => ""] + array_filter([lang('Functions') => $functions, lang('Aggregation') => $grouping]), $val["fun"]),
|
||||
"</select>",
|
||||
on_help("getTarget(event).value && getTarget(event).value.replace(/ |\$/, '(') + ')'", 1),
|
||||
script("qsl('select').onchange = (event) => { helpClose();" . ($key !== "" ? "" : " qsl('select, input:not(.remove)', event.target.parentNode).onchange();") . " };", ""),
|
||||
help_script_command("value && value.replace(/ |\$/, '(') + ')'", true),
|
||||
script("qsl('select').onchange = (event) => { " . ($key !== "" ? "" : " qsl('select, input:not(.remove)', event.target.parentNode).onchange();") . " };", ""),
|
||||
"($column)";
|
||||
} else {
|
||||
echo $column;
|
||||
@@ -557,7 +557,7 @@ class Adminer {
|
||||
json_row($key);
|
||||
}
|
||||
echo ";\n";
|
||||
echo "selectFieldChange.call(qs('#form')['select']);\n";
|
||||
echo "selectFieldChange.call(gid('form')['select']);\n";
|
||||
echo "</script>\n";
|
||||
echo "</div></fieldset>\n";
|
||||
}
|
||||
@@ -1073,7 +1073,7 @@ class Adminer {
|
||||
}
|
||||
}
|
||||
if ($output) {
|
||||
echo "<ul id='logins'>\n$output</ul>\n" . script("mixin(qs('#logins'), {onmouseover: menuOver, onmouseout: menuOut});");
|
||||
echo "<ul id='logins'>\n$output</ul>\n" . script("mixin(gid('logins'), {onmouseover: menuOver, onmouseout: menuOut});");
|
||||
}
|
||||
} else {
|
||||
$tables = array();
|
||||
@@ -1156,7 +1156,7 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
|
||||
|
||||
if ($databases) {
|
||||
echo "<select id='database-select' name='db'>" . optionlist(["" => lang('Database')] + $databases, DB) . "</select>"
|
||||
. script("mixin(qs('#database-select'), {onmousedown: dbMouseDown, onchange: dbChange});");
|
||||
. script("mixin(gid('database-select'), {onmousedown: dbMouseDown, onchange: dbChange});");
|
||||
} else {
|
||||
echo "<input id='database-select' name='db' value='" . h(DB) . "' autocapitalize='off'>\n";
|
||||
}
|
||||
@@ -1164,7 +1164,7 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
|
||||
|
||||
if (support("scheme") && $missing != "db" && DB != "" && $connection->select_db(DB)) {
|
||||
echo "<br><select id='scheme-select' name='ns'>" . optionlist(["" => lang('Schema')] + $adminer->schemas(), $_GET["ns"]) . "</select>"
|
||||
. script("mixin(qs('#scheme-select'), {onmousedown: dbMouseDown, onchange: dbChange});");
|
||||
. script("mixin(gid('scheme-select'), {onmousedown: dbMouseDown, onchange: dbChange});");
|
||||
|
||||
if ($_GET["ns"] != "") {
|
||||
set_schema($_GET["ns"]);
|
||||
@@ -1200,7 +1200,7 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
|
||||
* @return null
|
||||
*/
|
||||
function tablesPrint($tables) {
|
||||
echo "<ul id='tables'>" . script("mixin(qs('#tables'), {onmouseover: menuOver, onmouseout: menuOut});");
|
||||
echo "<ul id='tables'>" . script("mixin(gid('tables'), {onmouseover: menuOver, onmouseout: menuOut});");
|
||||
|
||||
foreach ($tables as $table => $status) {
|
||||
$name = $this->tableName($status);
|
||||
|
@@ -71,7 +71,7 @@ if (!function_exists('is_server_host_valid')) {
|
||||
*/
|
||||
function build_http_url($server, $username, $password, $defaultServer, $defaultPort = null) {
|
||||
if (!preg_match('~^(https?://)?([^:]*)(:\d+)?$~', rtrim($server, '/'), $matches)) {
|
||||
$this->error = lang('Invalid server or credentials.');
|
||||
auth_error(lang('Invalid server or credentials.'));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -29,9 +29,9 @@ function page_header($title, $error = "", $breadcrumb = [], $title2 = "") {
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="robots" content="noindex">
|
||||
<title><?php echo $title_page; ?></title>
|
||||
<link rel="stylesheet" type="text/css" href="../adminer/static/default.css">
|
||||
<?php echo script_src("../adminer/static/functions.js"); ?>
|
||||
<?php echo script_src("static/editing.js"); ?>
|
||||
<link rel="stylesheet" type="text/css" href="../adminer/static/default.css?<?php echo filemtime("../adminer/static/default.css"); ?>">
|
||||
<?php echo script_src("../adminer/static/functions.js?" . filemtime("../adminer/static/functions.js")); ?>
|
||||
<?php echo script_src("static/editing.js?" . filemtime("../adminer/static/editing.js")); ?>
|
||||
<?php if ($adminer->head()) { ?>
|
||||
<link rel="shortcut icon" type="image/x-icon" href="../adminer/static/favicon.ico">
|
||||
<link rel="apple-touch-icon" href="../adminer/static/favicon.ico">
|
||||
@@ -54,7 +54,7 @@ function page_header($title, $error = "", $breadcrumb = [], $title2 = "") {
|
||||
</script>
|
||||
|
||||
<div id="help" class="jush-<?php echo $jush; ?> jsonly hidden"></div>
|
||||
<?php echo script("mixin(qs('#help'), {onmouseover: function () { helpOpen = 1; }, onmouseout: helpMouseout});"); ?>
|
||||
<?php echo script("initHelpPopup();"); ?>
|
||||
|
||||
<div id="content">
|
||||
<?php
|
||||
|
@@ -297,7 +297,7 @@ function edit_fields(array $fields, array $collations, $type = "TABLE", $foreign
|
||||
}
|
||||
?>
|
||||
<th id="label-name"><?php echo ($type == "TABLE" ? lang('Column name') : lang('Parameter name')); ?></th>
|
||||
<td id="label-type"><?php echo lang('Type'); ?><textarea id="enum-edit" rows="4" cols="12" wrap="off" style="display: none;"></textarea><?php echo script("qs('#enum-edit').onblur = editingLengthBlur;"); ?></td>
|
||||
<td id="label-type"><?php echo lang('Type'); ?><textarea id="enum-edit" rows="4" cols="12" wrap="off" style="display: none;"></textarea><?php echo script("gid('enum-edit').onblur = editingLengthBlur;"); ?></td>
|
||||
<td id="label-length"><?php echo lang('Length'); ?></td>
|
||||
<td><?php echo lang('Options'); /* no label required, options have their own label */ ?></td>
|
||||
<?php if ($type == "TABLE") { ?>
|
||||
@@ -621,7 +621,7 @@ function doc_link(array $paths, $text = "<sup>?</sup>") {
|
||||
];
|
||||
|
||||
if (preg_match('~MariaDB~', $server_info)) {
|
||||
$urls['sql'] = "https://mariadb.com/kb/en/library/";
|
||||
$urls['sql'] = "https://mariadb.com/kb/en/";
|
||||
$paths['sql'] = (isset($paths['mariadb']) ? $paths['mariadb'] : str_replace(".html", "/", $paths['sql']));
|
||||
}
|
||||
|
||||
|
@@ -967,7 +967,7 @@ function input($field, $value, $function) {
|
||||
$has_function = (in_array($function, $functions) || isset($functions[$function]));
|
||||
echo (count($functions) > 1
|
||||
? "<select name='function[$name]' $disabled>" . optionlist($functions, $function === null || $has_function ? $function : "") . "</select>"
|
||||
. on_help("getTarget(event).value.replace(/^SQL\$/, '')", 1)
|
||||
. help_script_command("value.replace(/^SQL\$/, '')", true)
|
||||
. script("qsl('select').onchange = functionChange;", "")
|
||||
: h(reset($functions))
|
||||
) . '<td>';
|
||||
@@ -1486,13 +1486,26 @@ function lzw_decompress($binary) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Return events to display help on mouse over
|
||||
* @param string JS expression
|
||||
* @param bool JS expression
|
||||
* @return string
|
||||
*/
|
||||
function on_help($command, $side = 0) {
|
||||
return script("mixin(qsl('select, input'), {onmouseover: function (event) { helpMouseover.call(this, event, $command, $side) }, onmouseout: helpMouseout});", "");
|
||||
/**
|
||||
* @param string $text Help text.
|
||||
* @param bool $side Side position.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function help_script($text, $side = false)
|
||||
{
|
||||
return script("initHelpFor(qsl('select, input'), '" . h($text) . "', $side);", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $command JS expression for returning the help text.
|
||||
* @param bool $side Side position.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function help_script_command($command, $side = false)
|
||||
{
|
||||
return script("initHelpFor(qsl('select, input'), (value) => { return $command; }, $side);", "");
|
||||
}
|
||||
|
||||
/** Print edit data form
|
||||
@@ -1586,7 +1599,7 @@ function edit_form($table, $fields, $row, $update) {
|
||||
}
|
||||
}
|
||||
echo ($update ? "<input type='submit' name='delete' value='" . lang('Delete') . "'>" . confirm() . "\n"
|
||||
: ($_POST || !$fields ? "" : script("focus(qsa('td', qs('#form'))[1].firstChild);"))
|
||||
: ($_POST || !$fields ? "" : script("focus(qsa('td', gid('form'))[1].firstChild);"))
|
||||
);
|
||||
if (isset($_GET["select"])) {
|
||||
hidden_fields(array("check" => (array) $_POST["check"], "clone" => $_POST["clone"], "all" => $_POST["all"]));
|
||||
|
@@ -1,2 +1,2 @@
|
||||
<?php
|
||||
$VERSION = "4.10";
|
||||
$VERSION = "4.11";
|
||||
|
@@ -1,11 +1,14 @@
|
||||
<?php
|
||||
/** Adminer - Compact database management
|
||||
* @link https://www.adminer.org/
|
||||
* @author Jakub Vrana, https://www.vrana.cz/
|
||||
* @copyright 2007 Jakub Vrana
|
||||
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
|
||||
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
|
||||
*/
|
||||
/**
|
||||
* Adminer - Database management in a single PHP file
|
||||
*
|
||||
* @link https://github.com/pematon/adminer
|
||||
* @author Jakub Vrana (https://www.vrana.cz/)
|
||||
* @author Peter Knut
|
||||
* @copyright 2007-2021 Jakub Vrana, 2024 Peter Knut
|
||||
* @license Apache License, Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
|
||||
* @license GNU General Public License, version 2 (https://www.gnu.org/licenses/gpl-2.0.html)
|
||||
*/
|
||||
|
||||
include "./include/bootstrap.inc.php";
|
||||
include "./include/tmpfile.inc.php";
|
||||
|
@@ -259,8 +259,8 @@ $translations = array(
|
||||
'%d row(s)' => array('%d řádek', '%d řádky', '%d řádků'),
|
||||
'Page' => 'Stránka',
|
||||
'last' => 'poslední',
|
||||
'Load more data' => 'Nahrát další data',
|
||||
'Loading' => 'Nahrává se',
|
||||
'Load more data' => 'Načíst další data',
|
||||
'Loading' => 'Načítá se',
|
||||
'Whole result' => 'Celý výsledek',
|
||||
'%d byte(s)' => array('%d bajt', '%d bajty', '%d bajtů'),
|
||||
|
||||
|
@@ -277,8 +277,8 @@ $translations = array(
|
||||
'DB' => 'DB',
|
||||
'File must be in UTF-8 encoding.' => 'Súbor musí byť v kódovaní UTF-8.',
|
||||
'Modify' => 'Zmeniť',
|
||||
'Load more data' => 'Nahráť ďalšie dáta',
|
||||
'Loading' => 'Nahráva sa',
|
||||
'Load more data' => 'Načítať ďalšie dáta',
|
||||
'Loading' => 'Načítava sa',
|
||||
'ATTACH queries are not supported.' => 'Dotazy ATTACH nie sú podporované.',
|
||||
'Warnings' => 'Varovania',
|
||||
'%d / ' => '%d / ',
|
||||
|
@@ -39,12 +39,16 @@ $routine_languages = routine_languages();
|
||||
<?php echo ($routine_languages ? lang('Language') . ": " . html_select("language", $routine_languages, $row["language"]) . "\n" : ""); ?>
|
||||
<input type="submit" value="<?php echo lang('Save'); ?>">
|
||||
<div class="scrollable">
|
||||
<table cellspacing="0" class="nowrap">
|
||||
<table cellspacing="0" class="nowrap" id="edit-fields">
|
||||
<?php
|
||||
edit_fields($row["fields"], $collations, $routine);
|
||||
if (isset($_GET["function"])) {
|
||||
echo "<tr><td>" . lang('Return type');
|
||||
echo "<tbody><tr><th></th>",
|
||||
"<th>", lang('Return type'), "</th>";
|
||||
|
||||
edit_type("returns", $row["returns"], $collations, array(), ($jush == "pgsql" ? array("void", "trigger") : array()));
|
||||
|
||||
echo "<td></td></tr></tbody>\n";
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
|
@@ -50,9 +50,9 @@ foreach (table_status('', true) as $table => $table_status) {
|
||||
?>
|
||||
<div id="schema" style="height: <?php echo $top; ?>em;">
|
||||
<script<?php echo nonce(); ?>>
|
||||
qs('#schema').onselectstart = function () { return false; };
|
||||
gid('schema').onselectstart = function () { return false; };
|
||||
var tablePos = {<?php echo implode(",", $table_pos_js) . "\n"; ?>};
|
||||
var em = qs('#schema').offsetHeight / <?php echo $top; ?>;
|
||||
var em = gid('schema').offsetHeight / <?php echo $top; ?>;
|
||||
document.onmousemove = schemaMousemove;
|
||||
document.onmouseup = partialArg(schemaMouseup, '<?php echo js_escape(DB); ?>');
|
||||
</script>
|
||||
@@ -61,12 +61,12 @@ foreach ($schema as $name => $table) {
|
||||
echo "<div class='table' style='top: " . $table["pos"][0] . "em; left: " . $table["pos"][1] . "em;'>";
|
||||
echo '<a href="' . h(ME) . 'table=' . urlencode($name) . '"><b>' . h($name) . "</b></a>";
|
||||
echo script("qsl('div').onmousedown = schemaMousedown;");
|
||||
|
||||
|
||||
foreach ($table["fields"] as $field) {
|
||||
$val = '<span' . type_class($field["type"]) . ' title="' . h($field["full_type"] . ($field["null"] ? " NULL" : '')) . '">' . h($field["field"]) . '</span>';
|
||||
echo "<br>" . ($field["primary"] ? "<i>$val</i>" : $val);
|
||||
}
|
||||
|
||||
|
||||
foreach ((array) $table["references"] as $target_name => $refs) {
|
||||
foreach ($refs as $left => $ref) {
|
||||
$left1 = $left - $table_pos[$name][1];
|
||||
@@ -76,7 +76,7 @@ foreach ($schema as $name => $table) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach ((array) $referenced[$name] as $target_name => $refs) {
|
||||
foreach ($refs as $left => $columns) {
|
||||
$left1 = $left - $table_pos[$name][1];
|
||||
@@ -86,7 +86,7 @@ foreach ($schema as $name => $table) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
echo "\n</div>\n";
|
||||
}
|
||||
|
||||
|
@@ -27,7 +27,7 @@ if (!$row) {
|
||||
|
||||
<form action="" method="post">
|
||||
<p><input name="name" id="name" value="<?php echo h($row["name"]); ?>" autocapitalize="off">
|
||||
<?php echo script("focus(qs('#name'));"); ?>
|
||||
<?php echo script("focus(gid('name'));"); ?>
|
||||
<input type="submit" value="<?php echo lang('Save'); ?>">
|
||||
<?php
|
||||
if ($_GET["ns"] != "") {
|
||||
|
@@ -322,10 +322,10 @@ if (!$columns && support("table")) {
|
||||
|
||||
echo "<div class='scrollable'>";
|
||||
echo "<table id='table' cellspacing='0' class='nowrap checkable'>";
|
||||
echo script("mixin(qs('#table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true), onkeydown: editingKeydown});");
|
||||
echo script("mixin(gid('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true), onkeydown: editingKeydown});");
|
||||
echo "<thead><tr>" . (!$group && $select
|
||||
? ""
|
||||
: "<td><input type='checkbox' id='all-page' class='jsonly'>" . script("qs('#all-page').onclick = partial(formCheck, /check/);", "")
|
||||
: "<td><input type='checkbox' id='all-page' class='jsonly'>" . script("gid('all-page').onclick = partial(formCheck, /check/);", "")
|
||||
. " <a href='" . h($_GET["modify"] ? remove_from_uri("modify") : $_SERVER["REQUEST_URI"] . "&modify=1") . "'>" . lang('Modify') . "</a>");
|
||||
$names = array();
|
||||
$functions = array();
|
||||
@@ -353,10 +353,10 @@ if (!$columns && support("table")) {
|
||||
}
|
||||
echo "<span class='column hidden'>";
|
||||
if ($sortable) {
|
||||
echo "<a href='" . h($href . $desc) . "' title='" . lang('descending') . "' class='text'> ↓</a>";
|
||||
echo "<a href='" . h($href . $desc) . "' title='" . lang('descending') . "' class='text'> ↓</a>";
|
||||
}
|
||||
if (!$val["fun"] && isset($field["privileges"]["where"])) {
|
||||
echo '<a href="#fieldset-search" title="' . lang('Search') . '" class="text jsonly"> =</a>';
|
||||
echo '<a href="#fieldset-search" title="' . lang('Search') . '" class="text jsonly"> =</a>';
|
||||
echo script("qsl('a').onclick = partial(selectSearch, '" . js_escape($key) . "');");
|
||||
}
|
||||
echo "</span>";
|
||||
|
@@ -243,7 +243,7 @@ if (!isset($_GET["import"])) {
|
||||
}
|
||||
echo "<p>";
|
||||
textarea("query", $q, 20);
|
||||
echo script(($_POST ? "" : "qs('textarea').focus();\n") . "qs('#form').onsubmit = partial(sqlSubmit, qs('#form'), '" . js_escape(remove_from_uri("sql|limit|error_stops|only_errors|history")) . "');");
|
||||
echo script(($_POST ? "" : "qs('textarea').focus();\n") . "gid('form').onsubmit = partial(sqlSubmit, gid('form'), '" . js_escape(remove_from_uri("sql|limit|error_stops|only_errors|history")) . "');");
|
||||
echo "<p>$execute\n";
|
||||
echo lang('Limit rows') . ": <input type='number' name='limit' class='size' value='" . h($_POST ? $_POST["limit"] : $_GET["limit"]) . "'>\n";
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/** @author Ondrej Valka, http://valka.info */
|
||||
body { color: #000; background: #fff; font: 90%/1.25 Verdana, Arial, Helvetica, sans-serif; margin: 0; width: -moz-fit-content; width: fit-content; }
|
||||
a { color: blue; text-decoration: none; }
|
||||
a:hover { color: red; text-decoration: underline; }
|
||||
a:link:hover { color: red; text-decoration: underline; }
|
||||
a.text:hover { text-decoration: none; }
|
||||
a.jush-help:hover { color: inherit; }
|
||||
h1 { font-size: 150%; margin: 0; padding: .8em 1em; border-bottom: 1px solid #999; font-weight: normal; color: #777; background: #eee; }
|
||||
@@ -25,7 +25,7 @@ pre code { display: block; font-size: 100%; }
|
||||
pre, textarea { font: 110%/1.25 monospace; }
|
||||
pre.jush { background: #fff; }
|
||||
input, textarea, select { box-sizing: border-box; }
|
||||
input:not([type="radio"]), select { vertical-align: middle; }
|
||||
input[type="image"] { vertical-align: middle; margin-top: -3px; }
|
||||
input[type="number"] { -moz-appearance: textfield; }
|
||||
input::-webkit-inner-spin-button { -webkit-appearance: none; }
|
||||
input.default { box-shadow: 1px 1px 1px #777; }
|
||||
@@ -76,7 +76,8 @@ p.nowrap { white-space: pre; }
|
||||
.handle:before { content: "="; display: inline-block; width: 18px; height: 18px; overflow: hidden; font-size: 130%; text-align: center; line-height: 16px; opacity: 0.2; }
|
||||
span.handle { display: inline-block; width: 18px; height: 18px; padding-right: .3em; }
|
||||
th.handle:before { vertical-align: middle; }
|
||||
.no-sort .handle { cursor: default; opacity: 0; }
|
||||
.no-sort .handle { cursor: default; }
|
||||
.no-sort .handle:before { content: "•"; font-size: 100%; }
|
||||
.placeholder { opacity: 0; }
|
||||
.dragging { position: absolute; margin: 0; background: #fff; }
|
||||
.dragging * { cursor: grabbing; }
|
||||
|
@@ -16,17 +16,22 @@ function bodyLoad(version, maria) {
|
||||
if (maria) {
|
||||
for (var i = 1; i < obj.length; i++) {
|
||||
obj[i] = obj[i]
|
||||
.replace(/\.html/, '/')
|
||||
.replace(/-type-syntax/, '-data-types')
|
||||
.replace('.html', '/')
|
||||
.replace('-type-syntax', '-data-types')
|
||||
.replace(/numeric-(data-types)/, '$1-$&')
|
||||
.replace(/#statvar_.*/, '#$$1')
|
||||
.replace(/replication-options-(master|binary-log)\//, 'replication-and-binary-log-system-variables/')
|
||||
.replace('server-options/', 'server-system-variables/')
|
||||
.replace('innodb-parameters/', 'innodb-system-variables/')
|
||||
.replace(/#(statvar|sysvar|option_mysqld)_(.*)/, '#$2')
|
||||
.replace(/#sysvar_(.*)/, '#$1')
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
obj[key] = (maria ? obj[key].replace(/dev\.mysql\.com\/doc\/mysql\/en\//, 'mariadb.com/kb/en/library/') : obj[key]) // MariaDB
|
||||
.replace(/\/doc\/mysql/, '/doc/refman/' + version) // MySQL
|
||||
.replace(/\/docs\/current/, '/docs/' + version) // PostgreSQL
|
||||
|
||||
obj[key] = (maria ? obj[key].replace('dev.mysql.com/doc/mysql/en/', 'mariadb.com/kb/en/') : obj[key]) // MariaDB
|
||||
.replace('/doc/mysql/', '/doc/refman/' + version) // MySQL
|
||||
.replace('/docs/current/', '/docs/' + version) // PostgreSQL
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -83,13 +88,17 @@ function messagesPrint(el) {
|
||||
|
||||
|
||||
|
||||
/** Hide or show some login rows for selected driver
|
||||
* @param HTMLSelectElement
|
||||
*/
|
||||
function loginDriver(driver) {
|
||||
var trs = parentTag(driver, 'table').rows;
|
||||
var disabled = /sqlite/.test(selectValue(driver));
|
||||
alterClass(trs[1], 'hidden', disabled); // 1 - row with server
|
||||
/**
|
||||
* Hides or shows some login rows for selected driver.
|
||||
*
|
||||
* @param {HTMLSelectElement} driverSelect
|
||||
*/
|
||||
function loginDriver(driverSelect) {
|
||||
const trs = parentTag(driverSelect, 'table').rows;
|
||||
const disabled = /sqlite/.test(selectValue(driverSelect));
|
||||
|
||||
// 1 - row with server
|
||||
trs[1].classList.toggle('hidden', disabled);
|
||||
trs[1].getElementsByTagName('input')[0].disabled = disabled;
|
||||
}
|
||||
|
||||
@@ -231,11 +240,13 @@ function editFields() {
|
||||
els = qsa('[name$="[type]"]');
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
mixin(els[i], {
|
||||
onfocus: function () { lastType = selectValue(this); },
|
||||
onfocus: () => {
|
||||
lastType = selectValue(this);
|
||||
},
|
||||
onchange: editingTypeChange,
|
||||
onmouseover: function (event) { helpMouseover.call(this, event, getTarget(event).value, 1) },
|
||||
onmouseout: helpMouseout
|
||||
});
|
||||
|
||||
initHelpFor(els[i], (value) => { return value; }, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +255,7 @@ function editFields() {
|
||||
* @return boolean false to cancel action
|
||||
*/
|
||||
function editingClick(event) {
|
||||
var el = getTarget(event);
|
||||
var el = event.target;
|
||||
if (!isTag(el, 'input')) {
|
||||
el = parentTag(el, 'label');
|
||||
el = el && qs('input', el);
|
||||
@@ -273,7 +284,7 @@ function editingClick(event) {
|
||||
* @param InputEvent
|
||||
*/
|
||||
function editingInput(event) {
|
||||
var el = getTarget(event);
|
||||
var el = event.target;
|
||||
if (/\[default]$/.test(el.name)) {
|
||||
el.previousSibling.checked = true;
|
||||
}
|
||||
@@ -398,26 +409,26 @@ function editingTypeChange() {
|
||||
el.checked = false;
|
||||
}
|
||||
if (el.name === name + '[collation]') {
|
||||
alterClass(el, 'hidden', !/(char|text|enum|set)$/.test(text));
|
||||
el.classList.toggle('hidden', !/(char|text|enum|set)$/.test(text));
|
||||
}
|
||||
if (el.name === name + '[unsigned]') {
|
||||
alterClass(el, 'hidden', !/(^|[^o])int(?!er)|numeric|real|float|double|decimal|money/.test(text));
|
||||
el.classList.toggle('hidden', !/(^|[^o])int(?!er)|numeric|real|float|double|decimal|money/.test(text));
|
||||
}
|
||||
if (el.name === name + '[on_update]') {
|
||||
alterClass(el, 'hidden', !/timestamp|datetime/.test(text)); // MySQL supports datetime since 5.6.5
|
||||
// MySQL supports datetime since 5.6.5.
|
||||
el.classList.toggle('hidden', !/timestamp|datetime/.test(text));
|
||||
}
|
||||
if (el.name === name + '[on_delete]') {
|
||||
alterClass(el, 'hidden', !/`/.test(text));
|
||||
el.classList.toggle('hidden', !/`/.test(text));
|
||||
}
|
||||
}
|
||||
helpClose();
|
||||
}
|
||||
|
||||
/** Mark length as required
|
||||
* @this HTMLInputElement
|
||||
*/
|
||||
function editingLengthChange() {
|
||||
alterClass(this, 'required', !this.value.length && /var(char|binary)$/.test(selectValue(this.parentNode.previousSibling.firstChild)));
|
||||
this.classList.toggle('required', !this.value.length && /var(char|binary)$/.test(selectValue(this.parentNode.previousSibling.firstChild)));
|
||||
}
|
||||
|
||||
/** Edit enum or set
|
||||
@@ -426,7 +437,7 @@ function editingLengthChange() {
|
||||
function editingLengthFocus() {
|
||||
var td = this.parentNode;
|
||||
if (/(enum|set)$/.test(selectValue(td.previousSibling.firstChild))) {
|
||||
var edit = qs('#enum-edit');
|
||||
var edit = gid('enum-edit');
|
||||
edit.value = enumValues(this.value);
|
||||
td.appendChild(edit);
|
||||
this.style.display = 'none';
|
||||
@@ -470,9 +481,9 @@ function editingLengthBlur() {
|
||||
* @param number
|
||||
*/
|
||||
function columnShow(checked, column) {
|
||||
var trs = qsa('tr', qs('#edit-fields'));
|
||||
var trs = qsa('tr', gid('edit-fields'));
|
||||
for (var i=0; i < trs.length; i++) {
|
||||
alterClass(qsa('td', trs[i])[column], 'hidden', !checked);
|
||||
qsa('td', trs[i])[column].classList.toggle('hidden', !checked);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -481,9 +492,9 @@ function columnShow(checked, column) {
|
||||
*/
|
||||
function partitionByChange() {
|
||||
var partitionTable = /RANGE|LIST/.test(selectValue(this));
|
||||
alterClass(this.form['partitions'], 'hidden', partitionTable || !this.selectedIndex);
|
||||
alterClass(qs('#partition-table'), 'hidden', !partitionTable);
|
||||
helpClose();
|
||||
|
||||
this.form['partitions'].classList.toggle('hidden', partitionTable || !this.selectedIndex);
|
||||
gid('partition-table').classList.toggle('hidden', !partitionTable);
|
||||
}
|
||||
|
||||
/** Add next partition row
|
||||
@@ -503,7 +514,7 @@ function partitionNameChange() {
|
||||
function editingCommentsClick(el, focus) {
|
||||
var comment = el.form['Comment'];
|
||||
columnShow(el.checked, 6);
|
||||
alterClass(comment, 'hidden', !el.checked);
|
||||
comment.classList.toggle('hidden', !el.checked);
|
||||
if (focus && el.checked) {
|
||||
comment.focus();
|
||||
}
|
||||
@@ -516,7 +527,7 @@ function editingCommentsClick(el, focus) {
|
||||
* @this HTMLTableElement
|
||||
*/
|
||||
function dumpClick(event) {
|
||||
var el = parentTag(getTarget(event), 'label');
|
||||
var el = parentTag(event.target, 'label');
|
||||
if (el) {
|
||||
el = qs('input', el);
|
||||
var match = /(.+)\[]$/.exec(el.name);
|
||||
@@ -646,7 +657,7 @@ function triggerChange(tableRe, table, form) {
|
||||
if (tableRe.test(form['Trigger'].value)) {
|
||||
form['Trigger'].value = table + '_' + (selectValue(form['Timing']).charAt(0) + formEvent.charAt(0)).toLowerCase();
|
||||
}
|
||||
alterClass(form['Of'], 'hidden', !/ OF/.test(formEvent));
|
||||
form['Of'].classList.toggle('hidden', !/ OF/.test(formEvent));
|
||||
}
|
||||
|
||||
|
||||
@@ -720,55 +731,114 @@ function schemaMouseup(event, db) {
|
||||
s += '_' + key + ':' + Math.round(tablePos[key][0] * 10000) / 10000 + 'x' + Math.round(tablePos[key][1] * 10000) / 10000;
|
||||
}
|
||||
s = encodeURIComponent(s.substr(1));
|
||||
var link = qs('#schema-link');
|
||||
var link = gid('schema-link');
|
||||
link.href = link.href.replace(/[^=]+$/, '') + s;
|
||||
cookie('adminer_schema-' + db + '=' + s, 30); //! special chars in db
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Help.
|
||||
(function() {
|
||||
let openTimeout = null;
|
||||
let closeTimeout = null;
|
||||
let helpVisible = false;
|
||||
|
||||
var helpOpen, helpIgnore; // when mouse outs <option> then it mouse overs border of <select> - ignore it
|
||||
window.initHelpPopup = function () {
|
||||
const help = gid("help");
|
||||
|
||||
/** Display help
|
||||
* @param MouseEvent
|
||||
* @param string
|
||||
* @param bool display on left side (otherwise on top)
|
||||
* @this HTMLElement
|
||||
*/
|
||||
function helpMouseover(event, text, side) {
|
||||
var target = getTarget(event);
|
||||
if (!text) {
|
||||
helpClose();
|
||||
} else if (window.jush && (!helpIgnore || this !== target)) {
|
||||
helpOpen = 1;
|
||||
var help = qs('#help');
|
||||
help.innerHTML = text;
|
||||
jush.highlight_tag([ help ]);
|
||||
alterClass(help, 'hidden');
|
||||
var rect = target.getBoundingClientRect();
|
||||
var body = document.documentElement;
|
||||
help.style.top = (body.scrollTop + rect.top - (side ? (help.offsetHeight - target.offsetHeight) / 2 : help.offsetHeight)) + 'px';
|
||||
help.style.left = (body.scrollLeft + rect.left - (side ? help.offsetWidth : (help.offsetWidth - target.offsetWidth) / 2)) + 'px';
|
||||
}
|
||||
}
|
||||
help.addEventListener("mouseenter", () => {
|
||||
clearTimeout(closeTimeout);
|
||||
closeTimeout = null;
|
||||
});
|
||||
|
||||
/** Close help after timeout
|
||||
* @param MouseEvent
|
||||
* @this HTMLElement
|
||||
*/
|
||||
function helpMouseout(event) {
|
||||
helpOpen = 0;
|
||||
helpIgnore = (this !== getTarget(event));
|
||||
setTimeout(function () {
|
||||
if (!helpOpen) {
|
||||
helpClose();
|
||||
help.addEventListener("mouseleave", hideHelp);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} element
|
||||
* @param {string|function} content
|
||||
* @param {boolean} side Displays on left side (otherwise on top).
|
||||
*/
|
||||
window.initHelpFor = function(element, content, side = false) {
|
||||
const withCallback = typeof content === "function";
|
||||
|
||||
element.addEventListener("mouseenter", (event) => {
|
||||
showHelp(event.target, withCallback ? content(event.target.value) : content, side)
|
||||
});
|
||||
|
||||
element.addEventListener("mouseleave", hideHelp);
|
||||
element.addEventListener("blur", hideHelp);
|
||||
|
||||
if (withCallback) {
|
||||
element.addEventListener("change", hideHelp);
|
||||
}
|
||||
}, 200);
|
||||
}
|
||||
};
|
||||
|
||||
/** Close help
|
||||
*/
|
||||
function helpClose() {
|
||||
alterClass(qs('#help'), 'hidden', true);
|
||||
}
|
||||
/**
|
||||
* Displays help popup after a small delay.
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
* @param {string} text
|
||||
* @param {boolean} side display on left side (otherwise on top)
|
||||
*/
|
||||
function showHelp(element, text, side) {
|
||||
if (!text) {
|
||||
hideHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
if (isSorting() || !window.jush) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearTimeout(openTimeout);
|
||||
openTimeout = null;
|
||||
clearTimeout(closeTimeout);
|
||||
closeTimeout = null;
|
||||
|
||||
const help = gid("help");
|
||||
help.innerHTML = text;
|
||||
jush.highlight_tag([help]);
|
||||
|
||||
// Display help briefly to calculate position properly.
|
||||
help.classList.remove("hidden");
|
||||
|
||||
const rect = element.getBoundingClientRect();
|
||||
const root = document.documentElement;
|
||||
|
||||
help.style.top = (root.scrollTop + rect.top - (side ? (help.offsetHeight - element.offsetHeight) / 2 : help.offsetHeight)) + 'px';
|
||||
help.style.left = (root.scrollLeft + rect.left - (side ? help.offsetWidth : (help.offsetWidth - element.offsetWidth) / 2)) + 'px';
|
||||
|
||||
if (helpVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
help.classList.add("hidden");
|
||||
|
||||
openTimeout = setTimeout(() => {
|
||||
gid("help").classList.remove("hidden");
|
||||
|
||||
helpVisible = true;
|
||||
openTimeout = null;
|
||||
}, 600);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the help popup after a small delay.
|
||||
*/
|
||||
function hideHelp() {
|
||||
if (openTimeout) {
|
||||
clearTimeout(openTimeout);
|
||||
openTimeout = null;
|
||||
return;
|
||||
}
|
||||
|
||||
closeTimeout = setTimeout(() => {
|
||||
gid("help").classList.add("hidden");
|
||||
|
||||
helpVisible = false;
|
||||
closeTimeout = null;
|
||||
}, 200);
|
||||
}
|
||||
})();
|
||||
|
@@ -73,17 +73,6 @@ function mixin(target, source) {
|
||||
}
|
||||
}
|
||||
|
||||
/** Add or remove CSS class
|
||||
* @param HTMLElement
|
||||
* @param string
|
||||
* @param [bool]
|
||||
*/
|
||||
function alterClass(el, className, enable) {
|
||||
if (el) {
|
||||
el.className = el.className.replace(RegExp('(^|\\s)' + className + '(\\s|$)'), '$2') + (enable ? ' ' + className : '');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles visibility of element with ID.
|
||||
*
|
||||
@@ -129,7 +118,7 @@ function verifyVersion(currentVersion, baseUrl, token) {
|
||||
ajax(baseUrl + 'script=version', function () {}, data);
|
||||
|
||||
if (currentVersion !== version) {
|
||||
qs('#version').innerText = version;
|
||||
gid('version').innerText = version;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -173,7 +162,7 @@ function parentTag(el, tag) {
|
||||
*/
|
||||
function trCheck(el) {
|
||||
var tr = parentTag(el, 'tr');
|
||||
alterClass(tr, 'checked', el.checked);
|
||||
tr.classList.toggle('checked', el.checked);
|
||||
if (el.form && el.form['all'] && el.form['all'].onclick) { // Opera treats form.all as document.all
|
||||
el.form['all'].onclick();
|
||||
}
|
||||
@@ -186,7 +175,7 @@ function trCheck(el) {
|
||||
*/
|
||||
function selectCount(id, count) {
|
||||
setHtml(id, (count === '' ? '' : '(' + (count + '').replace(/\B(?=(\d{3})+$)/g, thousandsSeparator) + ')'));
|
||||
var el = qs('#' + id);
|
||||
var el = gid(id);
|
||||
if (el) {
|
||||
var inputs = qsa('input', el.parentNode.parentNode);
|
||||
for (var i = 0; i < inputs.length; i++) {
|
||||
@@ -259,7 +248,7 @@ function formChecked(el, name) {
|
||||
* @param [boolean] force click
|
||||
*/
|
||||
function tableClick(event, click) {
|
||||
var td = parentTag(getTarget(event), 'td');
|
||||
var td = parentTag(event.target, 'td');
|
||||
var text;
|
||||
if (td && (text = td.getAttribute('data-text'))) {
|
||||
if (selectClick.call(td, event, +text, td.getAttribute('data-warning'))) {
|
||||
@@ -267,7 +256,7 @@ function tableClick(event, click) {
|
||||
}
|
||||
}
|
||||
click = (click || !window.getSelection || getSelection().isCollapsed);
|
||||
var el = getTarget(event);
|
||||
var el = event.target;
|
||||
while (!isTag(el, 'tr')) {
|
||||
if (isTag(el, 'table|a|input|textarea')) {
|
||||
if (el.type !== 'checkbox') {
|
||||
@@ -374,7 +363,7 @@ function initTablesFilter(dbName) {
|
||||
if (sessionStorage) {
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
if (dbName === sessionStorage.getItem('adminer_tables_filter_db') && sessionStorage.getItem('adminer_tables_filter')) {
|
||||
qs('#tables-filter').value = sessionStorage.getItem('adminer_tables_filter');
|
||||
gid('tables-filter').value = sessionStorage.getItem('adminer_tables_filter');
|
||||
filterTables();
|
||||
} else {
|
||||
sessionStorage.removeItem('adminer_tables_filter');
|
||||
@@ -384,7 +373,7 @@ function initTablesFilter(dbName) {
|
||||
});
|
||||
}
|
||||
|
||||
const filterInput = qs('#tables-filter');
|
||||
const filterInput = gid('tables-filter');
|
||||
filterInput.addEventListener('input', function () {
|
||||
window.clearTimeout(tablesFilterTimeout);
|
||||
tablesFilterTimeout = window.setTimeout(filterTables, 200);
|
||||
@@ -401,7 +390,7 @@ function initTablesFilter(dbName) {
|
||||
}
|
||||
|
||||
function filterTables() {
|
||||
const value = qs('#tables-filter').value.toLowerCase();
|
||||
const value = gid('tables-filter').value.toLowerCase();
|
||||
if (value === tablesFilterValue) {
|
||||
return;
|
||||
}
|
||||
@@ -445,7 +434,7 @@ function filterTables() {
|
||||
* @this HTMLElement
|
||||
*/
|
||||
function menuOver(event) {
|
||||
var a = getTarget(event);
|
||||
var a = event.target;
|
||||
if (isTag(a, 'a|span') && a.offsetLeft + a.offsetWidth > a.parentNode.offsetWidth - 15) { // 15 - ellipsis
|
||||
this.style.overflow = 'visible';
|
||||
}
|
||||
@@ -544,13 +533,13 @@ function selectSearchSearch() {
|
||||
|
||||
// Sorting.
|
||||
(function() {
|
||||
let placeholderRow, nextRow, dragHelper;
|
||||
let placeholderRow = null, nextRow = null, dragHelper = null;
|
||||
let startY, minY, maxY;
|
||||
|
||||
/**
|
||||
* Initializes sortable list of DIV elements.
|
||||
*
|
||||
* @param {string} parentId
|
||||
* @param {string} parentSelector
|
||||
*/
|
||||
window.initSortable = function(parentSelector) {
|
||||
const parent = qs(parentSelector);
|
||||
@@ -572,65 +561,73 @@ function selectSearchSearch() {
|
||||
row.classList.remove("no-sort");
|
||||
|
||||
const handle = qs(".handle", row);
|
||||
handle.addEventListener("mousedown", (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const parent = row.parentNode;
|
||||
startY = event.clientY - getOffsetTop(row);
|
||||
minY = getOffsetTop(parent);
|
||||
maxY = minY + parent.offsetHeight - row.offsetHeight;
|
||||
|
||||
placeholderRow = row.cloneNode(true);
|
||||
placeholderRow.classList.add("placeholder");
|
||||
parent.insertBefore(placeholderRow, row);
|
||||
|
||||
nextRow = row.nextElementSibling;
|
||||
|
||||
let top = event.clientY - startY;
|
||||
let left = getOffsetLeft(row);
|
||||
let width = row.getBoundingClientRect().width;
|
||||
|
||||
if (row.tagName === "TR") {
|
||||
const firstChild = row.firstElementChild;
|
||||
const borderWidth = (firstChild.offsetWidth - firstChild.clientWidth) / 2;
|
||||
const borderHeight = (firstChild.offsetHeight - firstChild.clientHeight) / 2;
|
||||
|
||||
minY -= borderHeight;
|
||||
maxY -= borderHeight;
|
||||
top -= borderHeight;
|
||||
left -= borderWidth;
|
||||
width += 2 * borderWidth;
|
||||
|
||||
for (const child of row.children) {
|
||||
child.style.width = child.getBoundingClientRect().width + "px";
|
||||
}
|
||||
|
||||
dragHelper = document.createElement("table");
|
||||
dragHelper.appendChild(row);
|
||||
} else {
|
||||
dragHelper = row;
|
||||
}
|
||||
|
||||
dragHelper.style.top = `${top}px`;
|
||||
dragHelper.style.left = `${left}px`;
|
||||
dragHelper.style.width = `${width}px`;
|
||||
dragHelper.classList.add("dragging");
|
||||
document.body.appendChild(dragHelper);
|
||||
|
||||
window.addEventListener("mousemove", updateSorting);
|
||||
|
||||
window.addEventListener("mouseup", () => {
|
||||
dragHelper.classList.remove("dragging");
|
||||
parent.insertBefore(dragHelper.tagName === "TABLE" ? dragHelper.firstChild : dragHelper, placeholderRow);
|
||||
placeholderRow.remove();
|
||||
|
||||
window.removeEventListener("mousemove", updateSorting);
|
||||
}, { once: true });
|
||||
});
|
||||
handle.addEventListener("mousedown", (event) => { startSorting(row, event) });
|
||||
handle.addEventListener("touchstart", (event) => { startSorting(row, event) });
|
||||
};
|
||||
|
||||
window.isSorting = function () {
|
||||
return dragHelper !== null;
|
||||
};
|
||||
|
||||
function startSorting(row, event) {
|
||||
event.preventDefault();
|
||||
|
||||
const pointerY = getPointerY(event);
|
||||
|
||||
const parent = row.parentNode;
|
||||
startY = pointerY - getOffsetTop(row);
|
||||
minY = getOffsetTop(parent);
|
||||
maxY = minY + parent.offsetHeight - row.offsetHeight;
|
||||
|
||||
placeholderRow = row.cloneNode(true);
|
||||
placeholderRow.classList.add("placeholder");
|
||||
parent.insertBefore(placeholderRow, row);
|
||||
|
||||
nextRow = row.nextElementSibling;
|
||||
|
||||
let top = pointerY - startY;
|
||||
let left = getOffsetLeft(row);
|
||||
let width = row.getBoundingClientRect().width;
|
||||
|
||||
if (row.tagName === "TR") {
|
||||
const firstChild = row.firstElementChild;
|
||||
const borderWidth = (firstChild.offsetWidth - firstChild.clientWidth) / 2;
|
||||
const borderHeight = (firstChild.offsetHeight - firstChild.clientHeight) / 2;
|
||||
|
||||
minY -= borderHeight;
|
||||
maxY -= borderHeight;
|
||||
top -= borderHeight;
|
||||
left -= borderWidth;
|
||||
width += 2 * borderWidth;
|
||||
|
||||
for (const child of row.children) {
|
||||
child.style.width = child.getBoundingClientRect().width + "px";
|
||||
}
|
||||
|
||||
dragHelper = document.createElement("table");
|
||||
dragHelper.appendChild(row);
|
||||
} else {
|
||||
dragHelper = row;
|
||||
}
|
||||
|
||||
dragHelper.style.top = `${top}px`;
|
||||
dragHelper.style.left = `${left}px`;
|
||||
dragHelper.style.width = `${width}px`;
|
||||
dragHelper.classList.add("dragging");
|
||||
document.body.appendChild(dragHelper);
|
||||
|
||||
window.addEventListener("mousemove", updateSorting);
|
||||
window.addEventListener("touchmove", updateSorting);
|
||||
|
||||
window.addEventListener("mouseup", finishSorting);
|
||||
window.addEventListener("touchend", finishSorting);
|
||||
window.addEventListener("touchcancel", finishSorting);
|
||||
}
|
||||
|
||||
function updateSorting(event) {
|
||||
let top = Math.min(Math.max(event.clientY - startY, minY), maxY);
|
||||
const pointerY = getPointerY(event);
|
||||
|
||||
let top = Math.min(Math.max(pointerY - startY, minY), maxY);
|
||||
dragHelper.style.top = `${top}px`;
|
||||
|
||||
const parent = placeholderRow.parentNode;
|
||||
@@ -656,6 +653,34 @@ function selectSearchSearch() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function finishSorting() {
|
||||
dragHelper.classList.remove("dragging");
|
||||
dragHelper.style.top = null;
|
||||
dragHelper.style.left = null;
|
||||
dragHelper.style.width = null;
|
||||
|
||||
placeholderRow.parentNode.insertBefore(dragHelper.tagName === "TABLE" ? dragHelper.firstChild : dragHelper, placeholderRow);
|
||||
placeholderRow.remove();
|
||||
|
||||
placeholderRow = nextRow = dragHelper = null;
|
||||
|
||||
window.removeEventListener("mousemove", updateSorting);
|
||||
window.removeEventListener("touchmove", updateSorting);
|
||||
|
||||
window.removeEventListener("mouseup", finishSorting);
|
||||
window.removeEventListener("touchend", finishSorting);
|
||||
window.removeEventListener("touchcancel", finishSorting);
|
||||
}
|
||||
|
||||
function getPointerY(event) {
|
||||
if (event.type.includes("touch")) {
|
||||
const touch = event.touches[0] || event.changedTouches[0];
|
||||
return touch.clientY;
|
||||
} else {
|
||||
return event.clientY;
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
@@ -681,7 +706,7 @@ function columnMouse(className) {
|
||||
* @return boolean false
|
||||
*/
|
||||
function selectSearch(name) {
|
||||
var el = qs('#fieldset-search');
|
||||
var el = gid('fieldset-search');
|
||||
el.className = '';
|
||||
var divs = qsa('div', el);
|
||||
for (var i=0; i < divs.length; i++) {
|
||||
@@ -708,16 +733,6 @@ function isCtrl(event) {
|
||||
return (event.ctrlKey || event.metaKey) && !event.altKey; // shiftKey allowed
|
||||
}
|
||||
|
||||
/** Return event target
|
||||
* @param Event
|
||||
* @return HTMLElement
|
||||
*/
|
||||
function getTarget(event) {
|
||||
return event.target || event.srcElement;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Send form by Ctrl+Enter on <select> and <textarea>
|
||||
* @param KeyboardEvent
|
||||
* @param [string]
|
||||
@@ -725,7 +740,7 @@ function getTarget(event) {
|
||||
*/
|
||||
function bodyKeydown(event, button) {
|
||||
eventStop(event);
|
||||
var target = getTarget(event);
|
||||
var target = event.target;
|
||||
if (target.jushTextarea) {
|
||||
target = target.jushTextarea;
|
||||
}
|
||||
@@ -749,7 +764,7 @@ function bodyKeydown(event, button) {
|
||||
* @param MouseEvent
|
||||
*/
|
||||
function bodyClick(event) {
|
||||
var target = getTarget(event);
|
||||
var target = event.target;
|
||||
if ((isCtrl(event) || event.shiftKey) && target.type === 'submit' && isTag(target, 'input')) {
|
||||
target.form.target = '_blank';
|
||||
setTimeout(function () {
|
||||
@@ -767,7 +782,7 @@ function bodyClick(event) {
|
||||
*/
|
||||
function editingKeydown(event) {
|
||||
if ((event.keyCode === 40 || event.keyCode === 38) && isCtrl(event)) { // 40 - Down, 38 - Up
|
||||
var target = getTarget(event);
|
||||
var target = event.target;
|
||||
var sibling = (event.keyCode === 40 ? 'nextSibling' : 'previousSibling');
|
||||
var el = target.parentNode.parentNode[sibling];
|
||||
if (el && (isTag(el, 'tr') || (el = el[sibling])) && isTag(el, 'tr') && (el = el.childNodes[nodePosition(target.parentNode)]) && (el = el.childNodes[nodePosition(target)])) {
|
||||
@@ -792,7 +807,6 @@ function functionChange() {
|
||||
|
||||
// Undefined with the set data type.
|
||||
if (!input) {
|
||||
helpClose();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -822,8 +836,6 @@ function functionChange() {
|
||||
}
|
||||
|
||||
oninput({target: input});
|
||||
|
||||
helpClose();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -868,7 +880,7 @@ function fieldChange() {
|
||||
function ajax(url, callback, data, message) {
|
||||
var request = (window.XMLHttpRequest ? new XMLHttpRequest() : (window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : false));
|
||||
if (request) {
|
||||
var ajaxStatus = qs('#ajaxstatus');
|
||||
var ajaxStatus = gid('ajaxstatus');
|
||||
if (message) {
|
||||
ajaxStatus.innerHTML = '<div class="message">' + message + '</div>';
|
||||
ajaxStatus.className = ajaxStatus.className.replace(/ hidden/g, '');
|
||||
@@ -938,9 +950,9 @@ function ajaxForm(form, message, button) {
|
||||
return ajax(url, function (request) {
|
||||
setHtml('ajaxstatus', request.responseText);
|
||||
if (window.jush) {
|
||||
jush.highlight_tag(qsa('code', qs('#ajaxstatus')), 0);
|
||||
jush.highlight_tag(qsa('code', gid('ajaxstatus')), 0);
|
||||
}
|
||||
messagesPrint(qs('#ajaxstatus'));
|
||||
messagesPrint(gid('ajaxstatus'));
|
||||
}, data, message);
|
||||
}
|
||||
|
||||
@@ -955,7 +967,7 @@ function ajaxForm(form, message, button) {
|
||||
*/
|
||||
function selectClick(event, text, warning) {
|
||||
var td = this;
|
||||
var target = getTarget(event);
|
||||
var target = event.target;
|
||||
if (!isCtrl(event) || isTag(td.firstChild, 'input|textarea') || isTag(target, 'a')) {
|
||||
return;
|
||||
}
|
||||
@@ -1042,7 +1054,7 @@ function selectLoadMore(limit, loading) {
|
||||
return !ajax(href, function (request) {
|
||||
var tbody = document.createElement('tbody');
|
||||
tbody.innerHTML = request.responseText;
|
||||
qs('#table').appendChild(tbody);
|
||||
gid('table').appendChild(tbody);
|
||||
if (tbody.children.length < limit) {
|
||||
a.parentNode.removeChild(a);
|
||||
} else {
|
||||
@@ -1096,9 +1108,9 @@ function setupSubmitHighlightInput(input) {
|
||||
* @this HTMLInputElement
|
||||
*/
|
||||
function inputFocus() {
|
||||
var submit = findDefaultSubmit(this);
|
||||
const submit = findDefaultSubmit(this);
|
||||
if (submit) {
|
||||
alterClass(submit, 'default', true);
|
||||
submit.classList.toggle('default', true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1106,9 +1118,9 @@ function inputFocus() {
|
||||
* @this HTMLInputElement
|
||||
*/
|
||||
function inputBlur() {
|
||||
var submit = findDefaultSubmit(this);
|
||||
const submit = findDefaultSubmit(this);
|
||||
if (submit) {
|
||||
alterClass(submit, 'default');
|
||||
submit.classList.toggle('default', false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1190,7 +1202,9 @@ function getOffsetLeft(element) {
|
||||
}
|
||||
|
||||
oninput = function (event) {
|
||||
var target = event.target;
|
||||
var maxLength = target.getAttribute('data-maxlength');
|
||||
alterClass(target, 'maxlength', target.value && maxLength != null && target.value.length > maxLength); // maxLength could be 0
|
||||
const target = event.target;
|
||||
const maxLength = target.getAttribute('data-maxlength');
|
||||
|
||||
// maxLength could be 0
|
||||
target.classList.toggle('maxlength', target.value && maxLength != null && target.value.length > maxLength);
|
||||
};
|
||||
|
@@ -40,7 +40,7 @@ page_header(($name != "" ? lang('Alter trigger') . ": " . h($name) : lang('Creat
|
||||
<tr><th><?php echo lang('Type'); ?><td><?php echo html_select("Type", $trigger_options["Type"], $row["Type"]); ?>
|
||||
</table>
|
||||
<p><?php echo lang('Name'); ?>: <input name="Trigger" value="<?php echo h($row["Trigger"]); ?>" data-maxlength="64" autocapitalize="off">
|
||||
<?php echo script("qs('#form')['Timing'].onchange();"); ?>
|
||||
<?php echo script("gid('form')['Timing'].onchange();"); ?>
|
||||
<p><?php textarea("Statement", $row["Statement"]); ?>
|
||||
<p>
|
||||
<input type="submit" value="<?php echo lang('Save'); ?>">
|
||||
|
@@ -142,7 +142,7 @@ if ($_POST) {
|
||||
<tr><th><?php echo lang('Server'); ?><td><input name="host" data-maxlength="60" value="<?php echo h($row["host"]); ?>" autocapitalize="off">
|
||||
<tr><th><?php echo lang('Username'); ?><td><input name="user" data-maxlength="80" value="<?php echo h($row["user"]); ?>" autocapitalize="off">
|
||||
<tr><th><?php echo lang('Password'); ?><td><input name="pass" id="pass" value="<?php echo h($row["pass"]); ?>" autocomplete="new-password">
|
||||
<?php if (!$row["hashed"]) { echo script("typePassword(qs('#pass'));"); } ?>
|
||||
<?php if (!$row["hashed"]) { echo script("typePassword(gid('pass'));"); } ?>
|
||||
<?php echo (min_version(8) ? "" : checkbox("hashed", 1, $row["hashed"], lang('Hashed'), "typePassword(this.form['pass'], this.checked);")); ?>
|
||||
</table>
|
||||
|
||||
|
@@ -439,13 +439,14 @@ if ($_SESSION["lang"]) {
|
||||
$file = str_replace("<?php switch_lang(); ?>\n", "", $file);
|
||||
$file = str_replace('<?php echo $LANG; ?>', $_SESSION["lang"], $file);
|
||||
}
|
||||
$file = str_replace('<?php echo script_src("static/editing.js"); ?>' . "\n", "", $file);
|
||||
$file = str_replace('<?php echo script_src("static/editing.js?" . filemtime("../adminer/static/editing.js")); ?>' . "\n", "", $file);
|
||||
$file = preg_replace('~\s+echo script_src\("\.\./vendor/vrana/jush/modules/jush-(textarea|txt|js|\$jush)\.js"\);~', '', $file);
|
||||
$file = str_replace('<link rel="stylesheet" type="text/css" href="../vendor/vrana/jush/jush.css">' . "\n", "", $file);
|
||||
$file = preg_replace_callback("~compile_file\\('([^']+)'(?:, '([^']*)')?\\)~", 'compile_file', $file); // integrate static files
|
||||
$replace = 'preg_replace("~\\\\\\\\?.*~", "", ME) . "?file=\1&version=' . substr(md5(microtime()), 0, 8) . '"';
|
||||
$file = preg_replace('~\.\./adminer/static/(default\.css|favicon\.ico)~', '<?php echo h(' . $replace . '); ?>', $file);
|
||||
$file = preg_replace('~"\.\./adminer/static/(functions\.js)"~', $replace, $file);
|
||||
$file = preg_replace('~\.\./adminer/static/(favicon\.ico)~', '<?php echo h(' . $replace . '); ?>', $file);
|
||||
$file = preg_replace('~\.\./adminer/static/(default\.css)\?.*default.css"\);\s+\?>~', '<?php echo h(' . $replace . '); ?>', $file);
|
||||
$file = preg_replace('~"\.\./adminer/static/(functions\.js)\?".*functions.js"\)~', $replace, $file);
|
||||
$file = preg_replace('~\.\./adminer/static/([^\'"]*)~', '" . h(' . $replace . ') . "', $file);
|
||||
$file = preg_replace('~"\.\./vendor/vrana/jush/modules/(jush\.js)"~', $replace, $file);
|
||||
$file = preg_replace("~<\\?php\\s*\\?>\n?|\\?>\n?<\\?php~", '', $file);
|
||||
|
@@ -29,7 +29,7 @@
|
||||
"php": "5.6 - 8.3",
|
||||
"ext-pdo": "*",
|
||||
"ext-json": "*",
|
||||
"vrana/jush": "@dev",
|
||||
"vrana/jush": "2.0.*",
|
||||
"vrana/jsshrink": "@dev"
|
||||
},
|
||||
"suggest": {
|
||||
@@ -57,7 +57,7 @@
|
||||
"repositories": [
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/vrana/jush.git"
|
||||
"url": "https://github.com/pematon/jush.git"
|
||||
},
|
||||
{
|
||||
"type": "vcs",
|
||||
|
@@ -11,11 +11,11 @@ if ($adminer->homepage()) {
|
||||
echo "<table cellspacing='0' class='nowrap checkable'>\n";
|
||||
echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});");
|
||||
echo '<thead><tr class="wrap">';
|
||||
echo '<td><input id="check-all" type="checkbox" class="jsonly">' . script("qs('#check-all').onclick = partial(formCheck, /^tables\[/);", "");
|
||||
echo '<td><input id="check-all" type="checkbox" class="jsonly">' . script("gid('check-all').onclick = partial(formCheck, /^tables\[/);", "");
|
||||
echo '<th>' . lang('Table');
|
||||
echo '<td>' . lang('Rows');
|
||||
echo "</thead>\n";
|
||||
|
||||
|
||||
foreach (table_status() as $table => $row) {
|
||||
$name = $adminer->tableName($row);
|
||||
if (isset($row["Engine"]) && $name != "") {
|
||||
@@ -25,7 +25,7 @@ if ($adminer->homepage()) {
|
||||
echo "<td align='right'><a href='" . h(ME . "edit=") . urlencode($table) . "'>" . ($row["Engine"] == "InnoDB" && $val ? "~ $val" : $val) . "</a>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
echo "</table>\n";
|
||||
echo "</div>\n";
|
||||
echo "</form>\n";
|
||||
|
@@ -77,7 +77,7 @@ class Adminer {
|
||||
|
||||
function loginForm() {
|
||||
echo "<table cellspacing='0' class='layout'>\n";
|
||||
echo $this->loginFormField('username', '<tr><th>' . lang('Username') . '<td>', '<input type="hidden" name="auth[driver]" value="server"><input name="auth[username]" id="username" value="' . h($_GET["username"]) . '" autocomplete="username" autocapitalize="off">' . script("focus(qs('#username'));"));
|
||||
echo $this->loginFormField('username', '<tr><th>' . lang('Username') . '<td>', '<input type="hidden" name="auth[driver]" value="server"><input name="auth[username]" id="username" value="' . h($_GET["username"]) . '" autocomplete="username" autocapitalize="off">' . script("focus(gid('username'));"));
|
||||
echo $this->loginFormField('password', '<tr><th>' . lang('Password') . '<td>', '<input type="password" name="auth[password]" autocomplete="current-password">' . "\n");
|
||||
echo "</table>\n";
|
||||
echo "<p><input type='submit' value='" . lang('Login') . "'>\n";
|
||||
@@ -620,7 +620,7 @@ qsl('div').onclick = whisperClick;", "")
|
||||
if ($password !== null) {
|
||||
if ($first) {
|
||||
echo "<ul id='logins'>";
|
||||
echo script("mixin(qs('#logins'), {onmouseover: menuOver, onmouseout: menuOut});");
|
||||
echo script("mixin(gid('logins'), {onmouseover: menuOver, onmouseout: menuOut});");
|
||||
$first = false;
|
||||
}
|
||||
echo "<li><a href='" . h(auth_url($vendor, "", $username)) . "'>" . ($username != "" ? h($username) : "<i>" . lang('empty') . "</i>") . "</a>\n";
|
||||
@@ -655,7 +655,7 @@ qsl('div').onclick = whisperClick;", "")
|
||||
}
|
||||
|
||||
function tablesPrint($tables) {
|
||||
echo "<ul id='tables'>" . script("mixin(qs('#tables'), {onmouseover: menuOver, onmouseout: menuOut});");
|
||||
echo "<ul id='tables'>" . script("mixin(gid('tables'), {onmouseover: menuOver, onmouseout: menuOut});");
|
||||
|
||||
foreach ($tables as $row) {
|
||||
// Skip views and tables without a name.
|
||||
|
@@ -1,11 +1,14 @@
|
||||
<?php
|
||||
/** Adminer Editor - Compact database editor
|
||||
* @link https://www.adminer.org/
|
||||
* @author Jakub Vrana, https://www.vrana.cz/
|
||||
* @copyright 2009 Jakub Vrana
|
||||
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
|
||||
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
|
||||
*/
|
||||
/**
|
||||
* Adminer Editor - Compact database editor for end-users
|
||||
*
|
||||
* @link https://github.com/pematon/adminer
|
||||
* @author Jakub Vrana (https://www.vrana.cz/)
|
||||
* @author Peter Knut
|
||||
* @copyright 2009-2021 Jakub Vrana, 2024 Peter Knut
|
||||
* @license Apache License, Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
|
||||
* @license GNU General Public License, version 2 (https://www.gnu.org/licenses/gpl-2.0.html)
|
||||
*/
|
||||
|
||||
include "../adminer/include/bootstrap.inc.php";
|
||||
$drivers[DRIVER] = lang('Login');
|
||||
|
@@ -6,13 +6,14 @@ function messagesPrint() {
|
||||
function selectFieldChange() {
|
||||
}
|
||||
|
||||
var helpOpen;
|
||||
// Help.
|
||||
(function() {
|
||||
window.initHelpPopup = function () {
|
||||
};
|
||||
|
||||
function helpMouseover() {
|
||||
}
|
||||
|
||||
function helpMouseout() {
|
||||
}
|
||||
window.initHelpFor = function(element, content, side = false) {
|
||||
};
|
||||
})();
|
||||
|
||||
/** Display typeahead
|
||||
* @param string
|
||||
@@ -42,7 +43,7 @@ function whisper(url) {
|
||||
*/
|
||||
function whisperClick(event) {
|
||||
var field = this.previousSibling;
|
||||
var el = getTarget(event);
|
||||
var el = event.target;
|
||||
if (isTag(el, 'a') && !(event.button || event.shiftKey || event.altKey || isCtrl(event))) {
|
||||
field.value = el.firstChild.data;
|
||||
field.previousSibling.value = decodeURIComponent(el.href.replace(/.*=/, ''));
|
||||
|
@@ -65,7 +65,7 @@ tinyMCE.init({
|
||||
return "<textarea$attrs id='fields-" . h($field["field"]) . "' rows='12' cols='50'>" . h($value) . "</textarea>" . script("
|
||||
tinyMCE.remove(tinyMCE.get('fields-" . js_escape($field["field"]) . "') || { });
|
||||
tinyMCE.EditorManager.execCommand('mceAddControl', true, 'fields-" . js_escape($field["field"]) . "');
|
||||
qs('#form').onsubmit = function () {
|
||||
gid('form').onsubmit = function () {
|
||||
tinyMCE.each(tinyMCE.editors, function (ed) {
|
||||
ed.remove();
|
||||
});
|
||||
|
Reference in New Issue
Block a user