mirror of
https://github.com/jaandrle/deka-dom-el
synced 2024-12-04 12:53:55 +01:00
cross-platform using enviroment
(#14)
* 🎉 * Dev bugs@v0.7.6 (#12) * Update observables-lib.js * `collectChildren` * Update todosComponent.js * 🚀 filter for `collectChildren` * finalization
This commit is contained in:
parent
d2ddaaec6f
commit
5e7f7558b5
32
dist/dde-with-observables.js
vendored
32
dist/dde-with-observables.js
vendored
File diff suppressed because one or more lines are too long
22
dist/dde.js
vendored
22
dist/dde.js
vendored
File diff suppressed because one or more lines are too long
8
dist/esm-with-observables.js
vendored
8
dist/esm-with-observables.js
vendored
File diff suppressed because one or more lines are too long
2
dist/esm.js
vendored
2
dist/esm.js
vendored
File diff suppressed because one or more lines are too long
8
jsdom.d.ts
vendored
8
jsdom.d.ts
vendored
@ -1,5 +1,13 @@
|
|||||||
import { el, assign, on } from "./index.d";
|
import { el, assign, on } from "./index.d";
|
||||||
export * from "./index.d";
|
export * from "./index.d";
|
||||||
|
type JSDOM= {
|
||||||
|
window: Window,
|
||||||
|
document: Document,
|
||||||
|
HTMLElement: typeof HTMLElement,
|
||||||
|
SVGElement: typeof SVGElement,
|
||||||
|
DocumentFragment: typeof DocumentFragment,
|
||||||
|
MutationObserver?: typeof MutationObserver
|
||||||
|
};
|
||||||
export function register(dom: JSDOM): Promise<{
|
export function register(dom: JSDOM): Promise<{
|
||||||
el: typeof el,
|
el: typeof el,
|
||||||
assign: typeof assign,
|
assign: typeof assign,
|
||||||
|
24
jsdom.js
24
jsdom.js
@ -1,23 +1,25 @@
|
|||||||
//TODO: https://www.npmjs.com/package/html-element
|
//TODO: https://www.npmjs.com/package/html-element
|
||||||
import { enviroment } from './src/dom-common.js';
|
import { enviroment as env } from './src/dom-common.js';
|
||||||
enviroment.ssr= " ssr";
|
env.ssr= " ssr";
|
||||||
const { setDeleteAttr }= enviroment;
|
const { setDeleteAttr }= env;
|
||||||
/** @param {HTMLElement} obj */
|
/** @param {HTMLElement} obj */
|
||||||
enviroment.setDeleteAttr= function(obj, prop, value){
|
env.setDeleteAttr= function(obj, prop, value){
|
||||||
if("value"===prop) return obj.setAttribute(prop, value);
|
if("value"===prop) return obj.setAttribute(prop, value);
|
||||||
if("checked"!==prop) return setDeleteAttr(obj, prop, value);
|
if("checked"!==prop) return setDeleteAttr(obj, prop, value);
|
||||||
if(value) return obj.setAttribute(prop, "");
|
if(value) return obj.setAttribute(prop, "");
|
||||||
obj.removeAttribute(prop);
|
obj.removeAttribute(prop);
|
||||||
};
|
};
|
||||||
const keys= [ "HTMLElement", "SVGElement", "DocumentFragment", "MutationObserver", "document" ];
|
const keys= { H: "HTMLElement", S: "SVGElement", F: "DocumentFragment", M: "MutationObserver", D: "document" };
|
||||||
|
let env_bk= {};
|
||||||
let dom_last;
|
let dom_last;
|
||||||
|
|
||||||
export function register(dom, keys_aditional= []){
|
export function register(dom){
|
||||||
if(dom_last!==dom){
|
if(dom_last!==dom){
|
||||||
keys.push(...keys_aditional);
|
|
||||||
const w= dom.window;
|
const w= dom.window;
|
||||||
keys.forEach(key=> globalThis[key]= w[key]);
|
Object.entries(keys).forEach(([ kE, kW ])=> {
|
||||||
globalThis.window= w;
|
env_bk[kE]= env[kE];
|
||||||
|
env[kE]= w[kW];
|
||||||
|
});
|
||||||
w.console= globalThis.console;
|
w.console= globalThis.console;
|
||||||
}
|
}
|
||||||
dom_last= dom;
|
dom_last= dom;
|
||||||
@ -28,8 +30,8 @@ export function unregister(){
|
|||||||
if(!dom_last)
|
if(!dom_last)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
keys.forEach(key=> Reflect.deleteProperty(globalThis, key));
|
Object.assign(env, env_bk);
|
||||||
Reflect.deleteProperty(globalThis, "window");
|
env_bk= {};
|
||||||
dom_last= undefined;
|
dom_last= undefined;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
"size-limit": [
|
"size-limit": [
|
||||||
{
|
{
|
||||||
"path": "./index.js",
|
"path": "./index.js",
|
||||||
"limit": "9.9 kB",
|
"limit": "10 kB",
|
||||||
"gzip": false,
|
"gzip": false,
|
||||||
"brotli": false
|
"brotli": false
|
||||||
|
|
||||||
|
@ -1,4 +1,12 @@
|
|||||||
export const enviroment= { setDeleteAttr, ssr: "" };
|
export const enviroment= {
|
||||||
|
setDeleteAttr,
|
||||||
|
ssr: "",
|
||||||
|
D: globalThis.document,
|
||||||
|
F: globalThis.DocumentFragment,
|
||||||
|
H: globalThis.HTMLElement,
|
||||||
|
S: globalThis.SVGElement,
|
||||||
|
M: globalThis.MutationObserver,
|
||||||
|
};
|
||||||
import { isUndef } from './helpers.js';
|
import { isUndef } from './helpers.js';
|
||||||
function setDeleteAttr(obj, prop, val){
|
function setDeleteAttr(obj, prop, val){
|
||||||
/* Issue
|
/* Issue
|
||||||
@ -13,7 +21,7 @@ function setDeleteAttr(obj, prop, val){
|
|||||||
Reflect.set(obj, prop, val);
|
Reflect.set(obj, prop, val);
|
||||||
if(!isUndef(val)) return;
|
if(!isUndef(val)) return;
|
||||||
Reflect.deleteProperty(obj, prop);
|
Reflect.deleteProperty(obj, prop);
|
||||||
if(obj instanceof HTMLElement && obj.getAttribute(prop)==="undefined")
|
if(obj instanceof enviroment.H && obj.getAttribute(prop)==="undefined")
|
||||||
return obj.removeAttribute(prop);
|
return obj.removeAttribute(prop);
|
||||||
if(Reflect.get(obj, prop)==="undefined")
|
if(Reflect.get(obj, prop)==="undefined")
|
||||||
return Reflect.set(obj, prop, "");
|
return Reflect.set(obj, prop, "");
|
||||||
|
28
src/dom.js
28
src/dom.js
@ -1,10 +1,10 @@
|
|||||||
import { observables } from "./observables-common.js";
|
import { observables } from "./observables-common.js";
|
||||||
import { enviroment } from './dom-common.js';
|
import { enviroment as env } from './dom-common.js';
|
||||||
|
|
||||||
/** @type {{ scope: object, prevent: boolean, host: function }[]} */
|
/** @type {{ scope: object, prevent: boolean, host: function }[]} */
|
||||||
const scopes= [ {
|
const scopes= [ {
|
||||||
scope: document.body,
|
get scope(){ return env.D.body; },
|
||||||
host: c=> c ? c(document.body) : document.body,
|
host: c=> c ? c(env.D.body) : env.D.body,
|
||||||
custom_element: false,
|
custom_element: false,
|
||||||
prevent: true,
|
prevent: true,
|
||||||
} ];
|
} ];
|
||||||
@ -43,7 +43,7 @@ export function createElement(tag, attributes, ...addons){
|
|||||||
scoped= 1;
|
scoped= 1;
|
||||||
scope.push({ scope: tag, host: (...c)=> c.length ? (scoped===1 ? addons.unshift(...c) : c.forEach(c=> c(el_host)), undefined) : el_host });
|
scope.push({ scope: tag, host: (...c)=> c.length ? (scoped===1 ? addons.unshift(...c) : c.forEach(c=> c(el_host)), undefined) : el_host });
|
||||||
el= tag(attributes || undefined);
|
el= tag(attributes || undefined);
|
||||||
const is_fragment= el instanceof DocumentFragment;
|
const is_fragment= el instanceof env.F;
|
||||||
if(el.nodeName==="#comment") break;
|
if(el.nodeName==="#comment") break;
|
||||||
const el_mark= createElement.mark({
|
const el_mark= createElement.mark({
|
||||||
type: "component",
|
type: "component",
|
||||||
@ -54,10 +54,10 @@ export function createElement(tag, attributes, ...addons){
|
|||||||
if(is_fragment) el_host= el_mark;
|
if(is_fragment) el_host= el_mark;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tag==="#text": el= assign.call(this, document.createTextNode(""), attributes); break;
|
case tag==="#text": el= assign.call(this, env.D.createTextNode(""), attributes); break;
|
||||||
case tag==="<>" || !tag: el= assign.call(this, document.createDocumentFragment(), attributes); break;
|
case tag==="<>" || !tag: el= assign.call(this, env.D.createDocumentFragment(), attributes); break;
|
||||||
case Boolean(namespace): el= assign.call(this, document.createElementNS(namespace, tag), attributes); break;
|
case Boolean(namespace): el= assign.call(this, env.D.createElementNS(namespace, tag), attributes); break;
|
||||||
case !el: el= assign.call(this, document.createElement(tag), attributes);
|
case !el: el= assign.call(this, env.D.createElement(tag), attributes);
|
||||||
}
|
}
|
||||||
chainableAppend(el);
|
chainableAppend(el);
|
||||||
if(!el_host) el_host= el;
|
if(!el_host) el_host= el;
|
||||||
@ -76,7 +76,7 @@ export function simulateSlots(element, root= element, mapper= undefined){
|
|||||||
apply(orig, _, els){
|
apply(orig, _, els){
|
||||||
if(!els.length) return element;
|
if(!els.length) return element;
|
||||||
|
|
||||||
const d= document.createDocumentFragment();
|
const d= env.D.createDocumentFragment();
|
||||||
for(const el of els){
|
for(const el of els){
|
||||||
if(!el || !el.slot){ if(has_d) d.appendChild(el); continue; }
|
if(!el || !el.slot){ if(has_d) d.appendChild(el); continue; }
|
||||||
const name= el.slot;
|
const name= el.slot;
|
||||||
@ -113,8 +113,8 @@ function simulateSlotReplace(slot, element, mapper){
|
|||||||
createElement.mark= function(attrs, is_open= false){
|
createElement.mark= function(attrs, is_open= false){
|
||||||
attrs= Object.entries(attrs).map(([ n, v ])=> n+`="${v}"`).join(" ");
|
attrs= Object.entries(attrs).map(([ n, v ])=> n+`="${v}"`).join(" ");
|
||||||
const end= is_open ? "" : "/";
|
const end= is_open ? "" : "/";
|
||||||
const out= document.createComment(`<dde:mark ${attrs}${enviroment.ssr}${end}>`);
|
const out= env.D.createComment(`<dde:mark ${attrs}${env.ssr}${end}>`);
|
||||||
if(!is_open) out.end= document.createComment("</dde:mark>");
|
if(!is_open) out.end= env.D.createComment("</dde:mark>");
|
||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
export { createElement as el };
|
export { createElement as el };
|
||||||
@ -131,8 +131,8 @@ export function createElementNS(ns){
|
|||||||
}
|
}
|
||||||
export { createElementNS as elNS };
|
export { createElementNS as elNS };
|
||||||
|
|
||||||
const { setDeleteAttr }= enviroment;
|
|
||||||
const assign_context= new WeakMap();
|
const assign_context= new WeakMap();
|
||||||
|
const { setDeleteAttr }= env;
|
||||||
export function assign(element, ...attributes){
|
export function assign(element, ...attributes){
|
||||||
if(!attributes.length) return element;
|
if(!attributes.length) return element;
|
||||||
assign_context.set(element, assignContext(element, this));
|
assign_context.set(element, assignContext(element, this));
|
||||||
@ -175,7 +175,7 @@ export function assignAttribute(element, key, value){
|
|||||||
}
|
}
|
||||||
function assignContext(element, _this){
|
function assignContext(element, _this){
|
||||||
if(assign_context.has(element)) return assign_context.get(element);
|
if(assign_context.has(element)) return assign_context.get(element);
|
||||||
const is_svg= element instanceof SVGElement;
|
const is_svg= element instanceof env.S;
|
||||||
const setRemoveAttr= (is_svg ? setRemoveNS : setRemove).bind(null, element, "Attribute");
|
const setRemoveAttr= (is_svg ? setRemoveNS : setRemove).bind(null, element, "Attribute");
|
||||||
const s= observables(_this);
|
const s= observables(_this);
|
||||||
return { setRemoveAttr, s };
|
return { setRemoveAttr, s };
|
||||||
@ -192,7 +192,7 @@ export function empty(el){
|
|||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
export function elementAttribute(element, op, key, value){
|
export function elementAttribute(element, op, key, value){
|
||||||
if(element instanceof HTMLElement)
|
if(element instanceof env.H)
|
||||||
return element[op+"Attribute"](key, value);
|
return element[op+"Attribute"](key, value);
|
||||||
return element[op+"AttributeNS"](null, key, value);
|
return element[op+"AttributeNS"](null, key, value);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
export { registerReactivity } from './observables-common.js';
|
export { registerReactivity } from './observables-common.js';
|
||||||
|
import { enviroment as env } from './dom-common.js';
|
||||||
|
|
||||||
export function dispatchEvent(name, options, host){
|
export function dispatchEvent(name, options, host){
|
||||||
if(!options) options= {};
|
if(!options) options= {};
|
||||||
@ -18,7 +19,9 @@ export function on(event, listener, options){
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const c_ch_o= connectionsChangesObserverConstructor();
|
const c_ch_o= env.M ? connectionsChangesObserverConstructor() : new Proxy({}, {
|
||||||
|
get(){ return ()=> {}; }
|
||||||
|
});
|
||||||
const els_attribute_store= new WeakSet();
|
const els_attribute_store= new WeakSet();
|
||||||
import { scope } from "./dom.js";
|
import { scope } from "./dom.js";
|
||||||
import { onAbort } from './helpers.js';
|
import { onAbort } from './helpers.js';
|
||||||
@ -77,7 +80,9 @@ on.attributeChanged= function(listener, options){
|
|||||||
if(element.__dde_lifecycleToEvents || els_attribute_store.has(element))
|
if(element.__dde_lifecycleToEvents || els_attribute_store.has(element))
|
||||||
return element;
|
return element;
|
||||||
|
|
||||||
const observer= new MutationObserver(function(mutations){
|
if(!env.M) return element;
|
||||||
|
|
||||||
|
const observer= new env.M(function(mutations){
|
||||||
for(const { attributeName, target } of mutations)
|
for(const { attributeName, target } of mutations)
|
||||||
target.dispatchEvent(
|
target.dispatchEvent(
|
||||||
new CustomEvent(event, { detail: [ attributeName, target.getAttribute(attributeName) ] }));
|
new CustomEvent(event, { detail: [ attributeName, target.getAttribute(attributeName) ] }));
|
||||||
@ -92,7 +97,7 @@ on.attributeChanged= function(listener, options){
|
|||||||
function connectionsChangesObserverConstructor(){
|
function connectionsChangesObserverConstructor(){
|
||||||
const store= new Map();
|
const store= new Map();
|
||||||
let is_observing= false;
|
let is_observing= false;
|
||||||
const observer= new MutationObserver(function(mutations){
|
const observer= new env.M(function(mutations){
|
||||||
for(const mutation of mutations){
|
for(const mutation of mutations){
|
||||||
if(mutation.type!=="childList") continue;
|
if(mutation.type!=="childList") continue;
|
||||||
if(observerAdded(mutation.addedNodes, true)){
|
if(observerAdded(mutation.addedNodes, true)){
|
||||||
@ -155,7 +160,7 @@ function connectionsChangesObserverConstructor(){
|
|||||||
function start(){
|
function start(){
|
||||||
if(is_observing) return;
|
if(is_observing) return;
|
||||||
is_observing= true;
|
is_observing= true;
|
||||||
observer.observe(document.body, { childList: true, subtree: true });
|
observer.observe(env.D.body, { childList: true, subtree: true });
|
||||||
}
|
}
|
||||||
function stop(){
|
function stop(){
|
||||||
if(!is_observing || store.size) return;
|
if(!is_observing || store.size) return;
|
||||||
|
@ -86,12 +86,13 @@ observable.clear= function(...observables){
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const key_reactive= "__dde_reactive";
|
const key_reactive= "__dde_reactive";
|
||||||
import { el, elementAttribute } from "./dom.js";
|
import { enviroment as env } from "./dom-common.js";
|
||||||
|
import { el } from "./dom.js";
|
||||||
import { scope } from "./dom.js";
|
import { scope } from "./dom.js";
|
||||||
observable.el= function(o, map){
|
observable.el= function(o, map){
|
||||||
const mark_start= el.mark({ type: "reactive" }, false);
|
const mark_start= el.mark({ type: "reactive" }, false);
|
||||||
const mark_end= mark_start.end;
|
const mark_end= mark_start.end;
|
||||||
const out= document.createDocumentFragment();
|
const out= env.D.createDocumentFragment();
|
||||||
out.append(mark_start, mark_end);
|
out.append(mark_start, mark_end);
|
||||||
const { current }= scope;
|
const { current }= scope;
|
||||||
const reRenderReactiveElement= v=> {
|
const reRenderReactiveElement= v=> {
|
||||||
|
Loading…
Reference in New Issue
Block a user