moving things, adding a test

This commit is contained in:
metacryst
2024-05-20 17:26:29 -05:00
parent 41ec6b7dd3
commit 65f79d1631
3 changed files with 80 additions and 53 deletions

View File

@@ -24,6 +24,7 @@ document.body.append(
## Needs Support:
Ternaries within render()
Other statements within render()
Multiple-argument attributes in render()
## Limitations:
While rendering is underway, an element's state can only be accessed from within that element

View File

@@ -99,4 +99,28 @@ window.testSuites.push( class testState {
}
}
StateWorksWithCustomStyleFunctions() {
// reactive setting needs to use the actual style functions
register(class File extends Shadow {
$paraWidth = 16
render = () => {
p("guppy")
.width(this.paraWidth)
}
constructor() {
super()
}
}, randomName("file"))
const file = File()
file.paraWidth = 18
if(file.firstChild.style.width !== "18px") {
return "Width did not reactively change!"
}
}
})

126
index.js
View File

@@ -139,7 +139,69 @@ function getSafariVersion() {
}
/* REGISTER */
class ObservedArray extends Array {
class ObservedObject {
constructor() {
this._observers = {}
}
static create(obj = {}) {
let instance = new this()
Object.keys(instance).forEach((key) => {
if(key[0] === "$") {
key = key.slice(1)
instance._observers[key] = new Map()
const backingFieldName = `_${key}`;
instance[backingFieldName] = instance["$" + key]
Object.defineProperty(instance, key, {
set: function(newValue) {
if(Array.isArray(newValue) && newValue.parent === undefined) {
instance[backingFieldName] = new ObservedObject.ObservedArray(newValue, this, key)
} else {
instance[backingFieldName] = newValue;
}
for (let [observer, properties] of instance._observers[key]) {
for (let property of properties) {
if(property === "children") {
Registry.rerender(observer)
} else {
if(Array.isArray(property)) {
observer[property[0]][property[1]] = newValue;
} else {
observer[property] = newValue;
}
}
}
}
},
get: function() {
if(Registry.lastState) {
Registry.lastState = [...Registry.lastState, key, instance[backingFieldName]]
}
return instance[backingFieldName];
},
enumerable: true,
configurable: true
});
delete instance["$" + key]
}
if(obj[key]) {
instance[key] = obj[key]
} else {
if(instance[key] === undefined || instance[key] === null) {
throw new Error(`ObservedObject: Non-default value "${key}" must be initialized!`)
}
}
})
return instance
}
static ObservedArray = class ObservedArray extends Array {
parent;
name;
@@ -190,66 +252,6 @@ class ObservedArray extends Array {
return removedItems;
}
}
class ObservedObject {
constructor() {
this._observers = {}
}
static create(obj = {}) {
let instance = new this()
Object.keys(instance).forEach((key) => {
if(key[0] === "$") {
key = key.slice(1)
instance._observers[key] = new Map()
const backingFieldName = `_${key}`;
instance[backingFieldName] = instance["$" + key]
Object.defineProperty(instance, key, {
set: function(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 property of properties) {
if(property === "children") {
Registry.rerender(observer)
} else {
if(Array.isArray(property)) {
observer[property[0]][property[1]] = newValue;
} else {
observer[property] = newValue;
}
}
}
}
},
get: function() {
if(Registry.lastState) {
Registry.lastState = [...Registry.lastState, key, instance[backingFieldName]]
}
return instance[backingFieldName];
},
enumerable: true,
configurable: true
});
delete instance["$" + key]
}
if(obj[key]) {
instance[key] = obj[key]
} else {
if(instance[key] === undefined || instance[key] === null) {
throw new Error(`ObservedObject: Non-default value "${key}" must be initialized!`)
}
}
})
return instance
}
}
window.Page = class Page {
@@ -421,7 +423,7 @@ window.Registry = class Registry {
foundReactives.push([identifier, expression, operators])
} else {
console.log("Variable or other usage at position:", statePos);
// console.log("Variable or other usage at position:", statePos);
}
if (observedObjectNames.includes(identifier)) {