adding render scheme
This commit is contained in:
@@ -2,12 +2,12 @@ window.testSuites.push( class testParse {
|
|||||||
|
|
||||||
|
|
||||||
testParseClassFieldsWithNoDefault() {
|
testParseClassFieldsWithNoDefault() {
|
||||||
class Space extends HTMLElement {
|
class Space extends Shadow {
|
||||||
form
|
form
|
||||||
contents = []
|
contents = []
|
||||||
|
|
||||||
constructor() {
|
constructor(...params) {
|
||||||
super()
|
super(...params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ testParseClassFieldsWithNoDefault() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testParseClassFieldsWithEqualityCheck() {
|
testParseClassFieldsWithEqualityCheck() {
|
||||||
class Space extends HTMLElement {
|
class Space extends Shadow {
|
||||||
form = Forms.observe(window.location.pathname, this)
|
form = Forms.observe(window.location.pathname, this)
|
||||||
|
|
||||||
contents = [
|
contents = [
|
||||||
@@ -34,8 +34,8 @@ testParseClassFieldsWithEqualityCheck() {
|
|||||||
})
|
})
|
||||||
]
|
]
|
||||||
|
|
||||||
constructor() {
|
constructor(...params) {
|
||||||
super()
|
super(...params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ testParseClassFieldsWithEqualityCheck() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testParseClassFieldsWithInnerFunctionVariable() {
|
testParseClassFieldsWithInnerFunctionVariable() {
|
||||||
class Space extends HTMLElement {
|
class Space extends Shadow {
|
||||||
form = Forms.observe(window.location.pathname, this)
|
form = Forms.observe(window.location.pathname, this)
|
||||||
|
|
||||||
contents = [
|
contents = [
|
||||||
@@ -64,8 +64,8 @@ testParseClassFieldsWithInnerFunctionVariable() {
|
|||||||
})
|
})
|
||||||
]
|
]
|
||||||
|
|
||||||
constructor() {
|
constructor(...params) {
|
||||||
super()
|
super(...params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
37
Test/shadow.test.js
Normal file
37
Test/shadow.test.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
window.testSuites.push( class testShadow {
|
||||||
|
|
||||||
|
testObjectAsStateField() {
|
||||||
|
class File extends Shadow {
|
||||||
|
$form
|
||||||
|
|
||||||
|
constructor(...params) {
|
||||||
|
super(...params)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.register(File, "file-el")
|
||||||
|
let form = {data: "asdf"}
|
||||||
|
const el = window.File(form)
|
||||||
|
console.log(el, el.$form, el._form)
|
||||||
|
if(!(el.form === form)) {
|
||||||
|
return `State field does not match object passed in!`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testRegisterThrowsIfNoConstructorParams() {
|
||||||
|
class File2 extends Shadow {
|
||||||
|
$form
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
window.register(File2, "file2-el")
|
||||||
|
} catch(e) {}
|
||||||
|
|
||||||
|
return "Error not thrown!"
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
@@ -2,6 +2,7 @@ console.log("Tests initializing.")
|
|||||||
window.testSuites = [];
|
window.testSuites = [];
|
||||||
|
|
||||||
import ("./parse.test.js")
|
import ("./parse.test.js")
|
||||||
|
import ("./shadow.test.js")
|
||||||
|
|
||||||
window.test = async function() {
|
window.test = async function() {
|
||||||
// window.testSuites.sort();
|
// window.testSuites.sort();
|
||||||
|
|||||||
185
index.js
185
index.js
@@ -16,6 +16,91 @@ window.$ = function(selector, el = document) {
|
|||||||
|
|
||||||
/* REGISTER */
|
/* REGISTER */
|
||||||
|
|
||||||
|
window.ObservedObject = class ObservedObject {
|
||||||
|
//
|
||||||
|
// "$" Variable: triggers a UI change
|
||||||
|
// Array: triggers a change if something is added, deleted, changed at the top level
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
window.Page = class Page {
|
||||||
|
appendChild(el) {
|
||||||
|
document.body.appendChild(el)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.Shadow = class Shadow extends HTMLElement {
|
||||||
|
constructor(stateVariables, ...params) {
|
||||||
|
super()
|
||||||
|
|
||||||
|
console.log(Object.getOwnPropertyDescriptors(this))
|
||||||
|
|
||||||
|
if(!stateVariables) {
|
||||||
|
console.log("No state variables passed in, returning")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// State -> Attributes
|
||||||
|
// set each state value as getter and setter
|
||||||
|
stateVariables.forEach(attrName => {
|
||||||
|
const backingFieldName = `_${attrName}`; // Construct the backing field name
|
||||||
|
|
||||||
|
Object.defineProperty(this, attrName, {
|
||||||
|
set: function(newValue) {
|
||||||
|
// console.log(`Setting attribute ${attrName} to `, newValue);
|
||||||
|
this[backingFieldName] = newValue; // Use the backing field to store the value
|
||||||
|
this.setAttribute(attrName, typeof newValue === "object" ? "{..}" : newValue); // Synchronize with the attribute
|
||||||
|
},
|
||||||
|
get: function() {
|
||||||
|
// console.log("get: ", this[backingFieldName])
|
||||||
|
return this[backingFieldName]; // Provide a getter to access the backing field value
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// if there are more than one, expect them to be named
|
||||||
|
if(stateVariables.length > 1) {
|
||||||
|
if(typeof params[0] !== "object") {
|
||||||
|
console.error(`Quill: elements with multiple state initializers must structure them like {color: "blue", type: 2}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let i = -1
|
||||||
|
for (let param in params[0]) {
|
||||||
|
i++
|
||||||
|
let paramName = "$" + param
|
||||||
|
if(stateVariables[i] !== paramName) {
|
||||||
|
if(!stateVariables[i]) {
|
||||||
|
console.error(`${el.prototype.constructor.name}: state ${state} must be initialized`)
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
console.error(`${el.prototype.constructor.name}: state initializer ${i} ${paramName} should be ${stateVariables[0]}`)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
this[paramName] = params[0][param]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(!params[0] && stateVariables[0]) {
|
||||||
|
console.log(params, stateVariables)
|
||||||
|
console.error(`${el.prototype.constructor.name}: state initializer $${params[0]} should be ${stateVariables[0]}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this[stateVariables[0]] = params[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if all state variables are set
|
||||||
|
for(let state of stateVariables) {
|
||||||
|
// console.log(elem[state])
|
||||||
|
if(!this[state]) {
|
||||||
|
console.error(`Quill: state ${state} must be initialized`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
window.Registry = class Registry {
|
window.Registry = class Registry {
|
||||||
|
|
||||||
static parseClassFields(classObject) {
|
static parseClassFields(classObject) {
|
||||||
@@ -42,6 +127,10 @@ window.Registry = class Registry {
|
|||||||
|
|
||||||
// If we encounter the constructor, stop the parsing as we're only interested in fields above it
|
// If we encounter the constructor, stop the parsing as we're only interested in fields above it
|
||||||
if (trimmedLine.startsWith('constructor')) {
|
if (trimmedLine.startsWith('constructor')) {
|
||||||
|
if(!trimmedLine.includes("...")) {
|
||||||
|
throw new Error(`Shadow: class constructor must include parameters! e.g. constructor(...params) {
|
||||||
|
super(...params)`)
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,12 +138,30 @@ window.Registry = class Registry {
|
|||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
static registerElement = (el, tagname) => {
|
static render = (el, parent) => {
|
||||||
console.log(this.parseClassFields(el))
|
if(!(el.constructor.name === "Home")) {
|
||||||
|
window.rendering[window.rendering.length-1].appendChild(el)
|
||||||
|
}
|
||||||
|
window.rendering.push(el)
|
||||||
|
el.render()
|
||||||
|
window.rendering.pop(el)
|
||||||
|
}
|
||||||
|
|
||||||
|
static registerHome(el) {
|
||||||
|
// console.log(params, stateVariables)
|
||||||
|
let home = new el()
|
||||||
|
Registry.render(home)
|
||||||
|
return home
|
||||||
|
}
|
||||||
|
|
||||||
|
static register = (el, tagname) => {
|
||||||
|
if(el.prototype.constructor.name === "Home") {
|
||||||
|
Registry.registerHome(el)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let stateVariables = this.parseClassFields(el).filter(field => field.startsWith('$'));
|
let stateVariables = this.parseClassFields(el).filter(field => field.startsWith('$'));
|
||||||
let stateVariablesWithout$ = stateVariables.map(str => str.substring(1));
|
let stateVariablesWithout$ = stateVariables.map(str => str.substring(1));
|
||||||
|
|
||||||
console.log(stateVariables)
|
|
||||||
|
|
||||||
// Observe attributes
|
// Observe attributes
|
||||||
Object.defineProperty(el, 'observedAttributes', {
|
Object.defineProperty(el, 'observedAttributes', {
|
||||||
@@ -67,7 +174,7 @@ window.Registry = class Registry {
|
|||||||
Object.defineProperty(el.prototype, 'attributeChangedCallback', {
|
Object.defineProperty(el.prototype, 'attributeChangedCallback', {
|
||||||
value: function(name, oldValue, newValue) {
|
value: function(name, oldValue, newValue) {
|
||||||
const fieldName = `$${name}`;
|
const fieldName = `$${name}`;
|
||||||
if (fieldName in this && this[fieldName] !== newValue) {
|
if (fieldName in this && this[fieldName] !== newValue && newValue !== "[object Object]") {
|
||||||
this[fieldName] = newValue;
|
this[fieldName] = newValue;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -80,72 +187,14 @@ window.Registry = class Registry {
|
|||||||
// Actual Constructor
|
// Actual Constructor
|
||||||
window[el.prototype.constructor.name] = function (...params) {
|
window[el.prototype.constructor.name] = function (...params) {
|
||||||
// console.log(params, stateVariables)
|
// console.log(params, stateVariables)
|
||||||
let elem = new el()
|
let elIncarnate = new el(stateVariablesWithout$, ...params)
|
||||||
|
Registry.render(elIncarnate)
|
||||||
// State -> Attributes
|
return elIncarnate
|
||||||
// set each state value as getter and setter
|
|
||||||
stateVariables.forEach(property => {
|
|
||||||
const attrName = property.substring(1); // Assuming 'property' starts with a symbol like '$'
|
|
||||||
const backingFieldName = `_${property}`; // Construct the backing field name
|
|
||||||
|
|
||||||
Object.defineProperty(elem, property, {
|
|
||||||
set: function(newValue) {
|
|
||||||
console.log(`Setting attribute ${attrName} to ${newValue}`);
|
|
||||||
this[backingFieldName] = newValue; // Use the backing field to store the value
|
|
||||||
this.setAttribute(attrName, newValue); // Synchronize with the attribute
|
|
||||||
},
|
|
||||||
get: function() {
|
|
||||||
return this[backingFieldName]; // Provide a getter to access the backing field value
|
|
||||||
},
|
|
||||||
enumerable: true,
|
|
||||||
configurable: true
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// if there are more than one, expect them to be named
|
|
||||||
if(stateVariables.length > 1) {
|
|
||||||
if(typeof params[0] !== "object") {
|
|
||||||
console.error(`Quill: elements with multiple state initializers must structure them like {color: "blue", type: 2}`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let i = -1
|
|
||||||
for (let param in params[0]) {
|
|
||||||
i++
|
|
||||||
let paramName = "$" + param
|
|
||||||
if(stateVariables[i] !== paramName) {
|
|
||||||
if(!stateVariables[i]) {
|
|
||||||
console.error(`${el.prototype.constructor.name}: state ${state} must be initialized`)
|
|
||||||
} else {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
console.error(`${el.prototype.constructor.name}: state initializer ${i} ${paramName} should be ${stateVariables[0]}`)
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
elem[paramName] = params[0][param]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(!params[0] && stateVariables[0]) {
|
|
||||||
console.log(params, stateVariables)
|
|
||||||
console.error(`${el.prototype.constructor.name}: state initializer $${params[0]} should be ${stateVariables[0]}`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
elem[stateVariables[0]] = params[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if all state variables are set
|
|
||||||
for(let state of stateVariables) {
|
|
||||||
console.log(elem[state])
|
|
||||||
if(!elem[state]) {
|
|
||||||
console.error(`Quill: state ${state} must be initialized`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return elem
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
window.registerElement = Registry.registerElement
|
window.register = Registry.register
|
||||||
|
window.rendering = []
|
||||||
|
|
||||||
/* PROTOTYPE FUNCTIONS */
|
/* PROTOTYPE FUNCTIONS */
|
||||||
|
|
||||||
|
|||||||
12
notes.txt
12
notes.txt
@@ -1,3 +1,13 @@
|
|||||||
|
3/16
|
||||||
|
const TestClass = () => new class {
|
||||||
|
constructor() {
|
||||||
|
console.log("hey")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
This works. Could extend shadow. This way the function and the actual code are not separate.
|
||||||
|
|
||||||
|
|
||||||
3/10
|
3/10
|
||||||
|
|
||||||
Ran into a problem where I can't call the same element within itself.
|
Ran into a problem where I can't call the same element within itself.
|
||||||
@@ -109,4 +119,4 @@ perhaps this would have a chance.
|
|||||||
// window.Space = () => "boi"
|
// window.Space = () => "boi"
|
||||||
// console.log(new instan())
|
// console.log(new instan())
|
||||||
|
|
||||||
window.registerElement(Space, "parchment-space")
|
window.register(Space, "parchment-space")
|
||||||
Reference in New Issue
Block a user