Skip to content

Commit

Permalink
add m-element lib
Browse files Browse the repository at this point in the history
  • Loading branch information
thipages committed Nov 4, 2024
1 parent d9fa089 commit 7fd452d
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 127 deletions.
211 changes: 116 additions & 95 deletions esm.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,111 @@
/*! (c) Andrea Giammarchi - ISC */
const HTMLParsedElement = (() => {
const DCL = 'DOMContentLoaded';
const init = new WeakMap;
const queue = [];
const isParsed = el => {
do {
if (el.nextSibling)
return true;
} while (el = el.parentNode);
return false;
};
const upgrade = () => {
queue.splice(0).forEach(info => {
if (init.get(info[0]) !== true) {
init.set(info[0], true);
info[0][info[1]]();
}
});
};
document.addEventListener(DCL, upgrade);
class HTMLParsedElement extends HTMLElement {
static withParsedCallback(Class, name = 'parsed') {
const {prototype} = Class;
const {connectedCallback} = prototype;
const method = name + 'Callback';
const cleanUp = (el, observer, ownerDocument, onDCL) => {
observer.disconnect();
ownerDocument.removeEventListener(DCL, onDCL);
parsedCallback(el);
};
const parsedCallback = el => {
if (!queue.length)
requestAnimationFrame(upgrade);
queue.push([el, method]);
};
Object.defineProperties(
prototype,
{
connectedCallback: {
configurable: true,
writable: true,
value() {
if (connectedCallback)
connectedCallback.apply(this, arguments);
if (method in this && !init.has(this)) {
const self = this;
const {ownerDocument} = self;
init.set(self, false);
if (ownerDocument.readyState === 'complete' || isParsed(self))
parsedCallback(self);
else {
const onDCL = () => cleanUp(self, observer, ownerDocument, onDCL);
ownerDocument.addEventListener(DCL, onDCL);
const observer = new MutationObserver(() => {
/* istanbul ignore else */
if (isParsed(self))
cleanUp(self, observer, ownerDocument, onDCL);
});
observer.observe(self.parentNode, {childList: true, subtree: true});
}
}
}
},
[name]: {
configurable: true,
get() {
return init.get(this) === true;
}
}
}
);
return Class;
}
}
return HTMLParsedElement.withParsedCallback(HTMLParsedElement);
})();

