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

♻️ split assign to assign and assignAttribute

This commit is contained in:
Jan Andrle 2023-10-15 11:12:06 +02:00
parent 7d4cc29174
commit f08d495a5c
Signed by: jaandrle
GPG Key ID: B3A25AED155AFFAB
3 changed files with 48 additions and 36 deletions

View File

@ -69,42 +69,54 @@ export { createElement as el };
import { prop_process } from './dom-common.js'; import { prop_process } from './dom-common.js';
const { setDeleteAttr }= prop_process; const { setDeleteAttr }= prop_process;
const assign_context= new WeakMap();
export function assign(element, ...attributes){ export function assign(element, ...attributes){
const _this= this;
const s= signals(this);
if(!attributes.length) return element; if(!attributes.length) return element;
const is_svg= element instanceof SVGElement; assign_context.set(element, assignContext(element, this));
const setRemoveAttr= (is_svg ? setRemoveNS : setRemove).bind(null, element, "Attribute");
/* jshint maxcomplexity:13 */ for(const [ key, value ] of Object.entries(Object.assign({}, ...attributes)))
Object.entries(Object.assign({}, ...attributes)).forEach(function assignNth([ key, attr ]){ assignAttribute.call(this, element, key, value);
attr= s.processReactiveAttribute(element, key, attr, assignNth); assign_context.delete(element);
return element;
}
export function assignAttribute(element, key, value){
/* jshint maxcomplexity:14 */
const { setRemoveAttr, s }= assignContext(element, this);
const _this= this;
value= s.processReactiveAttribute(element, key, value,
(key, value)=> assignAttribute.call(_this, element, key, value));
const [ k ]= key; const [ k ]= key;
if("="===k) return setRemoveAttr(key.slice(1), attr); if("="===k) return setRemoveAttr(key.slice(1), value);
if("."===k) return setDelete(element, key.slice(1), attr); if("."===k) return setDelete(element, key.slice(1), value);
if(/(aria|data)([A-Z])/.test(key)){//TODO: temporal as aria* exists in Element for some browsers 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, value);
} }
if("className"===key) key= "class";//just optimalization, `isPropSetter` returns false immediately if("className"===key) key= "class";//just optimalization, `isPropSetter` returns false immediately
switch(key){ switch(key){
case "xlink:href": case "xlink:href":
return setRemoveAttr(key, attr, "http://www.w3.org/1999/xlink"); return setRemoveAttr(key, value, "http://www.w3.org/1999/xlink");
case "textContent": //just optimalization, its part of Node ⇒ deep for `isPropSetter` case "textContent": //just optimalization, its part of Node ⇒ deep for `isPropSetter`
return setDeleteAttr(element, key, attr); return setDeleteAttr(element, key, value);
case "style": case "style":
if(typeof attr!=="object") break; if(typeof value!=="object") break;
/* falls through */ /* falls through */
case "dataset": case "dataset":
return forEachEntries(s, attr, setDelete.bind(null, element[key])); return forEachEntries(s, value, setDelete.bind(null, element[key]));
case "ariaset": case "ariaset":
return forEachEntries(s, attr, (key, val)=> setRemoveAttr("aria-"+key, val)); return forEachEntries(s, value, (key, val)=> setRemoveAttr("aria-"+key, val));
case "classList": case "classList":
return classListDeclarative.call(_this, element, attr); return classListDeclarative.call(_this, element, value);
} }
return isPropSetter(element, key) ? setDeleteAttr(element, key, attr) : setRemoveAttr(key, attr); return isPropSetter(element, key) ? setDeleteAttr(element, key, value) : setRemoveAttr(key, value);
}); }
return element; function assignContext(element, _this){
if(assign_context.has(element)) return assign_context.get(element);
const is_svg= element instanceof SVGElement;
const setRemoveAttr= (is_svg ? setRemoveNS : setRemove).bind(null, element, "Attribute");
const s= signals(_this);
return { setRemoveAttr, s };
} }
export function classListDeclarative(element, toggle){ export function classListDeclarative(element, toggle){
const s= signals(this); const s= signals(this);
@ -137,7 +149,7 @@ function forEachEntries(s, obj, cb){
if(typeof obj !== "object" || obj===null) 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, cb);
cb(key, val); cb(key, val);
}); });
} }

View File

@ -1,6 +1,6 @@
export const signals_global= { export const signals_global= {
isSignal(attributes){ return false; }, isSignal(attributes){ return false; },
processReactiveAttribute(obj, key, attr, assignNth){ return attr; }, processReactiveAttribute(obj, key, attr, set){ return attr; },
}; };
export function registerReactivity(def, global= true){ export function registerReactivity(def, global= true){
if(global) return Object.assign(signals_global, def); if(global) return Object.assign(signals_global, def);

View File

@ -107,9 +107,9 @@ S.el= function(signal, map){
import { typeOf } from './helpers.js'; import { typeOf } from './helpers.js';
export const signals_config= { export const signals_config= {
isSignal, isSignal,
processReactiveAttribute(_, key, attrs, assignNth){ processReactiveAttribute(_, key, attrs, set){
if(!isSignal(attrs)) return attrs; if(!isSignal(attrs)) return attrs;
const l= attr=> assignNth([ key, attr ]); const l= attr=> set(key, attr);
addSignalListener(attrs, l); addSignalListener(attrs, l);
removeSignalsFromElements(attrs, l, _, key); removeSignalsFromElements(attrs, l, _, key);
return attrs(); return attrs();