move to standard linter for simpler configuration

This commit is contained in:
JFH
2021-12-28 11:02:29 -03:00
parent 258e2bd6a1
commit fdcfc8a253
251 changed files with 19760 additions and 19935 deletions

View File

@@ -1,4 +1,4 @@
import { jGraduate } from './jgraduate/jQuery.jGraduate.js';
import { jGraduate } from './jgraduate/jQuery.jGraduate.js'
/**
*
*/
@@ -16,17 +16,17 @@ class PaintBox {
<defs><linearGradient id="gradbox_${PaintBox.ctr++}"/></defs>
</svg>`,
'text/xml'
);
)
let docElem = svgdocbox.documentElement;
docElem = document.importNode(docElem, true);
container.appendChild(docElem);
let docElem = svgdocbox.documentElement
docElem = document.importNode(docElem, true)
container.appendChild(docElem)
this.rect = docElem.firstElementChild;
this.defs = docElem.getElementsByTagName('defs')[0];
this.grad = this.defs.firstElementChild;
this.rect = docElem.firstElementChild
this.defs = docElem.getElementsByTagName('defs')[0]
this.grad = this.defs.firstElementChild
// this.paint = new $.jGraduate.Paint({solidColor: color});
this.type = type;
this.type = type
}
/**
@@ -34,30 +34,31 @@ class PaintBox {
* @returns {void}
*/
setPaint (paint) {
this.paint = paint;
this.paint = paint
const ptype = paint.type;
const opac = paint.alpha / 100;
const ptype = paint.type
const opac = paint.alpha / 100
let fillAttr = 'none';
let fillAttr = 'none'
switch (ptype) {
case 'solidColor':
fillAttr = (paint[ptype] !== 'none') ? '#' + paint[ptype] : paint[ptype];
break;
case 'linearGradient':
case 'radialGradient': {
this.grad.remove();
this.grad = paint[ptype];
this.defs.appendChild(this.grad);
const id = this.grad.id = 'gradbox_' + this.type;
fillAttr = 'url(#' + id + ')';
break;
}
case 'solidColor':
fillAttr = (paint[ptype] !== 'none') ? '#' + paint[ptype] : paint[ptype]
break
case 'linearGradient':
case 'radialGradient': {
this.grad.remove()
this.grad = paint[ptype]
this.defs.appendChild(this.grad)
const id = this.grad.id = 'gradbox_' + this.type
fillAttr = 'url(#' + id + ')'
break
}
}
this.rect.setAttribute('fill', fillAttr);
this.rect.setAttribute('opacity', opac);
this.rect.setAttribute('fill', fillAttr)
this.rect.setAttribute('opacity', opac)
}
/**
* @param {PlainObject} svgCanvas
* @param {string} color
@@ -67,20 +68,20 @@ class PaintBox {
*/
static getPaint (svgCanvas, color, opac, type) {
// update the editor's fill paint
const opts = { alpha: opac };
const opts = { alpha: opac }
if (color.startsWith('url(#')) {
let refElem = svgCanvas.getRefElem(color);
refElem = (refElem) ? refElem.cloneNode(true) : document.querySelectorAll('#' + type + '_color defs *')[0];
let refElem = svgCanvas.getRefElem(color)
refElem = (refElem) ? refElem.cloneNode(true) : document.querySelectorAll('#' + type + '_color defs *')[0]
if (!refElem) {
console.error(`the color ${color} is referenced by an url that can't be identified - using 'none'`);
opts.solidColor = 'none';
console.error(`the color ${color} is referenced by an url that can't be identified - using 'none'`)
opts.solidColor = 'none'
} else {
opts[refElem.tagName] = refElem;
opts[refElem.tagName] = refElem
}
} else if (color.startsWith('#')) {
opts.solidColor = color.substr(1);
opts.solidColor = color.substr(1)
}
return new jGraduate.Paint(opts);
return new jGraduate.Paint(opts)
}
/**
@@ -89,59 +90,59 @@ class PaintBox {
* @returns {any}
*/
update (svgcanvas, selectedElement) {
if (!selectedElement) { return null; }
if (!selectedElement) { return null }
const { type } = this;
const { type } = this
switch (selectedElement.tagName) {
case 'use':
case 'image':
case 'foreignObject':
case 'use':
case 'image':
case 'foreignObject':
// These elements don't have fill or stroke, so don't change
// the current value
return null;
case 'g':
case 'a': {
const childs = selectedElement.getElementsByTagName('*');
return null
case 'g':
case 'a': {
const childs = selectedElement.getElementsByTagName('*')
let gPaint = null;
for (let i = 0, len = childs.length; i < len; i++) {
const elem = childs[i];
const p = elem.getAttribute(type);
if (i === 0) {
gPaint = p;
} else if (gPaint !== p) {
gPaint = null;
break;
let gPaint = null
for (let i = 0, len = childs.length; i < len; i++) {
const elem = childs[i]
const p = elem.getAttribute(type)
if (i === 0) {
gPaint = p
} else if (gPaint !== p) {
gPaint = null
break
}
}
}
if (gPaint === null) {
if (gPaint === null) {
// No common color, don't update anything
this._paintColor = null;
return null;
}
this._paintColor = gPaint;
this._paintOpacity = 1;
break;
} default: {
this._paintOpacity = Number.parseFloat(selectedElement.getAttribute(type + '-opacity'));
if (Number.isNaN(this._paintOpacity)) {
this._paintOpacity = 1.0;
}
this._paintColor = null
return null
}
this._paintColor = gPaint
this._paintOpacity = 1
break
} default: {
this._paintOpacity = Number.parseFloat(selectedElement.getAttribute(type + '-opacity'))
if (Number.isNaN(this._paintOpacity)) {
this._paintOpacity = 1.0
}
const defColor = type === 'fill' ? 'black' : 'none';
this._paintColor = selectedElement.getAttribute(type) || defColor;
}
const defColor = type === 'fill' ? 'black' : 'none'
this._paintColor = selectedElement.getAttribute(type) || defColor
}
}
this._paintOpacity *= 100;
this._paintOpacity *= 100
const paint = PaintBox.getPaint(svgcanvas, this._paintColor, this._paintOpacity, type);
const paint = PaintBox.getPaint(svgcanvas, this._paintColor, this._paintOpacity, type)
// update the rect inside #fill_color/#stroke_color
this.setPaint(paint);
return (paint);
this.setPaint(paint)
return (paint)
}
}
PaintBox.ctr = 0;
PaintBox.ctr = 0
export default PaintBox;
export default PaintBox

View File

@@ -1,15 +1,14 @@
import './seButton.js';
import './seFlyingButton.js';
import './seExplorerButton.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';
import './seSelect.js';
import './seText.js';
import './seButton.js'
import './seFlyingButton.js'
import './seExplorerButton.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'
import './seSelect.js'
import './seText.js'

View File

@@ -8,8 +8,8 @@
* @returns {Float}
*/
function toFixedNumeric (value, precision) {
if (precision === undefined) precision = 0;
return Math.round(value * (10 ** precision)) / (10 ** precision);
if (precision === undefined) precision = 0
return Math.round(value * (10 ** precision)) / (10 ** precision)
}
/**
* Whether a value is `null` or `undefined`.
@@ -17,8 +17,8 @@ function toFixedNumeric (value, precision) {
* @returns {boolean}
*/
const isNullish = (val) => {
return val === null || val === undefined;
};
return val === null || val === undefined
}
/**
* Controls for all the input elements for the typing in color values.
*/
@@ -30,8 +30,8 @@ export default class ColorValuePicker {
* @param {Float} alphaPrecision
*/
constructor (picker, color, bindedHex, alphaPrecision) {
const that = this; // private properties and methods
const inputs = picker.querySelectorAll('td.Text input');
const that = this // private properties and methods
const inputs = picker.querySelectorAll('td.Text input')
// input box key down - use arrows to alter color
/**
*
@@ -39,95 +39,95 @@ export default class ColorValuePicker {
* @returns {Event|false|void}
*/
function keyDown (e) {
if (e.target.value === '' && e.target !== hex && ((!isNullish(bindedHex) && e.target !== bindedHex) || isNullish(bindedHex))) return undefined;
if (!validateKey(e)) return e;
if (e.target.value === '' && e.target !== hex && ((!isNullish(bindedHex) && e.target !== bindedHex) || isNullish(bindedHex))) return undefined
if (!validateKey(e)) return e
switch (e.target) {
case red:
switch (e.keyCode) {
case 38:
red.value = setValueInRange.call(that, (red.value << 0) + 1, 0, 255);
color.val('r', red.value, e.target);
return false;
case 40:
red.value = setValueInRange.call(that, (red.value << 0) - 1, 0, 255);
color.val('r', red.value, e.target);
return false;
}
break;
case green:
switch (e.keyCode) {
case 38:
green.value = setValueInRange.call(that, (green.value << 0) + 1, 0, 255);
color.val('g', green.value, e.target);
return false;
case 40:
green.value = setValueInRange.call(that, (green.value << 0) - 1, 0, 255);
color.val('g', green.value, e.target);
return false;
}
break;
case blue:
switch (e.keyCode) {
case 38:
blue.value = setValueInRange.call(that, (blue.value << 0) + 1, 0, 255);
color.val('b', blue.value, e.target);
return false;
case 40:
blue.value = setValueInRange.call(that, (blue.value << 0) - 1, 0, 255);
color.val('b', blue.value, e.target);
return false;
}
break;
case alpha:
switch (e.keyCode) {
case 38:
alpha.value = setValueInRange.call(that, Number.parseFloat(alpha.value) + 1, 0, 100);
color.val('a', toFixedNumeric((alpha.value * 255) / 100, alphaPrecision), e.target);
return false;
case 40:
alpha.value = setValueInRange.call(that, Number.parseFloat(alpha.value) - 1, 0, 100);
color.val('a', toFixedNumeric((alpha.value * 255) / 100, alphaPrecision), e.target);
return false;
}
break;
case hue:
switch (e.keyCode) {
case 38:
hue.value = setValueInRange.call(that, (hue.value << 0) + 1, 0, 360);
color.val('h', hue.value, e.target);
return false;
case 40:
hue.value =setValueInRange.call(that, (hue.value << 0) - 1, 0, 360);
color.val('h', hue.value, e.target);
return false;
}
break;
case saturation:
switch (e.keyCode) {
case 38:
saturation.value = setValueInRange.call(that, (saturation.value << 0) + 1, 0, 100);
color.val('s', saturation.value, e.target);
return false;
case 40:
saturation.value = setValueInRange.call(that, (saturation.value << 0) - 1, 0, 100);
color.val('s', saturation.value, e.target);
return false;
}
break;
case value:
switch (e.keyCode) {
case 38:
value.value = setValueInRange.call(that, (value.value << 0) + 1, 0, 100);
color.val('v', value.value, e.target);
return false;
case 40:
value.value = setValueInRange.call(that, (value.value << 0) - 1, 0, 100);
color.val('v', value.value, e.target);
return false;
}
break;
case red:
switch (e.keyCode) {
case 38:
red.value = setValueInRange.call(that, (red.value << 0) + 1, 0, 255)
color.val('r', red.value, e.target)
return false
case 40:
red.value = setValueInRange.call(that, (red.value << 0) - 1, 0, 255)
color.val('r', red.value, e.target)
return false
}
break
case green:
switch (e.keyCode) {
case 38:
green.value = setValueInRange.call(that, (green.value << 0) + 1, 0, 255)
color.val('g', green.value, e.target)
return false
case 40:
green.value = setValueInRange.call(that, (green.value << 0) - 1, 0, 255)
color.val('g', green.value, e.target)
return false
}
break
case blue:
switch (e.keyCode) {
case 38:
blue.value = setValueInRange.call(that, (blue.value << 0) + 1, 0, 255)
color.val('b', blue.value, e.target)
return false
case 40:
blue.value = setValueInRange.call(that, (blue.value << 0) - 1, 0, 255)
color.val('b', blue.value, e.target)
return false
}
break
case alpha:
switch (e.keyCode) {
case 38:
alpha.value = setValueInRange.call(that, Number.parseFloat(alpha.value) + 1, 0, 100)
color.val('a', toFixedNumeric((alpha.value * 255) / 100, alphaPrecision), e.target)
return false
case 40:
alpha.value = setValueInRange.call(that, Number.parseFloat(alpha.value) - 1, 0, 100)
color.val('a', toFixedNumeric((alpha.value * 255) / 100, alphaPrecision), e.target)
return false
}
break
case hue:
switch (e.keyCode) {
case 38:
hue.value = setValueInRange.call(that, (hue.value << 0) + 1, 0, 360)
color.val('h', hue.value, e.target)
return false
case 40:
hue.value = setValueInRange.call(that, (hue.value << 0) - 1, 0, 360)
color.val('h', hue.value, e.target)
return false
}
break
case saturation:
switch (e.keyCode) {
case 38:
saturation.value = setValueInRange.call(that, (saturation.value << 0) + 1, 0, 100)
color.val('s', saturation.value, e.target)
return false
case 40:
saturation.value = setValueInRange.call(that, (saturation.value << 0) - 1, 0, 100)
color.val('s', saturation.value, e.target)
return false
}
break
case value:
switch (e.keyCode) {
case 38:
value.value = setValueInRange.call(that, (value.value << 0) + 1, 0, 100)
color.val('v', value.value, e.target)
return false
case 40:
value.value = setValueInRange.call(that, (value.value << 0) - 1, 0, 100)
color.val('v', value.value, e.target)
return false
}
break
}
return undefined;
return undefined
}
// input box key up - validate value and set color
/**
@@ -138,53 +138,53 @@ export default class ColorValuePicker {
function keyUp (e) {
if (e.target.value === '' && e.target !== hex &&
((!isNullish(bindedHex) && e.target !== bindedHex) ||
isNullish(bindedHex))) return undefined;
if (!validateKey(e)) return e;
isNullish(bindedHex))) return undefined
if (!validateKey(e)) return e
switch (e.target) {
case red:
red.value = setValueInRange.call(that, red.value, 0, 255);
color.val('r', red.value, e.target);
break;
case green:
green.value = setValueInRange.call(that, green.value, 0, 255);
color.val('g', green.value, e.target);
break;
case blue:
blue.value = setValueInRange.call(that, blue.value, 0, 255);
color.val('b', blue.value, e.target);
break;
case alpha:
alpha.value = setValueInRange.call(that, alpha.value, 0, 100);
color.val('a', toFixedNumeric((alpha.value * 255) / 100, alphaPrecision), e.target);
break;
case hue:
hue.value = setValueInRange.call(that, hue.value, 0, 360);
color.val('h', hue.value, e.target);
break;
case saturation:
saturation.value = setValueInRange.call(that, saturation.value, 0, 100);
color.val('s', saturation.value, e.target);
break;
case value:
value.value = setValueInRange.call(that, value.value, 0, 100);
color.val('v', value.value, e.target);
break;
case hex:
hex.value = hex.value.replace(/[^a-fA-F\d]/g, '').toLowerCase().substring(0, 6);
bindedHex && bindedHex.val(hex.value);
color.val('hex', hex.value !== '' ? hex.value : null, e.target);
break;
case bindedHex:
bindedHex.value = bindedHex.value.replace(/[^a-fA-F\d]/g, '').toLowerCase().substring(0, 6);
hex.val(bindedHex.value);
color.val('hex', bindedHex.value !== '' ? bindedHex.value : null, e.target);
break;
case ahex:
ahex.value = ahex.value.replace(/[^a-fA-F\d]/g, '').toLowerCase().substring(0, 2);
color.val('a', !isNullish(ahex.value) ? Number.parseInt(ahex.value, 16) : null, e.target);
break;
case red:
red.value = setValueInRange.call(that, red.value, 0, 255)
color.val('r', red.value, e.target)
break
case green:
green.value = setValueInRange.call(that, green.value, 0, 255)
color.val('g', green.value, e.target)
break
case blue:
blue.value = setValueInRange.call(that, blue.value, 0, 255)
color.val('b', blue.value, e.target)
break
case alpha:
alpha.value = setValueInRange.call(that, alpha.value, 0, 100)
color.val('a', toFixedNumeric((alpha.value * 255) / 100, alphaPrecision), e.target)
break
case hue:
hue.value = setValueInRange.call(that, hue.value, 0, 360)
color.val('h', hue.value, e.target)
break
case saturation:
saturation.value = setValueInRange.call(that, saturation.value, 0, 100)
color.val('s', saturation.value, e.target)
break
case value:
value.value = setValueInRange.call(that, value.value, 0, 100)
color.val('v', value.value, e.target)
break
case hex:
hex.value = hex.value.replace(/[^a-fA-F\d]/g, '').toLowerCase().substring(0, 6)
bindedHex && bindedHex.val(hex.value)
color.val('hex', hex.value !== '' ? hex.value : null, e.target)
break
case bindedHex:
bindedHex.value = bindedHex.value.replace(/[^a-fA-F\d]/g, '').toLowerCase().substring(0, 6)
hex.val(bindedHex.value)
color.val('hex', bindedHex.value !== '' ? bindedHex.value : null, e.target)
break
case ahex:
ahex.value = ahex.value.replace(/[^a-fA-F\d]/g, '').toLowerCase().substring(0, 2)
color.val('a', !isNullish(ahex.value) ? Number.parseInt(ahex.value, 16) : null, e.target)
break
}
return undefined;
return undefined
}
// input box blur - reset to original if value empty
/**
@@ -194,44 +194,44 @@ export default class ColorValuePicker {
function blur (e) {
if (!isNullish(color.value)) {
switch (e.target) {
case red:
color.value = 'r';
red.value = color.value;
break;
case green:
color.value = 'g';
green.value = color.value;
break;
case blue:
color.value = 'b';
blue.value = color.value;
break;
case alpha:
color.value = 'a';
alpha.value = toFixedNumeric((color.value * 100) / 255, alphaPrecision);
break;
case hue:
color.value = 'h';
hue.value = color.value;
break;
case saturation:
color.value = 's';
saturation.value = color.value;
break;
case value:
color.value = 'v';
value.value = color.value;
break;
case hex:
case bindedHex:
color.value = 'hex';
hex.value = color.value;
bindedHex.value = color.value;
break;
case ahex:
color.value = 'ahex';
ahex.value = color.value.substring(6);
break;
case red:
color.value = 'r'
red.value = color.value
break
case green:
color.value = 'g'
green.value = color.value
break
case blue:
color.value = 'b'
blue.value = color.value
break
case alpha:
color.value = 'a'
alpha.value = toFixedNumeric((color.value * 100) / 255, alphaPrecision)
break
case hue:
color.value = 'h'
hue.value = color.value
break
case saturation:
color.value = 's'
saturation.value = color.value
break
case value:
color.value = 'v'
value.value = color.value
break
case hex:
case bindedHex:
color.value = 'hex'
hex.value = color.value
bindedHex.value = color.value
break
case ahex:
color.value = 'ahex'
ahex.value = color.value.substring(6)
break
}
}
}
@@ -241,17 +241,17 @@ export default class ColorValuePicker {
*/
function validateKey (e) {
switch (e.keyCode) {
case 9:
case 16:
case 29:
case 37:
case 39:
return false;
case 'c'.charCodeAt():
case 'v'.charCodeAt():
if (e.ctrlKey) return false;
case 9:
case 16:
case 29:
case 37:
case 39:
return false
case 'c'.charCodeAt():
case 'v'.charCodeAt():
if (e.ctrlKey) return false
}
return true;
return true
}
/**
@@ -262,10 +262,10 @@ export default class ColorValuePicker {
* @returns {Float|string} Returns a number or numeric string
*/
function setValueInRange (value, min, max) {
if (value === '' || isNaN(value)) return min;
if (value > max) return max;
if (value < min) return min;
return value;
if (value === '' || isNaN(value)) return min
if (value > max) return max
if (value < min) return min
return value
}
/**
* @param {external:jQuery} ui
@@ -273,117 +273,117 @@ export default class ColorValuePicker {
* @returns {void}
*/
function colorChanged (ui, context) {
const all = ui.val('all');
if (context !== red) red.value = (!isNullish(all) ? all.r : '');
if (context !== green) green.value = (!isNullish(all) ? all.g : '');
if (context !== blue) blue.value = (!isNullish(all) ? all.b : '');
if (alpha && context !== alpha) alpha.value = (!isNullish(all) ? toFixedNumeric((all.a * 100) / 255, alphaPrecision) : '');
if (context !== hue) hue.value = (!isNullish(all) ? all.h : '');
if (context !== saturation) saturation.value = (!isNullish(all) ? all.s : '');
if (context !== value) value.value = (!isNullish(all) ? all.v : '');
if (context !== hex && ((bindedHex && context !== bindedHex) || !bindedHex)) hex.value = (!isNullish(all) ? all.hex : '');
if (bindedHex && context !== bindedHex && context !== hex) bindedHex.value = (!isNullish(all) ? all.hex : '');
if (ahex && context !== ahex) ahex.value = (!isNullish(all) ? all.ahex.substring(6) : '');
const all = ui.val('all')
if (context !== red) red.value = (!isNullish(all) ? all.r : '')
if (context !== green) green.value = (!isNullish(all) ? all.g : '')
if (context !== blue) blue.value = (!isNullish(all) ? all.b : '')
if (alpha && context !== alpha) alpha.value = (!isNullish(all) ? toFixedNumeric((all.a * 100) / 255, alphaPrecision) : '')
if (context !== hue) hue.value = (!isNullish(all) ? all.h : '')
if (context !== saturation) saturation.value = (!isNullish(all) ? all.s : '')
if (context !== value) value.value = (!isNullish(all) ? all.v : '')
if (context !== hex && ((bindedHex && context !== bindedHex) || !bindedHex)) hex.value = (!isNullish(all) ? all.hex : '')
if (bindedHex && context !== bindedHex && context !== hex) bindedHex.value = (!isNullish(all) ? all.hex : '')
if (ahex && context !== ahex) ahex.value = (!isNullish(all) ? all.ahex.substring(6) : '')
}
/**
* Unbind all events and null objects.
* @returns {void}
*/
function destroy () {
red.removeEventListener('keyup', keyUp);
green.removeEventListener('keyup', keyUp);
blue.removeEventListener('keyup', keyUp);
hue.removeEventListener('keyup', keyUp);
saturation.removeEventListener('keyup', keyUp);
value.removeEventListener('keyup', keyUp);
hex.removeEventListener('keyup', keyUp);
red.removeEventListener('keyup', keyUp)
green.removeEventListener('keyup', keyUp)
blue.removeEventListener('keyup', keyUp)
hue.removeEventListener('keyup', keyUp)
saturation.removeEventListener('keyup', keyUp)
value.removeEventListener('keyup', keyUp)
hex.removeEventListener('keyup', keyUp)
red.removeEventListener('blur', blur);
green.removeEventListener('blur', blur);
blue.removeEventListener('blur', blur);
hue.removeEventListener('blur', blur);
saturation.removeEventListener('blur', blur);
value.removeEventListener('blur', blur);
hex.removeEventListener('blur', blur);
red.removeEventListener('blur', blur)
green.removeEventListener('blur', blur)
blue.removeEventListener('blur', blur)
hue.removeEventListener('blur', blur)
saturation.removeEventListener('blur', blur)
value.removeEventListener('blur', blur)
hex.removeEventListener('blur', blur)
red.removeEventListener('keydown', keyDown);
green.removeEventListener('keydown', keyDown);
blue.removeEventListener('keydown', keyDown);
hue.removeEventListener('keydown', keyDown);
saturation.removeEventListener('keydown', keyDown);
value.removeEventListener('keydown', keyDown);
red.removeEventListener('keydown', keyDown)
green.removeEventListener('keydown', keyDown)
blue.removeEventListener('keydown', keyDown)
hue.removeEventListener('keydown', keyDown)
saturation.removeEventListener('keydown', keyDown)
value.removeEventListener('keydown', keyDown)
if (alpha !== null) {
alpha.removeEventListener('keyup', keyUp);
alpha.removeEventListener('blur', blur);
alpha.removeEventListener('keydown', keyDown);
alpha.removeEventListener('keyup', keyUp)
alpha.removeEventListener('blur', blur)
alpha.removeEventListener('keydown', keyDown)
}
if (ahex !== null) {
ahex.removeEventListener('keyup', keyUp);
ahex.removeEventListener('blur', blur);
ahex.removeEventListener('keyup', keyUp)
ahex.removeEventListener('blur', blur)
}
if (bindedHex !== null) {
bindedHex.removeEventListener('keyup', keyUp);
bindedHex.removeEventListener('blur', blur);
bindedHex.removeEventListener('keyup', keyUp)
bindedHex.removeEventListener('blur', blur)
}
color.unbind(colorChanged);
red = null;
green = null;
blue = null;
alpha = null;
hue = null;
saturation = null;
value = null;
hex = null;
ahex = null;
color.unbind(colorChanged)
red = null
green = null
blue = null
alpha = null
hue = null
saturation = null
value = null
hex = null
ahex = null
}
let
red = inputs[3];
let green = inputs[4];
let blue = inputs[5];
let alpha = inputs.length > 7 ? inputs[6] : null;
let hue = inputs[0];
let saturation = inputs[1];
let value = inputs[2];
let hex = inputs[(inputs.length > 7) ? 7 : 6];
let ahex = inputs.length > 7 ? inputs[8] : null;
Object.assign(that, { destroy });
red.addEventListener('keyup', keyUp);
green.addEventListener('keyup', keyUp);
blue.addEventListener('keyup', keyUp);
hue.addEventListener('keyup', keyUp);
saturation.addEventListener('keyup', keyUp);
value.addEventListener('keyup', keyUp);
hex.addEventListener('keyup', keyUp);
red = inputs[3]
let green = inputs[4]
let blue = inputs[5]
let alpha = inputs.length > 7 ? inputs[6] : null
let hue = inputs[0]
let saturation = inputs[1]
let value = inputs[2]
let hex = inputs[(inputs.length > 7) ? 7 : 6]
let ahex = inputs.length > 7 ? inputs[8] : null
Object.assign(that, { destroy })
red.addEventListener('keyup', keyUp)
green.addEventListener('keyup', keyUp)
blue.addEventListener('keyup', keyUp)
hue.addEventListener('keyup', keyUp)
saturation.addEventListener('keyup', keyUp)
value.addEventListener('keyup', keyUp)
hex.addEventListener('keyup', keyUp)
red.addEventListener('blur', blur);
green.addEventListener('blur', blur);
blue.addEventListener('blur', blur);
hue.addEventListener('blur', blur);
saturation.addEventListener('blur', blur);
value.addEventListener('blur', blur);
hex.addEventListener('blur', blur);
red.addEventListener('blur', blur)
green.addEventListener('blur', blur)
blue.addEventListener('blur', blur)
hue.addEventListener('blur', blur)
saturation.addEventListener('blur', blur)
value.addEventListener('blur', blur)
hex.addEventListener('blur', blur)
red.addEventListener('keydown', keyDown);
green.addEventListener('keydown', keyDown);
blue.addEventListener('keydown', keyDown);
hue.addEventListener('keydown', keyDown);
saturation.addEventListener('keydown', keyDown);
value.addEventListener('keydown', keyDown);
red.addEventListener('keydown', keyDown)
green.addEventListener('keydown', keyDown)
blue.addEventListener('keydown', keyDown)
hue.addEventListener('keydown', keyDown)
saturation.addEventListener('keydown', keyDown)
value.addEventListener('keydown', keyDown)
if (alpha !== null) {
alpha.addEventListener('keyup', keyUp);
alpha.addEventListener('blur', blur);
alpha.addEventListener('keydown', keyDown);
alpha.addEventListener('keyup', keyUp)
alpha.addEventListener('blur', blur)
alpha.addEventListener('keydown', keyDown)
}
if (ahex !== null) {
ahex.addEventListener('keyup', keyUp);
ahex.addEventListener('blur', blur);
ahex.addEventListener('keyup', keyUp)
ahex.addEventListener('blur', blur)
}
if (bindedHex !== null) {
bindedHex.addEventListener('keyup', keyUp);
bindedHex.addEventListener('blur', blur);
bindedHex.addEventListener('keyup', keyUp)
bindedHex.addEventListener('blur', blur)
}
color.bind(colorChanged);
color.bind(colorChanged)
}
}

