1
0
mirror of https://github.com/jaandrle/deka-dom-el synced 2024-11-24 17:39:36 +01:00

SVGElement (.apend), attrs handling in assing

This commit is contained in:
Jan Andrle 2023-09-21 16:25:36 +02:00
parent d20e2041f6
commit eb68fff211
Signed by: jaandrle
GPG Key ID: B3A25AED155AFFAB
3 changed files with 15 additions and 13 deletions

View File

@ -1,4 +1,4 @@
[ HTMLElement, DocumentFragment ].forEach(c=> { [ HTMLElement, SVGElement, DocumentFragment ].forEach(c=> {
const { append }= c.prototype; const { append }= c.prototype;
c.prototype.append= function(...els){ append.apply(this, els); return this; }; c.prototype.append= function(...els){ append.apply(this, els); return this; };
}); });

View File

@ -12,6 +12,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);
if(obj instanceof HTMLElement && obj.getAttribute(prop)==="undefined") if(obj instanceof HTMLElement && obj.getAttribute(prop)==="undefined")
return obj.removeAttribute(prop); return obj.removeAttribute(prop);
if(Reflect.get(obj, prop)==="undefined") if(Reflect.get(obj, prop)==="undefined")

View File

@ -44,26 +44,26 @@ export function assign(element, ...attributes){
const is_svg= element instanceof SVGElement; const is_svg= element instanceof SVGElement;
const setRemoveAttr= (is_svg ? setRemoveNS : setRemove).bind(null, element, "Attribute"); const setRemoveAttr= (is_svg ? setRemoveNS : setRemove).bind(null, element, "Attribute");
/* jshint maxcomplexity:17 */ /* jshint maxcomplexity:13 */
Object.entries(Object.assign({}, ...attributes)).forEach(function assignNth([ key, attr ]){ Object.entries(Object.assign({}, ...attributes)).forEach(function assignNth([ key, attr ]){
attr= s.processReactiveAttribute(element, key, attr, assignNth); attr= s.processReactiveAttribute(element, key, attr, assignNth);
const [ k ]= key; const [ k ]= key;
if("="===k) return setRemoveAttr(key.slice(1), attr); if("="===k) return setRemoveAttr(key.slice(1), attr);
if("."===k) return setDelete(element, key.slice(1), attr); if("."===k) return setDelete(element, key.slice(1), attr);
if(/(aria|data)([A-Z])/.test(key)){ if(/(aria|data)([A-Z])/.test(key)){//TODO: temporal as aria* exists in Element for some browsers
key= key.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(); key= key.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
return setRemoveAttr(key, attr); return setRemoveAttr(key, attr);
} }
if("className"===key) key= "class"; if("className"===key) key= "class";//just optimalization, `isPropSetter` returns false immediately
switch(key){ switch(key){
case "href": case "src": case "class":
return setRemoveAttr(key, attr);
case "xlink:href": case "xlink:href":
return setRemoveAttr(key, attr, "http://www.w3.org/1999/xlink"); return setRemoveAttr(key, attr, "http://www.w3.org/1999/xlink");
case "textContent": case "innerText": case "textContent": //just optimalization, its part of Node ⇒ deep for `isPropSetter`
if(!is_svg) return setDeleteAttr(element, key, attr); return setDeleteAttr(element, key, attr);
return element.appendChild(document.createTextNode(attr)); case "style":
case "style": case "dataset": if(typeof attr!=="object") break;
/* falls through */
case "dataset":
return forEachEntries(s, attr, setDelete.bind(null, element[key])); return forEachEntries(s, attr, setDelete.bind(null, element[key]));
case "ariaset": case "ariaset":
return forEachEntries(s, attr, (key, val)=> setRemoveAttr("aria-"+key, val)); return forEachEntries(s, attr, (key, val)=> setRemoveAttr("aria-"+key, val));
@ -86,22 +86,23 @@ export function empty(el){
return el; return el;
} }
import { isUndef } from "./helpers.js"; import { isUndef } from "./helpers.js";
//TODO add cache? `Map<el.tagName+key,isUndef>`
function isPropSetter(el, key){ function isPropSetter(el, key){
if(!Reflect.has(el, key)) return false; if(!Reflect.has(el, key)) return false;
const des= getPropDescriptor(el, key); const des= getPropDescriptor(el, key);
return !isUndef(des.set); return !isUndef(des.set);
} }
function getPropDescriptor(p, key, level= 0){ function getPropDescriptor(p, key){
p= Object.getPrototypeOf(p); p= Object.getPrototypeOf(p);
if(!p) return {}; if(!p) return {};
const des= Object.getOwnPropertyDescriptor(p, key); const des= Object.getOwnPropertyDescriptor(p, key);
if(!des) return getPropDescriptor(p, key, level+1); if(!des) return getPropDescriptor(p, key);
return des; return des;
} }
/** @template {Record<any, any>} T @param {object} s @param {T} obj @param {(param: [ keyof T, T[keyof T] ])=> void} cb */ /** @template {Record<any, any>} T @param {object} s @param {T} obj @param {(param: [ keyof T, T[keyof T] ])=> void} cb */
function forEachEntries(s, obj, cb){ function forEachEntries(s, obj, cb){
if(typeof obj !== "object") return; if(typeof obj !== "object" || obj===null) return;
return Object.entries(obj).forEach(function process([ key, val ]){ return Object.entries(obj).forEach(function process([ key, val ]){
if(!key) return; if(!key) return;
val= s.processReactiveAttribute(obj, key, val, a=> cb(...a)); val= s.processReactiveAttribute(obj, key, val, a=> cb(...a));