mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2025-12-12 17:20:30 +08:00
js cleanup
This commit is contained in:
parent
beb5d541b0
commit
94fe2226f1
@ -39,23 +39,39 @@ export function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function __setAppText() {
|
function __setAppText() {
|
||||||
|
let e_href = tools.escape(window.location.href);
|
||||||
$("app-text").innerHTML = `
|
$("app-text").innerHTML = `
|
||||||
<span class="code-comment"># On Linux using Chromium/Chrome via any terminal:<br>
|
<span class="code-comment"># On Linux using Chromium/Chrome via any terminal:<br>
|
||||||
$</span> \`which chromium 2>/dev/null || which chrome 2>/dev/null || which google-chrome\` --app="${window.location.href}"<br>
|
$</span> \`which chromium 2>/dev/null || which chrome 2>/dev/null || which google-chrome\` --app="${e_href}"<br>
|
||||||
<br>
|
<br>
|
||||||
<span class="code-comment"># On MacOS using Terminal application:<br>
|
<span class="code-comment"># On MacOS using Terminal application:<br>
|
||||||
$</span> /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --app="${window.location.href}"<br>
|
$</span> /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --app="${e_href}"<br>
|
||||||
<br>
|
<br>
|
||||||
<span class="code-comment"># On Windows via cmd.exe:<br>
|
<span class="code-comment"># On Windows via cmd.exe:<br>
|
||||||
C:\></span> start chrome --app="${window.location.href}"
|
C:\></span> start chrome --app="${e_href}"
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function __loadKvmdInfo() {
|
function __loadKvmdInfo() {
|
||||||
tools.httpGet("api/info", {"fields": "auth,meta,extras"}, function(http) {
|
tools.httpGet("api/info", {"fields": "auth,meta,extras"}, function(http) {
|
||||||
if (http.status === 200) {
|
switch (http.status) {
|
||||||
let info = JSON.parse(http.responseText).result;
|
case 200:
|
||||||
|
__showKvmdInfo(JSON.parse(http.responseText).result);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 401:
|
||||||
|
case 403:
|
||||||
|
tools.currentOpen("login");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
setTimeout(__loadKvmdInfo, 1000);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function __showKvmdInfo(info) {
|
||||||
let apps = [];
|
let apps = [];
|
||||||
if (info.extras === null) {
|
if (info.extras === null) {
|
||||||
wm.error("Not all applications in the menu can be displayed due an error.<br>See KVMD logs for details.");
|
wm.error("Not all applications in the menu can be displayed due an error.<br>See KVMD logs for details.");
|
||||||
@ -71,7 +87,7 @@ function __loadKvmdInfo() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$("apps-box").innerHTML = "<ul id=\"apps\"></ul>";
|
let html = "";
|
||||||
|
|
||||||
// Don't use this option, it may be removed in any time
|
// Don't use this option, it may be removed in any time
|
||||||
let hide_kvm_button = (
|
let hide_kvm_button = (
|
||||||
@ -79,17 +95,22 @@ function __loadKvmdInfo() {
|
|||||||
|| tools.config.getBool("index--hide-kvm-button", false)
|
|| tools.config.getBool("index--hide-kvm-button", false)
|
||||||
);
|
);
|
||||||
if (!hide_kvm_button) {
|
if (!hide_kvm_button) {
|
||||||
$("apps").innerHTML += __makeApp(null, "kvm", "share/svg/kvm.svg", "KVM");
|
html += __makeApp(null, "kvm", "share/svg/kvm.svg", "KVM");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let app of apps) {
|
for (let app of apps) {
|
||||||
if (app.place >= 0 && (app.enabled || app.started)) {
|
if (app.place >= 0 && (app.enabled || app.started)) {
|
||||||
$("apps").innerHTML += __makeApp(null, app.path, app.icon, app.name);
|
html += __makeApp(null, app.path, app.icon, app.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.auth.enabled) {
|
if (info.auth.enabled) {
|
||||||
$("apps").innerHTML += __makeApp("logout-button", "#", "share/svg/logout.svg", "Logout");
|
html += __makeApp("logout-button", "#", "share/svg/logout.svg", "Logout");
|
||||||
|
}
|
||||||
|
|
||||||
|
$("apps-box").innerHTML = `<ul id="apps">${html}</ul>`;
|
||||||
|
|
||||||
|
if (info.auth.enabled) {
|
||||||
tools.el.setOnClick($("logout-button"), __logout);
|
tools.el.setOnClick($("logout-button"), __logout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,23 +121,18 @@ function __loadKvmdInfo() {
|
|||||||
$("kvmd-meta-server-host").innerHTML = "";
|
$("kvmd-meta-server-host").innerHTML = "";
|
||||||
document.title = "PiKVM Index";
|
document.title = "PiKVM Index";
|
||||||
}
|
}
|
||||||
} else if (http.status === 401 || http.status === 403) {
|
|
||||||
tools.currentOpen("login");
|
|
||||||
} else {
|
|
||||||
setTimeout(__loadKvmdInfo, 1000);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function __makeApp(id, path, icon, name) {
|
function __makeApp(id, path, icon, name) {
|
||||||
// Tailing slash in href is added to avoid Nginx 301 redirect
|
// Tailing slash in href is added to avoid Nginx 301 redirect
|
||||||
// when the location doesn't have tailing slash: "foo -> foo/".
|
// when the location doesn't have tailing slash: "foo -> foo/".
|
||||||
// Reverse proxy over PiKVM can be misconfigured to handle this.
|
// Reverse proxy over PiKVM can be misconfigured to handle this.
|
||||||
|
let e_add_id = (id ? `id="${tools.escape(id)}"` : "");
|
||||||
return `<li>
|
return `<li>
|
||||||
<div ${id ? "id=\"" + id + "\"" : ""} class="app">
|
<div ${e_add_id} class="app">
|
||||||
<a href="${ROOT_PREFIX}${path}/">
|
<a href="${tools.escape(ROOT_PREFIX + path)}/">
|
||||||
<div>
|
<div>
|
||||||
<img class="svg-gray" src="${ROOT_PREFIX}${icon}">
|
<img class="svg-gray" src="${tools.escape(ROOT_PREFIX + icon)}">
|
||||||
${tools.escape(name)}
|
${tools.escape(name)}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
@ -126,10 +142,16 @@ function __makeApp(id, path, icon, name) {
|
|||||||
|
|
||||||
function __logout() {
|
function __logout() {
|
||||||
tools.httpPost("api/auth/logout", null, function(http) {
|
tools.httpPost("api/auth/logout", null, function(http) {
|
||||||
if (http.status === 200 || http.status === 401 || http.status === 403) {
|
switch (http.status) {
|
||||||
|
case 200:
|
||||||
|
case 401:
|
||||||
|
case 403:
|
||||||
tools.currentOpen("login");
|
tools.currentOpen("login");
|
||||||
} else {
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
wm.error("Logout error", http.responseText);
|
wm.error("Logout error", http.responseText);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,29 +32,43 @@ export function main() {
|
|||||||
|
|
||||||
function __loadKvmdInfo() {
|
function __loadKvmdInfo() {
|
||||||
tools.httpGet("api/info", null, function(http) {
|
tools.httpGet("api/info", null, function(http) {
|
||||||
if (http.status === 200) {
|
switch (http.status) {
|
||||||
let ipmi_port = JSON.parse(http.responseText).result.extras.ipmi.port;
|
case 200:
|
||||||
let make_item = (comment, ipmi, api) => `
|
__showKvmdInfo(JSON.parse(http.responseText).result);
|
||||||
<span class="code-comment"># ${comment}:<br>$</span>
|
break;
|
||||||
ipmitool -I lanplus -U admin -P admin -H ${window.location.hostname} -p ${ipmi_port} ${ipmi}<br>
|
|
||||||
<span class="code-comment">$</span> curl -XPOST -HX-KVMD-User:admin -HX-KVMD-Passwd:admin -k \\<br>
|
case 401:
|
||||||
${window.location.protocol}//${window.location.host}/api/atx${api}<br>
|
case 403:
|
||||||
`;
|
|
||||||
$("ipmi-text").innerHTML = `
|
|
||||||
${make_item("Power on the server if it's off", "power on", "/power?action=on")}
|
|
||||||
<br>
|
|
||||||
${make_item("Soft power off the server if it's on", "power soft", "/power?action=off")}
|
|
||||||
<br>
|
|
||||||
${make_item("Hard power off the server if it's on", "power off", "/power?action=off_hard")}
|
|
||||||
<br>
|
|
||||||
${make_item("Hard reset the server if it's on", "power reset", "/power?action=reset_hard")}
|
|
||||||
<br>
|
|
||||||
${make_item("Check the power status", "power status", "")}
|
|
||||||
`;
|
|
||||||
} else if (http.status === 401 || http.status === 403) {
|
|
||||||
tools.currentOpen("login");
|
tools.currentOpen("login");
|
||||||
} else {
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
setTimeout(__loadKvmdInfo, 1000);
|
setTimeout(__loadKvmdInfo, 1000);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function __showKvmdInfo(info) {
|
||||||
|
let make_item = function (comment, cmd, api) {
|
||||||
|
return `
|
||||||
|
<span class="code-comment">
|
||||||
|
# ${tools.escape(comment)}:<br>$
|
||||||
|
</span>
|
||||||
|
ipmitool -I lanplus -U admin -P admin
|
||||||
|
-H ${tools.escape(window.location.hostname)}
|
||||||
|
-p ${tools.escape(info.extras.ipmi.port)} ${tools.escape(cmd)}
|
||||||
|
<br>
|
||||||
|
<span class="code-comment">$</span>
|
||||||
|
curl -XPOST -HX-KVMD-User:admin -HX-KVMD-Passwd:admin -k \\<br>
|
||||||
|
${tools.escape(window.location.protocol + "//" + window.location.host + "/api/atx" + api)}
|
||||||
|
`;
|
||||||
|
};
|
||||||
|
$("ipmi-text").innerHTML = [
|
||||||
|
make_item("Power on the server if it's off", "power on", "/power?action=on"),
|
||||||
|
make_item("Soft power off the server if it's on", "power soft", "/power?action=off"),
|
||||||
|
make_item("Hard power off the server if it's on", "power off", "/power?action=off_hard"),
|
||||||
|
make_item("Hard reset the server if it's on", "power reset", "/power?action=reset_hard"),
|
||||||
|
make_item("Check the power status", "power status", ""),
|
||||||
|
].join("<br><br>");
|
||||||
|
}
|
||||||
|
|||||||
@ -106,7 +106,7 @@ export function Atx(__recorder) {
|
|||||||
|
|
||||||
if ($("atx-ask-switch").checked) {
|
if ($("atx-ask-switch").checked) {
|
||||||
wm.confirm(`
|
wm.confirm(`
|
||||||
Are you sure you want to press the <b>${button}</b> button?<br>
|
Are you sure you want to press the <b>${tools.escape(button)}</b> button?<br>
|
||||||
Warning! This could cause data loss on the server.
|
Warning! This could cause data loss on the server.
|
||||||
`).then(function(ok) {
|
`).then(function(ok) {
|
||||||
if (ok) {
|
if (ok) {
|
||||||
|
|||||||
@ -135,30 +135,36 @@ export function Gpio(__recorder) {
|
|||||||
var __createItem = function(item) {
|
var __createItem = function(item) {
|
||||||
if (item.type === "label") {
|
if (item.type === "label") {
|
||||||
return item.text;
|
return item.text;
|
||||||
|
|
||||||
} else if (item.type === "input") {
|
} else if (item.type === "input") {
|
||||||
|
let e_ch_class = tools.escape(`__gpio-led-${item.channel}`);
|
||||||
|
let e_icon = tools.escape(`${ROOT_PREFIX}share/svg/led-circle.svg`);
|
||||||
return `
|
return `
|
||||||
<img
|
<img
|
||||||
class="__gpio-led __gpio-led-${item.channel} inline-lamp-big led-gray"
|
class="__gpio-led ${e_ch_class} inline-lamp-big led-gray"
|
||||||
src="${ROOT_PREFIX}share/svg/led-circle.svg"
|
src="${e_icon}"
|
||||||
data-color="${item.color}"
|
data-color="${tools.escape(item.color)}"
|
||||||
/>
|
/>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
} else if (item.type === "output") {
|
} else if (item.type === "output") {
|
||||||
let controls = [];
|
let controls = [];
|
||||||
let confirm = (item.confirm ? "Are you sure you want to perform this action?" : "");
|
let e_ch = tools.escape(item.channel);
|
||||||
|
let e_confirm = (item.confirm ? tools.escape("Are you sure you want to perform this action?") : "");
|
||||||
if (item.scheme["switch"]) {
|
if (item.scheme["switch"]) {
|
||||||
let id = tools.makeId();
|
let e_id = tools.escape(`__gpio-switch-${tools.makeRandomId()}`);
|
||||||
|
let e_ch_class = tools.escape(`__gpio-switch-${item.channel}`);
|
||||||
controls.push(`
|
controls.push(`
|
||||||
<td><div class="switch-box">
|
<td><div class="switch-box">
|
||||||
<input
|
<input
|
||||||
disabled
|
disabled
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
id="__gpio-switch-${id}"
|
id="${e_id}"
|
||||||
class="__gpio-switch __gpio-switch-${item.channel}"
|
class="__gpio-switch ${e_ch_class}"
|
||||||
data-channel="${item.channel}"
|
data-channel="${e_ch}"
|
||||||
data-confirm="${confirm}"
|
data-confirm="${e_confirm}"
|
||||||
/>
|
/>
|
||||||
<label for="__gpio-switch-${id}">
|
<label for="${e_id}">
|
||||||
<span class="switch-inner"></span>
|
<span class="switch-inner"></span>
|
||||||
<span class="switch"></span>
|
<span class="switch"></span>
|
||||||
</label>
|
</label>
|
||||||
@ -166,22 +172,23 @@ export function Gpio(__recorder) {
|
|||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
if (item.scheme.pulse.delay) {
|
if (item.scheme.pulse.delay) {
|
||||||
|
let e_ch_class = tools.escape(`__gpio-button-${item.channel}`);
|
||||||
controls.push(`
|
controls.push(`
|
||||||
<td><button
|
<td><button
|
||||||
disabled
|
disabled
|
||||||
class="__gpio-button __gpio-button-${item.channel}"
|
class="__gpio-button ${e_ch_class}"
|
||||||
${item.hide ? "data-force-hide-menu" : ""}
|
${item.hide ? "data-force-hide-menu" : ""}
|
||||||
data-channel="${item.channel}"
|
data-channel="${e_ch}"
|
||||||
data-confirm="${confirm}"
|
data-confirm="${e_confirm}"
|
||||||
>
|
>
|
||||||
${(item.hide ? "• " : "") + item.text}
|
${(item.hide ? "• " : "") + tools.escape(item.text)}
|
||||||
</button></td>
|
</button></td>
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
return `<table><tr>${controls.join("<td> </td>")}</tr></table>`;
|
return `<table><tr>${controls.join("<td> </td>")}</tr></table>`;
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
};
|
};
|
||||||
|
|
||||||
var __setLedState = function(el, on) {
|
var __setLedState = function(el, on) {
|
||||||
|
|||||||
@ -112,7 +112,7 @@ export function Mouse(__getGeometry, __recordWsEvent) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var __updateRate = function(value) {
|
var __updateRate = function(value) {
|
||||||
$("hid-mouse-rate-value").innerHTML = value + " ms";
|
$("hid-mouse-rate-value").innerText = value + " ms";
|
||||||
tools.storage.set("hid.mouse.rate", value);
|
tools.storage.set("hid.mouse.rate", value);
|
||||||
if (__timer) {
|
if (__timer) {
|
||||||
clearInterval(__timer);
|
clearInterval(__timer);
|
||||||
@ -121,13 +121,13 @@ export function Mouse(__getGeometry, __recordWsEvent) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var __updateScrollRate = function(value) {
|
var __updateScrollRate = function(value) {
|
||||||
$("hid-mouse-scroll-value").innerHTML = value;
|
$("hid-mouse-scroll-value").innerText = value;
|
||||||
tools.storage.set("hid.mouse.scroll_rate", value);
|
tools.storage.set("hid.mouse.scroll_rate", value);
|
||||||
__scroll_rate = value;
|
__scroll_rate = value;
|
||||||
};
|
};
|
||||||
|
|
||||||
var __updateRelativeSens = function(value) {
|
var __updateRelativeSens = function(value) {
|
||||||
$("hid-mouse-sens-value").innerHTML = value.toFixed(1);
|
$("hid-mouse-sens-value").innerText = value.toFixed(1);
|
||||||
tools.storage.set("hid.mouse.sens", value);
|
tools.storage.set("hid.mouse.sens", value);
|
||||||
__relative_sens = value;
|
__relative_sens = value;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -208,7 +208,7 @@ export function Msd() {
|
|||||||
if (el.__names_json !== names_json) {
|
if (el.__names_json !== names_json) {
|
||||||
el.innerHTML = names.map(name => `
|
el.innerHTML = names.map(name => `
|
||||||
<div class="text">
|
<div class="text">
|
||||||
<div id="__msd-storage-${tools.makeIdByText(name)}-progress" class="progress">
|
<div id="__msd-storage-${tools.makeTextId(name)}-progress" class="progress">
|
||||||
<span class="progress-value"></span>
|
<span class="progress-value"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -223,7 +223,7 @@ export function Msd() {
|
|||||||
? `${names.length === 1 ? "Storage: %s" : "Internal storage: %s"}` // eslint-disable-line
|
? `${names.length === 1 ? "Storage: %s" : "Internal storage: %s"}` // eslint-disable-line
|
||||||
: `Storage [${name}${part.writable ? "]" : ", read-only]"}: %s` // eslint-disable-line
|
: `Storage [${name}${part.writable ? "]" : ", read-only]"}: %s` // eslint-disable-line
|
||||||
);
|
);
|
||||||
let id = `__msd-storage-${tools.makeIdByText(name)}-progress`;
|
let id = `__msd-storage-${tools.makeTextId(name)}-progress`;
|
||||||
tools.progress.setSizeOf($(id), title, part.size, part.free);
|
tools.progress.setSizeOf($(id), title, part.size, part.free);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -270,8 +270,8 @@ export function Msd() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var __clickDownloadButton = function() {
|
var __clickDownloadButton = function() {
|
||||||
let image = encodeURIComponent($("msd-image-selector").value);
|
let e_image = encodeURIComponent($("msd-image-selector").value);
|
||||||
tools.windowOpen(`api/msd/read?image=${image}`);
|
tools.windowOpen(`api/msd/read?image=${e_image}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
var __clickRemoveButton = function() {
|
var __clickRemoveButton = function() {
|
||||||
@ -299,13 +299,13 @@ export function Msd() {
|
|||||||
var __clickUploadNewButton = function() {
|
var __clickUploadNewButton = function() {
|
||||||
let file = tools.input.getFile($("msd-new-file"));
|
let file = tools.input.getFile($("msd-new-file"));
|
||||||
__http = new XMLHttpRequest();
|
__http = new XMLHttpRequest();
|
||||||
let prefix = encodeURIComponent($("msd-new-part-selector").value);
|
let e_prefix = encodeURIComponent($("msd-new-part-selector").value);
|
||||||
if (file) {
|
if (file) {
|
||||||
let image = encodeURIComponent(file.name);
|
let e_image = encodeURIComponent(file.name);
|
||||||
__http.open("POST", `${ROOT_PREFIX}api/msd/write?prefix=${prefix}&image=${image}&remove_incomplete=1`, true);
|
__http.open("POST", `${ROOT_PREFIX}api/msd/write?prefix=${e_prefix}&image=${e_image}&remove_incomplete=1`, true);
|
||||||
} else {
|
} else {
|
||||||
let url = encodeURIComponent($("msd-new-url").value);
|
let e_url = encodeURIComponent($("msd-new-url").value);
|
||||||
__http.open("POST", `${ROOT_PREFIX}api/msd/write_remote?prefix=${prefix}&url=${url}&remove_incomplete=1`, true);
|
__http.open("POST", `${ROOT_PREFIX}api/msd/write_remote?prefix=${e_prefix}&url=${e_url}&remove_incomplete=1`, true);
|
||||||
}
|
}
|
||||||
__http.upload.timeout = 7 * 24 * 3600;
|
__http.upload.timeout = 7 * 24 * 3600;
|
||||||
__http.onreadystatechange = __uploadStateChange;
|
__http.onreadystatechange = __uploadStateChange;
|
||||||
@ -402,7 +402,8 @@ export function Msd() {
|
|||||||
if (__state && __state.storage && __state.storage.parts) {
|
if (__state && __state.storage && __state.storage.parts) {
|
||||||
let part = __state.storage.parts[$("msd-new-part-selector").value];
|
let part = __state.storage.parts[$("msd-new-part-selector").value];
|
||||||
if (part && (file.size > part.size)) {
|
if (part && (file.size > part.size)) {
|
||||||
wm.error(`The new image is too big for the Mass Storage partition.<br>Maximum: ${tools.formatSize(part.size)}`);
|
let e_size = tools.escape(tools.formatSize(part.size));
|
||||||
|
wm.error(`The new image is too big for the Mass Storage partition.<br>Maximum: ${e_size}`);
|
||||||
el.value = "";
|
el.value = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -220,7 +220,8 @@ export function MediaStreamer(__setActive, __setInactive, __setInfo, __orient) {
|
|||||||
let width = frame.displayWidth;
|
let width = frame.displayWidth;
|
||||||
let height = frame.displayHeight;
|
let height = frame.displayHeight;
|
||||||
switch (__orient) {
|
switch (__orient) {
|
||||||
case 90: case 270:
|
case 90:
|
||||||
|
case 270:
|
||||||
width = frame.displayHeight;
|
width = frame.displayHeight;
|
||||||
height = frame.displayWidth;
|
height = frame.displayWidth;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,7 +32,7 @@ export function MjpegStreamer(__setActive, __setInactive, __setInfo) {
|
|||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
var __key = tools.makeId();
|
var __key = tools.makeRandomId();
|
||||||
var __id = "";
|
var __id = "";
|
||||||
var __fps = -1;
|
var __fps = -1;
|
||||||
var __state = null;
|
var __state = null;
|
||||||
@ -91,7 +91,7 @@ export function MjpegStreamer(__setActive, __setInactive, __setInfo) {
|
|||||||
|
|
||||||
var __setStreamInactive = function() {
|
var __setStreamInactive = function() {
|
||||||
let old_fps = __fps;
|
let old_fps = __fps;
|
||||||
__key = tools.makeId();
|
__key = tools.makeRandomId();
|
||||||
__id = "";
|
__id = "";
|
||||||
__fps = -1;
|
__fps = -1;
|
||||||
__state = null;
|
__state = null;
|
||||||
@ -139,7 +139,7 @@ export function MjpegStreamer(__setActive, __setInactive, __setInfo) {
|
|||||||
__setStreamInactive();
|
__setStreamInactive();
|
||||||
__stopChecking();
|
__stopChecking();
|
||||||
|
|
||||||
let path = `${ROOT_PREFIX}streamer/stream?key=${__key}`;
|
let path = `${ROOT_PREFIX}streamer/stream?key=${encodeURIComponent(__key)}`;
|
||||||
if (tools.browser.is_safari || tools.browser.is_ios) {
|
if (tools.browser.is_safari || tools.browser.is_ios) {
|
||||||
// uStreamer fix for WebKit
|
// uStreamer fix for WebKit
|
||||||
__logInfo("Using dual_final_frames=1 to fix WebKit bugs");
|
__logInfo("Using dual_final_frames=1 to fix WebKit bugs");
|
||||||
|
|||||||
@ -178,8 +178,8 @@ export function Switch() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var __clickAddEdidButton = function() {
|
var __clickAddEdidButton = function() {
|
||||||
let create_content = function(el_parent, el_ok_button) {
|
let create_content = function(el_parent, el_ok_bt) {
|
||||||
tools.el.setEnabled(el_ok_button, false);
|
tools.el.setEnabled(el_ok_bt, false);
|
||||||
el_parent.innerHTML = `
|
el_parent.innerHTML = `
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
@ -203,7 +203,7 @@ export function Switch() {
|
|||||||
el_name.oninput = el_data.oninput = function() {
|
el_name.oninput = el_data.oninput = function() {
|
||||||
let name = el_name.value.replace(/\s+/g, "");
|
let name = el_name.value.replace(/\s+/g, "");
|
||||||
let data = el_data.value.replace(/\s+/g, "");
|
let data = el_data.value.replace(/\s+/g, "");
|
||||||
tools.el.setEnabled(el_ok_button, ((name.length > 0) && /[0-9a-fA-F]{512}/.test(data)));
|
tools.el.setEnabled(el_ok_bt, ((name.length > 0) && /[0-9a-fA-F]{512}/.test(data)));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -584,7 +584,7 @@ export function Switch() {
|
|||||||
};
|
};
|
||||||
if ($("switch-atx-ask-switch").checked) {
|
if ($("switch-atx-ask-switch").checked) {
|
||||||
wm.confirm(`
|
wm.confirm(`
|
||||||
Are you sure you want to press the <b>${button}</b> button?<br>
|
Are you sure you want to press the <b>${tools.escape(button)}</b> button?<br>
|
||||||
Warning! This could cause data loss on the server.
|
Warning! This could cause data loss on the server.
|
||||||
`).then(function(ok) {
|
`).then(function(ok) {
|
||||||
if (ok) {
|
if (ok) {
|
||||||
|
|||||||
@ -52,20 +52,28 @@ function __login() {
|
|||||||
let passwd = $("passwd-input").value + $("code-input").value;
|
let passwd = $("passwd-input").value + $("code-input").value;
|
||||||
let body = `user=${encodeURIComponent(user)}&passwd=${encodeURIComponent(passwd)}`;
|
let body = `user=${encodeURIComponent(user)}&passwd=${encodeURIComponent(passwd)}`;
|
||||||
tools.httpPost("api/auth/login", null, function(http) {
|
tools.httpPost("api/auth/login", null, function(http) {
|
||||||
if (http.status === 200) {
|
switch (http.status) {
|
||||||
|
case 200:
|
||||||
tools.currentOpen("");
|
tools.currentOpen("");
|
||||||
} else if (http.status === 403) {
|
break;
|
||||||
|
|
||||||
|
case 403:
|
||||||
wm.error("Invalid credentials").then(__tryAgain);
|
wm.error("Invalid credentials").then(__tryAgain);
|
||||||
} else {
|
break;
|
||||||
|
|
||||||
|
default: {
|
||||||
let error = "";
|
let error = "";
|
||||||
if (http.status === 400) {
|
if (http.status === 400) {
|
||||||
try { error = JSON.parse(http.responseText)["result"]["error"]; } catch { /* Nah */ }
|
try {
|
||||||
|
error = JSON.parse(http.responseText)["result"]["error"];
|
||||||
|
} catch { /* Nah */ }
|
||||||
}
|
}
|
||||||
if (error === "ValidatorError") {
|
if (error === "ValidatorError") {
|
||||||
wm.error("Invalid characters in credentials").then(__tryAgain);
|
wm.error("Invalid characters in credentials").then(__tryAgain);
|
||||||
} else {
|
} else {
|
||||||
wm.error("Login error", http.responseText).then(__tryAgain);
|
wm.error("Login error", http.responseText).then(__tryAgain);
|
||||||
}
|
}
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
}, body, "application/x-www-form-urlencoded");
|
}, body, "application/x-www-form-urlencoded");
|
||||||
__setEnabled(false);
|
__setEnabled(false);
|
||||||
|
|||||||
@ -86,8 +86,11 @@ export var tools = new function() {
|
|||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
self.escape = function(text) {
|
self.escape = function(text) {
|
||||||
|
if (typeof text !== "string") {
|
||||||
|
text = "" + text;
|
||||||
|
}
|
||||||
return text.replace(
|
return text.replace(
|
||||||
/[^0-9A-Za-z ]/g,
|
/[^-_0-9A-Za-z ]/g,
|
||||||
ch => "&#" + ch.charCodeAt(0) + ";"
|
ch => "&#" + ch.charCodeAt(0) + ";"
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -100,7 +103,7 @@ export var tools = new function() {
|
|||||||
return text[0].toUpperCase() + text.slice(1);
|
return text[0].toUpperCase() + text.slice(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
self.makeId = function() {
|
self.makeRandomId = function() {
|
||||||
let chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
let chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
let id = "";
|
let id = "";
|
||||||
for (let count = 0; count < 16; ++count) {
|
for (let count = 0; count < 16; ++count) {
|
||||||
@ -109,16 +112,10 @@ export var tools = new function() {
|
|||||||
return id;
|
return id;
|
||||||
};
|
};
|
||||||
|
|
||||||
self.makeIdByText = function(text) {
|
self.makeTextId = function(text) {
|
||||||
return btoa(text).replace("=", "_");
|
return btoa(text).replace("=", "_");
|
||||||
};
|
};
|
||||||
|
|
||||||
self.getRandomInt = function(min, max) {
|
|
||||||
min = Math.ceil(min);
|
|
||||||
max = Math.floor(max);
|
|
||||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
||||||
};
|
|
||||||
|
|
||||||
self.formatSize = function(size) {
|
self.formatSize = function(size) {
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
let index = Math.floor( Math.log(size) / Math.log(1024) );
|
let index = Math.floor( Math.log(size) / Math.log(1024) );
|
||||||
@ -149,6 +146,12 @@ export var tools = new function() {
|
|||||||
return remapped;
|
return remapped;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.getRandomInt = function(min, max) {
|
||||||
|
min = Math.ceil(min);
|
||||||
|
max = Math.floor(max);
|
||||||
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
|
};
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
self.el = new function() {
|
self.el = new function() {
|
||||||
@ -270,26 +273,34 @@ export var tools = new function() {
|
|||||||
self.radio = new function() {
|
self.radio = new function() {
|
||||||
return {
|
return {
|
||||||
"makeItem": function(name, title, value) {
|
"makeItem": function(name, title, value) {
|
||||||
|
let e_id = self.escape(name) + self.makeTextId(value);
|
||||||
return `
|
return `
|
||||||
<input type="radio" id="${name}-${value}" name="${name}" value="${value}" />
|
<input
|
||||||
<label for="${name}-${value}">${title}</label>
|
type="radio"
|
||||||
|
id="${e_id}"
|
||||||
|
name="${tools.escape(name)}"
|
||||||
|
value="${tools.escape(value)}"
|
||||||
|
/>
|
||||||
|
<label for="${e_id}">
|
||||||
|
${tools.escape(title)}
|
||||||
|
</label>
|
||||||
`;
|
`;
|
||||||
},
|
},
|
||||||
"setOnClick": function(name, callback, prevent_default=true) {
|
"setOnClick": function(name, callback, prevent_default=true) {
|
||||||
for (let el of $$$(`input[type="radio"][name="${name}"]`)) {
|
for (let el of $$$(`input[type="radio"][name="${CSS.escape(name)}"]`)) {
|
||||||
self.el.setOnClick(el, callback, prevent_default);
|
self.el.setOnClick(el, callback, prevent_default);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"getValue": function(name) {
|
"getValue": function(name) {
|
||||||
return document.querySelector(`input[type="radio"][name="${name}"]:checked`).value;
|
return document.querySelector(`input[type="radio"][name="${CSS.escape(name)}"]:checked`).value;
|
||||||
},
|
},
|
||||||
"setValue": function(name, value) {
|
"setValue": function(name, value) {
|
||||||
for (let el of $$$(`input[type="radio"][name="${name}"]`)) {
|
for (let el of $$$(`input[type="radio"][name="${CSS.escape(name)}"]`)) {
|
||||||
el.checked = (el.value === value);
|
el.checked = (el.value === value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"clickValue": function(name, value) {
|
"clickValue": function(name, value) {
|
||||||
for (let el of $$$(`input[type="radio"][name="${name}"]`)) {
|
for (let el of $$$(`input[type="radio"][name="${CSS.escape(name)}"]`)) {
|
||||||
if (el.value === value) {
|
if (el.value === value) {
|
||||||
el.click();
|
el.click();
|
||||||
return;
|
return;
|
||||||
@ -297,7 +308,7 @@ export var tools = new function() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"setEnabled": function(name, enabled) {
|
"setEnabled": function(name, enabled) {
|
||||||
for (let el of $$$(`input[type="radio"][name="${name}"]`)) {
|
for (let el of $$$(`input[type="radio"][name="${CSS.escape(name)}"]`)) {
|
||||||
self.el.setEnabled(el, enabled);
|
self.el.setEnabled(el, enabled);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -32,16 +32,26 @@ export function main() {
|
|||||||
|
|
||||||
function __loadKvmdInfo() {
|
function __loadKvmdInfo() {
|
||||||
tools.httpGet("api/info", null, function(http) {
|
tools.httpGet("api/info", null, function(http) {
|
||||||
if (http.status === 200) {
|
switch (http.status) {
|
||||||
let vnc_port = JSON.parse(http.responseText).result.extras.vnc.port;
|
case 200:
|
||||||
$("vnc-text").innerHTML = `
|
__showKvmdInfo(JSON.parse(http.responseText).result);
|
||||||
<span class="code-comment"># How to connect using the Linux terminal:<br>
|
break;
|
||||||
$</span> vncviewer ${window.location.hostname}::${vnc_port}
|
|
||||||
`;
|
case 401:
|
||||||
} else if (http.status === 401 || http.status === 403) {
|
case 403:
|
||||||
tools.currentOpen("login");
|
tools.currentOpen("login");
|
||||||
} else {
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
setTimeout(__loadKvmdInfo, 1000);
|
setTimeout(__loadKvmdInfo, 1000);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function __showKvmdInfo(info) {
|
||||||
|
$("vnc-text").innerHTML = `
|
||||||
|
<span class="code-comment"># How to connect using the Linux terminal:<br>
|
||||||
|
$</span> vncviewer ${tools.escape(window.location.hostname + "::" + info.extras.vnc.port)}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|||||||
@ -42,96 +42,105 @@ function __WindowManager() {
|
|||||||
var __menu_buttons = [];
|
var __menu_buttons = [];
|
||||||
|
|
||||||
var __init__ = function() {
|
var __init__ = function() {
|
||||||
for (let el_button of $$$("button")) {
|
for (let el of $$$("button")) {
|
||||||
// XXX: Workaround for iOS Safari:
|
// XXX: Workaround for iOS Safari:
|
||||||
// https://stackoverflow.com/questions/3885018/active-pseudo-class-doesnt-work-in-mobile-safari
|
// https://stackoverflow.com/questions/3885018/active-pseudo-class-doesnt-work-in-mobile-safari
|
||||||
el_button.ontouchstart = function() {};
|
el.ontouchstart = function() {};
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let el_button of $$("menu-button")) {
|
for (let el of $$("menu-button")) {
|
||||||
el_button.parentElement.querySelector(".menu").setAttribute("tabindex", "-1");
|
el.parentElement.querySelector(".menu").setAttribute("tabindex", "-1");
|
||||||
tools.el.setOnDown(el_button, () => __toggleMenu(el_button));
|
tools.el.setOnDown(el, () => __toggleMenu(el));
|
||||||
__menu_buttons.push(el_button);
|
__menu_buttons.push(el);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!window.ResizeObserver) {
|
if (!window.ResizeObserver) {
|
||||||
tools.error("ResizeObserver not supported");
|
tools.error("ResizeObserver not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let el_window of $$("window")) {
|
for (let el_win of $$("window")) {
|
||||||
el_window.setAttribute("tabindex", "-1");
|
el_win.setAttribute("tabindex", "-1");
|
||||||
__makeWindowMovable(el_window);
|
__makeWindowMovable(el_win);
|
||||||
__windows.push(el_window);
|
__windows.push(el_win);
|
||||||
|
|
||||||
if (el_window.classList.contains("window-resizable") && window.ResizeObserver) {
|
if (el_win.classList.contains("window-resizable") && window.ResizeObserver) {
|
||||||
new ResizeObserver(function() {
|
new ResizeObserver(function() {
|
||||||
// При переполнении рабочей области сократить размер окна по высоте.
|
// При переполнении рабочей области сократить размер окна по высоте.
|
||||||
// По ширине оно настраивается само в CSS.
|
// По ширине оно настраивается само в CSS.
|
||||||
let view = self.getViewGeometry();
|
let view = self.getViewGeometry();
|
||||||
let rect = el_window.getBoundingClientRect();
|
let rect = el_win.getBoundingClientRect();
|
||||||
if ((rect.bottom - rect.top) > (view.bottom - view.top)) {
|
if ((rect.bottom - rect.top) > (view.bottom - view.top)) {
|
||||||
let ratio = (rect.bottom - rect.top) / (view.bottom - view.top);
|
let ratio = (rect.bottom - rect.top) / (view.bottom - view.top);
|
||||||
el_window.style.height = view.bottom - view.top + "px";
|
el_win.style.height = view.bottom - view.top + "px";
|
||||||
el_window.style.width = Math.round((rect.right - rect.left) / ratio) + "px";
|
el_win.style.width = Math.round((rect.right - rect.left) / ratio) + "px";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (el_window.hasAttribute("data-centered")) {
|
if (el_win.hasAttribute("data-centered")) {
|
||||||
__centerWindow(el_window);
|
__centerWindow(el_win);
|
||||||
}
|
}
|
||||||
}).observe(el_window);
|
}).observe(el_win);
|
||||||
}
|
}
|
||||||
|
|
||||||
let el_close_button = el_window.querySelector(".window-header .window-button-close");
|
{
|
||||||
if (el_close_button) {
|
let el = el_win.querySelector(".window-header .window-button-close");
|
||||||
el_close_button.title = "Close window";
|
if (el) {
|
||||||
tools.el.setOnClick(el_close_button, () => self.closeWindow(el_window));
|
el.title = "Close window";
|
||||||
|
tools.el.setOnClick(el, () => self.closeWindow(el_win));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let el_maximize_button = el_window.querySelector(".window-header .window-button-maximize");
|
{
|
||||||
if (el_maximize_button) {
|
let el = el_win.querySelector(".window-header .window-button-maximize");
|
||||||
el_maximize_button.title = "Maximize window";
|
if (el) {
|
||||||
tools.el.setOnClick(el_maximize_button, function() {
|
el.title = "Maximize window";
|
||||||
__maximizeWindow(el_window);
|
tools.el.setOnClick(el, function() {
|
||||||
__activateLastWindow(el_window);
|
__maximizeWindow(el_win);
|
||||||
});
|
__activateLastWindow(el_win);
|
||||||
}
|
|
||||||
|
|
||||||
let el_orig_button = el_window.querySelector(".window-header .window-button-original");
|
|
||||||
if (el_orig_button) {
|
|
||||||
el_orig_button.title = "Reduce window to its original size and center it";
|
|
||||||
tools.el.setOnClick(el_orig_button, function() {
|
|
||||||
el_window.style.width = "";
|
|
||||||
el_window.style.height = "";
|
|
||||||
__centerWindow(el_window);
|
|
||||||
__activateLastWindow(el_window);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let el_enter_full_tab_button = el_window.querySelector(".window-header .window-button-enter-full-tab");
|
|
||||||
let el_exit_full_tab_button = el_window.querySelector(".window-button-exit-full-tab");
|
|
||||||
if (el_enter_full_tab_button && el_exit_full_tab_button) {
|
|
||||||
el_enter_full_tab_button.title = "Stretch to the entire tab";
|
|
||||||
tools.el.setOnClick(el_enter_full_tab_button, () => self.setFullTabWindow(el_window, true));
|
|
||||||
tools.el.setOnClick(el_exit_full_tab_button, () => self.setFullTabWindow(el_window, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
let el_full_screen_button = el_window.querySelector(".window-header .window-button-full-screen");
|
|
||||||
if (el_full_screen_button && __getFullScreenFunction(el_window)) {
|
|
||||||
el_full_screen_button.title = "Go to full-screen mode";
|
|
||||||
tools.el.setOnClick(el_full_screen_button, function() {
|
|
||||||
__fullScreenWindow(el_window);
|
|
||||||
el_window.focus(el_window); // Почему-то теряется фокус
|
|
||||||
__activateLastWindow(el_window);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let el_button of $$$("button[data-show-window]")) {
|
{
|
||||||
tools.el.setOnClick(el_button, () => self.showWindow($(el_button.getAttribute("data-show-window"))));
|
let el = el_win.querySelector(".window-header .window-button-original");
|
||||||
|
if (el) {
|
||||||
|
el.title = "Reduce window to its original size and center it";
|
||||||
|
tools.el.setOnClick(el, function() {
|
||||||
|
el_win.style.width = "";
|
||||||
|
el_win.style.height = "";
|
||||||
|
__centerWindow(el_win);
|
||||||
|
__activateLastWindow(el_win);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.onmouseup = __globalMouseButtonHandler;
|
{
|
||||||
window.ontouchend = __globalMouseButtonHandler;
|
let el_enter = el_win.querySelector(".window-header .window-button-enter-full-tab");
|
||||||
|
let el_exit = el_win.querySelector(".window-button-exit-full-tab");
|
||||||
|
if (el_enter && el_exit) {
|
||||||
|
el_enter.title = "Stretch to the entire tab";
|
||||||
|
tools.el.setOnClick(el_enter, () => self.setFullTabWindow(el_win, true));
|
||||||
|
tools.el.setOnClick(el_exit, () => self.setFullTabWindow(el_win, false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let el = el_win.querySelector(".window-header .window-button-full-screen");
|
||||||
|
if (el && __getFullScreenFunction(el_win)) {
|
||||||
|
el.title = "Go to full-screen mode";
|
||||||
|
tools.el.setOnClick(el, function() {
|
||||||
|
__fullScreenWindow(el_win);
|
||||||
|
el_win.focus(el_win); // Почему-то теряется фокус
|
||||||
|
__activateLastWindow(el_win);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let el of $$$("button[data-show-window]")) {
|
||||||
|
tools.el.setOnClick(el, () => self.showWindow($(el.getAttribute("data-show-window"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onmouseup = window.ontouchend = __globalMouseButtonHandler;
|
||||||
|
|
||||||
window.addEventListener("focusin", (event) => __focusInOut(event, true));
|
window.addEventListener("focusin", (event) => __focusInOut(event, true));
|
||||||
window.addEventListener("focusout", (event) => __focusInOut(event, false));
|
window.addEventListener("focusout", (event) => __focusInOut(event, false));
|
||||||
@ -196,7 +205,12 @@ function __WindowManager() {
|
|||||||
var __modalCodeDialog = function(header, html, code, ok, cancel) {
|
var __modalCodeDialog = function(header, html, code, ok, cancel) {
|
||||||
let create_content = function(el_content) {
|
let create_content = function(el_content) {
|
||||||
if (code) {
|
if (code) {
|
||||||
html += `<br><br><div class="code"><pre style="margin:0px">${tools.escape(code)}</pre></div>`;
|
html += `
|
||||||
|
<br><br>
|
||||||
|
<div class="code">
|
||||||
|
<pre style="margin:0px">${tools.escape(code)}</pre>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
el_content.innerHTML = html;
|
el_content.innerHTML = html;
|
||||||
};
|
};
|
||||||
@ -210,49 +224,49 @@ function __WindowManager() {
|
|||||||
el_modal.className = "modal";
|
el_modal.className = "modal";
|
||||||
el_modal.style.visibility = "visible";
|
el_modal.style.visibility = "visible";
|
||||||
|
|
||||||
let el_window = document.createElement("div");
|
let el_win = document.createElement("div");
|
||||||
el_window.className = "modal-window";
|
el_win.className = "modal-window";
|
||||||
el_window.setAttribute("tabindex", "-1");
|
el_win.setAttribute("tabindex", "-1");
|
||||||
el_modal.appendChild(el_window);
|
el_modal.appendChild(el_win);
|
||||||
|
|
||||||
let el_header = document.createElement("div");
|
let el_header = document.createElement("div");
|
||||||
el_header.className = "modal-header";
|
el_header.className = "modal-header";
|
||||||
el_header.innerText = header;
|
el_header.innerText = header;
|
||||||
el_window.appendChild(el_header);
|
el_win.appendChild(el_header);
|
||||||
|
|
||||||
let el_content = document.createElement("div");
|
let el_content = document.createElement("div");
|
||||||
el_content.className = "modal-content";
|
el_content.className = "modal-content";
|
||||||
el_window.appendChild(el_content);
|
el_win.appendChild(el_content);
|
||||||
|
|
||||||
let el_buttons = document.createElement("div");
|
let el_buttons = document.createElement("div");
|
||||||
el_buttons.classList.add("modal-buttons", "buttons-row");
|
el_buttons.classList.add("modal-buttons", "buttons-row");
|
||||||
el_window.appendChild(el_buttons);
|
el_win.appendChild(el_buttons);
|
||||||
|
|
||||||
let el_cancel_button = null;
|
let el_cancel_bt = null;
|
||||||
let el_ok_button = null;
|
let el_ok_bt = null;
|
||||||
if (cancel) {
|
if (cancel) {
|
||||||
el_cancel_button = document.createElement("button");
|
el_cancel_bt = document.createElement("button");
|
||||||
el_cancel_button.className = "row100";
|
el_cancel_bt.className = "row100";
|
||||||
el_cancel_button.innerText = "Cancel";
|
el_cancel_bt.innerText = "Cancel";
|
||||||
el_buttons.appendChild(el_cancel_button);
|
el_buttons.appendChild(el_cancel_bt);
|
||||||
}
|
}
|
||||||
if (ok) {
|
if (ok) {
|
||||||
el_ok_button = document.createElement("button");
|
el_ok_bt = document.createElement("button");
|
||||||
el_ok_button.className = "row100";
|
el_ok_bt.className = "row100";
|
||||||
el_ok_button.innerText = "OK";
|
el_ok_bt.innerText = "OK";
|
||||||
el_buttons.appendChild(el_ok_button);
|
el_buttons.appendChild(el_ok_bt);
|
||||||
}
|
}
|
||||||
if (ok && cancel) {
|
if (ok && cancel) {
|
||||||
el_ok_button.className = "row50";
|
el_ok_bt.className = "row50";
|
||||||
el_cancel_button.className = "row50";
|
el_cancel_bt.className = "row50";
|
||||||
}
|
}
|
||||||
|
|
||||||
el_window.onkeyup = function(event) {
|
el_win.onkeyup = function(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (ok && event.code === "Enter") {
|
if (ok && event.code === "Enter") {
|
||||||
el_ok_button.click();
|
el_ok_bt.click();
|
||||||
} else if (cancel && event.code === "Escape") {
|
} else if (cancel && event.code === "Escape") {
|
||||||
el_cancel_button.click();
|
el_cancel_bt.click();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -260,7 +274,7 @@ function __WindowManager() {
|
|||||||
if (ok || cancel) {
|
if (ok || cancel) {
|
||||||
promise = new Promise(function(resolve) {
|
promise = new Promise(function(resolve) {
|
||||||
function close(retval) {
|
function close(retval) {
|
||||||
__closeWindow(el_window);
|
__closeWindow(el_win);
|
||||||
let index = __windows.indexOf(el_modal);
|
let index = __windows.indexOf(el_modal);
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
__windows.splice(index, 1);
|
__windows.splice(index, 1);
|
||||||
@ -276,10 +290,10 @@ function __WindowManager() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cancel) {
|
if (cancel) {
|
||||||
tools.el.setOnClick(el_cancel_button, () => close(false));
|
tools.el.setOnClick(el_cancel_bt, () => close(false));
|
||||||
}
|
}
|
||||||
if (ok) {
|
if (ok) {
|
||||||
tools.el.setOnClick(el_ok_button, () => close(true));
|
tools.el.setOnClick(el_ok_bt, () => close(true));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -288,7 +302,7 @@ function __WindowManager() {
|
|||||||
(parent || document.fullscreenElement || document.body).appendChild(el_modal);
|
(parent || document.fullscreenElement || document.body).appendChild(el_modal);
|
||||||
if (typeof html === "function") {
|
if (typeof html === "function") {
|
||||||
// Это должно быть здесь, потому что элемент должен иметь родителя чтобы существовать
|
// Это должно быть здесь, потому что элемент должен иметь родителя чтобы существовать
|
||||||
html(el_content, el_ok_button);
|
html(el_content, el_ok_bt);
|
||||||
} else {
|
} else {
|
||||||
el_content.innerHTML = html;
|
el_content.innerHTML = html;
|
||||||
}
|
}
|
||||||
@ -297,26 +311,26 @@ function __WindowManager() {
|
|||||||
return promise;
|
return promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
self.showWindow = function(el_window, activate=true, center=false) {
|
self.showWindow = function(el_win, activate=true, center=false) {
|
||||||
let showed = false;
|
let showed = false;
|
||||||
if (!self.isWindowVisible(el_window)) {
|
if (!self.isWindowVisible(el_win)) {
|
||||||
center = true;
|
center = true;
|
||||||
showed = true;
|
showed = true;
|
||||||
}
|
}
|
||||||
__organizeWindow(el_window, center);
|
__organizeWindow(el_win, center);
|
||||||
el_window.style.visibility = "visible";
|
el_win.style.visibility = "visible";
|
||||||
if (activate) {
|
if (activate) {
|
||||||
__activateWindow(el_window);
|
__activateWindow(el_win);
|
||||||
}
|
}
|
||||||
if (el_window.show_hook) {
|
if (el_win.show_hook) {
|
||||||
if (showed) {
|
if (showed) {
|
||||||
el_window.show_hook();
|
el_win.show_hook();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.isWindowVisible = function(el_window) {
|
self.isWindowVisible = function(el_win) {
|
||||||
return (window.getComputedStyle(el_window, null).visibility !== "hidden");
|
return (window.getComputedStyle(el_win, null).visibility !== "hidden");
|
||||||
};
|
};
|
||||||
|
|
||||||
self.getViewGeometry = function() {
|
self.getViewGeometry = function() {
|
||||||
@ -329,35 +343,35 @@ function __WindowManager() {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
self.closeWindow = function(el_window) {
|
self.closeWindow = function(el_win) {
|
||||||
__closeWindow(el_window);
|
__closeWindow(el_win);
|
||||||
__activateLastWindow(el_window);
|
__activateLastWindow(el_win);
|
||||||
};
|
};
|
||||||
|
|
||||||
self.setFullTabWindow = function(el_window, enabled) {
|
self.setFullTabWindow = function(el_win, enabled) {
|
||||||
el_window.classList.toggle("window-full-tab", enabled);
|
el_win.classList.toggle("window-full-tab", enabled);
|
||||||
__activateLastWindow(el_window);
|
__activateLastWindow(el_win);
|
||||||
let el_navbar = $("navbar");
|
let el_navbar = $("navbar");
|
||||||
if (el_navbar) {
|
if (el_navbar) {
|
||||||
tools.hidden.setVisible(el_navbar, !enabled);
|
tools.hidden.setVisible(el_navbar, !enabled);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var __closeWindow = function(el_window) {
|
var __closeWindow = function(el_win) {
|
||||||
el_window.focus();
|
el_win.focus();
|
||||||
el_window.blur();
|
el_win.blur();
|
||||||
el_window.style.visibility = "hidden";
|
el_win.style.visibility = "hidden";
|
||||||
if (el_window.close_hook) {
|
if (el_win.close_hook) {
|
||||||
el_window.close_hook();
|
el_win.close_hook();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var __toggleMenu = function(el_a) {
|
var __toggleMenu = function(el_a) {
|
||||||
let all_hidden = true;
|
let all_hidden = true;
|
||||||
|
|
||||||
for (let el_button of __menu_buttons) {
|
for (let el_bt of __menu_buttons) {
|
||||||
let el_menu = el_button.parentElement.querySelector(".menu");
|
let el_menu = el_bt.parentElement.querySelector(".menu");
|
||||||
if (el_button === el_a && window.getComputedStyle(el_menu, null).visibility === "hidden") {
|
if (el_bt === el_a && window.getComputedStyle(el_menu, null).visibility === "hidden") {
|
||||||
let rect = el_menu.getBoundingClientRect();
|
let rect = el_menu.getBoundingClientRect();
|
||||||
let offset = self.getViewGeometry().right - (rect.left + el_menu.clientWidth + 2); // + 2 is ugly hack
|
let offset = self.getViewGeometry().right - (rect.left + el_menu.clientWidth + 2); // + 2 is ugly hack
|
||||||
if (offset < 0) {
|
if (offset < 0) {
|
||||||
@ -366,13 +380,13 @@ function __WindowManager() {
|
|||||||
el_menu.style.removeProperty("right");
|
el_menu.style.removeProperty("right");
|
||||||
}
|
}
|
||||||
|
|
||||||
el_button.classList.add("menu-button-pressed");
|
el_bt.classList.add("menu-button-pressed");
|
||||||
el_menu.style.visibility = "visible";
|
el_menu.style.visibility = "visible";
|
||||||
let el_focus = el_menu.querySelector("[data-focus]");
|
let el_focus = el_menu.querySelector("[data-focus]");
|
||||||
(el_focus !== null ? el_focus : el_menu).focus();
|
(el_focus !== null ? el_focus : el_menu).focus();
|
||||||
all_hidden &= false;
|
all_hidden &= false;
|
||||||
} else {
|
} else {
|
||||||
el_button.classList.remove("menu-button-pressed");
|
el_bt.classList.remove("menu-button-pressed");
|
||||||
el_menu.style.visibility = "hidden";
|
el_menu.style.visibility = "hidden";
|
||||||
el_menu.style.removeProperty("right");
|
el_menu.style.removeProperty("right");
|
||||||
}
|
}
|
||||||
@ -394,9 +408,9 @@ function __WindowManager() {
|
|||||||
|
|
||||||
var __closeAllMenues = function() {
|
var __closeAllMenues = function() {
|
||||||
document.onkeyup = null;
|
document.onkeyup = null;
|
||||||
for (let el_button of __menu_buttons) {
|
for (let el_bt of __menu_buttons) {
|
||||||
let el_menu = el_button.parentElement.querySelector(".menu");
|
let el_menu = el_bt.parentElement.querySelector(".menu");
|
||||||
el_button.classList.remove("menu-button-pressed");
|
el_bt.classList.remove("menu-button-pressed");
|
||||||
el_menu.style.visibility = "hidden";
|
el_menu.style.visibility = "hidden";
|
||||||
el_menu.style.removeProperty("right");
|
el_menu.style.removeProperty("right");
|
||||||
}
|
}
|
||||||
@ -420,10 +434,10 @@ function __WindowManager() {
|
|||||||
&& !event.target.closest(".menu-button")
|
&& !event.target.closest(".menu-button")
|
||||||
&& !event.target.closest(".modal")
|
&& !event.target.closest(".modal")
|
||||||
) {
|
) {
|
||||||
for (let el_item = event.target; el_item && el_item !== document; el_item = el_item.parentNode) {
|
for (let el = event.target; el && el !== document; el = el.parentNode) {
|
||||||
if (el_item.classList.contains("menu")) {
|
if (el.classList.contains("menu")) {
|
||||||
return;
|
return;
|
||||||
} else if (el_item.hasAttribute("data-force-hide-menu")) {
|
} else if (el.hasAttribute("data-force-hide-menu")) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -433,122 +447,122 @@ function __WindowManager() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var __organizeWindowsOnBrowserResize = function() {
|
var __organizeWindowsOnBrowserResize = function() {
|
||||||
for (let el_window of $$("window")) {
|
for (let el_win of $$("window")) {
|
||||||
if (el_window.style.visibility === "visible") {
|
if (el_win.style.visibility === "visible") {
|
||||||
if (tools.browser.is_mobile && el_window.classList.contains("window-resizable")) {
|
if (tools.browser.is_mobile && el_win.classList.contains("window-resizable")) {
|
||||||
// FIXME: При смене ориентации на мобильном браузере надо сбрасывать
|
// FIXME: При смене ориентации на мобильном браузере надо сбрасывать
|
||||||
// настройки окна стрима, поэтому тут стоит вот этот костыль
|
// настройки окна стрима, поэтому тут стоит вот этот костыль
|
||||||
el_window.style.width = "";
|
el_win.style.width = "";
|
||||||
el_window.style.height = "";
|
el_win.style.height = "";
|
||||||
}
|
}
|
||||||
__organizeWindow(el_window);
|
__organizeWindow(el_win);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var __organizeWindow = function(el_window, center=false) {
|
var __organizeWindow = function(el_win, center=false) {
|
||||||
let view = self.getViewGeometry();
|
let view = self.getViewGeometry();
|
||||||
let rect = el_window.getBoundingClientRect();
|
let rect = el_win.getBoundingClientRect();
|
||||||
|
|
||||||
if (el_window.classList.contains("window-resizable")) {
|
if (el_win.classList.contains("window-resizable")) {
|
||||||
// При переполнении рабочей области сократить размер окна
|
// При переполнении рабочей области сократить размер окна
|
||||||
if ((rect.bottom - rect.top) > (view.bottom - view.top)) {
|
if ((rect.bottom - rect.top) > (view.bottom - view.top)) {
|
||||||
let ratio = (rect.bottom - rect.top) / (view.bottom - view.top);
|
let ratio = (rect.bottom - rect.top) / (view.bottom - view.top);
|
||||||
el_window.style.height = view.bottom - view.top + "px";
|
el_win.style.height = view.bottom - view.top + "px";
|
||||||
el_window.style.width = Math.round((rect.right - rect.left) / ratio) + "px";
|
el_win.style.width = Math.round((rect.right - rect.left) / ratio) + "px";
|
||||||
}
|
}
|
||||||
if ((rect.right - rect.left) > (view.right - view.left)) {
|
if ((rect.right - rect.left) > (view.right - view.left)) {
|
||||||
el_window.style.width = view.right - view.left + "px";
|
el_win.style.width = view.right - view.left + "px";
|
||||||
}
|
}
|
||||||
rect = el_window.getBoundingClientRect();
|
rect = el_win.getBoundingClientRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (el_window.hasAttribute("data-centered") || center) {
|
if (el_win.hasAttribute("data-centered") || center) {
|
||||||
__centerWindow(el_window);
|
__centerWindow(el_win);
|
||||||
} else {
|
} else {
|
||||||
if (rect.top <= view.top) {
|
if (rect.top <= view.top) {
|
||||||
el_window.style.top = view.top + "px";
|
el_win.style.top = view.top + "px";
|
||||||
} else if (rect.bottom > view.bottom) {
|
} else if (rect.bottom > view.bottom) {
|
||||||
el_window.style.top = view.bottom - rect.height + "px";
|
el_win.style.top = view.bottom - rect.height + "px";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rect.left <= view.left) {
|
if (rect.left <= view.left) {
|
||||||
el_window.style.left = view.left + "px";
|
el_win.style.left = view.left + "px";
|
||||||
} else if (rect.right > view.right) {
|
} else if (rect.right > view.right) {
|
||||||
el_window.style.left = view.right - rect.width + "px";
|
el_win.style.left = view.right - rect.width + "px";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var __centerWindow = function(el_window) {
|
var __centerWindow = function(el_win) {
|
||||||
let view = self.getViewGeometry();
|
let view = self.getViewGeometry();
|
||||||
let rect = el_window.getBoundingClientRect();
|
let rect = el_win.getBoundingClientRect();
|
||||||
el_window.style.top = Math.max(view.top, Math.round((view.bottom - rect.height) / 2)) + "px";
|
el_win.style.top = Math.max(view.top, Math.round((view.bottom - rect.height) / 2)) + "px";
|
||||||
el_window.style.left = Math.round((view.right - rect.width) / 2) + "px";
|
el_win.style.left = Math.round((view.right - rect.width) / 2) + "px";
|
||||||
el_window.setAttribute("data-centered", "");
|
el_win.setAttribute("data-centered", "");
|
||||||
};
|
};
|
||||||
|
|
||||||
var __activateLastWindow = function(el_except_window=null) {
|
var __activateLastWindow = function(el_except_win=null) {
|
||||||
let el_last_window = null;
|
let el_last_win = null;
|
||||||
|
|
||||||
if (document.activeElement) {
|
if (document.activeElement) {
|
||||||
el_last_window = (document.activeElement.closest(".modal-window") || document.activeElement.closest(".window"));
|
el_last_win = (document.activeElement.closest(".modal-window") || document.activeElement.closest(".window"));
|
||||||
if (el_last_window && window.getComputedStyle(el_last_window, null).visibility === "hidden") {
|
if (el_last_win && window.getComputedStyle(el_last_win, null).visibility === "hidden") {
|
||||||
el_last_window = null;
|
el_last_win = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!el_last_window || el_last_window === el_except_window) {
|
if (!el_last_win || el_last_win === el_except_win) {
|
||||||
let max_z_index = 0;
|
let max_z_index = 0;
|
||||||
|
|
||||||
for (let el_window of __windows) {
|
for (let el_win of __windows) {
|
||||||
let z_index = parseInt(window.getComputedStyle(el_window, null).zIndex) || 0;
|
let z_index = parseInt(window.getComputedStyle(el_win, null).zIndex) || 0;
|
||||||
let visibility = window.getComputedStyle(el_window, null).visibility;
|
let visibility = window.getComputedStyle(el_win, null).visibility;
|
||||||
|
|
||||||
if (max_z_index < z_index && visibility !== "hidden" && el_window !== el_except_window) {
|
if (max_z_index < z_index && visibility !== "hidden" && el_win !== el_except_win) {
|
||||||
el_last_window = el_window;
|
el_last_win = el_win;
|
||||||
max_z_index = z_index;
|
max_z_index = z_index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (el_last_window) {
|
if (el_last_win) {
|
||||||
tools.debug("UI: Activating last window:", el_last_window);
|
tools.debug("UI: Activating last window:", el_last_win);
|
||||||
__activateWindow(el_last_window);
|
__activateWindow(el_last_win);
|
||||||
} else {
|
} else {
|
||||||
tools.debug("UI: No last window to activation");
|
tools.debug("UI: No last window to activation");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var __activateWindow = function(el_window) {
|
var __activateWindow = function(el_win) {
|
||||||
if (window.getComputedStyle(el_window, null).visibility !== "hidden") {
|
if (window.getComputedStyle(el_win, null).visibility !== "hidden") {
|
||||||
let el_to_focus;
|
let el_to_focus;
|
||||||
let el_window_contains_focus;
|
let el_focused; // A window which contains a focus
|
||||||
|
|
||||||
if (el_window.className === "modal") {
|
if (el_win.className === "modal") {
|
||||||
el_to_focus = el_window.querySelector(".modal-window");
|
el_to_focus = el_win.querySelector(".modal-window");
|
||||||
el_window_contains_focus = (document.activeElement && document.activeElement.closest(".modal-window"));
|
el_focused = (document.activeElement && document.activeElement.closest(".modal-window"));
|
||||||
} else { // .window
|
} else { // .window
|
||||||
el_to_focus = el_window;
|
el_to_focus = el_win;
|
||||||
el_window_contains_focus = (document.activeElement && document.activeElement.closest(".window"));
|
el_focused = (document.activeElement && document.activeElement.closest(".window"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (el_window.className !== "modal" && parseInt(el_window.style.zIndex) !== __top_z_index) {
|
if (el_win.className !== "modal" && parseInt(el_win.style.zIndex) !== __top_z_index) {
|
||||||
__top_z_index += 1;
|
__top_z_index += 1;
|
||||||
el_window.style.zIndex = __top_z_index;
|
el_win.style.zIndex = __top_z_index;
|
||||||
tools.debug("UI: Activated window:", el_window);
|
tools.debug("UI: Activated window:", el_win);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (el_window !== el_window_contains_focus) {
|
if (el_win !== el_focused) {
|
||||||
el_to_focus.focus();
|
el_to_focus.focus();
|
||||||
tools.debug("UI: Focused window:", el_window);
|
tools.debug("UI: Focused window:", el_win);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var __makeWindowMovable = function(el_window) {
|
var __makeWindowMovable = function(el_win) {
|
||||||
let el_header = el_window.querySelector(".window-header");
|
let el_header = el_win.querySelector(".window-header");
|
||||||
let el_grab = el_window.querySelector(".window-header .window-grab");
|
let el_grab = el_win.querySelector(".window-header .window-grab");
|
||||||
if (el_header === null || el_grab === null) {
|
if (el_header === null || el_grab === null) {
|
||||||
// Для псевдоокна OCR
|
// Для псевдоокна OCR
|
||||||
return;
|
return;
|
||||||
@ -559,10 +573,10 @@ function __WindowManager() {
|
|||||||
function startMoving(event) {
|
function startMoving(event) {
|
||||||
// При перетаскивании resizable-окна за правый кран экрана оно ужимается.
|
// При перетаскивании resizable-окна за правый кран экрана оно ужимается.
|
||||||
// Этот костыль фиксит это.
|
// Этот костыль фиксит это.
|
||||||
el_window.style.width = el_window.offsetWidth + "px";
|
el_win.style.width = el_win.offsetWidth + "px";
|
||||||
|
|
||||||
__closeAllMenues();
|
__closeAllMenues();
|
||||||
__activateWindow(el_window);
|
__activateWindow(el_win);
|
||||||
event = (event || window.event);
|
event = (event || window.event);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
@ -580,7 +594,7 @@ function __WindowManager() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function doMoving(event) {
|
function doMoving(event) {
|
||||||
el_window.removeAttribute("data-centered");
|
el_win.removeAttribute("data-centered");
|
||||||
|
|
||||||
event = (event || window.event);
|
event = (event || window.event);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -589,8 +603,8 @@ function __WindowManager() {
|
|||||||
let x = prev_pos.x - event_pos.x;
|
let x = prev_pos.x - event_pos.x;
|
||||||
let y = prev_pos.y - event_pos.y;
|
let y = prev_pos.y - event_pos.y;
|
||||||
|
|
||||||
el_window.style.top = (el_window.offsetTop - y) + "px";
|
el_win.style.top = (el_win.offsetTop - y) + "px";
|
||||||
el_window.style.left = (el_window.offsetLeft - x) + "px";
|
el_win.style.left = (el_win.offsetLeft - x) + "px";
|
||||||
|
|
||||||
prev_pos = event_pos;
|
prev_pos = event_pos;
|
||||||
}
|
}
|
||||||
@ -613,29 +627,29 @@ function __WindowManager() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
el_window.setAttribute("data-centered", "");
|
el_win.setAttribute("data-centered", "");
|
||||||
el_window.onmousedown = el_window.ontouchstart = () => __activateWindow(el_window);
|
el_win.onmousedown = el_win.ontouchstart = () => __activateWindow(el_win);
|
||||||
|
|
||||||
el_grab.onmousedown = startMoving;
|
el_grab.onmousedown = startMoving;
|
||||||
el_grab.ontouchstart = startMoving;
|
el_grab.ontouchstart = startMoving;
|
||||||
};
|
};
|
||||||
|
|
||||||
var __onFullScreenChange = function(event) {
|
var __onFullScreenChange = function(event) {
|
||||||
let el_window = event.target;
|
let el_win = event.target;
|
||||||
if (!document.fullscreenElement) {
|
if (!document.fullscreenElement) {
|
||||||
let rect = el_window.before_full_screen;
|
let rect = el_win.before_full_screen;
|
||||||
if (rect) {
|
if (rect) {
|
||||||
el_window.style.width = rect.width + "px";
|
el_win.style.width = rect.width + "px";
|
||||||
el_window.style.height = rect.height + "px";
|
el_win.style.height = rect.height + "px";
|
||||||
el_window.style.top = rect.top + "px";
|
el_win.style.top = rect.top + "px";
|
||||||
el_window.style.left = rect.left + "px";
|
el_win.style.left = rect.left + "px";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var __fullScreenWindow = function(el_window) {
|
var __fullScreenWindow = function(el_win) {
|
||||||
el_window.before_full_screen = el_window.getBoundingClientRect();
|
el_win.before_full_screen = el_win.getBoundingClientRect();
|
||||||
__getFullScreenFunction(el_window).call(el_window);
|
__getFullScreenFunction(el_win).call(el_win);
|
||||||
if (navigator.keyboard && navigator.keyboard.lock) {
|
if (navigator.keyboard && navigator.keyboard.lock) {
|
||||||
navigator.keyboard.lock();
|
navigator.keyboard.lock();
|
||||||
} else {
|
} else {
|
||||||
@ -647,26 +661,26 @@ function __WindowManager() {
|
|||||||
+ "In Chrome use HTTPS and enable <i>system-keyboard-lock</i><br>"
|
+ "In Chrome use HTTPS and enable <i>system-keyboard-lock</i><br>"
|
||||||
+ "by putting at URL <i>chrome://flags/#system-keyboard-lock</i>"
|
+ "by putting at URL <i>chrome://flags/#system-keyboard-lock</i>"
|
||||||
);
|
);
|
||||||
__modalDialog("Keyboard lock is unsupported", msg, true, false, el_window);
|
__modalDialog("Keyboard lock is unsupported", msg, true, false, el_win);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var __maximizeWindow = function(el_window) {
|
var __maximizeWindow = function(el_win) {
|
||||||
let el_navbar = $("navbar");
|
let el_navbar = $("navbar");
|
||||||
let vertical_offset = (el_navbar ? el_navbar.offsetHeight : 0);
|
let vertical_offset = (el_navbar ? el_navbar.offsetHeight : 0);
|
||||||
el_window.style.left = "0px";
|
el_win.style.left = "0px";
|
||||||
el_window.style.top = vertical_offset + "px";
|
el_win.style.top = vertical_offset + "px";
|
||||||
el_window.style.width = window.innerWidth + "px";
|
el_win.style.width = window.innerWidth + "px";
|
||||||
el_window.style.height = window.innerHeight - vertical_offset + "px";
|
el_win.style.height = window.innerHeight - vertical_offset + "px";
|
||||||
};
|
};
|
||||||
|
|
||||||
var __getFullScreenFunction = function(el_window) {
|
var __getFullScreenFunction = function(el_win) {
|
||||||
if (el_window.requestFullscreen) {
|
if (el_win.requestFullscreen) {
|
||||||
return el_window.requestFullscreen;
|
return el_win.requestFullscreen;
|
||||||
} else if (el_window.webkitRequestFullscreen) {
|
} else if (el_win.webkitRequestFullscreen) {
|
||||||
return el_window.webkitRequestFullscreen;
|
return el_win.webkitRequestFullscreen;
|
||||||
} else if (el_window.mozRequestFullscreen) {
|
} else if (el_win.mozRequestFullscreen) {
|
||||||
return el_window.mozRequestFullscreen;
|
return el_win.mozRequestFullscreen;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user