mirror of
https://github.com/Pomax/BezierInfo-2.git
synced 2025-08-29 02:59:58 +02:00
renamed graphics-element dir
This commit is contained in:
120
docs/js/graphics-element/custom-element.js
Normal file
120
docs/js/graphics-element/custom-element.js
Normal file
@@ -0,0 +1,120 @@
|
||||
const REG_KEY = `registered as custom element`;
|
||||
|
||||
// helper function
|
||||
function NotImplemented(instance, fname) {
|
||||
console.warn(`missing implementation for ${fname}(...data) in ${instance.__proto__.constructor.name}`);
|
||||
}
|
||||
|
||||
// helper function for turning "ClassName" into "class-name"
|
||||
function getElementTagName(cls) {
|
||||
return cls.prototype.constructor.name.replace(/([A-Z])([a-z])/g, (a, b, c, d) => {
|
||||
const r = `${b.toLowerCase()}${c}`;
|
||||
return d > 0 ? `-${r}` : r;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an enrichment class to make working with custom elements
|
||||
* actually pleasant, rather than a ridiculous exercise in figuring
|
||||
* out a low-level spec.
|
||||
*/
|
||||
class CustomElement extends HTMLElement {
|
||||
static register(cls) {
|
||||
if (!cls[REG_KEY]) {
|
||||
const tagName = cls.tagName || getElementTagName(cls);
|
||||
customElements.define(tagName, cls);
|
||||
cls[REG_KEY] = true;
|
||||
return customElements.whenDefined(tagName);
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
static get tagName() {
|
||||
return getElementTagName(this);
|
||||
}
|
||||
|
||||
constructor(options = {}) {
|
||||
super();
|
||||
|
||||
if (!customElements.resolveScope) {
|
||||
customElements.resolveScope = function (scope) {
|
||||
try {
|
||||
return scope.getRootNode().host;
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
}
|
||||
return window;
|
||||
};
|
||||
}
|
||||
|
||||
this._options = options;
|
||||
|
||||
const route = {
|
||||
childList: (record) => {
|
||||
this.handleChildChanges(Array.from(record.addedNodes), Array.from(record.removedNodes));
|
||||
this.render();
|
||||
},
|
||||
attributes: (record) => {
|
||||
this.handleAttributeChange(record.attributeName, record.oldValue, this.getAttribute(record.attributeName));
|
||||
this.render();
|
||||
},
|
||||
};
|
||||
|
||||
// Set up a mutation observer because there are no custom
|
||||
// element lifecycle functions for changes to the childNodes
|
||||
// nodelist.
|
||||
|
||||
this._observer = new MutationObserver((records) => {
|
||||
if (this.isConnected) {
|
||||
records.forEach((record) => {
|
||||
// console.log(record);
|
||||
route[record.type](record);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this._observer.observe(this, {
|
||||
childList: true,
|
||||
attributes: true,
|
||||
});
|
||||
|
||||
// Set up an open shadow DOM, because the web is open,
|
||||
// and hiding your internals is ridiculous.
|
||||
|
||||
const shadowProps = { mode: `open` };
|
||||
|
||||
this._shadow = this.attachShadow(shadowProps);
|
||||
this._style = document.createElement(`style`);
|
||||
this._style.textContent = this.getStyle();
|
||||
|
||||
if (this._options.header !== false) this._header = document.createElement(`header`);
|
||||
if (this._options.slot !== false && this._options.void !== true) this._slot = document.createElement(`slot`);
|
||||
if (this._options.footer !== false) this._footer = document.createElement(`footer`);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.render();
|
||||
}
|
||||
|
||||
handleChildChanges(added, removed) {
|
||||
if (!this._options.void) NotImplemented(this, `handleChildChanges`);
|
||||
}
|
||||
|
||||
handleAttributeChange(name, oldValue, newValue) {
|
||||
NotImplemented(this, `handleAttributeChange`);
|
||||
}
|
||||
|
||||
getStyle() {
|
||||
return ``;
|
||||
}
|
||||
|
||||
render() {
|
||||
this._shadow.innerHTML = ``;
|
||||
this._shadow.append(this._style);
|
||||
if (this._options.header !== false) this._shadow.append(this._header);
|
||||
if (this._options.slot !== false) this._shadow.append(this._slot);
|
||||
if (this._options.footer !== false) this._shadow.append(this._footer);
|
||||
}
|
||||
}
|
||||
|
||||
export { CustomElement };
|
Reference in New Issue
Block a user