mirror of
https://github.com/jaandrle/deka-dom-el
synced 2025-07-02 04:32:14 +02:00
85 lines
2.1 KiB
JavaScript
85 lines
2.1 KiB
JavaScript
import { enviroment as env } from './common.js';
|
|
import { oAssign } from "../helpers.js";
|
|
import { on } from "./events.js";
|
|
|
|
/**
|
|
* Array of scope contexts for tracking component hierarchies
|
|
* @type {{ scope: object, prevent: boolean, host: function }[]}
|
|
*/
|
|
const scopes= [ {
|
|
get scope(){ return env.D.body; },
|
|
host: c=> c ? c(env.D.body) : env.D.body,
|
|
prevent: true,
|
|
} ];
|
|
/** Store for disconnect abort controllers */
|
|
const store_abort= new WeakMap();
|
|
/**
|
|
* Scope management utility for tracking component hierarchies
|
|
*/
|
|
export const scope= {
|
|
/**
|
|
* Gets the current scope
|
|
* @returns {Object} Current scope context
|
|
*/
|
|
get current(){ return scopes[scopes.length-1]; },
|
|
|
|
/**
|
|
* Gets the host element of the current scope
|
|
* @returns {Function} Host accessor function
|
|
*/
|
|
get host(){ return this.current.host; },
|
|
|
|
/**
|
|
* Creates/gets an AbortController that triggers when the element disconnects
|
|
* */
|
|
get signal(){
|
|
const { host }= this;
|
|
if(store_abort.has(host)) return store_abort.get(host);
|
|
|
|
const a= new AbortController();
|
|
store_abort.set(host, a);
|
|
host(on.disconnected(()=> a.abort()));
|
|
return a.signal;
|
|
},
|
|
|
|
/**
|
|
* Prevents default behavior in the current scope
|
|
* @returns {Object} Current scope context
|
|
*/
|
|
preventDefault(){
|
|
const { current }= this;
|
|
current.prevent= true;
|
|
return current;
|
|
},
|
|
|
|
/**
|
|
* Gets a copy of the current scope stack
|
|
* @returns {Array} Copy of scope stack
|
|
*/
|
|
get state(){ return [ ...scopes ]; },
|
|
|
|
/**
|
|
* Pushes a new scope to the stack
|
|
* @param {Object} [s={}] - Scope object to push
|
|
* @returns {number} New length of the scope stack
|
|
*/
|
|
push(s= {}){ return scopes.push(oAssign({}, this.current, { prevent: false }, s)); },
|
|
|
|
/**
|
|
* Pushes the root scope to the stack
|
|
* @returns {number} New length of the scope stack
|
|
*/
|
|
pushRoot(){ return scopes.push(scopes[0]); },
|
|
|
|
/**
|
|
* Pops the current scope from the stack
|
|
* @returns {Object|undefined} Popped scope or undefined if only one scope remains
|
|
*/
|
|
pop(){
|
|
if(scopes.length===1) return;
|
|
return scopes.pop();
|
|
},
|
|
};
|
|
// TODO: better place while no cross-import?
|
|
on.host= (fn, host= scope.host)=> el=> host(()=> fn(el));
|