Observed Object reactivity with array
This commit is contained in:
@@ -26,6 +26,19 @@ window.testSuites.push( class testObservedObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MustInitAllFields() {
|
||||||
|
// class Form extends ObservedObject {
|
||||||
|
// id
|
||||||
|
// path
|
||||||
|
// $canvasPosition
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let obj = Form.decode({id: "123", path: "/", canvasPosition: "25|25"})
|
||||||
|
// if(!(obj && obj["id"] === "123" && obj["path"] === "/" && obj["canvasPosition"] === "25|25")) {
|
||||||
|
// return "Not all fields initialized!"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
// ChangingObjChangesInstance() {
|
// ChangingObjChangesInstance() {
|
||||||
// class Form extends ObservedObject {
|
// class Form extends ObservedObject {
|
||||||
// id
|
// id
|
||||||
|
|||||||
@@ -98,11 +98,10 @@ window.testSuites.push( class testRender {
|
|||||||
let Form = class Form extends ObservedObject {
|
let Form = class Form extends ObservedObject {
|
||||||
id
|
id
|
||||||
$path
|
$path
|
||||||
$children
|
|
||||||
$canvasPosition
|
$canvasPosition
|
||||||
}
|
}
|
||||||
|
|
||||||
let object = Form.decode({id: "123", path: "/", children: [], canvasPosition: "25|25"});
|
let object = Form.decode({id: "123", path: "/", canvasPosition: "25|25"});
|
||||||
|
|
||||||
register(class File extends Shadow {
|
register(class File extends Shadow {
|
||||||
$$form
|
$$form
|
||||||
@@ -127,39 +126,34 @@ window.testSuites.push( class testRender {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ObservedObjectWithArray() {
|
ObservedObjectWithArray() {
|
||||||
// let Form = class Form extends ObservedObject {
|
let Form = class Form extends ObservedObject {
|
||||||
// id
|
id
|
||||||
// $path
|
$children
|
||||||
// $children
|
}
|
||||||
// $canvasPosition
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let object = Form.decode({id: "123", path: "/", children: [], canvasPosition: "25|25"});
|
let object = Form.decode({id: "123", children: [{path: "berry"}, {path: "blue"}]});
|
||||||
|
|
||||||
// register(class File extends Shadow {
|
register(class File extends Shadow {
|
||||||
// $$form
|
$$form
|
||||||
|
|
||||||
// render = () => {
|
render = () => {
|
||||||
// p(this.form.path)
|
ForEach(this.form.children, (child) => {
|
||||||
// }
|
p(child.path)
|
||||||
// }, randomName("file"))
|
})
|
||||||
|
}
|
||||||
|
}, randomName("file"))
|
||||||
|
|
||||||
// let file = File(object)
|
let file = File(object)
|
||||||
|
|
||||||
// if(file.firstChild?.innerText !== "/") {
|
if(file.firstChild?.innerText !== "berry" || file.children[1].innerText !== "blue") {
|
||||||
// return "Path is not inside of paragraph tag"
|
return "Paths did not render correctly in children"
|
||||||
// }
|
}
|
||||||
|
|
||||||
// file.form.children.push("hello")
|
file.form.children.push({path: "hello"})
|
||||||
|
if(file.children.length !== 3) {
|
||||||
// object.path = "/asd"
|
return "No reactivity for adding children"
|
||||||
// if(file.form.path !== "/asd") {
|
}
|
||||||
// return "Path did not change when changing original object"
|
}
|
||||||
// }
|
|
||||||
// if(file.firstChild?.innerText !== "/asd") {
|
|
||||||
// return "Observed Object did not cause a reactive change"
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
})
|
})
|
||||||
93
index.js
93
index.js
@@ -144,6 +144,58 @@ function getSafariVersion() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* REGISTER */
|
/* REGISTER */
|
||||||
|
class ObservedArray extends Array {
|
||||||
|
parent;
|
||||||
|
name;
|
||||||
|
|
||||||
|
constructor(arr = [], parent, name) {
|
||||||
|
super();
|
||||||
|
this.parent = parent
|
||||||
|
this.name = name
|
||||||
|
this.push(...arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
triggerParent() {
|
||||||
|
this.parent[this.name] = this
|
||||||
|
}
|
||||||
|
|
||||||
|
push(...args) {
|
||||||
|
const result = super.push(...args);
|
||||||
|
this.triggerParent()
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
pop() {
|
||||||
|
const result = super.pop();
|
||||||
|
this.triggerParent()
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
shift() {
|
||||||
|
const result = super.shift();
|
||||||
|
this.triggerParent()
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
unshift(...args) {
|
||||||
|
const result = super.unshift(...args);
|
||||||
|
this.triggerParent()
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
splice(start, deleteCount, ...items) {
|
||||||
|
const removedItems = super.splice(start, deleteCount, ...items);
|
||||||
|
if (items.length > 0) {
|
||||||
|
console.log(`Inserted ${items.length} items:`, items);
|
||||||
|
}
|
||||||
|
if (removedItems.length > 0) {
|
||||||
|
console.log(`Removed ${removedItems.length} items:`, removedItems);
|
||||||
|
}
|
||||||
|
this.triggerParent()
|
||||||
|
return removedItems;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ObservedObject {
|
class ObservedObject {
|
||||||
constructor() {
|
constructor() {
|
||||||
this._observers = {}
|
this._observers = {}
|
||||||
@@ -159,10 +211,18 @@ class ObservedObject {
|
|||||||
const backingFieldName = `_${key}`;
|
const backingFieldName = `_${key}`;
|
||||||
Object.defineProperty(instance, key, {
|
Object.defineProperty(instance, key, {
|
||||||
set: function(newValue) {
|
set: function(newValue) {
|
||||||
instance[backingFieldName] = newValue;
|
if(Array.isArray(newValue) && newValue.parent === undefined) {
|
||||||
|
instance[backingFieldName] = new ObservedArray(newValue, this, key)
|
||||||
|
} else {
|
||||||
|
instance[backingFieldName] = newValue;
|
||||||
|
}
|
||||||
for (let [observer, properties] of instance._observers[key]) {
|
for (let [observer, properties] of instance._observers[key]) {
|
||||||
for (let property of properties) {
|
for (let property of properties) {
|
||||||
observer[property] = newValue;
|
if(property === "children") {
|
||||||
|
Registry.rerender(observer)
|
||||||
|
} else {
|
||||||
|
observer[property] = newValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -206,7 +266,7 @@ window.Shadow = class Shadow extends HTMLElement {
|
|||||||
window.Registry = class Registry {
|
window.Registry = class Registry {
|
||||||
|
|
||||||
static initReactivity(elem, name, value) {
|
static initReactivity(elem, name, value) {
|
||||||
let parent = window.rendering[window.rendering.length-1]
|
let parent = window.rendering.last()
|
||||||
|
|
||||||
if(Registry.lastState.length === 3) {
|
if(Registry.lastState.length === 3) {
|
||||||
let [objName, objField, fieldValue] = Registry.lastState
|
let [objName, objField, fieldValue] = Registry.lastState
|
||||||
@@ -217,7 +277,10 @@ window.Registry = class Registry {
|
|||||||
if(!parent[objName]._observers[objField].get(elem)) {
|
if(!parent[objName]._observers[objField].get(elem)) {
|
||||||
parent[objName]._observers[objField].set(elem, [])
|
parent[objName]._observers[objField].set(elem, [])
|
||||||
}
|
}
|
||||||
parent[objName]._observers[objField].get(elem).push(name)
|
let properties = parent[objName]._observers[objField].get(elem)
|
||||||
|
if(!properties.includes(name)) {
|
||||||
|
properties.push(name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let [stateUsed, stateValue] = Registry.lastState
|
let [stateUsed, stateValue] = Registry.lastState
|
||||||
@@ -243,6 +306,17 @@ window.Registry = class Registry {
|
|||||||
window.rendering.pop(el)
|
window.rendering.pop(el)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static rerender = (el) => {
|
||||||
|
if(el.parentElement) {
|
||||||
|
window.rendering.push(el.parentElement)
|
||||||
|
}
|
||||||
|
window.rendering.push(el)
|
||||||
|
el.innerHTML = ""
|
||||||
|
el.render()
|
||||||
|
window.rendering.pop()
|
||||||
|
window.rendering.pop()
|
||||||
|
}
|
||||||
|
|
||||||
static testInitialized(el) {
|
static testInitialized(el) {
|
||||||
let fields = Object.keys(el).filter(key =>
|
let fields = Object.keys(el).filter(key =>
|
||||||
typeof el[key] !== 'function' && key !== "_observers"
|
typeof el[key] !== 'function' && key !== "_observers"
|
||||||
@@ -485,6 +559,13 @@ window.Registry = class Registry {
|
|||||||
|
|
||||||
/* DEFAULT WRAPPERS */
|
/* DEFAULT WRAPPERS */
|
||||||
|
|
||||||
|
window.ForEach = function (arr, cb) {
|
||||||
|
Registry.initReactivity(window.rendering.last(), "children", arr)
|
||||||
|
arr.forEach((el, i) => {
|
||||||
|
cb(el, i)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
window.a = function a({ href, name=href } = {}) {
|
window.a = function a({ href, name=href } = {}) {
|
||||||
let link = document.createElement("a")
|
let link = document.createElement("a")
|
||||||
link.setAttribute('href', href);
|
link.setAttribute('href', href);
|
||||||
@@ -525,6 +606,10 @@ window.span = function (innerText) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* PROTOTYPE FUNCTIONS */
|
/* PROTOTYPE FUNCTIONS */
|
||||||
|
|
||||||
|
Array.prototype.last = function() {
|
||||||
|
return this[this.length-1]
|
||||||
|
}
|
||||||
HTMLElement.prototype.addAttribute = function(name) {
|
HTMLElement.prototype.addAttribute = function(name) {
|
||||||
this.setAttribute(name, "")
|
this.setAttribute(name, "")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user