const isAsyncFunction = fn => fn.constructor.name === 'AsyncFunction';
const replace = (that) => {
if (that.hasAttribute('level-up')) {
that.replaceWith(...that.children);
}
};
class MElement extends HTMLParsedElement {
#config
constructor(config = {}) {
super();
this.#config = config;
}
connectedCallback() {
if (this.parsed && this.#config.oneConnect) return
super.connectedCallback();
}
parsedCallback() {
if (this.init) {
if (isAsyncFunction(this.init)) {
this.init().then (
() => replace(this)
);
} else {
this.init();
replace(this);
}
}
}
}

// Id generator
const fixedId = ('dry-'+Math.random()).replace('.', '');
let count = 1;
Expand Down Expand Up @@ -41,14 +149,11 @@ function defineCustomElement(templateId) {
const {refClone, refData, tClass} = setup(templateId);
//
customElements.define(templateId,
class extends HTMLElement {
class extends MElement {
constructor() {
super();
}
connectedCallback() {
// Avoid multiple connection when this element is deconnected
if (this.connected) return
this.connected = true;
init() {
this.style.display = 'block';
if (!this.hasAttribute('class')) this.setAttribute('class', tClass);
this.tRefs = structuredClone(refData);
Expand Down Expand Up @@ -168,97 +273,13 @@ const handler = {
*/
var fetch$1 = (input, ...init) => new Proxy(fetch(input, ...init), handler);

/*! (c) Andrea Giammarchi - ISC */
const HTMLParsedElement = (() => {
const DCL = 'DOMContentLoaded';
const init = new WeakMap;
const queue = [];
const isParsed = el => {
do {
if (el.nextSibling)
return true;
} while (el = el.parentNode);
return false;
};
const upgrade = () => {
queue.splice(0).forEach(info => {
if (init.get(info[0]) !== true) {
init.set(info[0], true);
info[0][info[1]]();
}
});
};
document.addEventListener(DCL, upgrade);
class HTMLParsedElement extends HTMLElement {
static withParsedCallback(Class, name = 'parsed') {
const {prototype} = Class;
const {connectedCallback} = prototype;
const method = name + 'Callback';
const cleanUp = (el, observer, ownerDocument, onDCL) => {
observer.disconnect();
ownerDocument.removeEventListener(DCL, onDCL);
parsedCallback(el);
};
const parsedCallback = el => {
if (!queue.length)
requestAnimationFrame(upgrade);
queue.push([el, method]);
};
Object.defineProperties(
prototype,
{
connectedCallback: {
configurable: true,
writable: true,
value() {
if (connectedCallback)
connectedCallback.apply(this, arguments);
if (method in this && !init.has(this)) {
const self = this;
const {ownerDocument} = self;
init.set(self, false);
if (ownerDocument.readyState === 'complete' || isParsed(self))
parsedCallback(self);
else {
const onDCL = () => cleanUp(self, observer, ownerDocument, onDCL);
ownerDocument.addEventListener(DCL, onDCL);
const observer = new MutationObserver(() => {
/* istanbul ignore else */
if (isParsed(self))
cleanUp(self, observer, ownerDocument, onDCL);
});
observer.observe(self.parentNode, {childList: true, subtree: true});
}
}
}
},
[name]: {
configurable: true,
get() {
return init.get(this) === true;
}
}
}
);
return Class;
}
}
return HTMLParsedElement.withParsedCallback(HTMLParsedElement);
})();

customElements.define(
'layout-m', class extends HTMLParsedElement {
'layout-m', class extends MElement {
constructor() {
super();
super({oneConnect:true});
}
parsedCallback() {
init(this).then (
() => {
if (this.hasAttribute('level-up')) {
this.replaceWith(...this.children);
}
}
);
async init() {
await initialize(this);
}
set data(d) {
const tag = this.getAttribute('template');
Expand All @@ -285,7 +306,7 @@ function allAttrs(props) {
([name, value]) => `t-${name}="${value}"`
)
}
async function init(that) {
async function initialize(that) {
const source = that.getAttribute('source');
if (!source) return
const data = await getSourceContent(source);
Expand All @@ -305,7 +326,7 @@ async function getSourceContent(source) {
}
} else {
try {
return fetch$1(source).json()
return await fetch$1(source).json()
} catch (e) {
return false
}
Expand Down
3 changes: 1 addition & 2 deletions esm.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 21 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@titsoft/layout-m",
"version": "0.4.1",
"description": "",
"version": "0.5.0",
"description": "Group template instances",
"main": "src/index.js",
"type": "module",
"scripts": {
Expand All @@ -21,9 +21,9 @@
},
"homepage": "https://github.com/thipages/layout-m#readme",
"dependencies": {
"@webreflection/fetch": "^0.1.5",
"@titsoft/dry-html": "^0.4.3",
"html-parsed-element": "^0.4.1"
"@titsoft/dry-html": "^0.5.0",
"@titsoft/m-element": "^0.2.0",
"@webreflection/fetch": "^0.1.5"
},
"devDependencies": {
"@rollup/plugin-node-resolve": "^15.3.0",
Expand Down
20 changes: 7 additions & 13 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
import {defineCustomElement} from '@titsoft/dry-html'
import fetch from '@webreflection/fetch'
import HTMLParsedElement from 'html-parsed-element'
import MElement from '@titsoft/m-element'
customElements.define(
'layout-m', class extends HTMLParsedElement {
'layout-m', class extends MElement {
constructor() {
super()
super({oneConnect:true})
}
parsedCallback() {
init(this).then (
() => {
if (this.hasAttribute('level-up')) {
this.replaceWith(...this.children)
}
}
)
async init() {
await initialize(this)
}
set data(d) {
const tag = this.getAttribute('template')
Expand All @@ -40,7 +34,7 @@ function allAttrs(props) {
([name, value]) => `t-${name}="${value}"`
)
}
async function init(that) {
async function initialize(that) {
const source = that.getAttribute('source')
if (!source) return
const data = await getSourceContent(source)
Expand All @@ -60,7 +54,7 @@ async function getSourceContent(source) {
}
} else {
try {
return fetch(source).json()
return await fetch(source).json()
} catch (e) {
return false
}
Expand Down
2 changes: 1 addition & 1 deletion test/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>layout-m Tests</title>
<script
data-imports="@titsoft/dry-html @webreflection/fetch html-parsed-element"
data-imports="@titsoft/dry-html @webreflection/fetch @titsoft/m-element"
src="https://esm.run/data-imports"
></script>
<script type="module" src="./index.js"></script>
Expand Down
Loading

0 comments on commit 7fd452d

Please sign in to comment.