initial commit
This commit is contained in:
commit
9fd405d39a
|
@ -0,0 +1,3 @@
|
|||
# Alps
|
||||
|
||||
A Alpine Inspired Framework Learning Experiment
|
|
@ -0,0 +1,91 @@
|
|||
|
||||
function saferEval(expression, dataContext, additionalHelperVariables = {}) {
|
||||
return (new Function(['$data', ...Object.keys(additionalHelperVariables)], `var result; with($data) { result = ${expression} }; return result`))(
|
||||
dataContext, ...Object.values(additionalHelperVariables)
|
||||
)
|
||||
}
|
||||
|
||||
const Alps = {
|
||||
directives: {
|
||||
'x-text': (el, value) => {
|
||||
el.innerText = value;
|
||||
},
|
||||
'x-show': (el, value) => {
|
||||
el.style.display = value ? 'block' : 'none';
|
||||
},
|
||||
},
|
||||
start() {
|
||||
// root scope
|
||||
this.root = document.querySelector('[x-data]');
|
||||
|
||||
// initialize proxy data
|
||||
this.data = this.initialize();
|
||||
|
||||
// add event listeners
|
||||
this.registerListeners();
|
||||
|
||||
// refresh dom
|
||||
this.refresh();
|
||||
},
|
||||
observe(data) {
|
||||
let self = this;
|
||||
|
||||
return new Proxy(data, {
|
||||
set(target, key, value) {
|
||||
target[key] = value;
|
||||
|
||||
self.refresh();
|
||||
}
|
||||
});
|
||||
},
|
||||
refresh() {
|
||||
// dom tree walker
|
||||
this.walkDom(this.root, (el) => {
|
||||
// loop through attributes and look for directives
|
||||
Array.from(el.attributes).forEach((attribute) => {
|
||||
if(!Object.keys(this.directives).includes(attribute.name)) return;
|
||||
|
||||
this.directives[attribute.name](el, eval(`with (this.data) {(${attribute.value})}`));
|
||||
});
|
||||
});
|
||||
},
|
||||
registerListeners() {
|
||||
this.walkDom(this.root, (el) => {
|
||||
// loop through attributes and look for events
|
||||
Array.from(el.attributes).forEach((attribute) => {
|
||||
// exit early (only events here)
|
||||
if(!attribute.name.startsWith('@')) return;
|
||||
|
||||
// find event
|
||||
let event = attribute.name.replace('@', '');
|
||||
|
||||
// register event
|
||||
el.addEventListener((event), () => {
|
||||
eval(`with (this.data) {(${attribute.value})}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
initialize() {
|
||||
// root scope data on x-data
|
||||
let raw = this.root.getAttribute('x-data');
|
||||
|
||||
// eval that
|
||||
return this.observe(eval(`(${raw})`));
|
||||
},
|
||||
walkDom(el, callback) {
|
||||
// root element
|
||||
callback(el);
|
||||
|
||||
// roots child
|
||||
el = el.firstElementChild;
|
||||
|
||||
while(el) {
|
||||
// get all the children's children
|
||||
this.walkDom(el, callback);
|
||||
|
||||
// next
|
||||
el = el.nextElementSibling;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue