UNPKG

svgedit

Version:

Powerful SVG-Editor for your browser

355 lines (341 loc) 10.8 kB
const template = document.createElement('template'); // eslint-disable-next-line no-unsanitized/property template.innerHTML = ` <style> .contextMenu { position: absolute; z-index: 99999; border: solid 1px rgba(0,0,0,.33); background: rgba(255,255,255,.95); padding: 5px 0; margin: 0px; display: none; font: 12px/15px Lucida Sans, Helvetica, Verdana, sans-serif; border-radius: 5px; -moz-border-radius: 5px; -moz-box-shadow: 2px 5px 10px rgba(0,0,0,.3); -webkit-box-shadow: 2px 5px 10px rgba(0,0,0,.3); box-shadow: 2px 5px 10px rgba(0,0,0,.3); } .contextMenu li { list-style: none; padding: 0px; margin: 0px; } .contextMenu .shortcut { width: 115px; text-align:right; float:right; } .contextMenu a { -moz-user-select: none; -webkit-user-select: none; color: #222; text-decoration: none; display: block; line-height: 20px; height: 20px; background-position: 6px center; background-repeat: no-repeat; outline: none; padding: 0px 15px 1px 20px; } .contextMenu li.hover a { background-color: #2e5dea; color: white; cursor: default; } .contextMenu li.disabled a { color: #999; } .contextMenu li.hover.disabled a { background-color: transparent; } .contextMenu li.separator { border-top: solid 1px #E3E3E3; padding-top: 5px; margin-top: 5px; } </style> <ul id="cmenu_canvas" class="contextMenu"> <li> <a href="#cut" id="se-cut"> <span class="shortcut">META+X</span> </a> </li> <li> <a href="#copy" id="se-copy"> <span class="shortcut">META+C</span> </a> </li> <li> <a href="#paste" id="se-paste"></a> </li> <li> <a href="#paste_in_place" id="se-paste-in-place"></a> </li> <li class="separator"> <a href="#delete" id="se-delete"> <span class="shortcut">BACKSPACE</span> </a> </li> <li class="separator"> <a href="#group" id="se-group"> <span class="shortcut">G</span> </a> </li> <li> <a href="#ungroup" id="se-ungroup"> <span class="shortcut">G</span> </a> </li> <li class="separator"> <a href="#move_front" id="se-move-front"> <span class="shortcut">CTRL+SHFT+]</span> </a> </li> <li> <a href="#move_up" id="se-move-up"> <span class="shortcut">CTRL+]</span> </a> </li> <li> <a href="#move_down" id="se-move-down"> <span class="shortcut">CTRL+[</span> </a> </li> <li> <a href="#move_back" id="se-move-back"> <span class="shortcut">CTRL+SHFT+[</span> </a> </li> </ul> `; /** * @class SeCMenuDialog */ export class SeCMenuDialog extends HTMLElement { /** * @function constructor */ constructor () { super(); // create the shadowDom and insert the template this._shadowRoot = this.attachShadow({ mode: 'open' }); this._shadowRoot.append(template.content.cloneNode(true)); this._workarea = document.getElementById('workarea'); this.$dialog = this._shadowRoot.querySelector('#cmenu_canvas'); this.$copyLink = this._shadowRoot.querySelector('#se-copy'); this.$cutLink = this._shadowRoot.querySelector('#se-cut'); this.$pasteLink = this._shadowRoot.querySelector('#se-paste'); this.$pasteInPlaceLink = this._shadowRoot.querySelector('#se-paste-in-place'); this.$deleteLink = this._shadowRoot.querySelector('#se-delete'); this.$groupLink = this._shadowRoot.querySelector('#se-group'); this.$ungroupLink = this._shadowRoot.querySelector('#se-ungroup'); this.$moveFrontLink = this._shadowRoot.querySelector('#se-move-front'); this.$moveUpLink = this._shadowRoot.querySelector('#se-move-up'); this.$moveDownLink = this._shadowRoot.querySelector('#se-move-down'); this.$moveBackLink = this._shadowRoot.querySelector('#se-move-back'); } /** * @function init * @param {any} name * @returns {void} */ init (i18next) { this.setAttribute('tools-cut', i18next.t('tools.cut')); this.setAttribute('tools-copy', i18next.t('tools.copy')); this.setAttribute('tools-paste', i18next.t('tools.paste')); this.setAttribute('tools-paste_in_place', i18next.t('tools.paste_in_place')); this.setAttribute('tools-delete', i18next.t('tools.delete')); this.setAttribute('tools-group', i18next.t('tools.group')); this.setAttribute('tools-ungroup', i18next.t('tools.ungroup')); this.setAttribute('tools-move_front', i18next.t('tools.move_front')); this.setAttribute('tools-move_up', i18next.t('tools.move_up')); this.setAttribute('tools-move_down', i18next.t('tools.move_down')); this.setAttribute('tools-move_back', i18next.t('tools.move_back')); } /** * @function observedAttributes * @returns {any} observed */ static get observedAttributes () { return [ 'disableallmenu', 'enablemenuitems', 'disablemenuitems', 'tools-cut', 'tools-copy', 'tools-paste', 'tools-paste_in_place', 'tools-delete', 'tools-group', 'tools-ungroup', 'tools-move_front', 'tools-move_up', 'tools-move_down', 'tools-move_back' ]; } /** * @function attributeChangedCallback * @param {string} name * @param {string} oldValue * @param {string} newValue * @returns {void} */ attributeChangedCallback (name, oldValue, newValue) { let eles = []; let textnode; const sdowRoot = this._shadowRoot; switch (name) { case 'disableallmenu': if (newValue === 'true') { const elesli = sdowRoot.querySelectorAll('li'); elesli.forEach(function (eleli) { eleli.classList.add('disabled'); }); } break; case 'enablemenuitems': eles = newValue.split(','); eles.forEach(function (ele) { const selEle = sdowRoot.querySelector('a[href*="' + ele + '"]'); selEle.parentElement.classList.remove('disabled'); }); break; case 'disablemenuitems': eles = newValue.split(','); eles.forEach(function (ele) { const selEle = sdowRoot.querySelector('a[href*="' + ele + '"]'); selEle.parentElement.classList.add('disabled'); }); break; case 'tools-cut': textnode = document.createTextNode(newValue); this.$cutLink.prepend(textnode); break; case 'tools-copy': textnode = document.createTextNode(newValue); this.$copyLink.prepend(textnode); break; case 'tools-paste': this.$pasteLink.textContent = newValue; break; case 'tools-paste_in_place': this.$pasteInPlaceLink.textContent = newValue; break; case 'tools-delete': textnode = document.createTextNode(newValue); this.$deleteLink.prepend(textnode); break; case 'tools-group': textnode = document.createTextNode(newValue); this.$groupLink.prepend(textnode); break; case 'tools-ungroup': textnode = document.createTextNode(newValue); this.$ungroupLink.prepend(textnode); break; case 'tools-move_front': textnode = document.createTextNode(newValue); this.$moveFrontLink.prepend(textnode); break; case 'tools-move_up': textnode = document.createTextNode(newValue); this.$moveUpLink.prepend(textnode); break; case 'tools-move_down': textnode = document.createTextNode(newValue); this.$moveDownLink.prepend(textnode); break; case 'tools-move_back': textnode = document.createTextNode(newValue); this.$moveBackLink.prepend(textnode); break; default: // super.attributeChangedCallback(name, oldValue, newValue); break; } } /** * @function get * @returns {any} */ get disableallmenu () { return this.getAttribute('disableallmenu'); } /** * @function set * @returns {void} */ set disableallmenu (value) { this.setAttribute('disableallmenu', value); } /** * @function get * @returns {any} */ get enablemenuitems () { return this.getAttribute('enablemenuitems'); } /** * @function set * @returns {void} */ set enablemenuitems (value) { this.setAttribute('enablemenuitems', value); } /** * @function get * @returns {any} */ get disablemenuitems () { return this.getAttribute('disablemenuitems'); } /** * @function set * @returns {void} */ set disablemenuitems (value) { this.setAttribute('disablemenuitems', value); } /** * @function connectedCallback * @returns {void} */ connectedCallback () { const current = this; const onMenuOpenHandler = (e) => { e.preventDefault(); // Detect mouse position let x = e.pageX; let y = e.pageY; const xOff = screen.width - 250; // menu width const yOff = screen.height - (276 + 150); // menu height + bottom panel height and scroll bar if (x > xOff) { x = xOff; } if (y > yOff) { y = yOff; } current.$dialog.style.top = y + 'px'; current.$dialog.style.left = x + 'px'; current.$dialog.style.display = 'block'; }; const onMenuCloseHandler = (e) => { if (e.button !== 2) { current.$dialog.style.display = 'none'; } }; const onMenuClickHandler = (e, action) => { const triggerEvent = new CustomEvent('change', { detail: { trigger: action } }); this.dispatchEvent(triggerEvent); }; this._workarea.addEventListener('contextmenu', onMenuOpenHandler); this._workarea.addEventListener('mousedown', onMenuCloseHandler); this.$cutLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'cut')); this.$copyLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'copy')); this.$pasteLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'paste')); this.$pasteInPlaceLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'paste_in_place')); this.$deleteLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'delete')); this.$groupLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'group')); this.$ungroupLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'ungroup')); this.$moveFrontLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'move_front')); this.$moveUpLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'move_up')); this.$moveDownLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'move_down')); this.$moveBackLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'move_back')); } } // Register customElements.define('se-cmenu_canvas-dialog', SeCMenuDialog);