diff --git a/index.html b/index.html index a1abe68..9a7794b 100644 --- a/index.html +++ b/index.html @@ -92,6 +92,6 @@ - +
diff --git a/src/css/popup.css b/src/css/popup.css index 8ba7347..d562119 100644 --- a/src/css/popup.css +++ b/src/css/popup.css @@ -1,4 +1,4 @@ -#popup { +#popups .popup { position:fixed; display:none; top: 15vh; @@ -18,13 +18,13 @@ font-size: 13px; overflow: hidden; } -#popup.wide{ +#popups .popup.wide{ max-width: 840px; } -#popup a{ +#popups .popup a{ color: var(--link-color); } -#popup h2{ +#popups .popup h2{ display: block; position: absolute; top: 0; @@ -40,12 +40,12 @@ z-index: 0; cursor:move; } -#popup #dialog_content { +#popups .popup .dialog_content { overflow-y: auto; max-height: calc(80vh - 9rem); padding: 1rem; } -#popup .buttons{ +#popups .popup .buttons{ position: absolute; background-color: var(--block-background-color); bottom: 0; @@ -59,7 +59,7 @@ border-top: 1px solid var(--header-background-color); z-index: 3; } -#popup .close{ +#popups .popup .close{ position: absolute; right: 0; top: 0; @@ -73,32 +73,32 @@ background: none; z-index: 1; } -#popup input[type="range"]{ +#popups .popup input[type="range"]{ margin:0; width: 100%; } -#popup table{ +#popups .popup table{ box-sizing: border-box; width: 100%; } -#popup td, #popup th{ +#popups .popup td, #popups .popup th{ height: 25px; } -#popup td{ +#popups .popup td{ vertical-align: middle; } -#popup th{ +#popups .popup th{ text-align:left; padding: 5px 5px 5px 0; width: 130px; } -#popup textarea{ +#popups .popup textarea{ color: var(--input-text-color); width:100%; border:1px solid #393939; padding-left:5px; } -#popup .button{ +#popups .popup .button{ margin: 0 3px; background-color: rgba(255, 255, 255, 0.2); background-color: var(--button-background-color); @@ -107,90 +107,90 @@ border:1px solid var(--border-color); padding: 5px 10px; } -#popup input[type="text"], #popup input[type="number"], #popup textarea{ +#popups .popup input[type="text"], #popups .popup input[type="number"], #popups .popup textarea{ width:100%; } -#popup input[type="number"]{ +#popups .popup input[type="number"]{ width:100px; } -#popup input[type="radio"], #popup input[type="checkbox"]{ +#popups .popup input[type="radio"], #popups .popup input[type="checkbox"]{ margin-left: 0; } -#popup label span{ +#popups .popup label span{ color:var(--text-color-muted); } -#popup .checkbox label{ +#popups .popup .checkbox label{ margin-top: 5px; color:var(--text-color-muted); } -#popup .preview_container{ +#popups .popup .preview_container{ margin-top:10px; margin-bottom:15px; text-align: center; } -#popup .preview_canvas_left{ +#popups .popup .preview_canvas_left{ position:relative; margin:0 5px 5px 0; border:1px solid #393939; display: inline-block; vertical-align: top; } -#popup .preview_canvas_post_back{ +#popups .popup .preview_canvas_post_back{ position:absolute; border:1px solid #393939; background-color:#ffffff; } -#popup .preview_canvas_post{ +#popups .popup .preview_canvas_post{ position:relative; border:1px solid #393939; } -#popup .canvas_preview_container{ +#popups .popup .canvas_preview_container{ position:relative; display: inline-block; vertical-align: top; } -#popup .radios label{ +#popups .popup .radios label{ display: inline-block; margin-right: 10px; } -#popup .range_value{ +#popups .popup .range_value{ padding-left:10px; width:50px; } -#popup .long_text_value{ +#popups .popup .long_text_value{ font-size: 12px; } -#popup .preview-item-title{ +#popups .popup .preview-item-title{ text-align: center; max-width: 150px; } -#popup .field_comment{ +#popups .popup .field_comment{ display: inline-block; margin-left: 10px; opacity: 0.5; } @media screen and (max-width:500px){ - #popup { + #popups .popup { max-height: calc(80vh - 20px); /* mobile phones has bottom menu */ } - #popup tr{ + #popups .popup tr{ display: block; margin-bottom: 10px; } - #popup td, #popup th{ + #popups .popup td, #popups .popup th{ display: block; width: 100%; height: auto; padding: 5px; } - #popup th{ + #popups .popup th{ padding: 5px 5px 0px 5px; } - #popup td{ + #popups .popup td{ padding: 5px 5px 5px 5px; } - #popup .range_value{ + #popups .popup .range_value{ display: none; } } diff --git a/src/css/reset.css b/src/css/reset.css index 7f1fe5e..5fe11b6 100644 --- a/src/css/reset.css +++ b/src/css/reset.css @@ -227,6 +227,7 @@ label{ @supports not (zoom:2) { input[type="radio"], input[type=checkbox]{ transform: scale(1.5); - margin: 8px; + transform-origin: left center; + margin: 8px 12px 8px 0; } } diff --git a/src/js/core/components/color-input.js b/src/js/core/components/color-input.js index 1bc3f54..2a440e2 100644 --- a/src/js/core/components/color-input.js +++ b/src/js/core/components/color-input.js @@ -3,7 +3,6 @@ import Dialog_class from './../../libs/popup.js'; import GUI_colors_class from './../gui/gui-colors.js'; const Helper = new Helper_class(); -let POP; /** * This input opens a custom color picker dialog that is more tightly integrated with the application (swatch selection, etc). @@ -33,9 +32,7 @@ let POP; event.preventDefault(); const $el = $(event.target.closest('.ui_color_input')); const { value } = $el.data(); - if (!POP) { - POP = new Dialog_class(); - } + const POP = new Dialog_class(); let colorsDialog = new GUI_colors_class(); var settings = { title: 'Color Picker', @@ -112,6 +109,7 @@ let POP; const classList = el.className; const id = definition.id != null ? definition.id : el.getAttribute('id'); + const inputId = definition.inputId || ''; const disabled = definition.disabled != null ? definition.disabled : el.hasAttribute('disabled') ? true : false; const value = definition.value != null ? definition.value : el.value || 0; const ariaLabeledBy = el.getAttribute('aria-labelledby'); @@ -139,6 +137,9 @@ let POP; if (id) { el.setAttribute('id', id); } + if (inputId) { + input.setAttribute('id', inputId); + } if (ariaLabeledBy) { input.setAttribute('aria-labelledby', ariaLabeledBy); } diff --git a/src/js/core/gui/gui-colors.js b/src/js/core/gui/gui-colors.js index 5b33104..f79b03f 100644 --- a/src/js/core/gui/gui-colors.js +++ b/src/js/core/gui/gui-colors.js @@ -195,7 +195,6 @@ class GUI_colors_class { } init_components() { - var _this = this; // Store button references this.buttons = { @@ -289,20 +288,10 @@ class GUI_colors_class { } Helper.setCookie('toggle_color_picker', isPressed ? 1 : 0); }); - document.getElementById('selected_color_sample').addEventListener('click', function (event) { - _this.buttons.toggleColorPicker.attr('aria-pressed', 'true' === _this.buttons.toggleColorPicker.attr('aria-pressed') ? 'false' : 'true'); - const isPressed = _this.buttons.toggleColorPicker.attr('aria-pressed') === 'true'; - if (isPressed) { - //show - _this.sections.pickerPlaceholder.parentNode.insertBefore(_this.sections.picker[0], _this.sections.pickerPlaceholder.nextSibling); - _this.sections.pickerPlaceholder.parentNode.removeChild(_this.sections.pickerPlaceholder); - } - else { - //hide - _this.sections.picker[0].parentNode.insertBefore(_this.sections.pickerPlaceholder, _this.sections.picker[0].nextSibling); - _this.sections.picker[0].parentNode.removeChild(_this.sections.picker[0]); - } + this.inputs.sample.on('click', (event) => { + this.buttons.toggleColorPicker.click(); }); + // Restore toggle preference, default to visible for picker const saved_toggle_color_picker = Helper.getCookie('toggle_color_picker'); if (saved_toggle_color_picker === 0) { diff --git a/src/js/libs/popup.js b/src/js/libs/popup.js index 33859a3..c0c5b5d 100644 --- a/src/js/libs/popup.js +++ b/src/js/libs/popup.js @@ -43,33 +43,31 @@ import Base_layers_class from './../core/base-layers.js'; import Base_gui_class from './../core/base-gui.js'; import Tools_translate_class from './../modules/tools/translate.js'; -var instance = null; - var template = ` - -
- - -
-
-
+ +
+ +