View File

@@ -1,12 +1,12 @@
import { findPos } from './Util.js';
import { findPos } from './Util.js'
/**
* Whether a value is `null` or `undefined`.
* @param {any} val
* @returns {boolean}
*/
const isNullish = (val) => {
return val === null || val === undefined;
};
return val === null || val === undefined
}
/**
* Encapsulate slider functionality for the ColorMap and ColorBar -
* could be useful to use a jQuery UI draggable for this with certain extensions.
@@ -18,7 +18,7 @@ export default class Slider {
* @param {module:jPicker.SliderOptions} options
*/
constructor (bar, options) {
const that = this;
const that = this
/**
* Fire events on the supplied `context`
* @param {module:jPicker.JPickerInit} context
@@ -26,8 +26,8 @@ export default class Slider {
*/
function fireChangeEvents (context) {
changeEvents.forEach((changeEvent) => {
changeEvent.call(that, that, context);
});
changeEvent.call(that, that, context)
})
}
/**
@@ -36,17 +36,17 @@ export default class Slider {
* @returns {void}
*/
function mouseDown (e) {
const off = findPos(bar);
offset = { l: off.left | 0, t: off.top | 0 };
clearTimeout(timeout);
const off = findPos(bar)
offset = { l: off.left | 0, t: off.top | 0 }
clearTimeout(timeout)
// using setTimeout for visual updates - once the style is updated the browser will re-render internally allowing the next Javascript to run
timeout = setTimeout(function () {
setValuesFromMousePosition.call(that, e);
}, 0);
setValuesFromMousePosition.call(that, e)
}, 0)
// Bind mousemove and mouseup event to the document so it responds when dragged of of the bar - we will unbind these when on mouseup to save processing
document.addEventListener('mousemove', mouseMove);
document.addEventListener('mouseup', mouseUp);
e.preventDefault(); // don't try to select anything or drag the image to the desktop
document.addEventListener('mousemove', mouseMove)
document.addEventListener('mouseup', mouseUp)
e.preventDefault() // don't try to select anything or drag the image to the desktop
}
/**
* Set the values as the mouse moves.
@@ -54,13 +54,13 @@ export default class Slider {
* @returns {false}
*/
function mouseMove (e) {
clearTimeout(timeout);
clearTimeout(timeout)
timeout = setTimeout(function () {
setValuesFromMousePosition.call(that, e);
}, 0);
e.stopPropagation();
e.preventDefault();
return false;
setValuesFromMousePosition.call(that, e)
}, 0)
e.stopPropagation()
e.preventDefault()
return false
}
/**
* Unbind the document events - they aren't needed when not dragging.
@@ -68,11 +68,11 @@ export default class Slider {
* @returns {false}
*/
function mouseUp (e) {
document.removeEventListener('mousemove', mouseMove);
document.removeEventListener('mouseup', mouseUp);
e.stopPropagation();
e.preventDefault();
return false;
document.removeEventListener('mousemove', mouseMove)
document.removeEventListener('mouseup', mouseUp)
e.stopPropagation()
e.preventDefault()
return false
}
/**
@@ -81,19 +81,19 @@ export default class Slider {
* @returns {void}
*/
function setValuesFromMousePosition (e) {
const barW = bar.w; // local copies for YUI compressor
const barH = bar.h;
let locX = e.pageX - offset.l;
let locY = e.pageY - offset.t;
const barW = bar.w // local copies for YUI compressor
const barH = bar.h
let locX = e.pageX - offset.l
let locY = e.pageY - offset.t
// keep the arrow within the bounds of the bar
if (locX < 0) locX = 0;
else if (locX > barW) locX = barW;
if (locY < 0) locY = 0;
else if (locY > barH) locY = barH;
if (locX < 0) locX = 0
else if (locX > barW) locX = barW
if (locY < 0) locY = 0
else if (locY > barH) locY = barH
val.call(that, 'xy', {
x: ((locX / barW) * rangeX) + minX,
y: ((locY / barH) * rangeY) + minY
});
})
}
/**
*
@@ -101,33 +101,33 @@ export default class Slider {
*/
function draw () {
const
barW = bar.w;
const barH = bar.h;
const arrowW = arrow.w;
const arrowH = arrow.h;
let arrowOffsetX = 0;
let arrowOffsetY = 0;
barW = bar.w
const barH = bar.h
const arrowW = arrow.w
const arrowH = arrow.h
let arrowOffsetX = 0
let arrowOffsetY = 0
setTimeout(function () {
if (rangeX > 0) { // range is greater than zero
// constrain to bounds
if (x === maxX) arrowOffsetX = barW;
else arrowOffsetX = ((x / rangeX) * barW) | 0;
if (x === maxX) arrowOffsetX = barW
else arrowOffsetX = ((x / rangeX) * barW) | 0
}
if (rangeY > 0) { // range is greater than zero
// constrain to bounds
if (y === maxY) arrowOffsetY = barH;
else arrowOffsetY = ((y / rangeY) * barH) | 0;
if (y === maxY) arrowOffsetY = barH
else arrowOffsetY = ((y / rangeY) * barH) | 0
}
// if arrow width is greater than bar width, center arrow and prevent horizontal dragging
if (arrowW >= barW) arrowOffsetX = (barW >> 1) - (arrowW >> 1); // number >> 1 - superfast bitwise divide by two and truncate (move bits over one bit discarding lowest)
else arrowOffsetX -= arrowW >> 1;
if (arrowW >= barW) arrowOffsetX = (barW >> 1) - (arrowW >> 1) // number >> 1 - superfast bitwise divide by two and truncate (move bits over one bit discarding lowest)
else arrowOffsetX -= arrowW >> 1
// if arrow height is greater than bar height, center arrow and prevent vertical dragging
if (arrowH >= barH) arrowOffsetY = (barH >> 1) - (arrowH >> 1);
else arrowOffsetY -= arrowH >> 1;
if (arrowH >= barH) arrowOffsetY = (barH >> 1) - (arrowH >> 1)
else arrowOffsetY -= arrowH >> 1
// set the arrow position based on these offsets
arrow.style.left = arrowOffsetX + 'px';
arrow.style.top = arrowOffsetY + 'px';
});
arrow.style.left = arrowOffsetX + 'px'
arrow.style.top = arrowOffsetY + 'px'
})
}
/**
@@ -138,52 +138,52 @@ export default class Slider {
* @returns {module:math.XYObject|Float|void}
*/
function val (name, value, context) {
const set = value !== undefined;
const set = value !== undefined
if (!set) {
if (isNullish(name)) name = 'xy';
if (isNullish(name)) name = 'xy'
switch (name.toLowerCase()) {
case 'x': return x;
case 'y': return y;
case 'xy':
default: return { x, y };
case 'x': return x
case 'y': return y
case 'xy':
default: return { x, y }
}
}
if (!isNullish(context) && context === that) return undefined;
let changed = false;
if (!isNullish(context) && context === that) return undefined
let changed = false
let newX; let newY;
if (isNullish(name)) name = 'xy';
let newX; let newY
if (isNullish(name)) name = 'xy'
switch (name.toLowerCase()) {
case 'x':
newX = (value && ((value.x && value.x | 0) || value | 0)) || 0;
break;
case 'y':
newY = (value && ((value.y && value.y | 0) || value | 0)) || 0;
break;
case 'xy':
default:
newX = (value && value.x && value.x | 0) || 0;
newY = (value && value.y && value.y | 0) || 0;
break;
case 'x':
newX = (value && ((value.x && value.x | 0) || value | 0)) || 0
break
case 'y':
newY = (value && ((value.y && value.y | 0) || value | 0)) || 0
break
case 'xy':
default:
newX = (value && value.x && value.x | 0) || 0
newY = (value && value.y && value.y | 0) || 0
break
}
if (!isNullish(newX)) {
if (newX < minX) newX = minX;
else if (newX > maxX) newX = maxX;
if (newX < minX) newX = minX
else if (newX > maxX) newX = maxX
if (x !== newX) {
x = newX;
changed = true;
x = newX
changed = true
}
}
if (!isNullish(newY)) {
if (newY < minY) newY = minY;
else if (newY > maxY) newY = maxY;
if (newY < minY) newY = minY
else if (newY > maxY) newY = maxY
if (y !== newY) {
y = newY;
changed = true;
y = newY
changed = true
}
}
changed && fireChangeEvents.call(that, context || that);
return undefined;
changed && fireChangeEvents.call(that, context || that)
return undefined
}
/**
@@ -209,89 +209,89 @@ export default class Slider {
* @returns {module:jPicker.MinMaxRangeXY|module:jPicker.MinMaxRangeX|module:jPicker.MinMaxRangeY|void}
*/
function range (name, value) {
const set = value !== undefined;
const set = value !== undefined
if (!set) {
if (isNullish(name)) name = 'all';
if (isNullish(name)) name = 'all'
switch (name.toLowerCase()) {
case 'minx': return minX;
case 'maxx': return maxX;
case 'rangex': return { minX, maxX, rangeX };
case 'miny': return minY;
case 'maxy': return maxY;
case 'rangey': return { minY, maxY, rangeY };
case 'all':
default: return { minX, maxX, rangeX, minY, maxY, rangeY };
case 'minx': return minX
case 'maxx': return maxX
case 'rangex': return { minX, maxX, rangeX }
case 'miny': return minY
case 'maxy': return maxY
case 'rangey': return { minY, maxY, rangeY }
case 'all':
default: return { minX, maxX, rangeX, minY, maxY, rangeY }
}
}
let // changed = false,
newMinX;
let newMaxX;
let newMinY;
let newMaxY;
if (isNullish(name)) name = 'all';
newMinX
let newMaxX
let newMinY
let newMaxY
if (isNullish(name)) name = 'all'
switch (name.toLowerCase()) {
case 'minx':
newMinX = (value && ((value.minX && value.minX | 0) || value | 0)) || 0;
break;
case 'maxx':
newMaxX = (value && ((value.maxX && value.maxX | 0) || value | 0)) || 0;
break;
case 'rangex':
newMinX = (value && value.minX && value.minX | 0) || 0;
newMaxX = (value && value.maxX && value.maxX | 0) || 0;
break;
case 'miny':
newMinY = (value && ((value.minY && value.minY | 0) || value | 0)) || 0;
break;
case 'maxy':
newMaxY = (value && ((value.maxY && value.maxY | 0) || value | 0)) || 0;
break;
case 'rangey':
newMinY = (value && value.minY && value.minY | 0) || 0;
newMaxY = (value && value.maxY && value.maxY | 0) || 0;
break;
case 'all':
default:
newMinX = (value && value.minX && value.minX | 0) || 0;
newMaxX = (value && value.maxX && value.maxX | 0) || 0;
newMinY = (value && value.minY && value.minY | 0) || 0;
newMaxY = (value && value.maxY && value.maxY | 0) || 0;
break;
case 'minx':
newMinX = (value && ((value.minX && value.minX | 0) || value | 0)) || 0
break
case 'maxx':
newMaxX = (value && ((value.maxX && value.maxX | 0) || value | 0)) || 0
break
case 'rangex':
newMinX = (value && value.minX && value.minX | 0) || 0
newMaxX = (value && value.maxX && value.maxX | 0) || 0
break
case 'miny':
newMinY = (value && ((value.minY && value.minY | 0) || value | 0)) || 0
break
case 'maxy':
newMaxY = (value && ((value.maxY && value.maxY | 0) || value | 0)) || 0
break
case 'rangey':
newMinY = (value && value.minY && value.minY | 0) || 0
newMaxY = (value && value.maxY && value.maxY | 0) || 0
break
case 'all':
default:
newMinX = (value && value.minX && value.minX | 0) || 0
newMaxX = (value && value.maxX && value.maxX | 0) || 0
newMinY = (value && value.minY && value.minY | 0) || 0
newMaxY = (value && value.maxY && value.maxY | 0) || 0
break
}
if (!isNullish(newMinX) && minX !== newMinX) {
minX = newMinX;
rangeX = maxX - minX;
minX = newMinX
rangeX = maxX - minX
}
if (!isNullish(newMaxX) && maxX !== newMaxX) {
maxX = newMaxX;
rangeX = maxX - minX;
maxX = newMaxX
rangeX = maxX - minX
}
if (!isNullish(newMinY) && minY !== newMinY) {
minY = newMinY;
rangeY = maxY - minY;
minY = newMinY
rangeY = maxY - minY
}
if (!isNullish(newMaxY) && maxY !== newMaxY) {
maxY = newMaxY;
rangeY = maxY - minY;
maxY = newMaxY
rangeY = maxY - minY
}
return undefined;
return undefined
}
/**
* @param {GenericCallback} callback
* @returns {void}
*/
function bind (callback) {
if (typeof callback === 'function') changeEvents.push(callback);
if (typeof callback === 'function') changeEvents.push(callback)
}
/**
* @param {GenericCallback} callback
* @returns {void}
*/
function unbind (callback) {
if (typeof callback !== 'function') return;
let i;
while ((i = changeEvents.includes(callback))) changeEvents.splice(i, 1);
if (typeof callback !== 'function') return
let i
while ((i = changeEvents.includes(callback))) changeEvents.splice(i, 1)
}
/**
*
@@ -299,39 +299,39 @@ export default class Slider {
*/
function destroy () {
// unbind all possible events and null objects
document.removeEventListener('mousemove', mouseMove);
document.removeEventListener('mouseup', mouseUp);
bar.removeEventListener('mousedown', mouseDown);
bar = null;
arrow = null;
changeEvents = null;
document.removeEventListener('mousemove', mouseMove)
document.removeEventListener('mouseup', mouseUp)
bar.removeEventListener('mousedown', mouseDown)
bar = null
arrow = null
changeEvents = null
}
let offset;
let timeout;
let x = 0;
let y = 0;
let minX = 0;
let maxX = 100;
let rangeX = 100;
let minY = 0;
let maxY = 100;
let rangeY = 100;
let arrow = bar.querySelector('img'); // the arrow image to drag
let changeEvents = [];
let offset
let timeout
let x = 0
let y = 0
let minX = 0
let maxX = 100
let rangeX = 100
let minY = 0
let maxY = 100
let rangeY = 100
let arrow = bar.querySelector('img') // the arrow image to drag
let changeEvents = []
Object.assign(that, {
val,
range,
bind,
unbind,
destroy
});
})
// initialize this control
arrow.src = options.arrow && options.arrow.image;
arrow.w = (options.arrow && options.arrow.width) || parseFloat(getComputedStyle(arrow, null).width.replace("px", ""));
arrow.h = (options.arrow && options.arrow.height) || parseFloat(getComputedStyle(arrow, null).height.replace("px", ""));
bar.w = (options.map && options.map.width) || parseFloat(getComputedStyle(bar, null).width.replace("px", ""));
bar.h = (options.map && options.map.height) || parseFloat(getComputedStyle(bar, null).height.replace("px", ""));
bar.addEventListener('mousedown', mouseDown);
bind.call(that, draw);
arrow.src = options.arrow && options.arrow.image
arrow.w = (options.arrow && options.arrow.width) || parseFloat(getComputedStyle(arrow, null).width.replace('px', ''))
arrow.h = (options.arrow && options.arrow.height) || parseFloat(getComputedStyle(arrow, null).height.replace('px', ''))
bar.w = (options.map && options.map.width) || parseFloat(getComputedStyle(bar, null).width.replace('px', ''))
bar.h = (options.map && options.map.height) || parseFloat(getComputedStyle(bar, null).height.replace('px', ''))
bar.addEventListener('mousedown', mouseDown)
bind.call(that, draw)
}
}

