Skip to content

Instantly share code, notes, and snippets.

@dfkaye
Created November 29, 2023 23:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dfkaye/4e06eb749f878662e31a6cb019fbd650 to your computer and use it in GitHub Desktop.
Save dfkaye/4e06eb749f878662e31a6cb019fbd650 to your computer and use it in GitHub Desktop.
onpropertychange signal v.3- sketch for form element nodes
// 17 September 2023
// onpropertychange signal v.3
// onpropertychange sketch for form element nodes
// cont'd from https://gist.github.com/dfkaye/d849596bdb9e926ad69ad38c974a4763
function N(node) {
var target = node;
var API = Object.setPrototypeOf({}, {
addEventListener(name, h) { return target.addEventListener(name, h); },
removeEventListener(name, h) {
return target.removeEventListener(name, h);
},
dispatchEvent(event) { return target.dispatchEvent(event); },
onpropertychange: null,
toJSON() { return target; },
toString() { return JSON.stringify(this); },
api() { return this; },
getAttribute(name, value) { return target.getAttribute(name, value); },
setAttribute(name, value) {
handler.defineProperty(API, name, {value});
return target.setAttribute(name, value);
},
value: target.value,
defaultValue: target.defaultValue
});
API.addEventListener("change", function (e) {
console.warn(e.detail);
if (e.detail) {
var value = e.detail.value;
Reflect.set(target, 'value', value);
return Reflect.set(API, 'value', value);
}
else {
return Reflect.set(API, 'value', e.target.value);
}
});
var handler = {
defineProperty(API, key, descriptor) {
var previous = Reflect.get(target, key);
var value = descriptor.value;
if (previous === value) {
return;
}
if (key == 'onpropertychange') {
var fn = Reflect.get(API, key);
target.removeEventListener('propertychange', fn);
target.addEventListener('propertychange', value);
return Reflect.set(API, key, value);
}
Reflect.set(target, key, value);
return target.dispatchEvent(new CustomEvent("propertychange", {
detail: { propertyName: key, previous, value }
}));
},
deleteProperty(API, key) {
console.error(key);
if (key == 'onpropertychange') {
var value = Reflect.get(API, key);
Reflect.deleteProperty(API, key);
return target.removeEventListener('propertychange', value);
}
return Reflect.deleteProperty(target, key);
}
};
return new Proxy(API, handler);
}
/* test it out */
// fixture
var source = `
<form name="test">
<fieldset>
<legend>LEGEND</legend>
<input name="checkbox" type="checkbox" value="yes">
<input name="text" value="yes">
</fieldset>
</form>
`;
var dom = (new DOMParser).parseFromString(source, "text/html").body;
document.body.replaceChildren( ...dom.childNodes );
var text = document.querySelector(`[name="text"]`);
var checkbox = document.querySelector(`[name="checkbox"]`);
// tests
var t = N(text);
function f(e) {
console.warn("propertychange\n", e)
}
t.addEventListener("propertychange", f);
function g(e) {
console.log("onpropertychange\n", e);
}
t.onpropertychange = g;
t.setAttribute('value', 'new value');
t.dispatchEvent(new CustomEvent("change", {
detail: { value: "dispatched change value"}
}));
t.onpropertychange = null;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment