V7 preview 2 (#463)
* commit toward svgcanvas/svgedit isolation * jquery removal, isolate svgcavas from svgedit, tests * refactor(panels) * fix update of colorpickers * update cypress * #tool_imagelib image library menu missing in main menu * #tool_imagelib lint issue fixed * #seConfirmDialog confirm change to elix alertdialog * #seConfirmDialog alert change to elix alert dialog * #seConfirmDialog remove super.attributeChangedCallback * #process_cancel prompt changes to alertDialog and seConfirmDialog * refactor to class step 1 * make load faster * #storageDialog dialog separate moved dialog * #process_cancel alert and process_cancel changes * #process_cancel lint issue fixed * add seList component * merge * fixes * storagedialog * move all storage related code to ext-storage * fix ruler * Update ConfigObj.js * fix resize * Update ext-storage.js * picker starts withthe right color * fix prefs * fix initial content load * npm update and fix some tests * npm run build
This commit is contained in:
@@ -6,15 +6,13 @@ class PaintBox {
|
||||
/**
|
||||
* @param {string|Element|external:jQuery} container
|
||||
* @param {"fill"} type
|
||||
* @param {string} color
|
||||
* @param {number} opacity
|
||||
*/
|
||||
constructor (container, type, color, opacity) {
|
||||
constructor (container, type) {
|
||||
// set up gradients to be used for the buttons
|
||||
const svgdocbox = new DOMParser().parseFromString(
|
||||
`<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
fill="#${color}" opacity="${opacity}" width="22" height="22"/>
|
||||
fill="#000000" opacity="1" width="22" height="22"/>
|
||||
<defs><linearGradient id="gradbox_${PaintBox.ctr++}"/></defs>
|
||||
</svg>`,
|
||||
'text/xml'
|
||||
@@ -26,7 +24,7 @@ class PaintBox {
|
||||
this.rect = docElem.firstElementChild;
|
||||
this.defs = docElem.getElementsByTagName('defs')[0];
|
||||
this.grad = this.defs.firstElementChild;
|
||||
this.paint = new $.jGraduate.Paint({solidColor: color});
|
||||
// this.paint = new $.jGraduate.Paint({solidColor: color});
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@@ -138,22 +136,6 @@ class PaintBox {
|
||||
this.setPaint(paint);
|
||||
return (paint);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {void}
|
||||
*/
|
||||
prep () {
|
||||
const ptype = this.paint.type;
|
||||
|
||||
switch (ptype) {
|
||||
case 'linearGradient':
|
||||
case 'radialGradient': {
|
||||
const paint = new $.jGraduate.Paint({copy: this.paint});
|
||||
this.setPaint(this.type, paint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PaintBox.ctr = 0;
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import './seButton.js';
|
||||
import './seFlyingButton.js';
|
||||
import './seExplorerButton.js';
|
||||
import './seDropdown.js';
|
||||
import './seZoom.js';
|
||||
import './seInput.js';
|
||||
import './seSpinInput.js';
|
||||
import './sePalette.js';
|
||||
import './seMenu.js';
|
||||
import './seMenuItem.js';
|
||||
import './seList.js';
|
||||
import './seListItem.js';
|
||||
import './seColorPicker.js';
|
||||
|
||||
@@ -283,7 +283,8 @@ export default function jQueryPluginJGraduate ($) {
|
||||
const $wc = (selector) => $($shadowRoot.querySelectorAll(selector));
|
||||
|
||||
if (!idref) {
|
||||
/* await */ $.alert('Container element must have an id attribute to maintain unique id strings for sub-elements.');
|
||||
// eslint-disable-next-line no-alert
|
||||
alert('Container element must have an id attribute to maintain unique id strings for sub-elements.');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
99
src/editor/components/seList.js
Normal file
99
src/editor/components/seList.js
Normal file
@@ -0,0 +1,99 @@
|
||||
/* eslint-disable node/no-unpublished-import */
|
||||
import 'elix/define/DropdownList.js';
|
||||
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
[part~="source"] {
|
||||
grid-template-columns: 20px 1fr auto;
|
||||
}
|
||||
::slotted(*) {
|
||||
padding: 4px;
|
||||
background: #E8E8E8;
|
||||
border: 1px solid #B0B0B0;
|
||||
width: 100%;
|
||||
}
|
||||
[part~="popup"] {
|
||||
width: 150%;
|
||||
}
|
||||
</style>
|
||||
<label>Label</label>
|
||||
<elix-dropdown-list>
|
||||
<slot></slot>
|
||||
</elix-dropdown-list>
|
||||
|
||||
`;
|
||||
/**
|
||||
* @class SeList
|
||||
*/
|
||||
export class SeList extends HTMLElement {
|
||||
/**
|
||||
* @function constructor
|
||||
*/
|
||||
constructor () {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot.appendChild(template.content.cloneNode(true));
|
||||
this.$dropdown = this._shadowRoot.querySelector('elix-dropdown-list');
|
||||
this.$label = this._shadowRoot.querySelector('label');
|
||||
}
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['label'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
* @param {string} name
|
||||
* @param {string} oldValue
|
||||
* @param {string} newValue
|
||||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
if (oldValue === newValue) return;
|
||||
switch (name) {
|
||||
case 'label':
|
||||
this.$label.textContent = newValue;
|
||||
break;
|
||||
default:
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get label () {
|
||||
return this.getAttribute('label');
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set label (value) {
|
||||
this.setAttribute('label', value);
|
||||
}
|
||||
/**
|
||||
* @function connectedCallback
|
||||
* @returns {void}
|
||||
*/
|
||||
connectedCallback () {
|
||||
this.$dropdown.addEventListener('change', (e) => {
|
||||
e.preventDefault();
|
||||
const selectedItem = e?.detail?.closeResult;
|
||||
if (selectedItem !== undefined && selectedItem?.id !== undefined) {
|
||||
document.getElementById(selectedItem.id).click();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-list', SeList);
|
||||
71
src/editor/components/seListItem.js
Normal file
71
src/editor/components/seListItem.js
Normal file
@@ -0,0 +1,71 @@
|
||||
/* eslint-disable node/no-unpublished-import */
|
||||
import 'elix/define/Option.js';
|
||||
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
</style>
|
||||
<elix-option aria-label="option">
|
||||
<slot></slot>
|
||||
</elix-option>
|
||||
`;
|
||||
/**
|
||||
* @class SeMenu
|
||||
*/
|
||||
export class SeListItem extends HTMLElement {
|
||||
/**
|
||||
* @function constructor
|
||||
*/
|
||||
constructor () {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot.appendChild(template.content.cloneNode(true));
|
||||
this.$menuitem = this._shadowRoot.querySelector('elix-menu-item');
|
||||
}
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['option'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
* @param {string} name
|
||||
* @param {string} oldValue
|
||||
* @param {string} newValue
|
||||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
if (oldValue === newValue) return;
|
||||
switch (name) {
|
||||
case 'option':
|
||||
this.$menuitem.setAttribute('option', newValue);
|
||||
break;
|
||||
default:
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get option () {
|
||||
return this.getAttribute('option');
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set option (value) {
|
||||
this.setAttribute('option', value);
|
||||
}
|
||||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-list-item', SeListItem);
|
||||
@@ -8,7 +8,7 @@ template.innerHTML = `
|
||||
</style>
|
||||
<elix-menu-item>
|
||||
<div style="display:inline-block;">
|
||||
<img src="" alt="icon" style="display:none;" />
|
||||
<img src="./images/logo.svg" alt="icon" style="display:none;" />
|
||||
<span></span>
|
||||
</div>
|
||||
</elix-menu-item>
|
||||
|
||||
@@ -18,7 +18,7 @@ template.innerHTML = `
|
||||
padding: 0px;
|
||||
}
|
||||
</style>
|
||||
<img src="./images/logo.svg" alt="icon" width="12" height="12" />
|
||||
<img src="./images/logo.svg" alt="icon" width="12" height="12" aria-labelledby="label" />
|
||||
<span id="label">label</span>
|
||||
<elix-number-spin-box min="1" step="1"></elix-number-spin-box>
|
||||
`;
|
||||
|
||||
179
src/editor/components/seZoom.js
Normal file
179
src/editor/components/seZoom.js
Normal file
@@ -0,0 +1,179 @@
|
||||
/* eslint-disable node/no-unpublished-import */
|
||||
import ListComboBox from 'elix/define/ListComboBox.js';
|
||||
import NumberSpinBox from 'elix/define/NumberSpinBox.js';
|
||||
// import Input from 'elix/src/base/Input.js';
|
||||
import * as internal from 'elix/src/base/internal.js';
|
||||
import {templateFrom, fragmentFrom} from 'elix/src/core/htmlLiterals.js';
|
||||
|
||||
/**
|
||||
* @class Dropdown
|
||||
*/
|
||||
class Zoom extends ListComboBox {
|
||||
/**
|
||||
* @function get
|
||||
* @returns {PlainObject}
|
||||
*/
|
||||
get [internal.defaultState] () {
|
||||
return Object.assign(super[internal.defaultState], {
|
||||
inputPartType: NumberSpinBox,
|
||||
src: './images/logo.svg',
|
||||
inputsize: '100%'
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @function get
|
||||
* @returns {PlainObject}
|
||||
*/
|
||||
get [internal.template] () {
|
||||
const result = super[internal.template];
|
||||
const source = result.content.getElementById('source');
|
||||
// add a icon before our dropdown
|
||||
source.prepend(fragmentFrom.html`
|
||||
<img src="./images/logo.svg" alt="icon" width="18" height="18"></img>
|
||||
`.cloneNode(true));
|
||||
// change the style so it fits in our toolbar
|
||||
result.content.append(
|
||||
templateFrom.html`
|
||||
<style>
|
||||
[part~="source"] {
|
||||
grid-template-columns: 20px 1fr auto;
|
||||
}
|
||||
::slotted(*) {
|
||||
padding: 4px;
|
||||
background: #E8E8E8;
|
||||
border: 1px solid #B0B0B0;
|
||||
width: 100%;
|
||||
}
|
||||
[part~="popup"] {
|
||||
width: 150%;
|
||||
}
|
||||
</style>
|
||||
`.content
|
||||
);
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['title', 'src', 'inputsize', 'value'];
|
||||
}
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
* @param {string} name
|
||||
* @param {string} oldValue
|
||||
* @param {string} newValue
|
||||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
if (oldValue === newValue) return;
|
||||
switch (name) {
|
||||
case 'title':
|
||||
// this.$span.setAttribute('title', `${newValue} ${shortcut ? `[${shortcut}]` : ''}`);
|
||||
break;
|
||||
case 'src':
|
||||
this.src = newValue;
|
||||
break;
|
||||
case 'inputsize':
|
||||
this.inputsize = newValue;
|
||||
break;
|
||||
default:
|
||||
super.attributeChangedCallback(name, oldValue, newValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @function [internal.render]
|
||||
* @param {PlainObject} changed
|
||||
* @returns {void}
|
||||
*/
|
||||
[internal.render] (changed) {
|
||||
super[internal.render](changed);
|
||||
if (this[internal.firstRender]) {
|
||||
this.$img = this.shadowRoot.querySelector('img');
|
||||
this.$input = this.shadowRoot.getElementById('input');
|
||||
}
|
||||
if (changed.src) {
|
||||
this.$img.setAttribute('src', this[internal.state].src);
|
||||
}
|
||||
if (changed.inputsize) {
|
||||
this.$input.shadowRoot.querySelector('[part~="input"]').style.width = this[internal.state].inputsize;
|
||||
}
|
||||
if (changed.inputPartType) {
|
||||
// Wire up handler on new input.
|
||||
this.addEventListener('close', (e) => {
|
||||
e.preventDefault();
|
||||
const value = e.detail?.closeResult?.getAttribute('value');
|
||||
if (value) {
|
||||
const closeEvent = new CustomEvent('change', {detail: {value}});
|
||||
this.dispatchEvent(closeEvent);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @function src
|
||||
* @returns {string} src
|
||||
*/
|
||||
get src () {
|
||||
return this[internal.state].src;
|
||||
}
|
||||
/**
|
||||
* @function src
|
||||
* @returns {void}
|
||||
*/
|
||||
set src (src) {
|
||||
this[internal.setState]({src});
|
||||
}
|
||||
/**
|
||||
* @function inputsize
|
||||
* @returns {string} src
|
||||
*/
|
||||
get inputsize () {
|
||||
return this[internal.state].inputsize;
|
||||
}
|
||||
/**
|
||||
* @function src
|
||||
* @returns {void}
|
||||
*/
|
||||
set inputsize (inputsize) {
|
||||
this[internal.setState]({inputsize});
|
||||
}
|
||||
/**
|
||||
* @function value
|
||||
* @returns {string} src
|
||||
*/
|
||||
get value () {
|
||||
return this[internal.state].value;
|
||||
}
|
||||
/**
|
||||
* @function value
|
||||
* @returns {void}
|
||||
*/
|
||||
set value (value) {
|
||||
this[internal.setState]({value});
|
||||
}
|
||||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-zoom', Zoom);
|
||||
|
||||
/*
|
||||
{TODO
|
||||
min: 0.001, max: 10000, step: 50, stepfunc: stepZoom,
|
||||
function stepZoom (elem, step) {
|
||||
const origVal = Number(elem.value);
|
||||
if (origVal === 0) { return 100; }
|
||||
const sugVal = origVal + step;
|
||||
if (step === 0) { return origVal; }
|
||||
|
||||
if (origVal >= 100) {
|
||||
return sugVal;
|
||||
}
|
||||
if (sugVal >= origVal) {
|
||||
return origVal * 2;
|
||||
}
|
||||
return origVal / 2;
|
||||
}
|
||||
*/
|
||||
Reference in New Issue
Block a user