View File

@@ -2,39 +2,36 @@
* @param {any} obj
* @returns {any}
*/
export function findPos(obj) {
let curleft = 0;
let curtop = 0;
export function findPos (obj) {
let curleft = 0
let curtop = 0
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
curleft += obj.offsetLeft
curtop += obj.offsetTop
// eslint-disable-next-line no-cond-assign
} while (obj = obj.offsetParent);
return { left: curleft, top: curtop };
} while (obj = obj.offsetParent)
return { left: curleft, top: curtop }
}
return { left: curleft, top: curtop };
return { left: curleft, top: curtop }
}
export function isObject(item) {
return (item && typeof item === 'object' && !Array.isArray(item));
export function isObject (item) {
return (item && typeof item === 'object' && !Array.isArray(item))
}
export function mergeDeep(target, source) {
const output = Object.assign({}, target);
export function mergeDeep (target, source) {
const output = Object.assign({}, target)
if (isObject(target) && isObject(source)) {
Object.keys(source).forEach((key) => {
if (isObject(source[key])) {
if (!(key in target))
Object.assign(output, { [key]: source[key] });
else
output[key] = mergeDeep(target[key], source[key]);
if (!(key in target)) { Object.assign(output, { [key]: source[key] }) } else { output[key] = mergeDeep(target[key], source[key]) }
} else {
Object.assign(output, { [key]: source[key] });
Object.assign(output, { [key]: source[key] })
}
});
})
}
return output;
return output
}
/**
@@ -43,17 +40,17 @@ export function mergeDeep(target, source) {
* @param {String} selector Selector to match against (class, ID, data attribute, or tag)
* @return {Boolean|Element} Returns null if not match found
*/
export function getClosest(elem, selector) {
const firstChar = selector.charAt(0);
const supports = 'classList' in document.documentElement;
let attribute; let value;
export function getClosest (elem, selector) {
const firstChar = selector.charAt(0)
const supports = 'classList' in document.documentElement
let attribute; let value
// If selector is a data attribute, split attribute from value
if (firstChar === '[') {
selector = selector.substr(1, selector.length - 2);
attribute = selector.split('=');
selector = selector.substr(1, selector.length - 2)
attribute = selector.split('=')
if (attribute.length > 1) {
value = true;
attribute[1] = attribute[1].replace(/"/g, '').replace(/'/g, '');
value = true
attribute[1] = attribute[1].replace(/"/g, '').replace(/'/g, '')
}
}
// Get closest match
@@ -62,18 +59,18 @@ export function getClosest(elem, selector) {
if (firstChar === '.') {
if (supports) {
if (elem.classList.contains(selector.substr(1))) {
return elem;
return elem
}
} else {
if (new RegExp('(^|\\s)' + selector.substr(1) + '(\\s|$)').test(elem.className)) {
return elem;
return elem
}
}
}
// If selector is an ID
if (firstChar === '#') {
if (elem.id === selector.substr(1)) {
return elem;
return elem
}
}
// If selector is a data attribute
@@ -81,19 +78,19 @@ export function getClosest(elem, selector) {
if (elem.hasAttribute(attribute[0])) {
if (value) {
if (elem.getAttribute(attribute[0]) === attribute[1]) {
return elem;
return elem
}
} else {
return elem;
return elem
}
}
}
// If selector is a tag
if (elem.tagName.toLowerCase() === selector) {
return elem;
return elem
}
}
return null;
return null
}
/**
@@ -102,100 +99,100 @@ export function getClosest(elem, selector) {
* @param {String} selector The class, id, data attribute, or tag to look for
* @return {Array} Null if no match
*/
export function getParents(elem, selector) {
const parents = [];
const firstChar = selector?.charAt(0);
export function getParents (elem, selector) {
const parents = []
const firstChar = selector?.charAt(0)
// Get matches
for ( ; elem && elem !== document; elem = elem.parentNode ) {
if ( selector ) {
for (; elem && elem !== document; elem = elem.parentNode) {
if (selector) {
// If selector is a class
if ( firstChar === '.' ) {
if ( elem.classList.contains( selector.substr(1) ) ) {
parents.push( elem );
if (firstChar === '.') {
if (elem.classList.contains(selector.substr(1))) {
parents.push(elem)
}
}
// If selector is an ID
if ( firstChar === '#' ) {
if ( elem.id === selector.substr(1) ) {
parents.push( elem );
if (firstChar === '#') {
if (elem.id === selector.substr(1)) {
parents.push(elem)
}
}
// If selector is a data attribute
if ( firstChar === '[' ) {
if ( elem.hasAttribute( selector.substr(1, selector.length - 1) ) ) {
parents.push( elem );
if (firstChar === '[') {
if (elem.hasAttribute(selector.substr(1, selector.length - 1))) {
parents.push(elem)
}
}
// If selector is a tag
if ( elem.tagName.toLowerCase() === selector ) {
parents.push( elem );
if (elem.tagName.toLowerCase() === selector) {
parents.push(elem)
}
} else {
parents.push( elem );
parents.push(elem)
}
}
// Return parents if any exist
return parents.length? parents : null;
return parents.length ? parents : null
}
export function getParentsUntil(elem, parent, selector) {
const parents = [];
const parentType = parent?.charAt(0);
const selectorType = selector?.selector.charAt(0);
export function getParentsUntil (elem, parent, selector) {
const parents = []
const parentType = parent?.charAt(0)
const selectorType = selector?.selector.charAt(0)
// Get matches
for ( ; elem && elem !== document; elem = elem.parentNode ) {
for (; elem && elem !== document; elem = elem.parentNode) {
// Check if parent has been reached
if ( parent ) {
if (parent) {
// If parent is a class
if ( parentType === '.' ) {
if ( elem.classList.contains( parent.substr(1) ) ) {
break;
if (parentType === '.') {
if (elem.classList.contains(parent.substr(1))) {
break
}
}
// If parent is an ID
if ( parentType === '#' ) {
if ( elem.id === parent.substr(1) ) {
break;
if (parentType === '#') {
if (elem.id === parent.substr(1)) {
break
}
}
// If parent is a data attribute
if ( parentType === '[' ) {
if ( elem.hasAttribute( parent.substr(1, parent.length - 1) ) ) {
break;
if (parentType === '[') {
if (elem.hasAttribute(parent.substr(1, parent.length - 1))) {
break
}
}
// If parent is a tag
if ( elem.tagName.toLowerCase() === parent ) {
break;
if (elem.tagName.toLowerCase() === parent) {
break
}
}
if ( selector ) {
if (selector) {
// If selector is a class
if ( selectorType === '.' ) {
if ( elem.classList.contains( selector.substr(1) ) ) {
parents.push( elem );
if (selectorType === '.') {
if (elem.classList.contains(selector.substr(1))) {
parents.push(elem)
}
}
// If selector is an ID
if ( selectorType === '#' ) {
if ( elem.id === selector.substr(1) ) {
parents.push( elem );
if (selectorType === '#') {
if (elem.id === selector.substr(1)) {
parents.push(elem)
}
}
// If selector is a data attribute
if ( selectorType === '[' ) {
if ( elem.hasAttribute( selector.substr(1, selector.length - 1) ) ) {
parents.push( elem );
if (selectorType === '[') {
if (elem.hasAttribute(selector.substr(1, selector.length - 1))) {
parents.push(elem)
}
}
// If selector is a tag
if ( elem.tagName.toLowerCase() === selector ) {
parents.push( elem );
if (elem.tagName.toLowerCase() === selector) {
parents.push(elem)
}
} else {
parents.push( elem );
parents.push(elem)
}
}
// Return parents if any exist
return parents.length? parents : null;
}
return parents.length ? parents : null
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -6,83 +6,83 @@ export default class Paint {
* @param {module:jGraduate.jGraduatePaintOptions} [opt]
*/
constructor (opt) {
const options = opt || {};
this.alpha = isNaN(options.alpha) ? 100 : options.alpha;
const options = opt || {}
this.alpha = isNaN(options.alpha) ? 100 : options.alpha
// copy paint object
if (options.copy) {
/**
* @name module:jGraduate~Paint#type
* @type {"none"|"solidColor"|"linearGradient"|"radialGradient"}
*/
this.type = options.copy.type;
this.type = options.copy.type
/**
* Represents opacity (0-100).
* @name module:jGraduate~Paint#alpha
* @type {Float}
*/
this.alpha = options.copy.alpha;
this.alpha = options.copy.alpha
/**
* Represents #RRGGBB hex of color.
* @name module:jGraduate~Paint#solidColor
* @type {string}
*/
this.solidColor = null;
this.solidColor = null
/**
* @name module:jGraduate~Paint#linearGradient
* @type {SVGLinearGradientElement}
*/
this.linearGradient = null;
this.linearGradient = null
/**
* @name module:jGraduate~Paint#radialGradient
* @type {SVGRadialGradientElement}
*/
this.radialGradient = null;
this.radialGradient = null
switch (this.type) {
case 'none':
break;
case 'solidColor':
this.solidColor = options.copy.solidColor;
break;
case 'linearGradient':
this.linearGradient = options.copy.linearGradient.cloneNode(true);
break;
case 'radialGradient':
this.radialGradient = options.copy.radialGradient.cloneNode(true);
break;
case 'none':
break
case 'solidColor':
this.solidColor = options.copy.solidColor
break
case 'linearGradient':
this.linearGradient = options.copy.linearGradient.cloneNode(true)
break
case 'radialGradient':
this.radialGradient = options.copy.radialGradient.cloneNode(true)
break
}
// create linear gradient paint
} else if (options.linearGradient) {
this.type = 'linearGradient';
this.solidColor = null;
this.radialGradient = null;
if(options.linearGradient.hasAttribute('xlink:href')) {
const xhref = document.getElementById(options.linearGradient.getAttribute('xlink:href').substr(1));
this.linearGradient = xhref.cloneNode(true);
this.type = 'linearGradient'
this.solidColor = null
this.radialGradient = null
if (options.linearGradient.hasAttribute('xlink:href')) {
const xhref = document.getElementById(options.linearGradient.getAttribute('xlink:href').substr(1))
this.linearGradient = xhref.cloneNode(true)
} else {
this.linearGradient = options.linearGradient.cloneNode(true);
this.linearGradient = options.linearGradient.cloneNode(true)
}
// create linear gradient paint
} else if (options.radialGradient) {
this.type = 'radialGradient';
this.solidColor = null;
this.linearGradient = null;
if(options.radialGradient.hasAttribute('xlink:href')) {
const xhref = document.getElementById(options.radialGradient.getAttribute('xlink:href').substr(1));
this.radialGradient = xhref.cloneNode(true);
this.type = 'radialGradient'
this.solidColor = null
this.linearGradient = null
if (options.radialGradient.hasAttribute('xlink:href')) {
const xhref = document.getElementById(options.radialGradient.getAttribute('xlink:href').substr(1))
this.radialGradient = xhref.cloneNode(true)
} else {
this.radialGradient = options.radialGradient.cloneNode(true);
this.radialGradient = options.radialGradient.cloneNode(true)
}
// create solid color paint
} else if (options.solidColor) {
this.type = 'solidColor';
this.solidColor = options.solidColor;
this.type = 'solidColor'
this.solidColor = options.solidColor
// create empty paint
} else {
this.type = 'none';
this.solidColor = null;
this.linearGradient = null;
this.radialGradient = null;
this.type = 'none'
this.solidColor = null
this.linearGradient = null
this.radialGradient = null
}
}
}
}

View File

@@ -1,6 +1,6 @@
/* globals svgEditor */
import { t } from '../locale.js';
const template = document.createElement('template');
import { t } from '../locale.js'
const template = document.createElement('template')
template.innerHTML = `
<style>
:host(:hover) :not(.disabled)
@@ -39,7 +39,7 @@ template.innerHTML = `
<div title="title">
<img alt="icon">
</div>
`;
`
/**
* @class ToolButton
*/
@@ -48,22 +48,24 @@ export class ToolButton extends HTMLElement {
* @function constructor
*/
constructor () {
super();
super()
// create the shadowDom and insert the template
this._shadowRoot = this.attachShadow({ mode: 'open' });
this._shadowRoot.append(template.content.cloneNode(true));
this._shadowRoot = this.attachShadow({ mode: 'open' })
this._shadowRoot.append(template.content.cloneNode(true))
// locate the component
this.$div = this._shadowRoot.querySelector('div');
this.$img = this._shadowRoot.querySelector('img');
this.imgPath = svgEditor.configObj.curConfig.imgPath;
this.$div = this._shadowRoot.querySelector('div')
this.$img = this._shadowRoot.querySelector('img')
this.imgPath = svgEditor.configObj.curConfig.imgPath
}
/**
* @function observedAttributes
* @returns {any} observed
*/
static get observedAttributes () {
return [ 'title', 'src', 'pressed', 'disabled', 'size', 'style' ];
return ['title', 'src', 'pressed', 'disabled', 'size', 'style']
}
/**
* @function attributeChangedCallback
* @param {string} name
@@ -72,56 +74,57 @@ export class ToolButton extends HTMLElement {
* @returns {void}
*/
attributeChangedCallback (name, oldValue, newValue) {
if (oldValue === newValue) return;
if (oldValue === newValue) return
switch (name) {
case 'title':
{
const shortcut = this.getAttribute('shortcut');
this.$div.setAttribute('title', `${t(newValue)} ${shortcut ? `[${t(shortcut)}]` : ''}`);
}
break;
case 'style':
this.$div.style = newValue;
break;
case 'src':
if (newValue.indexOf("data:") !== -1) {
this.$img.setAttribute('src', newValue);
} else {
this.$img.setAttribute('src', this.imgPath + "/" + newValue);
}
break;
case 'pressed':
if (newValue === null) {
this.$div.classList.remove('pressed');
} else {
this.$div.classList.add('pressed');
}
break;
case 'size':
if (newValue === 'small') {
this.$div.classList.add('small');
} else {
this.$div.classList.remove('small');
}
break;
case 'disabled':
if (newValue) {
this.$div.classList.add('disabled');
} else {
this.$div.classList.remove('disabled');
}
break;
default:
console.error(`unknown attribute: ${name}`);
break;
case 'title':
{
const shortcut = this.getAttribute('shortcut')
this.$div.setAttribute('title', `${t(newValue)} ${shortcut ? `[${t(shortcut)}]` : ''}`)
}
break
case 'style':
this.$div.style = newValue
break
case 'src':
if (newValue.indexOf('data:') !== -1) {
this.$img.setAttribute('src', newValue)
} else {
this.$img.setAttribute('src', this.imgPath + '/' + newValue)
}
break
case 'pressed':
if (newValue === null) {
this.$div.classList.remove('pressed')
} else {
this.$div.classList.add('pressed')
}
break
case 'size':
if (newValue === 'small') {
this.$div.classList.add('small')
} else {
this.$div.classList.remove('small')
}
break
case 'disabled':
if (newValue) {
this.$div.classList.add('disabled')
} else {
this.$div.classList.remove('disabled')
}
break
default:
console.error(`unknown attribute: ${name}`)
break
}
}
/**
* @function get
* @returns {any}
*/
get title () {
return this.getAttribute('title');
return this.getAttribute('title')
}
/**
@@ -129,14 +132,15 @@ export class ToolButton extends HTMLElement {
* @returns {void}
*/
set title (value) {
this.setAttribute('title', value);
this.setAttribute('title', value)
}
/**
* @function get
* @returns {any}
*/
get pressed () {
return this.hasAttribute('pressed');
return this.hasAttribute('pressed')
}
/**
@@ -146,17 +150,18 @@ export class ToolButton extends HTMLElement {
set pressed (value) {
// boolean value => existence = true
if (value) {
this.setAttribute('pressed', 'true');
this.setAttribute('pressed', 'true')
} else {
this.removeAttribute('pressed');
this.removeAttribute('pressed')
}
}
/**
* @function get
* @returns {any}
*/
get disabled () {
return this.hasAttribute('disabled');
return this.hasAttribute('disabled')
}
/**
@@ -166,17 +171,18 @@ export class ToolButton extends HTMLElement {
set disabled (value) {
// boolean value => existence = true
if (value) {
this.setAttribute('disabled', 'true');
this.setAttribute('disabled', 'true')
} else {
this.removeAttribute('disabled');
this.removeAttribute('disabled')
}
}
/**
* @function get
* @returns {any}
*/
get src () {
return this.getAttribute('src');
return this.getAttribute('src')
}
/**
@@ -184,7 +190,7 @@ export class ToolButton extends HTMLElement {
* @returns {void}
*/
set src (value) {
this.setAttribute('src', value);
this.setAttribute('src', value)
}
/**
@@ -192,7 +198,7 @@ export class ToolButton extends HTMLElement {
* @returns {any}
*/
get size () {
return this.getAttribute('size');
return this.getAttribute('size')
}
/**
@@ -200,7 +206,7 @@ export class ToolButton extends HTMLElement {
* @returns {void}
*/
set size (value) {
this.setAttribute('size', value);
this.setAttribute('size', value)
}
/**
@@ -209,22 +215,22 @@ export class ToolButton extends HTMLElement {
*/
connectedCallback () {
// capture shortcuts
const shortcut = this.getAttribute('shortcut');
const shortcut = this.getAttribute('shortcut')
if (shortcut) {
// register the keydown event
document.addEventListener('keydown', (e) => {
// only track keyboard shortcuts for the body containing the SVG-Editor
if (e.target.nodeName !== 'BODY') return;
if (e.target.nodeName !== 'BODY') return
// normalize key
const key = `${(e.metaKey) ? 'meta+' : ''}${(e.ctrlKey) ? 'ctrl+' : ''}${e.key.toUpperCase()}`;
if (shortcut !== key) return;
const key = `${(e.metaKey) ? 'meta+' : ''}${(e.ctrlKey) ? 'ctrl+' : ''}${e.key.toUpperCase()}`
if (shortcut !== key) return
// launch the click event
this.click();
e.preventDefault();
});
this.click()
e.preventDefault()
})
}
}
}
// Register
customElements.define('se-button', ToolButton);
customElements.define('se-button', ToolButton)

View File

@@ -1,9 +1,9 @@
/* globals svgEditor */
import { jGraduate, jGraduateMethod } from './jgraduate/jQuery.jGraduate.js';
import PaintBox from './PaintBox.js';
import { t } from '../locale.js';
import { jGraduate, jGraduateMethod } from './jgraduate/jQuery.jGraduate.js'
import PaintBox from './PaintBox.js'
import { t } from '../locale.js'
const template = document.createElement('template');
const template = document.createElement('template')
template.innerHTML = `
<style>
.jPicker .Icon {
@@ -645,7 +645,7 @@ div.jGraduate_Slider img {
</div>
<!-- hidden div -->
<div id="color_picker"></div>
`;
`
/**
* @class SeColorPicker
*/
@@ -654,35 +654,38 @@ export class SeColorPicker extends HTMLElement {
* @function constructor
*/
constructor () {
super();
super()
// create the shadowDom and insert the template
this._shadowRoot = this.attachShadow({ mode: 'open' });
this._shadowRoot.append(template.content.cloneNode(true));
this.$logo = this._shadowRoot.getElementById('logo');
this.$label = this._shadowRoot.getElementById('label');
this.$block = this._shadowRoot.getElementById('block');
this.paintBox = null;
this.i18next = null;
this.$picker = this._shadowRoot.getElementById('picker');
this.$color_picker = this._shadowRoot.getElementById('color_picker');
this.imgPath = svgEditor.configObj.curConfig.imgPath;
this._shadowRoot = this.attachShadow({ mode: 'open' })
this._shadowRoot.append(template.content.cloneNode(true))
this.$logo = this._shadowRoot.getElementById('logo')
this.$label = this._shadowRoot.getElementById('label')
this.$block = this._shadowRoot.getElementById('block')
this.paintBox = null
this.i18next = null
this.$picker = this._shadowRoot.getElementById('picker')
this.$color_picker = this._shadowRoot.getElementById('color_picker')
this.imgPath = svgEditor.configObj.curConfig.imgPath
}
/**
* @function init
* @param {any} name
* @returns {void}
*/
init (i18next) {
this.i18next = i18next;
this.setAttribute('config-change_xxx_color', t('config.change_xxx_color'));
this.i18next = i18next
this.setAttribute('config-change_xxx_color', t('config.change_xxx_color'))
}
/**
* @function observedAttributes
* @returns {any} observed
*/
static get observedAttributes () {
return [ 'label', 'src', 'type', 'config-change_xxx_color' ];
return ['label', 'src', 'type', 'config-change_xxx_color']
}
/**
* @function attributeChangedCallback
* @param {string} name
@@ -691,31 +694,32 @@ export class SeColorPicker extends HTMLElement {
* @returns {void}
*/
attributeChangedCallback (name, oldValue, newValue) {
if (oldValue === newValue) return;
if (oldValue === newValue) return
switch (name) {
case 'src':
this.$logo.setAttribute('src', this.imgPath + '/' + newValue);
break;
case 'label':
this.setAttribute('title', t(newValue));
break;
case 'type':
this.$label.setAttribute('title', 'config.pick_paint_opavity');
break;
case 'config-change_xxx_color':
this.$label.setAttribute('title', newValue);
break;
default:
console.error(`unknown attribute: ${name}`);
break;
case 'src':
this.$logo.setAttribute('src', this.imgPath + '/' + newValue)
break
case 'label':
this.setAttribute('title', t(newValue))
break
case 'type':
this.$label.setAttribute('title', 'config.pick_paint_opavity')
break
case 'config-change_xxx_color':
this.$label.setAttribute('title', newValue)
break
default:
console.error(`unknown attribute: ${name}`)
break
}
}
/**
* @function get
* @returns {any}
*/
get label () {
return this.$label.getAttribute('title');
return this.$label.getAttribute('title')
}
/**
@@ -723,14 +727,15 @@ export class SeColorPicker extends HTMLElement {
* @returns {void}
*/
set label (value) {
this.setAttribute('label', value);
this.setAttribute('label', value)
}
/**
* @function get
* @returns {any}
*/
get type () {
return this.getAttribute('type');
return this.getAttribute('type')
}
/**
@@ -738,14 +743,15 @@ export class SeColorPicker extends HTMLElement {
* @returns {void}
*/
set type (value) {
this.setAttribute('type', value);
this.setAttribute('type', value)
}
/**
* @function get
* @returns {any}
*/
get src () {
return this.getAttribute('src');
return this.getAttribute('src')
}
/**
@@ -753,7 +759,7 @@ export class SeColorPicker extends HTMLElement {
* @returns {void}
*/
set src (value) {
this.setAttribute('src', value);
this.setAttribute('src', value)
}
/**
@@ -763,20 +769,23 @@ export class SeColorPicker extends HTMLElement {
* @returns {void}
*/
update (svgCanvas, selectedElement, apply) {
const paint = this.paintBox.update(svgCanvas, selectedElement);
const paint = this.paintBox.update(svgCanvas, selectedElement)
if (paint && apply) {
const changeEvent = new CustomEvent('change', { detail: {
paint
} });
this.dispatchEvent(changeEvent);
const changeEvent = new CustomEvent('change', {
detail: {
paint
}
})
this.dispatchEvent(changeEvent)
}
}
/**
* @param {PlainObject} paint
* @returns {void}
*/
setPaint (paint) {
this.paintBox.setPaint(paint);
this.paintBox.setPaint(paint)
}
/**
@@ -784,9 +793,9 @@ export class SeColorPicker extends HTMLElement {
* @returns {void}
*/
connectedCallback () {
this.paintBox = new PaintBox(this.$block, this.type);
this.paintBox = new PaintBox(this.$block, this.type)
this.$picker.addEventListener('click', () => {
let { paint } = this.paintBox;
let { paint } = this.paintBox
jGraduateMethod(
this.$color_picker,
{
@@ -796,22 +805,24 @@ export class SeColorPicker extends HTMLElement {
newstop: 'inverse'
},
(p) => {
paint = new jGraduate.Paint(p);
this.setPaint(paint);
const changeEvent = new CustomEvent('change', { detail: {
paint
} });
this.dispatchEvent(changeEvent);
this.$color_picker.style.display = 'none';
paint = new jGraduate.Paint(p)
this.setPaint(paint)
const changeEvent = new CustomEvent('change', {
detail: {
paint
}
})
this.dispatchEvent(changeEvent)
this.$color_picker.style.display = 'none'
},
() => {
this.$color_picker.style.display = 'none';
this.$color_picker.style.display = 'none'
},
this.i18next
);
});
)
})
}
}
// Register
customElements.define('se-colorpicker', SeColorPicker);
customElements.define('se-colorpicker', SeColorPicker)

View File

@@ -1,8 +1,8 @@
import ListComboBox from 'elix/define/ListComboBox.js';
import { defaultState } from 'elix/src/base/internal.js';
import { templateFrom, fragmentFrom } from 'elix/src/core/htmlLiterals.js';
import { internal } from 'elix';
import NumberSpinBox from '../dialogs/se-elix/define/NumberSpinBox.js';
import ListComboBox from 'elix/define/ListComboBox.js'
import { defaultState } from 'elix/src/base/internal.js'
import { templateFrom, fragmentFrom } from 'elix/src/core/htmlLiterals.js'
import { internal } from 'elix'
import NumberSpinBox from '../dialogs/se-elix/define/NumberSpinBox.js'
/**
* @class Dropdown
@@ -15,21 +15,22 @@ class Dropdown extends ListComboBox {
get [defaultState] () {
return Object.assign(super[defaultState], {
inputPartType: NumberSpinBox,
src: "logo.svg",
src: 'logo.svg',
inputsize: '100%'
});
})
}
/**
* @function get
* @returns {PlainObject}
*/
get [internal.template] () {
const result = super[internal.template];
const source = result.content.getElementById('source');
const result = super[internal.template]
const source = result.content.getElementById('source')
// add a icon before our dropdown
source.prepend(fragmentFrom.html`
<img src="dropdown.svg" alt="icon" width="18" height="18"></img>
`.cloneNode(true));
`.cloneNode(true))
// change the style so it fits in our toolbar
result.content.append(
templateFrom.html`
@@ -48,16 +49,18 @@ class Dropdown extends ListComboBox {
}
</style>
`.content
);
return result;
)
return result
}
/**
* @function observedAttributes
* @returns {any} observed
*/
static get observedAttributes () {
return [ 'title', 'src', 'inputsize', 'value' ];
return ['title', 'src', 'inputsize', 'value']
}
/**
* @function attributeChangedCallback
* @param {string} name
@@ -66,97 +69,104 @@ class Dropdown extends ListComboBox {
* @returns {void}
*/
attributeChangedCallback (name, oldValue, newValue) {
if (oldValue === newValue) return;
if (oldValue === newValue) return
switch (name) {
case 'title':
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;
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);
super[internal.render](changed)
if (this[internal.firstRender]) {
this.$img = this.shadowRoot.querySelector('img');
this.$input = this.shadowRoot.getElementById('input');
this.$img = this.shadowRoot.querySelector('img')
this.$input = this.shadowRoot.getElementById('input')
}
if (changed.src) {
this.$img.setAttribute('src', this[internal.state].src);
this.$img.setAttribute('src', this[internal.state].src)
}
if (changed.inputsize) {
this.$input.shadowRoot.querySelector('[part~="input"]').style.width = this[internal.state].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');
e.preventDefault()
const value = e.detail?.closeResult?.getAttribute('value')
if (value) {
const closeEvent = new CustomEvent('change', { detail: { value } });
this.dispatchEvent(closeEvent);
const closeEvent = new CustomEvent('change', { detail: { value } })
this.dispatchEvent(closeEvent)
}
});
})
}
}
/**
* @function src
* @returns {string} src
*/
get src () {
return this[internal.state].src;
return this[internal.state].src
}
/**
* @function src
* @returns {void}
*/
set src (src) {
this[internal.setState]({ src });
this[internal.setState]({ src })
}
/**
* @function inputsize
* @returns {string} src
*/
get inputsize () {
return this[internal.state].inputsize;
return this[internal.state].inputsize
}
/**
* @function src
* @returns {void}
*/
set inputsize (inputsize) {
this[internal.setState]({ inputsize });
this[internal.setState]({ inputsize })
}
/**
* @function value
* @returns {string} src
*/
get value () {
return this[internal.state].value;
return this[internal.state].value
}
/**
* @function value
* @returns {void}
*/
set value (value) {
this[internal.setState]({ value });
this[internal.setState]({ value })
}
}
// Register
customElements.define('se-dropdown', Dropdown);
customElements.define('se-dropdown', Dropdown)
/*
{TODO

View File

@@ -1,6 +1,5 @@
/* globals svgEditor */
/* eslint-disable no-unsanitized/property */
const template = document.createElement('template');
const template = document.createElement('template')
template.innerHTML = `
<style>
:host {
@@ -98,7 +97,7 @@ template.innerHTML = `
</div>
</div>
`;
`
/**
* @class ExplorerButton
*/
@@ -107,28 +106,30 @@ export class ExplorerButton extends HTMLElement {
* @function constructor
*/
constructor () {
super();
super()
// create the shadowDom and insert the template
this._shadowRoot = this.attachShadow({ mode: 'open' });
this._shadowRoot.append(template.content.cloneNode(true));
this._shadowRoot = this.attachShadow({ mode: 'open' })
this._shadowRoot.append(template.content.cloneNode(true))
// locate the component
this.$button = this._shadowRoot.querySelector('.menu-button');
this.$overall = this._shadowRoot.querySelector('.overall');
this.$img = this._shadowRoot.querySelector('.menu-button img');
this.$menu = this._shadowRoot.querySelector('.menu');
this.$handle = this._shadowRoot.querySelector('.handle');
this.$lib = this._shadowRoot.querySelector('.image-lib');
this.files = [];
this.request = new XMLHttpRequest();
this.imgPath = svgEditor.configObj.curConfig.imgPath;
this.$button = this._shadowRoot.querySelector('.menu-button')
this.$overall = this._shadowRoot.querySelector('.overall')
this.$img = this._shadowRoot.querySelector('.menu-button img')
this.$menu = this._shadowRoot.querySelector('.menu')
this.$handle = this._shadowRoot.querySelector('.handle')
this.$lib = this._shadowRoot.querySelector('.image-lib')
this.files = []
this.request = new XMLHttpRequest()
this.imgPath = svgEditor.configObj.curConfig.imgPath
}
/**
* @function observedAttributes
* @returns {any} observed
*/
static get observedAttributes () {
return [ 'title', 'pressed', 'disabled', 'lib', 'src' ];
return ['title', 'pressed', 'disabled', 'lib', 'src']
}
/**
* @function attributeChangedCallback
* @param {string} name
@@ -137,55 +138,56 @@ export class ExplorerButton extends HTMLElement {
* @returns {void}
*/
async attributeChangedCallback (name, oldValue, newValue) {
if (oldValue === newValue) return;
if (oldValue === newValue) return
switch (name) {
case 'title':
{
const shortcut = this.getAttribute('shortcut');
this.$button.setAttribute('title', `${newValue} [${shortcut}]`);
}
break;
case 'pressed':
if (newValue) {
this.$overall.classList.add('pressed');
} else {
this.$overall.classList.remove('pressed');
}
break;
case 'disabled':
if (newValue) {
this.$overall.classList.add('disabled');
} else {
this.$overall.classList.remove('disabled');
}
break;
case 'lib':
try {
const response = await fetch(`${newValue}index.json`);
const json = await response.json();
const { lib } = json;
this.$menu.innerHTML = lib.map((menu, i) => (
case 'title':
{
const shortcut = this.getAttribute('shortcut')
this.$button.setAttribute('title', `${newValue} [${shortcut}]`)
}
break
case 'pressed':
if (newValue) {
this.$overall.classList.add('pressed')
} else {
this.$overall.classList.remove('pressed')
}
break
case 'disabled':
if (newValue) {
this.$overall.classList.add('disabled')
} else {
this.$overall.classList.remove('disabled')
}
break
case 'lib':
try {
const response = await fetch(`${newValue}index.json`)
const json = await response.json()
const { lib } = json
this.$menu.innerHTML = lib.map((menu, i) => (
`<div data-menu="${menu}" class="menu-item ${(i === 0) ? 'pressed' : ''} ">${menu}</div>`
)).join('');
await this.updateLib(lib[0]);
} catch (error) {
console.error(error);
}
break;
case 'src':
this.$img.setAttribute('src', this.imgPath + '/' + newValue);
break;
default:
console.error(`unknown attribute: ${name}`);
break;
)).join('')
await this.updateLib(lib[0])
} catch (error) {
console.error(error)
}
break
case 'src':
this.$img.setAttribute('src', this.imgPath + '/' + newValue)
break
default:
console.error(`unknown attribute: ${name}`)
break
}
}
/**
* @function get
* @returns {any}
*/
get title () {
return this.getAttribute('title');
return this.getAttribute('title')
}
/**
@@ -193,14 +195,15 @@ export class ExplorerButton extends HTMLElement {
* @returns {void}
*/
set title (value) {
this.setAttribute('title', value);
this.setAttribute('title', value)
}
/**
* @function get
* @returns {any}
*/
get pressed () {
return this.hasAttribute('pressed');
return this.hasAttribute('pressed')
}
/**
@@ -210,17 +213,18 @@ export class ExplorerButton extends HTMLElement {
set pressed (value) {
// boolean value => existence = true
if (value) {
this.setAttribute('pressed', 'true');
this.setAttribute('pressed', 'true')
} else {
this.removeAttribute('pressed', '');
this.removeAttribute('pressed', '')
}
}
/**
* @function get
* @returns {any}
*/
get disabled () {
return this.hasAttribute('disabled');
return this.hasAttribute('disabled')
}
/**
@@ -230,11 +234,12 @@ export class ExplorerButton extends HTMLElement {
set disabled (value) {
// boolean value => existence = true
if (value) {
this.setAttribute('disabled', 'true');
this.setAttribute('disabled', 'true')
} else {
this.removeAttribute('disabled', '');
this.removeAttribute('disabled', '')
}
}
/**
* @function connectedCallback
* @returns {void}
@@ -242,73 +247,74 @@ export class ExplorerButton extends HTMLElement {
connectedCallback () {
// capture click event on the button to manage the logic
const onClickHandler = (ev) => {
ev.stopPropagation();
ev.stopPropagation()
switch (ev.target.nodeName) {
case 'SE-EXPLORERBUTTON':
this.$menu.classList.add('open');
this.$lib.classList.add('open-lib');
break;
case 'SE-BUTTON':
case 'SE-EXPLORERBUTTON':
this.$menu.classList.add('open')
this.$lib.classList.add('open-lib')
break
case 'SE-BUTTON':
// change to the current action
this.currentAction = ev.target;
this.$img.setAttribute('src', this.currentAction.getAttribute('src'));
this.dataset.draw = this.data[this.currentAction.dataset.shape];
this._shadowRoot.querySelectorAll('.image-lib [pressed]').forEach((b) => { b.pressed = false; });
this.currentAction.setAttribute('pressed', 'pressed');
// and close the menu
this.$menu.classList.remove('open');
this.$lib.classList.remove('open-lib');
break;
case 'DIV':
if (ev.target.classList[0] === 'handle') {
this.currentAction = ev.target
this.$img.setAttribute('src', this.currentAction.getAttribute('src'))
this.dataset.draw = this.data[this.currentAction.dataset.shape]
this._shadowRoot.querySelectorAll('.image-lib [pressed]').forEach((b) => { b.pressed = false })
this.currentAction.setAttribute('pressed', 'pressed')
// and close the menu
this.$menu.classList.remove('open')
this.$lib.classList.remove('open-lib')
break
case 'DIV':
if (ev.target.classList[0] === 'handle') {
// this is a click on the handle so let's open/close the menu.
this.$menu.classList.toggle('open');
this.$lib.classList.toggle('open-lib');
} else {
this._shadowRoot.querySelectorAll('.menu > .pressed').forEach((b) => { b.classList.remove('pressed'); });
ev.target.classList.add('pressed');
this.updateLib(ev.target.dataset.menu);
}
break;
default:
console.error('unknown nodeName for:', ev.target, ev.target.className);
this.$menu.classList.toggle('open')
this.$lib.classList.toggle('open-lib')
} else {
this._shadowRoot.querySelectorAll('.menu > .pressed').forEach((b) => { b.classList.remove('pressed') })
ev.target.classList.add('pressed')
this.updateLib(ev.target.dataset.menu)
}
break
default:
console.error('unknown nodeName for:', ev.target, ev.target.className)
}
};
}
// capture event from slots
this.addEventListener('click', onClickHandler);
this.$menu.addEventListener('click', onClickHandler);
this.$lib.addEventListener('click', onClickHandler);
this.$handle.addEventListener('click', onClickHandler);
this.addEventListener('click', onClickHandler)
this.$menu.addEventListener('click', onClickHandler)
this.$lib.addEventListener('click', onClickHandler)
this.$handle.addEventListener('click', onClickHandler)
}
/**
* @function updateLib
* @param {string} lib
* @returns {void}
*/
async updateLib (lib) {
const libDir = this.getAttribute('lib');
const libDir = this.getAttribute('lib')
try {
// initialize buttons for all shapes defined for this library
const response = await fetch(`${libDir}${lib}.json`);
const json = await response.json();
this.data = json.data;
const size = json.size ?? 300;
const fill = json.fill ? '#333' : 'none';
const off = size * 0.05;
const vb = [ -off, -off, size + off * 2, size + off * 2 ].join(' ');
const stroke = json.fill ? 0 : (size / 30);
this.$lib.innerHTML = Object.entries(this.data).map(([ key, path ]) => {
const response = await fetch(`${libDir}${lib}.json`)
const json = await response.json()
this.data = json.data
const size = json.size ?? 300
const fill = json.fill ? '#333' : 'none'
const off = size * 0.05
const vb = [-off, -off, size + off * 2, size + off * 2].join(' ')
const stroke = json.fill ? 0 : (size / 30)
this.$lib.innerHTML = Object.entries(this.data).map(([key, path]) => {
const encoded = btoa(`
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24">
<svg viewBox="${vb}"><path fill="${fill}" stroke="#f8bb00" stroke-width="${stroke}" d="${path}"></path></svg>
</svg>`);
return `<se-button data-shape="${key}"src="data:image/svg+xml;base64,${encoded}"></se-button>`;
}).join('');
</svg>`)
return `<se-button data-shape="${key}"src="data:image/svg+xml;base64,${encoded}"></se-button>`
}).join('')
} catch (error) {
console.error(`could not read file:${libDir}${lib}.json`, error);
console.error(`could not read file:${libDir}${lib}.json`, error)
}
}
}
// Register
customElements.define('se-explorerbutton', ExplorerButton);
customElements.define('se-explorerbutton', ExplorerButton)

View File

@@ -1,6 +1,6 @@
/* globals svgEditor */
import { t } from '../locale.js';
const template = document.createElement('template');
import { t } from '../locale.js'
const template = document.createElement('template')
template.innerHTML = `
<style>
:host {
@@ -79,7 +79,7 @@ template.innerHTML = `
</div>
`;
`
/**
* @class FlyingButton
*/
@@ -88,28 +88,30 @@ export class FlyingButton extends HTMLElement {
* @function constructor
*/
constructor () {
super();
super()
// create the shadowDom and insert the template
this._shadowRoot = this.attachShadow({ mode: 'open' });
this._shadowRoot.append(template.content.cloneNode(true));
this._shadowRoot = this.attachShadow({ mode: 'open' })
this._shadowRoot.append(template.content.cloneNode(true))
// locate the component
this.$button = this._shadowRoot.querySelector('.menu-button');
this.$handle = this._shadowRoot.querySelector('.handle');
this.$overall = this._shadowRoot.querySelector('.overall');
this.$img = this._shadowRoot.querySelector('img');
this.$menu = this._shadowRoot.querySelector('.menu');
this.$button = this._shadowRoot.querySelector('.menu-button')
this.$handle = this._shadowRoot.querySelector('.handle')
this.$overall = this._shadowRoot.querySelector('.overall')
this.$img = this._shadowRoot.querySelector('img')
this.$menu = this._shadowRoot.querySelector('.menu')
// the last element of the div is the slot
// we retrieve all elements added in the slot (i.e. se-buttons)
this.$elements = this.$menu.lastElementChild.assignedElements();
this.imgPath = svgEditor.configObj.curConfig.imgPath;
this.$elements = this.$menu.lastElementChild.assignedElements()
this.imgPath = svgEditor.configObj.curConfig.imgPath
}
/**
* @function observedAttributes
* @returns {any} observed
*/
static get observedAttributes () {
return [ 'title', 'pressed', 'disabled', 'opened' ];
return ['title', 'pressed', 'disabled', 'opened']
}
/**
* @function attributeChangedCallback
* @param {string} name
@@ -118,46 +120,47 @@ export class FlyingButton extends HTMLElement {
* @returns {void}
*/
attributeChangedCallback (name, oldValue, newValue) {
if (oldValue === newValue) return;
if (oldValue === newValue) return
switch (name) {
case 'title':
{
const shortcut = this.getAttribute('shortcut');
this.$button.setAttribute('title', `${t(newValue)} ${shortcut ? `[${t(shortcut)}]` : ''}`);
}
break;
case 'pressed':
if (newValue) {
this.$overall.classList.add('pressed');
} else {
this.$overall.classList.remove('pressed');
}
break;
case 'opened':
if (newValue) {
this.$menu.classList.add('open');
} else {
this.$menu.classList.remove('open');
}
break;
case 'disabled':
if (newValue) {
this.$overall.classList.add('disabled');
} else {
this.$overall.classList.remove('disabled');
}
break;
default:
console.error(`unknown attribute: ${name}`);
break;
case 'title':
{
const shortcut = this.getAttribute('shortcut')
this.$button.setAttribute('title', `${t(newValue)} ${shortcut ? `[${t(shortcut)}]` : ''}`)
}
break
case 'pressed':
if (newValue) {
this.$overall.classList.add('pressed')
} else {
this.$overall.classList.remove('pressed')
}
break
case 'opened':
if (newValue) {
this.$menu.classList.add('open')
} else {
this.$menu.classList.remove('open')
}
break
case 'disabled':
if (newValue) {
this.$overall.classList.add('disabled')
} else {
this.$overall.classList.remove('disabled')
}
break
default:
console.error(`unknown attribute: ${name}`)
break
}
}
/**
* @function get
* @returns {any}
*/
get title () {
return this.getAttribute('title');
return this.getAttribute('title')
}
/**
@@ -165,14 +168,15 @@ export class FlyingButton extends HTMLElement {
* @returns {void}
*/
set title (value) {
this.setAttribute('title', value);
this.setAttribute('title', value)
}
/**
* @function get
* @returns {any}
*/
get pressed () {
return this.hasAttribute('pressed');
return this.hasAttribute('pressed')
}
/**
@@ -182,19 +186,20 @@ export class FlyingButton extends HTMLElement {
set pressed (value) {
// boolean value => existence = true
if (value) {
this.setAttribute('pressed', 'true');
this.setAttribute('pressed', 'true')
} else {
this.removeAttribute('pressed', '');
this.removeAttribute('pressed', '')
// close also the menu if open
this.removeAttribute('opened');
this.removeAttribute('opened')
}
}
/**
* @function get
* @returns {any}
*/
get opened () {
return this.hasAttribute('opened');
return this.hasAttribute('opened')
}
/**
@@ -204,17 +209,18 @@ export class FlyingButton extends HTMLElement {
set opened (value) {
// boolean value => existence = true
if (value) {
this.setAttribute('opened', 'opened');
this.setAttribute('opened', 'opened')
} else {
this.removeAttribute('opened');
this.removeAttribute('opened')
}
}
/**
* @function get
* @returns {any}
*/
get disabled () {
return this.hasAttribute('disabled');
return this.hasAttribute('disabled')
}
/**
@@ -224,59 +230,60 @@ export class FlyingButton extends HTMLElement {
set disabled (value) {
// boolean value => existence = true
if (value) {
this.setAttribute('disabled', 'true');
this.setAttribute('disabled', 'true')
} else {
this.removeAttribute('disabled', '');
this.removeAttribute('disabled', '')
}
}
/**
* @function connectedCallback
* @returns {void}
*/
connectedCallback () {
this.activeSlot = this.shadowRoot.querySelector('slot').assignedElements()[0];
this.$img.setAttribute('src', this.imgPath + '/' + this.activeSlot.getAttribute('src'));
this.activeSlot = this.shadowRoot.querySelector('slot').assignedElements()[0]
this.$img.setAttribute('src', this.imgPath + '/' + this.activeSlot.getAttribute('src'))
// capture click event on the button to manage the logic
const onClickHandler = (ev) => {
ev.stopPropagation();
ev.stopPropagation()
switch (ev.target.nodeName) {
case 'SE-FLYINGBUTTON':
if (this.pressed) {
this.setAttribute('opened', 'opened');
} else {
case 'SE-FLYINGBUTTON':
if (this.pressed) {
this.setAttribute('opened', 'opened')
} else {
// launch current action
this.activeSlot.click();
this.setAttribute('pressed', 'pressed');
}
break;
case 'SE-BUTTON':
this.activeSlot.click()
this.setAttribute('pressed', 'pressed')
}
break
case 'SE-BUTTON':
// change to the current action
this.$img.setAttribute('src', this.imgPath + '/' + ev.target.getAttribute('src'));
this.activeSlot = ev.target;
this.setAttribute('pressed', 'pressed');
// and close the menu
this.$menu.classList.remove('open');
break;
case 'DIV':
this.$img.setAttribute('src', this.imgPath + '/' + ev.target.getAttribute('src'))
this.activeSlot = ev.target
this.setAttribute('pressed', 'pressed')
// and close the menu
this.$menu.classList.remove('open')
break
case 'DIV':
// this is a click on the handle so let's open/close the menu.
if (this.opened) {
this.removeAttribute('opened');
} else {
this.setAttribute('opened', 'opened');
// In case menu scroll on top or bottom position based popup position set
const rect = this.getBoundingClientRect();
this.$menu.style.top = rect.top + "px";
}
break;
default:
console.error('unkonw nodeName for:', ev.target, ev.target.className);
if (this.opened) {
this.removeAttribute('opened')
} else {
this.setAttribute('opened', 'opened')
// In case menu scroll on top or bottom position based popup position set
const rect = this.getBoundingClientRect()
this.$menu.style.top = rect.top + 'px'
}
break
default:
console.error('unkonw nodeName for:', ev.target, ev.target.className)
}
};
}
// capture event from slots
this.addEventListener('click', onClickHandler);
this.$handle.addEventListener('click', onClickHandler);
this.addEventListener('click', onClickHandler)
this.$handle.addEventListener('click', onClickHandler)
}
}
// Register
customElements.define('se-flyingbutton', FlyingButton);
customElements.define('se-flyingbutton', FlyingButton)

View File

@@ -1,7 +1,7 @@
import 'elix/define/Input.js';
import { t } from '../locale.js';
import 'elix/define/Input.js'
import { t } from '../locale.js'
const template = document.createElement('template');
const template = document.createElement('template')
template.innerHTML = `
<style>
div {
@@ -32,7 +32,7 @@ template.innerHTML = `
<span id="label">label</span>
<elix-input></elix-input>
</div>
`;
`
/**
* @class SEInput
@@ -42,24 +42,26 @@ export class SEInput extends HTMLElement {
* @function constructor
*/
constructor () {
super();
super()
// create the shadowDom and insert the template
this._shadowRoot = this.attachShadow({ mode: 'open' });
this._shadowRoot.append(template.content.cloneNode(true));
this._shadowRoot = this.attachShadow({ mode: 'open' })
this._shadowRoot.append(template.content.cloneNode(true))
// locate the component
this.$div = this._shadowRoot.querySelector('div');
this.$img = this._shadowRoot.querySelector('img');
this.$label = this.shadowRoot.getElementById('label');
this.$event = new CustomEvent('change');
this.$input = this._shadowRoot.querySelector('elix-input');
this.$div = this._shadowRoot.querySelector('div')
this.$img = this._shadowRoot.querySelector('img')
this.$label = this.shadowRoot.getElementById('label')
this.$event = new CustomEvent('change')
this.$input = this._shadowRoot.querySelector('elix-input')
}
/**
* @function observedAttributes
* @returns {any} observed
*/
static get observedAttributes () {
return [ 'value', 'label', 'src', 'size', 'title' ];
return ['value', 'label', 'src', 'size', 'title']
}
/**
* @function attributeChangedCallback
* @param {string} name
@@ -68,36 +70,37 @@ export class SEInput extends HTMLElement {
* @returns {void}
*/
attributeChangedCallback (name, oldValue, newValue) {
if (oldValue === newValue) return;
if (oldValue === newValue) return
switch (name) {
case 'title':
this.$div.setAttribute('title', `${t(newValue)}`);
break;
case 'src':
this.$img.setAttribute('src', newValue);
this.$label.remove();
break;
case 'size':
this.$input.setAttribute('size', newValue);
break;
case 'label':
this.$label.textContent = t(newValue);
this.$img.remove();
break;
case 'value':
this.$input.value = newValue;
break;
default:
console.error(`unknown attribute: ${name}`);
break;
case 'title':
this.$div.setAttribute('title', `${t(newValue)}`)
break
case 'src':
this.$img.setAttribute('src', newValue)
this.$label.remove()
break
case 'size':
this.$input.setAttribute('size', newValue)
break
case 'label':
this.$label.textContent = t(newValue)
this.$img.remove()
break
case 'value':
this.$input.value = newValue
break
default:
console.error(`unknown attribute: ${name}`)
break
}
}
/**
* @function get
* @returns {any}
*/
get title () {
return this.getAttribute('title');
return this.getAttribute('title')
}
/**
@@ -105,14 +108,15 @@ export class SEInput extends HTMLElement {
* @returns {void}
*/
set title (value) {
this.setAttribute('title', value);
this.setAttribute('title', value)
}
/**
* @function get
* @returns {any}
*/
get label () {
return this.getAttribute('label');
return this.getAttribute('label')
}
/**
@@ -120,14 +124,15 @@ export class SEInput extends HTMLElement {
* @returns {void}
*/
set label (value) {
this.setAttribute('label', value);
this.setAttribute('label', value)
}
/**
* @function get
* @returns {any}
*/
get value () {
return this.$input.value;
return this.$input.value
}
/**
@@ -135,14 +140,15 @@ export class SEInput extends HTMLElement {
* @returns {void}
*/
set value (value) {
this.$input.value = value;
this.$input.value = value
}
/**
* @function get
* @returns {any}
*/
get src () {
return this.getAttribute('src');
return this.getAttribute('src')
}
/**
@@ -150,7 +156,7 @@ export class SEInput extends HTMLElement {
* @returns {void}
*/
set src (value) {
this.setAttribute('src', value);
this.setAttribute('src', value)
}
/**
@@ -158,7 +164,7 @@ export class SEInput extends HTMLElement {
* @returns {any}
*/
get size () {
return this.getAttribute('size');
return this.getAttribute('size')
}
/**
@@ -166,7 +172,7 @@ export class SEInput extends HTMLElement {
* @returns {void}
*/
set size (value) {
this.setAttribute('size', value);
this.setAttribute('size', value)
}
/**
@@ -175,16 +181,16 @@ export class SEInput extends HTMLElement {
*/
connectedCallback () {
this.$input.addEventListener('change', (e) => {
e.preventDefault();
this.value = e.target.value;
this.dispatchEvent(this.$event);
});
e.preventDefault()
this.value = e.target.value
this.dispatchEvent(this.$event)
})
this.$input.addEventListener('keyup', (e) => {
e.preventDefault();
this.value = e.target.value;
this.dispatchEvent(this.$event);
});
e.preventDefault()
this.value = e.target.value
this.dispatchEvent(this.$event)
})
}
}
// Register
customElements.define('se-input', SEInput);
customElements.define('se-input', SEInput)

View File

@@ -1,8 +1,8 @@
/* globals svgEditor */
import 'elix/define/DropdownList.js';
import { t } from '../locale.js';
import 'elix/define/DropdownList.js'
import { t } from '../locale.js'
const template = document.createElement('template');
const template = document.createElement('template')
template.innerHTML = `
<style>
elix-dropdown-list {
@@ -30,7 +30,7 @@ elix-dropdown-list::part(popup-toggle) {
<slot></slot>
</elix-dropdown-list>
`;
`
/**
* @class SeList
*/
@@ -39,22 +39,23 @@ export class SeList extends HTMLElement {
* @function constructor
*/
constructor () {
super();
super()
// create the shadowDom and insert the template
this._shadowRoot = this.attachShadow({ mode: 'open' });
this._shadowRoot.append(template.content.cloneNode(true));
this.$dropdown = this._shadowRoot.querySelector('elix-dropdown-list');
this.$label = this._shadowRoot.querySelector('label');
this.$selection = this.$dropdown.shadowRoot.querySelector('#value');
this.items = this.querySelectorAll("se-list-item");
this.imgPath = svgEditor.configObj.curConfig.imgPath;
this._shadowRoot = this.attachShadow({ mode: 'open' })
this._shadowRoot.append(template.content.cloneNode(true))
this.$dropdown = this._shadowRoot.querySelector('elix-dropdown-list')
this.$label = this._shadowRoot.querySelector('label')
this.$selection = this.$dropdown.shadowRoot.querySelector('#value')
this.items = this.querySelectorAll('se-list-item')
this.imgPath = svgEditor.configObj.curConfig.imgPath
}
/**
* @function observedAttributes
* @returns {any} observed
*/
static get observedAttributes () {
return [ 'label', 'width', 'height', 'title', 'value' ];
return ['label', 'width', 'height', 'title', 'value']
}
/**
@@ -65,51 +66,51 @@ export class SeList extends HTMLElement {
* @returns {void}
*/
attributeChangedCallback (name, oldValue, newValue) {
const currentObj = this;
if (oldValue === newValue) return;
const currentObj = this
if (oldValue === newValue) return
switch (name) {
case 'title':
this.$dropdown.setAttribute('title', t(newValue));
break;
case 'label':
this.$label.textContent = t(newValue);
break;
case 'height':
this.$dropdown.style.height = newValue;
break;
case 'width':
this.$dropdown.style.width = newValue;
break;
case 'value':
Array.from(this.items).forEach(function (element) {
if(element.getAttribute("value") === newValue) {
if (element.hasAttribute("src")) {
case 'title':
this.$dropdown.setAttribute('title', t(newValue))
break
case 'label':
this.$label.textContent = t(newValue)
break
case 'height':
this.$dropdown.style.height = newValue
break
case 'width':
this.$dropdown.style.width = newValue
break
case 'value':
Array.from(this.items).forEach(function (element) {
if (element.getAttribute('value') === newValue) {
if (element.hasAttribute('src')) {
// empty current selection children
while(currentObj.$selection.firstChild)
currentObj.$selection.removeChild(currentObj.$selection.firstChild);
// replace selection child with image of new value
const img = document.createElement('img');
img.src = currentObj.imgPath + '/' + element.getAttribute("src");
img.style.height = element.getAttribute("img-height");
img.setAttribute('title', t(element.getAttribute("title")));
currentObj.$selection.append(img);
} else {
currentObj.$selection.textContent = t(element.getAttribute('option'));
while (currentObj.$selection.firstChild) { currentObj.$selection.removeChild(currentObj.$selection.firstChild) }
// replace selection child with image of new value
const img = document.createElement('img')
img.src = currentObj.imgPath + '/' + element.getAttribute('src')
img.style.height = element.getAttribute('img-height')
img.setAttribute('title', t(element.getAttribute('title')))
currentObj.$selection.append(img)
} else {
currentObj.$selection.textContent = t(element.getAttribute('option'))
}
}
}
});
break;
default:
console.error(`unknown attribute: ${name}`);
break;
})
break
default:
console.error(`unknown attribute: ${name}`)
break
}
}
/**
* @function get
* @returns {any}
*/
get title () {
return this.getAttribute('title');
return this.getAttribute('title')
}
/**
@@ -117,14 +118,15 @@ export class SeList extends HTMLElement {
* @returns {void}
*/
set title (value) {
this.setAttribute('title', value);
this.setAttribute('title', value)
}
/**
* @function get
* @returns {any}
*/
get label () {
return this.getAttribute('label');
return this.getAttribute('label')
}
/**
@@ -132,14 +134,15 @@ export class SeList extends HTMLElement {
* @returns {void}
*/
set label (value) {
this.setAttribute('label', value);
this.setAttribute('label', value)
}
/**
* @function get
* @returns {any}
*/
get width () {
return this.getAttribute('width');
return this.getAttribute('width')
}
/**
@@ -147,14 +150,15 @@ export class SeList extends HTMLElement {
* @returns {void}
*/
set width (value) {
this.setAttribute('width', value);
this.setAttribute('width', value)
}
/**
* @function get
* @returns {any}
*/
get height () {
return this.getAttribute('height');
return this.getAttribute('height')
}
/**
@@ -162,31 +166,32 @@ export class SeList extends HTMLElement {
* @returns {void}
*/
set height (value) {
this.setAttribute('height', value);
this.setAttribute('height', value)
}
/**
* @function connectedCallback
* @returns {void}
*/
connectedCallback () {
const currentObj = this;
const currentObj = this
this.$dropdown.addEventListener('selectedindexchange', (e) => {
if (e?.detail?.selectedIndex !== undefined) {
const value = this.$dropdown.selectedItem.getAttribute('value');
const closeEvent = new CustomEvent('change', { detail: { value } });
currentObj.dispatchEvent(closeEvent);
currentObj.value = value;
currentObj.setAttribute("value", value);
const value = this.$dropdown.selectedItem.getAttribute('value')
const closeEvent = new CustomEvent('change', { detail: { value } })
currentObj.dispatchEvent(closeEvent)
currentObj.value = value
currentObj.setAttribute('value', value)
}
});
})
this.$dropdown.addEventListener('close', (_e) => {
/** with Chrome, selectedindexchange does not fire consistently
* unless you forec change in this close event
*/
this.$dropdown.selectedIndex = this.$dropdown.currentIndex;
});
this.$dropdown.selectedIndex = this.$dropdown.currentIndex
})
}
}
// Register
customElements.define('se-list', SeList);
customElements.define('se-list', SeList)

View File

@@ -1,8 +1,8 @@
/* globals svgEditor */
import 'elix/define/Option.js';
import { t } from '../locale.js';
import 'elix/define/Option.js'
import { t } from '../locale.js'
const template = document.createElement('template');
const template = document.createElement('template')
template.innerHTML = `
<style>
elix-option{
@@ -17,7 +17,7 @@ template.innerHTML = `
<img alt="icon" />
<slot></slot>
</elix-option>
`;
`
/**
* @class SeMenu
*/
@@ -26,23 +26,24 @@ export class SeListItem extends HTMLElement {
* @function constructor
*/
constructor () {
super();
super()
// create the shadowDom and insert the template
this._shadowRoot = this.attachShadow({ mode: 'open' });
this._shadowRoot.append(template.content.cloneNode(true));
this.$menuitem = this._shadowRoot.querySelector('elix-option');
this.$svg = this.$menuitem.shadowRoot.querySelector('#checkmark');
this.$svg.setAttribute('style', 'display: none;');
this.$img = this._shadowRoot.querySelector('img');
this.$img.setAttribute('style', 'display: none;');
this.imgPath = svgEditor.configObj.curConfig.imgPath;
this._shadowRoot = this.attachShadow({ mode: 'open' })
this._shadowRoot.append(template.content.cloneNode(true))
this.$menuitem = this._shadowRoot.querySelector('elix-option')
this.$svg = this.$menuitem.shadowRoot.querySelector('#checkmark')
this.$svg.setAttribute('style', 'display: none;')
this.$img = this._shadowRoot.querySelector('img')
this.$img.setAttribute('style', 'display: none;')
this.imgPath = svgEditor.configObj.curConfig.imgPath
}
/**
* @function observedAttributes
* @returns {any} observed
*/
static get observedAttributes () {
return [ 'option', 'src', 'title', 'img-height' ];
return ['option', 'src', 'title', 'img-height']
}
/**
@@ -53,33 +54,34 @@ export class SeListItem extends HTMLElement {
* @returns {void}
*/
attributeChangedCallback (name, oldValue, newValue) {
if (oldValue === newValue) return;
if (oldValue === newValue) return
switch (name) {
case 'option':
this.$menuitem.setAttribute('option', newValue);
this.$menuitem.textContent = t(newValue);
break;
case 'src':
this.$img.setAttribute('style', 'display: block;');
this.$img.setAttribute('src', this.imgPath + '/' + newValue);
break;
case 'title':
this.$img.setAttribute('title', t(newValue));
break;
case 'img-height':
this.$img.setAttribute('height', newValue);
break;
default:
console.error(`unknown attribute: ${name}`);
break;
case 'option':
this.$menuitem.setAttribute('option', newValue)
this.$menuitem.textContent = t(newValue)
break
case 'src':
this.$img.setAttribute('style', 'display: block;')
this.$img.setAttribute('src', this.imgPath + '/' + newValue)
break
case 'title':
this.$img.setAttribute('title', t(newValue))
break
case 'img-height':
this.$img.setAttribute('height', newValue)
break
default:
console.error(`unknown attribute: ${name}`)
break
}
}
/**
* @function get
* @returns {any}
*/
get option () {
return this.getAttribute('option');
return this.getAttribute('option')
}
/**
@@ -87,14 +89,15 @@ export class SeListItem extends HTMLElement {
* @returns {void}
*/
set option (value) {
this.setAttribute('option', value);
this.setAttribute('option', value)
}
/**
* @function get
* @returns {any}
*/
get title () {
return this.getAttribute('title');
return this.getAttribute('title')
}
/**
@@ -102,14 +105,15 @@ export class SeListItem extends HTMLElement {
* @returns {void}
*/
set title (value) {
this.setAttribute('title', value);
this.setAttribute('title', value)
}
/**
* @function get
* @returns {any}
*/
get imgHeight () {
return this.getAttribute('img-height');
return this.getAttribute('img-height')
}
/**
@@ -117,14 +121,15 @@ export class SeListItem extends HTMLElement {
* @returns {void}
*/
set imgHeight (value) {
this.setAttribute('img-height', value);
this.setAttribute('img-height', value)
}
/**
* @function get
* @returns {any}
*/
get src () {
return this.getAttribute('src');
return this.getAttribute('src')
}
/**
@@ -132,9 +137,9 @@ export class SeListItem extends HTMLElement {
* @returns {void}
*/
set src (value) {
this.setAttribute('src', value);
this.setAttribute('src', value)
}
}
// Register
customElements.define('se-list-item', SeListItem);
customElements.define('se-list-item', SeListItem)

View File

@@ -1,8 +1,8 @@
/* globals svgEditor */
import 'elix/define/MenuItem.js';
import './sePlainMenuButton.js';
import 'elix/define/MenuItem.js'
import './sePlainMenuButton.js'
const template = document.createElement('template');
const template = document.createElement('template')
template.innerHTML = `
<style>
:host {
@@ -29,7 +29,7 @@ template.innerHTML = `
<slot></slot>
</elix-menu-button>
`;
`
/**
* @class SeMenu
*/
@@ -38,20 +38,21 @@ export class SeMenu extends HTMLElement {
* @function constructor
*/
constructor () {
super();
super()
// create the shadowDom and insert the template
this._shadowRoot = this.attachShadow({ mode: 'open' });
this._shadowRoot.append(template.content.cloneNode(true));
this.$menu = this._shadowRoot.querySelector('elix-menu-button');
this.$label = this.$menu.shadowRoot.querySelector('#popupToggle').shadowRoot;
this.imgPath = svgEditor.configObj.curConfig.imgPath;
this._shadowRoot = this.attachShadow({ mode: 'open' })
this._shadowRoot.append(template.content.cloneNode(true))
this.$menu = this._shadowRoot.querySelector('elix-menu-button')
this.$label = this.$menu.shadowRoot.querySelector('#popupToggle').shadowRoot
this.imgPath = svgEditor.configObj.curConfig.imgPath
}
/**
* @function observedAttributes
* @returns {any} observed
*/
static get observedAttributes () {
return [ 'label', 'src' ];
return ['label', 'src']
}
/**
@@ -62,29 +63,30 @@ export class SeMenu extends HTMLElement {
* @returns {void}
*/
attributeChangedCallback (name, oldValue, newValue) {
const image = new Image();
if (oldValue === newValue) return;
const image = new Image()
if (oldValue === newValue) return
switch (name) {
case 'src':
image.src = this.imgPath + '/' + newValue;
image.width = 24;
image.height = 24;
this.$label.prepend(image);
break;
case 'label':
this.$label.prepend(newValue);
break;
default:
console.error(`unknown attribute: ${name}`);
break;
case 'src':
image.src = this.imgPath + '/' + newValue
image.width = 24
image.height = 24
this.$label.prepend(image)
break
case 'label':
this.$label.prepend(newValue)
break
default:
console.error(`unknown attribute: ${name}`)
break
}
}
/**
* @function get
* @returns {any}
*/
get label () {
return this.getAttribute('label');
return this.getAttribute('label')
}
/**
@@ -92,14 +94,15 @@ export class SeMenu extends HTMLElement {
* @returns {void}
*/
set label (value) {
this.setAttribute('label', value);
this.setAttribute('label', value)
}
/**
* @function get
* @returns {any}
*/
get src () {
return this.getAttribute('src');
return this.getAttribute('src')
}
/**
@@ -107,7 +110,7 @@ export class SeMenu extends HTMLElement {
* @returns {void}
*/
set src (value) {
this.setAttribute('src', value);
this.setAttribute('src', value)
}
/**
* @function connectedCallback
@@ -125,4 +128,4 @@ export class SeMenu extends HTMLElement {
}
// Register
customElements.define('se-menu', SeMenu);
customElements.define('se-menu', SeMenu)

View File

@@ -1,8 +1,8 @@
/* globals svgEditor */
import 'elix/define/Menu.js';
import 'elix/define/MenuItem.js';
import { t } from '../locale.js';
const template = document.createElement('template');
import 'elix/define/Menu.js'
import 'elix/define/MenuItem.js'
import { t } from '../locale.js'
const template = document.createElement('template')
template.innerHTML = `
<style>
</style>
@@ -12,7 +12,7 @@ template.innerHTML = `
<span style="margin-left: 7px;"></span>
</div>
</elix-menu-item>
`;
`
/**
* @class SeMenuItem
*/
@@ -21,24 +21,26 @@ export class SeMenuItem extends HTMLElement {
* @function constructor
*/
constructor () {
super();
super()
// create the shadowDom and insert the template
this._shadowRoot = this.attachShadow({ mode: 'open' });
this._shadowRoot.append(template.content.cloneNode(true));
this.$img = this._shadowRoot.querySelector('img');
this.$label = this._shadowRoot.querySelector('span');
this.$menuitem = this._shadowRoot.querySelector('elix-menu-item');
this.$svg = this.$menuitem.shadowRoot.querySelector('#checkmark');
this.$svg.setAttribute('style', 'display: none;');
this.imgPath = svgEditor.configObj.curConfig.imgPath;
this._shadowRoot = this.attachShadow({ mode: 'open' })
this._shadowRoot.append(template.content.cloneNode(true))
this.$img = this._shadowRoot.querySelector('img')
this.$label = this._shadowRoot.querySelector('span')
this.$menuitem = this._shadowRoot.querySelector('elix-menu-item')
this.$svg = this.$menuitem.shadowRoot.querySelector('#checkmark')
this.$svg.setAttribute('style', 'display: none;')
this.imgPath = svgEditor.configObj.curConfig.imgPath
}
/**
* @function observedAttributes
* @returns {any} observed
*/
static get observedAttributes () {
return [ 'label', 'src' ];
return ['label', 'src']
}
/**
* @function attributeChangedCallback
* @param {string} name
@@ -47,28 +49,29 @@ export class SeMenuItem extends HTMLElement {
* @returns {void}
*/
attributeChangedCallback (name, oldValue, newValue) {
let shortcut = '';
if (oldValue === newValue) return;
let shortcut = ''
if (oldValue === newValue) return
switch (name) {
case 'src':
this.$img.style.display = 'inline-block';
this.$img.setAttribute('src', this.imgPath + '/' + newValue);
break;
case 'label':
shortcut = this.getAttribute('shortcut');
this.$label.textContent = `${t(newValue)} ${shortcut ? `(${shortcut})` : ''}`;
break;
default:
console.error(`unknown attribute: ${name}`);
break;
case 'src':
this.$img.style.display = 'inline-block'
this.$img.setAttribute('src', this.imgPath + '/' + newValue)
break
case 'label':
shortcut = this.getAttribute('shortcut')
this.$label.textContent = `${t(newValue)} ${shortcut ? `(${shortcut})` : ''}`
break
default:
console.error(`unknown attribute: ${name}`)
break
}
}
/**
* @function get
* @returns {any}
*/
get label () {
return this.getAttribute('label');
return this.getAttribute('label')
}
/**
@@ -76,14 +79,15 @@ export class SeMenuItem extends HTMLElement {
* @returns {void}
*/
set label (value) {
this.setAttribute('label', value);
this.setAttribute('label', value)
}
/**
* @function get
* @returns {any}
*/
get src () {
return this.getAttribute('src');
return this.getAttribute('src')
}
/**
@@ -91,7 +95,7 @@ export class SeMenuItem extends HTMLElement {
* @returns {void}
*/
set src (value) {
this.setAttribute('src', value);
this.setAttribute('src', value)
}
/**
@@ -100,24 +104,24 @@ export class SeMenuItem extends HTMLElement {
*/
connectedCallback () {
// capture shortcuts
const shortcut = this.getAttribute('shortcut');
const shortcut = this.getAttribute('shortcut')
if (shortcut) {
// register the keydown event
document.addEventListener('keydown', (e) => {
// only track keyboard shortcuts for the body containing the SVG-Editor
if (e.target.nodeName !== 'BODY') return;
if (e.target.nodeName !== 'BODY') return
// normalize key
const key = `${(e.metaKey) ? 'meta+' : ''}${(e.ctrlKey) ? 'ctrl+' : ''}${e.key.toUpperCase()}`;
if (shortcut !== key) return;
const key = `${(e.metaKey) ? 'meta+' : ''}${(e.ctrlKey) ? 'ctrl+' : ''}${e.key.toUpperCase()}`
if (shortcut !== key) return
// launch the click event
if (this.id) {
document.getElementById(this.id).click();
document.getElementById(this.id).click()
}
e.preventDefault();
});
e.preventDefault()
})
}
}
}
// Register
customElements.define('se-menu-item', SeMenuItem);
customElements.define('se-menu-item', SeMenuItem)

View File

@@ -11,9 +11,9 @@ const palette = [
'#ffaaaa', '#ffd4aa', '#ffffaa', '#d4ffaa',
'#aaffaa', '#aaffd4', '#aaffff', '#aad4ff',
'#aaaaff', '#d4aaff', '#ffaaff', '#ffaad4'
];
]
const template = document.createElement('template');
const template = document.createElement('template')
template.innerHTML = `
<style>
.square {
@@ -50,7 +50,7 @@ template.innerHTML = `
<div id="js-se-palette">
</div>
</div>
`;
`
/**
* @class SEPalette
@@ -60,38 +60,38 @@ export class SEPalette extends HTMLElement {
* @function constructor
*/
constructor () {
super();
super()
// create the shadowDom and insert the template
this._shadowRoot = this.attachShadow({ mode: 'open' });
this._shadowRoot.append(template.content.cloneNode(true));
this.$strip = this._shadowRoot.querySelector('#js-se-palette');
this._shadowRoot = this.attachShadow({ mode: 'open' })
this._shadowRoot.append(template.content.cloneNode(true))
this.$strip = this._shadowRoot.querySelector('#js-se-palette')
palette.forEach((rgb) => {
const newDiv = document.createElement('div');
newDiv.classList.add('square');
if(rgb === 'none') {
const img = document.createElement('img');
img.src = `data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgY2xhc3M9InN2Z19pY29uIj48c3ZnIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+CiAgICA8bGluZSBmaWxsPSJub25lIiBzdHJva2U9IiNkNDAwMDAiIGlkPSJzdmdfOTAiIHkyPSIyNCIgeDI9IjI0IiB5MT0iMCIgeDE9IjAiLz4KICAgIDxsaW5lIGlkPSJzdmdfOTIiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2Q0MDAwMCIgeTI9IjI0IiB4Mj0iMCIgeTE9IjAiIHgxPSIyNCIvPgogIDwvc3ZnPjwvc3ZnPg==`;
img.style.width = "15px";
img.style.height = "15px";
newDiv.append(img);
const newDiv = document.createElement('div')
newDiv.classList.add('square')
if (rgb === 'none') {
const img = document.createElement('img')
img.src = 'data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgY2xhc3M9InN2Z19pY29uIj48c3ZnIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+CiAgICA8bGluZSBmaWxsPSJub25lIiBzdHJva2U9IiNkNDAwMDAiIGlkPSJzdmdfOTAiIHkyPSIyNCIgeDI9IjI0IiB5MT0iMCIgeDE9IjAiLz4KICAgIDxsaW5lIGlkPSJzdmdfOTIiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2Q0MDAwMCIgeTI9IjI0IiB4Mj0iMCIgeTE9IjAiIHgxPSIyNCIvPgogIDwvc3ZnPjwvc3ZnPg=='
img.style.width = '15px'
img.style.height = '15px'
newDiv.append(img)
} else {
newDiv.style.backgroundColor = rgb;
newDiv.style.backgroundColor = rgb
}
newDiv.dataset.rgb = rgb;
newDiv.dataset.rgb = rgb
newDiv.addEventListener('click', (evt) => {
evt.preventDefault();
evt.preventDefault()
// shift key or right click for stroke
const picker = evt.shiftKey || evt.button === 2 ? 'stroke' : 'fill';
let color = newDiv.dataset.rgb;
const picker = evt.shiftKey || evt.button === 2 ? 'stroke' : 'fill'
let color = newDiv.dataset.rgb
// Webkit-based browsers returned 'initial' here for no stroke
if (color === 'none' || color === 'transparent' || color === 'initial') {
color = 'none';
color = 'none'
}
const paletteEvent = new CustomEvent('change', { detail: { picker, color }, bubbles: false });
this.dispatchEvent(paletteEvent);
});
this.$strip.append(newDiv);
});
const paletteEvent = new CustomEvent('change', { detail: { picker, color }, bubbles: false })
this.dispatchEvent(paletteEvent)
})
this.$strip.append(newDiv)
})
}
/**
@@ -100,15 +100,17 @@ export class SEPalette extends HTMLElement {
* @returns {void}
*/
init (i18next) {
this.setAttribute('ui-palette_info', i18next.t('ui.palette_info'));
this.setAttribute('ui-palette_info', i18next.t('ui.palette_info'))
}
/**
* @function observedAttributes
* @returns {any} observed
*/
static get observedAttributes () {
return [ 'ui-palette_info' ];
return ['ui-palette_info']
}
/**
* @function attributeChangedCallback
* @param {string} name
@@ -117,12 +119,13 @@ export class SEPalette extends HTMLElement {
* @returns {void}
*/
attributeChangedCallback (name, oldValue, newValue) {
let node;
let node
if (name === 'ui-palette_info') {
node = this._shadowRoot.querySelector('#palette_holder');
node.setAttribute('title', newValue);
node = this._shadowRoot.querySelector('#palette_holder')
node.setAttribute('title', newValue)
}
}
/**
* @function connectedCallback
* @returns {void}
@@ -132,4 +135,4 @@ export class SEPalette extends HTMLElement {
}
// Register
customElements.define('se-palette', SEPalette);
customElements.define('se-palette', SEPalette)

View File

@@ -1,6 +1,6 @@
import { template } from 'elix/src/base/internal.js';
import { fragmentFrom } from 'elix/src/core/htmlLiterals.js';
import PlainButton from 'elix/src/plain/PlainButton.js';
import { template } from 'elix/src/base/internal.js'
import { fragmentFrom } from 'elix/src/core/htmlLiterals.js'
import PlainButton from 'elix/src/plain/PlainButton.js'
/**
* @class SePlainBorderButton
@@ -13,7 +13,7 @@ class SePlainBorderButton extends PlainButton {
* @returns {PlainObject}
*/
get [template] () {
const result = super[template];
const result = super[template]
result.content.append(
fragmentFrom.html`
<style>
@@ -23,9 +23,9 @@ class SePlainBorderButton extends PlainButton {
}
</style>
`
);
return result;
)
return result
}
}
export default SePlainBorderButton;
export default SePlainBorderButton

View File

@@ -1,6 +1,6 @@
import PlainMenuButton from 'elix/src/plain/PlainMenuButton.js';
import { defaultState } from 'elix/src/base/internal.js';
import sePlainBorderButton from './sePlainBorderButton.js';
import PlainMenuButton from 'elix/src/plain/PlainMenuButton.js'
import { defaultState } from 'elix/src/base/internal.js'
import sePlainBorderButton from './sePlainBorderButton.js'
/**
* @class ElixMenuButton
@@ -13,8 +13,8 @@ export default class ElixMenuButton extends PlainMenuButton {
get [defaultState] () {
return Object.assign(super[defaultState], {
sourcePartType: sePlainBorderButton
});
})
}
}
customElements.define('elix-menu-button', ElixMenuButton);
customElements.define('elix-menu-button', ElixMenuButton)

View File

@@ -1,5 +1,5 @@
import { t } from '../locale.js';
const template = document.createElement('template');
import { t } from '../locale.js'
const template = document.createElement('template')
template.innerHTML = `
<style>
select {
@@ -21,7 +21,7 @@ label {
<select>
</select>
`;
`
/**
* @class SeList
*/
@@ -30,19 +30,20 @@ export class SeSelect extends HTMLElement {
* @function constructor
*/
constructor () {
super();
super()
// create the shadowDom and insert the template
this._shadowRoot = this.attachShadow({ mode: 'open' });
this._shadowRoot.append(template.content.cloneNode(true));
this.$select = this._shadowRoot.querySelector('select');
this.$label = this._shadowRoot.querySelector('label');
this._shadowRoot = this.attachShadow({ mode: 'open' })
this._shadowRoot.append(template.content.cloneNode(true))
this.$select = this._shadowRoot.querySelector('select')
this.$label = this._shadowRoot.querySelector('label')
}
/**
* @function observedAttributes
* @returns {any} observed
*/
static get observedAttributes () {
return [ 'label', 'width', 'height', 'options', 'values', 'title', 'disabled' ];
return ['label', 'width', 'height', 'options', 'values', 'title', 'disabled']
}
/**
@@ -53,64 +54,63 @@ export class SeSelect extends HTMLElement {
* @returns {void}
*/
attributeChangedCallback (name, oldValue, newValue) {
let options;
if (oldValue === newValue) return;
let options
if (oldValue === newValue) return
switch (name) {
case 'label':
this.$label.textContent = t(newValue);
break;
case 'title':
this.$select.setAttribute("title", t(newValue));
break;
case 'disabled':
if(newValue === null) {
this.$select.removeAttribute("disabled");
} else {
this.$select.setAttribute("disabled", newValue);
}
break;
case 'height':
this.$select.style.height = newValue;
break;
case 'width':
this.$select.style.width = newValue;
break;
case 'options':
if(newValue === "") {
while(this.$select.firstChild)
this.$select.removeChild(this.$select.firstChild);
} else {
options = newValue.split(',');
options.forEach((option) => {
const optionNode = document.createElement("OPTION");
const text = document.createTextNode(t(option));
optionNode.appendChild(text);
this.$select.appendChild(optionNode);
});
}
break;
case 'values':
if(newValue === "") {
while(this.$select.firstChild)
this.$select.removeChild(this.$select.firstChild);
} else {
options = newValue.split('::');
options.forEach((option, index) => {
this.$select.children[index].setAttribute('value', option);
});
}
break;
default:
console.error(`unknown attribute: ${name}`);
break;
case 'label':
this.$label.textContent = t(newValue)
break
case 'title':
this.$select.setAttribute('title', t(newValue))
break
case 'disabled':
if (newValue === null) {
this.$select.removeAttribute('disabled')
} else {
this.$select.setAttribute('disabled', newValue)
}
break
case 'height':
this.$select.style.height = newValue
break
case 'width':
this.$select.style.width = newValue
break
case 'options':
if (newValue === '') {
while (this.$select.firstChild) { this.$select.removeChild(this.$select.firstChild) }
} else {
options = newValue.split(',')
options.forEach((option) => {
const optionNode = document.createElement('OPTION')
const text = document.createTextNode(t(option))
optionNode.appendChild(text)
this.$select.appendChild(optionNode)
})
}
break
case 'values':
if (newValue === '') {
while (this.$select.firstChild) { this.$select.removeChild(this.$select.firstChild) }
} else {
options = newValue.split('::')
options.forEach((option, index) => {
this.$select.children[index].setAttribute('value', option)
})
}
break
default:
console.error(`unknown attribute: ${name}`)
break
}
}
/**
* @function get
* @returns {any}
*/
get label () {
return this.getAttribute('label');
return this.getAttribute('label')
}
/**
@@ -118,14 +118,15 @@ export class SeSelect extends HTMLElement {
* @returns {void}
*/
set label (value) {
this.setAttribute('label', value);
this.setAttribute('label', value)
}
/**
* @function get
* @returns {any}
*/
get width () {
return this.getAttribute('width');
return this.getAttribute('width')
}
/**
@@ -133,14 +134,15 @@ export class SeSelect extends HTMLElement {
* @returns {void}
*/
set width (value) {
this.setAttribute('width', value);
this.setAttribute('width', value)
}
/**
* @function get
* @returns {any}
*/
get height () {
return this.getAttribute('height');
return this.getAttribute('height')
}
/**
@@ -148,14 +150,15 @@ export class SeSelect extends HTMLElement {
* @returns {void}
*/
set height (value) {
this.setAttribute('height', value);
this.setAttribute('height', value)
}
/**
* @function get
* @returns {any}
*/
get value () {
return this.$select.value;
return this.$select.value
}
/**
@@ -163,14 +166,15 @@ export class SeSelect extends HTMLElement {
* @returns {void}
*/
set value (value) {
this.$select.value = value;
this.$select.value = value
}
/**
* @function get
* @returns {any}
*/
get disabled () {
return this.$select.getAttribute('disabled');
return this.$select.getAttribute('disabled')
}
/**
@@ -178,22 +182,23 @@ export class SeSelect extends HTMLElement {
* @returns {void}
*/
set disabled (value) {
this.$select.setAttribute('disabled', value);
this.$select.setAttribute('disabled', value)
}
/**
* @function connectedCallback
* @returns {void}
*/
connectedCallback () {
const currentObj = this;
const currentObj = this
this.$select.addEventListener('change', () => {
const value = this.$select.value;
const closeEvent = new CustomEvent('change', { detail: { value } });
currentObj.dispatchEvent(closeEvent);
currentObj.value = value;
});
const value = this.$select.value
const closeEvent = new CustomEvent('change', { detail: { value } })
currentObj.dispatchEvent(closeEvent)
currentObj.value = value
})
}
}
// Register
customElements.define('se-select', SeSelect);
customElements.define('se-select', SeSelect)

View File

@@ -1,8 +1,8 @@
/* globals svgEditor */
import '../dialogs/se-elix/define/NumberSpinBox.js';
import { t } from '../locale.js';
import '../dialogs/se-elix/define/NumberSpinBox.js'
import { t } from '../locale.js'
const template = document.createElement('template');
const template = document.createElement('template')
template.innerHTML = `
<style>
div {
@@ -49,7 +49,7 @@ template.innerHTML = `
<span id="label">label</span>
<elix-number-spin-box min="1" step="1"></elix-number-spin-box>
</div>
`;
`
/**
* @class SESpinInput
@@ -59,25 +59,27 @@ export class SESpinInput extends HTMLElement {
* @function constructor
*/
constructor () {
super();
super()
// create the shadowDom and insert the template
this._shadowRoot = this.attachShadow({ mode: 'open' });
this._shadowRoot.append(template.content.cloneNode(true));
this._shadowRoot = this.attachShadow({ mode: 'open' })
this._shadowRoot.append(template.content.cloneNode(true))
// locate the component
this.$div = this._shadowRoot.querySelector('div');
this.$img = this._shadowRoot.querySelector('img');
this.$label = this.shadowRoot.getElementById('label');
this.$event = new CustomEvent('change');
this.$input = this._shadowRoot.querySelector('elix-number-spin-box');
this.imgPath = svgEditor.configObj.curConfig.imgPath;
this.$div = this._shadowRoot.querySelector('div')
this.$img = this._shadowRoot.querySelector('img')
this.$label = this.shadowRoot.getElementById('label')
this.$event = new CustomEvent('change')
this.$input = this._shadowRoot.querySelector('elix-number-spin-box')
this.imgPath = svgEditor.configObj.curConfig.imgPath
}
/**
* @function observedAttributes
* @returns {any} observed
*/
static get observedAttributes () {
return [ 'value', 'label', 'src', 'size', 'min', 'max', 'step', 'title' ];
return ['value', 'label', 'src', 'size', 'min', 'max', 'step', 'title']
}
/**
* @function attributeChangedCallback
* @param {string} name
@@ -86,52 +88,53 @@ export class SESpinInput extends HTMLElement {
* @returns {void}
*/
attributeChangedCallback (name, oldValue, newValue) {
if (oldValue === newValue) return;
if (oldValue === newValue) return
switch (name) {
case 'title':
{
const shortcut = this.getAttribute('shortcut');
this.$div.setAttribute('title', `${t(newValue)} ${shortcut ? `[${t(shortcut)}]` : ''}`);
}
break;
case 'src':
this.$img.setAttribute('src', this.imgPath + '/' + newValue);
this.$label.remove();
this.$div.classList.add('imginside');
break;
case 'size':
case 'title':
{
const shortcut = this.getAttribute('shortcut')
this.$div.setAttribute('title', `${t(newValue)} ${shortcut ? `[${t(shortcut)}]` : ''}`)
}
break
case 'src':
this.$img.setAttribute('src', this.imgPath + '/' + newValue)
this.$label.remove()
this.$div.classList.add('imginside')
break
case 'size':
// access to the underlying input box
this.$input.shadowRoot.getElementById('input').size = newValue;
// below seems mandatory to override the default width style that takes precedence on size
this.$input.shadowRoot.getElementById('input').style.width = 'unset';
break;
case 'step':
this.$input.setAttribute('step', newValue);
break;
case 'min':
this.$input.setAttribute('min', newValue);
break;
case 'max':
this.$input.setAttribute('max', newValue);
break;
case 'label':
this.$label.textContent = t(newValue);
this.$img.remove();
break;
case 'value':
this.$input.value = newValue;
break;
default:
console.error(`unknown attribute: ${name}`);
break;
this.$input.shadowRoot.getElementById('input').size = newValue
// below seems mandatory to override the default width style that takes precedence on size
this.$input.shadowRoot.getElementById('input').style.width = 'unset'
break
case 'step':
this.$input.setAttribute('step', newValue)
break
case 'min':
this.$input.setAttribute('min', newValue)
break
case 'max':
this.$input.setAttribute('max', newValue)
break
case 'label':
this.$label.textContent = t(newValue)
this.$img.remove()
break
case 'value':
this.$input.value = newValue
break
default:
console.error(`unknown attribute: ${name}`)
break
}
}
/**
* @function get
* @returns {any}
*/
get title () {
return this.getAttribute('title');
return this.getAttribute('title')
}
/**
@@ -139,14 +142,15 @@ export class SESpinInput extends HTMLElement {
* @returns {void}
*/
set title (value) {
this.setAttribute('title', value);
this.setAttribute('title', value)
}
/**
* @function get
* @returns {any}
*/
get label () {
return this.getAttribute('label');
return this.getAttribute('label')
}
/**
@@ -154,14 +158,15 @@ export class SESpinInput extends HTMLElement {
* @returns {void}
*/
set label (value) {
this.setAttribute('label', value);
this.setAttribute('label', value)
}
/**
* @function get
* @returns {any}
*/
get value () {
return this.$input.value;
return this.$input.value
}
/**
@@ -169,14 +174,15 @@ export class SESpinInput extends HTMLElement {
* @returns {void}
*/
set value (value) {
this.$input.value = value;
this.$input.value = value
}
/**
* @function get
* @returns {any}
*/
get src () {
return this.getAttribute('src');
return this.getAttribute('src')
}
/**
@@ -184,7 +190,7 @@ export class SESpinInput extends HTMLElement {
* @returns {void}
*/
set src (value) {
this.setAttribute('src', value);
this.setAttribute('src', value)
}
/**
@@ -192,7 +198,7 @@ export class SESpinInput extends HTMLElement {
* @returns {any}
*/
get size () {
return this.getAttribute('size');
return this.getAttribute('size')
}
/**
@@ -200,7 +206,7 @@ export class SESpinInput extends HTMLElement {
* @returns {void}
*/
set size (value) {
this.setAttribute('size', value);
this.setAttribute('size', value)
}
/**
@@ -208,31 +214,31 @@ export class SESpinInput extends HTMLElement {
* @returns {void}
*/
connectedCallback () {
const shadow = this.$input.shadowRoot;
const childNodes = Array.from(shadow.childNodes);
childNodes.forEach( (childNode) => {
if(childNode?.id === "input") {
const shadow = this.$input.shadowRoot
const childNodes = Array.from(shadow.childNodes)
childNodes.forEach((childNode) => {
if (childNode?.id === 'input') {
childNode.addEventListener('keyup', (e) => {
e.preventDefault();
e.preventDefault()
if (!isNaN(e.target.value)) {
this.value = e.target.value;
this.dispatchEvent(this.$event);
this.value = e.target.value
this.dispatchEvent(this.$event)
}
});
})
}
});
})
this.$input.addEventListener('change', (e) => {
e.preventDefault();
this.value = e.target.value;
this.dispatchEvent(this.$event);
});
e.preventDefault()
this.value = e.target.value
this.dispatchEvent(this.$event)
})
this.$input.addEventListener('click', (e) => {
e.preventDefault();
this.value = e.target.value;
this.dispatchEvent(this.$event);
});
e.preventDefault()
this.value = e.target.value
this.dispatchEvent(this.$event)
})
}
}
// Register
customElements.define('se-spin-input', SESpinInput);
customElements.define('se-spin-input', SESpinInput)

View File

@@ -1,5 +1,5 @@
import { t } from '../locale.js';
const template = document.createElement('template');
import { t } from '../locale.js'
const template = document.createElement('template')
template.innerHTML = `
<style>
#layersLabel {
@@ -9,7 +9,7 @@ template.innerHTML = `
}
</style>
<div></div>
`;
`
/**
* @class SeText
*/
@@ -18,20 +18,22 @@ export class SeText extends HTMLElement {
* @function constructor
*/
constructor () {
super();
super()
// create the shadowDom and insert the template
this._shadowRoot = this.attachShadow({ mode: 'open' });
this._shadowRoot.append(template.content.cloneNode(true));
this._shadowRoot = this.attachShadow({ mode: 'open' })
this._shadowRoot.append(template.content.cloneNode(true))
// locate the component
this.$div = this._shadowRoot.querySelector('div');
this.$div = this._shadowRoot.querySelector('div')
}
/**
* @function observedAttributes
* @returns {any} observed
*/
static get observedAttributes () {
return [ 'text', 'value', 'style', 'title', 'id' ];
return ['text', 'value', 'style', 'title', 'id']
}
/**
* @function attributeChangedCallback
* @param {string} name
@@ -40,35 +42,36 @@ export class SeText extends HTMLElement {
* @returns {void}
*/
attributeChangedCallback (name, oldValue, newValue) {
if (oldValue === newValue) return;
if (oldValue === newValue) return
switch (name) {
case 'text':
this.$div.textContent = t(newValue);
break;
case 'title':
this.$div.setAttribute("title", t(newValue));
break;
case 'style':
this.$div.style = newValue;
break;
case 'id':
this.$div.id = newValue;
break;
case 'value':
this.$div.value = newValue;
//this.$div.setAttribute("value", newValue);
break;
default:
console.error(`unknown attribute: ${name}`);
break;
case 'text':
this.$div.textContent = t(newValue)
break
case 'title':
this.$div.setAttribute('title', t(newValue))
break
case 'style':
this.$div.style = newValue
break
case 'id':
this.$div.id = newValue
break
case 'value':
this.$div.value = newValue
// this.$div.setAttribute("value", newValue);
break
default:
console.error(`unknown attribute: ${name}`)
break
}
}
/**
* @function get
* @returns {any}
*/
get text () {
return this.$div.textContent;
return this.$div.textContent
}
/**
@@ -76,14 +79,15 @@ export class SeText extends HTMLElement {
* @returns {void}
*/
set text (value) {
this.$div.setAttribute("title", t(value));
this.$div.setAttribute('title', t(value))
}
/**
* @function get
* @returns {any}
*/
get value () {
return this.value;
return this.value
}
/**
@@ -91,14 +95,15 @@ export class SeText extends HTMLElement {
* @returns {void}
*/
set value (value) {
this.value = value;
this.value = value
}
/**
* @function get
* @returns {any}
*/
get title () {
return this.getAttribute('title');
return this.getAttribute('title')
}
/**
@@ -106,8 +111,9 @@ export class SeText extends HTMLElement {
* @returns {void}
*/
set title (value) {
this.setAttribute('title', value);
this.setAttribute('title', value)
}
/**
* @function connectedCallback
* @returns {void}
@@ -118,4 +124,4 @@ export class SeText extends HTMLElement {
}
// Register
customElements.define('se-text', SeText);
customElements.define('se-text', SeText)

View File

@@ -1,8 +1,8 @@
/* globals svgEditor */
import ListComboBox from 'elix/define/ListComboBox.js';
import * as internal from 'elix/src/base/internal.js';
import { templateFrom, fragmentFrom } from 'elix/src/core/htmlLiterals.js';
import NumberSpinBox from '../dialogs/se-elix/define/NumberSpinBox.js';
import ListComboBox from 'elix/define/ListComboBox.js'
import * as internal from 'elix/src/base/internal.js'
import { templateFrom, fragmentFrom } from 'elix/src/core/htmlLiterals.js'
import NumberSpinBox from '../dialogs/se-elix/define/NumberSpinBox.js'
/**
* @class Dropdown
@@ -17,20 +17,21 @@ class Zoom extends ListComboBox {
inputPartType: NumberSpinBox,
src: 'logo.svg',
inputsize: '100%'
});
})
}
/**
* @function get
* @returns {PlainObject}
*/
get [internal.template] () {
const result = super[internal.template];
const source = result.content.getElementById('source');
const result = super[internal.template]
const source = result.content.getElementById('source')
// add a icon before our dropdown
source.prepend(fragmentFrom.html`
<img src="zoom" alt="icon" width="18" height="18">
</img>
`.cloneNode(true));
`.cloneNode(true))
// change the style so it fits in our toolbar
result.content.append(
templateFrom.html`
@@ -57,16 +58,18 @@ class Zoom extends ListComboBox {
</style>
`.content
);
return result;
)
return result
}
/**
* @function observedAttributes
* @returns {any} observed
*/
static get observedAttributes () {
return [ 'title', 'src', 'inputsize', 'value' ];
return ['title', 'src', 'inputsize', 'value']
}
/**
* @function attributeChangedCallback
* @param {string} name
@@ -75,97 +78,104 @@ class Zoom extends ListComboBox {
* @returns {void}
*/
attributeChangedCallback (name, oldValue, newValue) {
if (oldValue === newValue && name !== "src") return;
if (oldValue === newValue && name !== 'src') return
switch (name) {
case 'title':
case 'title':
// this.$span.setAttribute('title', `${newValue} ${shortcut ? `[${shortcut}]` : ''}`);
break;
case 'src':
{
const { imgPath } = svgEditor.configObj.curConfig;
this.src = imgPath + '/' + newValue;
}
break;
case 'inputsize':
this.inputsize = newValue;
break;
default:
super.attributeChangedCallback(name, oldValue, newValue);
break;
break
case 'src':
{
const { imgPath } = svgEditor.configObj.curConfig
this.src = imgPath + '/' + 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);
super[internal.render](changed)
if (this[internal.firstRender]) {
this.$img = this.shadowRoot.querySelector('img');
this.$input = this.shadowRoot.getElementById('input');
this.$img = this.shadowRoot.querySelector('img')
this.$input = this.shadowRoot.getElementById('input')
}
if (changed.src) {
this.$img.setAttribute('src', this[internal.state].src);
this.$img.setAttribute('src', this[internal.state].src)
}
if (changed.inputsize) {
this.$input.shadowRoot.querySelector('[part~="input"]').style.width = this[internal.state].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');
e.preventDefault()
const value = e.detail?.closeResult?.getAttribute('value')
if (value) {
const closeEvent = new CustomEvent('change', { detail: { value } });
this.dispatchEvent(closeEvent);
const closeEvent = new CustomEvent('change', { detail: { value } })
this.dispatchEvent(closeEvent)
}
});
})
}
}
/**
* @function src
* @returns {string} src
*/
get src () {
return this[internal.state].src;
return this[internal.state].src
}
/**
* @function src
* @returns {void}
*/
set src (src) {
this[internal.setState]({ src });
this[internal.setState]({ src })
}
/**
* @function inputsize
* @returns {string} src
*/
get inputsize () {
return this[internal.state].inputsize;
return this[internal.state].inputsize
}
/**
* @function src
* @returns {void}
*/
set inputsize (inputsize) {
this[internal.setState]({ inputsize });
this[internal.setState]({ inputsize })
}
/**
* @function value
* @returns {string} src
*/
get value () {
return this[internal.state].value;
return this[internal.state].value
}
/**
* @function value
* @returns {void}
*/
set value (value) {
this[internal.setState]({ value });
this[internal.setState]({ value })
}
}
// Register
customElements.define('se-zoom', Zoom);
customElements.define('se-zoom', Zoom)