2019-05-31 01:10:13 +02:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
(function(){
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
let scope;
|
|
|
|
if ((typeof exports) !== "undefined"){
|
|
|
|
scope = exports;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
scope = require.register("./modal", {});
|
|
|
|
}
|
|
|
|
|
|
|
|
const extension = require("./extension");
|
|
|
|
|
|
|
|
function getGlobalOffsetTop(node){
|
|
|
|
if (node){
|
|
|
|
return node.offsetTop + getGlobalOffsetTop(node.offsetParent);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function getGlobalScrollTop(node){
|
|
|
|
if (node && node.scrollTop){
|
|
|
|
return node.scrollTop + getGlobalScrollTop(node.parentNode);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return window.scrollY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function openDialog(text, buttons, parent = document.body){
|
|
|
|
if (!(parent instanceof Node)){
|
|
|
|
const parentSelector = parent.selector;
|
|
|
|
parent = parent.node;
|
|
|
|
while (parent && !parent.matches(parentSelector)){
|
|
|
|
parent = parent.parentNode;
|
|
|
|
}
|
|
|
|
if (!parent){
|
|
|
|
parent = document.body;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const container = document.createElement("div");
|
|
|
|
container.className = "modal";
|
|
|
|
parent.appendChild(container);
|
|
|
|
|
|
|
|
const overlay = document.createElement("div");
|
|
|
|
overlay.className = "overlay";
|
|
|
|
container.appendChild(overlay);
|
|
|
|
|
|
|
|
const dialogPosition = document.createElement("div");
|
|
|
|
dialogPosition.className = "dialogPosition";
|
|
|
|
container.appendChild(dialogPosition);
|
|
|
|
|
|
|
|
const dialog = document.createElement("div");
|
|
|
|
dialog.className = "dialog";
|
|
|
|
dialogPosition.appendChild(dialog);
|
|
|
|
|
|
|
|
const textNode = document.createElement("span");
|
|
|
|
textNode.className = "text";
|
|
|
|
textNode.textContent = text;
|
|
|
|
dialog.appendChild(textNode);
|
|
|
|
|
|
|
|
const buttonsNode = document.createElement("div");
|
|
|
|
buttonsNode.className = "buttons";
|
|
|
|
dialog.appendChild(buttonsNode);
|
|
|
|
|
|
|
|
let defaultButton;
|
|
|
|
buttons.forEach(function(button){
|
|
|
|
const buttonNode = document.createElement("button");
|
|
|
|
buttonNode.textContent = button.text;
|
|
|
|
buttonNode.addEventListener("click", function(){
|
|
|
|
close();
|
|
|
|
button.callback();
|
|
|
|
});
|
|
|
|
buttonsNode.appendChild(buttonNode);
|
|
|
|
if (button.focused){
|
|
|
|
buttonNode.focus();
|
|
|
|
}
|
|
|
|
if (button.default){
|
|
|
|
defaultButton = button;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
function closeOnEscape(event){
|
|
|
|
if (event.keyCode === 27){
|
|
|
|
close();
|
|
|
|
if (defaultButton){
|
|
|
|
defaultButton.callback();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function positionDialog(){
|
|
|
|
const parentTop = getGlobalOffsetTop(parent) - getGlobalScrollTop(parent);
|
|
|
|
const parentHeight = parent.offsetHeight;
|
|
|
|
const height = dialog.offsetHeight;
|
2019-11-28 01:26:35 +01:00
|
|
|
const top = Math.max(0,
|
2019-05-31 01:10:13 +02:00
|
|
|
Math.min(
|
|
|
|
container.offsetHeight - height,
|
|
|
|
parentTop + parentHeight / 2 - height / 2
|
|
|
|
)
|
|
|
|
);
|
|
|
|
dialogPosition.style.top = top + "px";
|
|
|
|
}
|
|
|
|
function close(){
|
|
|
|
window.removeEventListener("keydown", closeOnEscape);
|
|
|
|
window.removeEventListener("scroll", positionDialog);
|
|
|
|
window.removeEventListener("resize", positionDialog);
|
|
|
|
parent.removeChild(container);
|
|
|
|
}
|
|
|
|
window.addEventListener("keydown", closeOnEscape);
|
|
|
|
|
|
|
|
if (parent !== document.body){
|
|
|
|
positionDialog();
|
|
|
|
window.addEventListener("scroll", positionDialog);
|
|
|
|
window.addEventListener("resize", positionDialog);
|
|
|
|
}
|
2019-06-14 10:45:34 +02:00
|
|
|
|
|
|
|
return container;
|
2019-05-31 01:10:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
scope.confirm = function(text, parent){
|
|
|
|
return new Promise(function(resolve){
|
|
|
|
openDialog(text, [
|
|
|
|
{text: extension.getTranslation("cancel"), default: true, callback: ()=>resolve(false)},
|
|
|
|
{text: extension.getTranslation("OK"), focused: true, callback: ()=>resolve(true)}
|
|
|
|
], parent);
|
|
|
|
});
|
|
|
|
};
|
2019-06-14 10:45:34 +02:00
|
|
|
|
|
|
|
scope.select = function(text, options, parent){
|
|
|
|
return new Promise(function(resolve, reject){
|
|
|
|
const select = document.createElement("select");
|
|
|
|
options.forEach(function(option){
|
|
|
|
const optionNode = document.createElement("option");
|
|
|
|
optionNode.text = option.name;
|
|
|
|
optionNode.object = option.object;
|
|
|
|
select.appendChild(optionNode);
|
|
|
|
});
|
|
|
|
|
|
|
|
const container = openDialog(text, [
|
2019-07-16 13:36:54 +02:00
|
|
|
{
|
|
|
|
text: extension.getTranslation("cancel"),
|
|
|
|
default: true,
|
|
|
|
callback: () => reject(false)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
text: extension.getTranslation("OK"),
|
|
|
|
focused: true,
|
|
|
|
callback: () => resolve(select.options[select.selectedIndex].object)
|
|
|
|
}
|
2019-06-14 10:45:34 +02:00
|
|
|
], parent);
|
|
|
|
container.querySelector(".text").insertAdjacentElement("afterend", select);
|
|
|
|
});
|
|
|
|
};
|
2019-05-31 01:10:13 +02:00
|
|
|
}());
|