mirror of
https://github.com/vrana/adminer.git
synced 2025-08-30 09:39:51 +02:00
Show help popup after a short delay, refactoring
This commit is contained in:
@@ -183,7 +183,7 @@ foreach ($engines as $engine) {
|
||||
<?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 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'"); ?>>
|
||||
|
@@ -147,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));
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
/**
|
||||
* @param string $text Help text.
|
||||
* @param bool $side Side position.
|
||||
*
|
||||
* @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});", "");
|
||||
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
|
||||
|
@@ -236,11 +236,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,7 +417,6 @@ function editingTypeChange() {
|
||||
alterClass(el, 'hidden', !/`/.test(text));
|
||||
}
|
||||
}
|
||||
helpClose();
|
||||
}
|
||||
|
||||
/** Mark length as required
|
||||
@@ -488,7 +489,6 @@ function partitionByChange() {
|
||||
var partitionTable = /RANGE|LIST/.test(selectValue(this));
|
||||
alterClass(this.form['partitions'], 'hidden', partitionTable || !this.selectedIndex);
|
||||
alterClass(qs('#partition-table'), 'hidden', !partitionTable);
|
||||
helpClose();
|
||||
}
|
||||
|
||||
/** Add next partition row
|
||||
@@ -732,48 +732,107 @@ function schemaMouseup(event, 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
|
||||
help.addEventListener("mouseenter", () => {
|
||||
clearTimeout(closeTimeout);
|
||||
closeTimeout = null;
|
||||
});
|
||||
|
||||
help.addEventListener("mouseleave", hideHelp);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} element
|
||||
* @param {string|function} content
|
||||
* @param {boolean} side Displays on left side (otherwise on top).
|
||||
*/
|
||||
function helpMouseover(event, text, side) {
|
||||
var target = getTarget(event);
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
helpClose();
|
||||
} else if (window.jush && (!helpIgnore || this !== target)) {
|
||||
helpOpen = 1;
|
||||
var help = qs('#help');
|
||||
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]);
|
||||
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';
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
/** Close help after timeout
|
||||
* @param MouseEvent
|
||||
* @this HTMLElement
|
||||
*/
|
||||
function helpMouseout(event) {
|
||||
helpOpen = 0;
|
||||
helpIgnore = (this !== getTarget(event));
|
||||
setTimeout(function () {
|
||||
if (!helpOpen) {
|
||||
helpClose();
|
||||
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);
|
||||
}
|
||||
|
||||
/** Close help
|
||||
*/
|
||||
function helpClose() {
|
||||
alterClass(qs('#help'), 'hidden', true);
|
||||
}
|
||||
})();
|
||||
|
@@ -544,13 +544,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);
|
||||
@@ -576,6 +576,10 @@ function selectSearchSearch() {
|
||||
handle.addEventListener("touchstart", (event) => { startSorting(row, event) });
|
||||
};
|
||||
|
||||
window.isSorting = function () {
|
||||
return dragHelper !== null;
|
||||
};
|
||||
|
||||
function startSorting(row, event) {
|
||||
event.preventDefault();
|
||||
|
||||
@@ -670,6 +674,8 @@ function selectSearchSearch() {
|
||||
placeholderRow.parentNode.insertBefore(dragHelper.tagName === "TABLE" ? dragHelper.firstChild : dragHelper, placeholderRow);
|
||||
placeholderRow.remove();
|
||||
|
||||
placeholderRow = nextRow = dragHelper = null;
|
||||
|
||||
window.removeEventListener("mousemove", updateSorting);
|
||||
window.removeEventListener("touchmove", updateSorting);
|
||||
|
||||
@@ -822,7 +828,6 @@ function functionChange() {
|
||||
|
||||
// Undefined with the set data type.
|
||||
if (!input) {
|
||||
helpClose();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -852,8 +857,6 @@ function functionChange() {
|
||||
}
|
||||
|
||||
oninput({target: input});
|
||||
|
||||
helpClose();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user