+
+
+
- - + +
`; class Dialog_class { constructor() { - //singleton - if (instance) { - return instance; + if (!window.POP) { + window.POP = this; } - instance = this; - window.POP = this; + this.previousPOP = null; + this.el = null; + this.eventHandles = []; this.active = false; this.title = null; this.onfinish = false; @@ -90,8 +88,6 @@ class Dialog_class { this.caller = null; this.resize_clicked = {x: null, y: null} this.element_offset = {x: null, y: null} - - this.set_events(); } /** @@ -100,6 +96,8 @@ class Dialog_class { * @param {array} config */ show(config) { + this.previousPOP = window.POP; + window.POP = this; if (this.active == true) { this.hide(); @@ -116,11 +114,15 @@ class Dialog_class { this.comment = config.comment || ''; //reset position - var target = document.querySelector('#popup'); - target.style.top = null; - target.style.left = null; + this.el = document.createElement('div'); + this.el.classList = 'popup'; + this.el.role = 'dialog'; + document.querySelector('#popups').appendChild(this.el); + this.el.style.top = null; + this.el.style.left = null; this.show_action(); + this.set_events(); } /** @@ -130,12 +132,15 @@ class Dialog_class { * @returns {undefined} */ hide(success) { + window.POP = this.previousPOP; var params = this.get_params(); if (success === false && this.oncancel) { this.oncancel(params); } - document.getElementById("popup").style.display = 'none'; + if (this.el && this.el.parentNode) { + this.el.parentNode.removeChild(this.el); + } this.parameters = []; this.active = false; this.preview = false; @@ -146,61 +151,79 @@ class Dialog_class { this.comment = ''; this.onfinish = false; this.oncancel = false; + + this.remove_events(); } /* ----------------- private functions ---------------------------------- */ - set_events() { - var _this = this; + addEventListener(target, type, listener, options) { + target.addEventListener(type, listener, options); + const handle = { + target, type, listener, + remove() { + target.removeEventListener(type, listener); + } + }; + this.eventHandles.push(handle); + } - document.addEventListener('keydown', function (event) { + set_events() { + this.addEventListener(document, 'keydown', (event) => { var code = event.code; if (code == "Escape") { //escape - _this.hide(false); + this.hide(false); } }, false); //register events - document.addEventListener('mousedown', function (event) { - if(event.target != document.querySelector('#popup h2')) + this.addEventListener(document, 'mousedown', (event) => { + if(event.target != this.el.querySelector('h2')) return; event.preventDefault(); - _this.resize_clicked.x = event.pageX; - _this.resize_clicked.y = event.pageY; + this.resize_clicked.x = event.pageX; + this.resize_clicked.y = event.pageY; - var target = document.querySelector('#popup'); - _this.element_offset.x = target.offsetLeft; - _this.element_offset.y = target.offsetTop; + var target = this.el; + this.element_offset.x = target.offsetLeft; + this.element_offset.y = target.offsetTop; }, false); - document.addEventListener('mousemove', function (event) { - if(_this.resize_clicked.x != null){ - var dx = _this.resize_clicked.x - event.pageX; - var dy = _this.resize_clicked.y - event.pageY; + this.addEventListener(document, 'mousemove', (event) => { + if(this.resize_clicked.x != null){ + var dx = this.resize_clicked.x - event.pageX; + var dy = this.resize_clicked.y - event.pageY; - var target = document.querySelector('#popup'); - target.style.left = (_this.element_offset.x - dx) + "px"; - target.style.top = (_this.element_offset.y - dy) + "px"; + var target = this.el; + target.style.left = (this.element_offset.x - dx) + "px"; + target.style.top = (this.element_offset.y - dy) + "px"; } }, false); - document.addEventListener('mouseup', function (event) { - if(event.target != document.querySelector('#popup h2')) + this.addEventListener(document, 'mouseup', (event) => { + if(event.target != this.el.querySelector('h2')) return; event.preventDefault(); - _this.resize_clicked.x = null; - _this.resize_clicked.y = null; + this.resize_clicked.x = null; + this.resize_clicked.y = null; }, false); - window.addEventListener('resize', function (event) { - var target = document.querySelector('#popup'); + this.addEventListener(window, 'resize', (event) => { + var target = this.el; target.style.top = null; target.style.left = null; }, false); } + remove_events() { + for (let handle of this.eventHandles) { + handle.remove(); + } + this.eventHandles = []; + } + onChangeEvent(e) { var params = this.get_params(); @@ -213,7 +236,7 @@ class Dialog_class { if (this.onchange != false) { if (this.preview != false) { - var canvas_right = document.getElementById("pop_post"); + var canvas_right = this.el.querySelector('[data-id="pop_post"]'); var ctx_right = canvas_right.getContext("2d"); ctx_right.clearRect(0, 0, this.width_mini, this.height_mini); @@ -255,7 +278,7 @@ class Dialog_class { get_params() { var response = {}; - var inputs = document.getElementsByTagName('input'); + var inputs = this.el.querySelectorAll('input'); for (var i = 0; i < inputs.length; i++) { if (inputs[i].id.substr(0, 9) == 'pop_data_') { var key = inputs[i].id.substr(9); @@ -284,14 +307,14 @@ class Dialog_class { } } - var selects = document.getElementsByTagName('select'); + var selects = this.el.querySelectorAll('select'); for (var i = 0; i < selects.length; i++) { if (selects[i].id.substr(0, 9) == 'pop_data_') { var key = selects[i].id.substr(9); response[key] = selects[i].value; } } - var textareas = document.getElementsByTagName('textarea'); + var textareas = this.el.querySelectorAll('textarea'); for (var i = 0; i < textareas.length; i++) { if (textareas[i].id.substr(0, 9) == 'pop_data_') { var key = textareas[i].id.substr(9); @@ -324,12 +347,12 @@ class Dialog_class { if (this.preview !== false) { html_preview_content += '
'; html_preview_content += ''; + + this.height_mini + '" data-id="pop_pre">'; html_preview_content += '
'; html_preview_content += ' '; + + '" height="' + this.height_mini + '" data-id="pop_post_back">'; html_preview_content += ' '; + + this.height_mini + '" data-id="pop_post">'; html_preview_content += '
'; html_preview_content += '
'; } @@ -337,44 +360,57 @@ class Dialog_class { //generate params html_params += this.generateParamsHtml(); - document.getElementById("popup").innerHTML = template; - document.getElementById("pretitle_area").innerHTML = html_pretitle_area; - document.getElementById("popup_title").innerHTML = this.title; - document.getElementById("popup_comment").innerHTML = this.comment; - document.getElementById("preview_content").innerHTML = html_preview_content; - document.getElementById("params_content").innerHTML = html_params; + this.el.innerHTML = template; + this.el.querySelector('[data-id="pretitle_area"').innerHTML = html_pretitle_area; + this.el.querySelector('[data-id="popup_title"').innerHTML = this.title; + this.el.querySelector('[data-id="popup_comment"').innerHTML = this.comment; + this.el.querySelector('[data-id="preview_content"').innerHTML = html_preview_content; + this.el.querySelector('[data-id="params_content"').innerHTML = html_params; if (this.onfinish != false) { - document.getElementById("popup_cancel").style.display = ''; + this.el.querySelector('[data-id="popup_cancel"').style.display = ''; } else { - document.getElementById("popup_cancel").style.display = 'none'; + this.el.querySelector('[data-id="popup_cancel"').style.display = 'none'; } - document.getElementById("popup").style.display = "block"; - document.getElementById("popup").className = this.className; + this.el.style.display = "block"; + if (this.className) { + this.el.classList.add(this.className); + } + + //replace color inputs + this.el.querySelectorAll('input[type="color"]').forEach((colorInput) => { + const id = colorInput.getAttribute('id'); + colorInput.removeAttribute('id'); + $(colorInput) + .uiColorInput({ inputId: id }) + .on('change', (e) => { + this.onChangeEvent(e); + }); + }); //events var _this = this; - document.getElementById('popup_ok').addEventListener('click', function (event) { - _this.save(); + this.el.querySelector('[data-id="popup_ok"').addEventListener('click', (event) => { + this.save(); }); - document.getElementById('popup_cancel').addEventListener('click', function (event) { - _this.hide(false); + this.el.querySelector('[data-id="popup_cancel"').addEventListener('click', (event) => { + this.hide(false); }); - document.getElementById('popup_close').addEventListener('click', function (event) { - _this.hide(false); + this.el.querySelector('[data-id="popup_close"').addEventListener('click', (event) => { + this.hide(false); }); - var targets = document.querySelectorAll('#popup input'); + var targets = this.el.querySelectorAll('input'); for (var i = 0; i < targets.length; i++) { - targets[i].addEventListener('keyup', function (event) { - _this.onkeyup(event); + targets[i].addEventListener('keyup', (event) => { + this.onkeyup(event); }); } //onload if (this.onload) { var params = this.get_params(); - this.onload(params); + this.onload(params, this); } //load preview @@ -383,7 +419,7 @@ class Dialog_class { var canvas = this.Base_layers.convert_layer_to_canvas(); //draw original image - var canvas_left = document.getElementById("pop_pre"); + var canvas_left = this.el.querySelector('[data-id="pop_pre"]'); var pop_pre = canvas_left.getContext("2d"); pop_pre.clearRect(0, 0, this.width_mini, this.height_mini); pop_pre.rect(0, 0, this.width_mini, this.height_mini); @@ -403,11 +439,11 @@ class Dialog_class { this.layer_active_small_ctx.scale(1, 1); //draw right background - var canvas_right_back = document.getElementById("pop_post_back").getContext("2d"); + var canvas_right_back = this.el.querySelector('[data-id="pop_post_back"]').getContext("2d"); this.draw_background(canvas_right_back, this.width_mini, this.height_mini, 10); //copy to right side - var canvas_right = document.getElementById("pop_post").getContext("2d"); + var canvas_right = this.el.querySelector('[data-id="pop_post"]').getContext("2d"); canvas_right.clearRect(0, 0, this.width_mini, this.height_mini); canvas_right.drawImage(canvas_left, 0, 0, this.width_mini, this.height_mini); diff --git a/src/js/modules/effects/browser.js b/src/js/modules/effects/browser.js index f4ee2f1..ff25bee 100644 --- a/src/js/modules/effects/browser.js +++ b/src/js/modules/effects/browser.js @@ -40,13 +40,13 @@ class Effects_browser_class extends Base_tools_class { var settings = { title: 'Effects browser', className: 'wide', - on_load: function (params) { + on_load: function (params, popup) { var node = document.createElement("div"); node.classList.add('flex-container'); node.innerHTML = html; - document.querySelector('#popup #dialog_content').appendChild(node); + popup.el.querySelector('.dialog_content').appendChild(node); //events - var targets = document.querySelectorAll('#popup .item canvas'); + var targets = popup.el.querySelectorAll('.item canvas'); for (var i = 0; i < targets.length; i++) { targets[i].addEventListener('click', function (event) { //we have click diff --git a/src/js/tools/media.js b/src/js/tools/media.js index d56ee9a..01b04b7 100644 --- a/src/js/tools/media.js +++ b/src/js/tools/media.js @@ -59,13 +59,13 @@ class Media_class extends Base_tools_class { params: [ {name: "query", title: "Keyword:", value: query}, ], - on_load: function (params) { + on_load: function (params, popup) { var node = document.createElement("div"); node.classList.add('flex-container'); node.innerHTML = html; - document.querySelector('#popup #dialog_content').appendChild(node); + popup.el.querySelector('.dialog_content').appendChild(node); //events - var targets = document.querySelectorAll('#popup .item img'); + var targets = popup.el.querySelectorAll('.item img'); for (var i = 0; i < targets.length; i++) { targets[i].addEventListener('click', function (event) { //we have click diff --git a/src/js/tools/shape.js b/src/js/tools/shape.js index fce685d..f5ba548 100644 --- a/src/js/tools/shape.js +++ b/src/js/tools/shape.js @@ -48,13 +48,13 @@ class Shape_class extends Base_tools_class { var settings = { title: 'Shapes', className: 'wide', - on_load: function (params) { + on_load: function (params, popup) { var node = document.createElement("div"); node.classList.add('flex-container'); node.innerHTML = html; - document.querySelector('#popup #dialog_content').appendChild(node); + popup.el.querySelector('.dialog_content').appendChild(node); //events - var targets = document.querySelectorAll('#popup .item canvas'); + var targets = popup.el.querySelectorAll('.item canvas'); for (var i = 0; i < targets.length; i++) { targets[i].addEventListener('click', function (event) { //we have click