Skip to content

Commit 9c978f6

Browse files
authored
Merge pull request #12 from Group-One-Technology/jr.feat/checked-attribute
Fix: :checked attribute when set to false
2 parents a129aa8 + 17caa09 commit 9c978f6

File tree

4 files changed

+69
-42
lines changed

4 files changed

+69
-42
lines changed

lib/entity.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Events } from './entity/events'
44
import { Attributes } from './entity/attributes'
55
import { State } from './state'
66

7-
export default class Entity {
7+
export class Entity {
88
constructor(el) {
99
this.element = el
1010
this.tagName = el.tagName

lib/entity/attributes.js

+54-39
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,19 @@ export class Attributes {
4444
}
4545
}
4646

47+
_handleError(attr, error) {
48+
if (!this.base.isExists()) return
49+
console.error(
50+
`Failed to evaluate ${attr} for Entity#${this.base.id}:`,
51+
error
52+
)
53+
}
54+
4755
async evaluate() {
4856
await this.evaluateClass()
4957
await this.evaluateText()
5058
await this.evaluateValue()
59+
await this.evaluateChecked()
5160

5261
for (const attr of this.dynamicAttributes) {
5362
if (Attributes.CUSTOM_ATTRIBUTES.includes(attr)) continue
@@ -62,7 +71,8 @@ export class Attributes {
6271
if (attr === ':parent') this.evaluateParent()
6372
else if (attr === ':class') await this.evaluateClass()
6473
else if (attr === ':text') await this.evaluateText()
65-
else if ([':value', ':checked'].includes(attr)) await this.evaluateValue()
74+
else if (attr === ':value') await this.evaluateValue()
75+
else if (attr === ':checked') await this.evaluateChecked()
6676
else if (attr === ':each') await this.evaluateEach()
6777
else {
6878
if (!this.dynamicAttributes.includes(attr))
@@ -89,8 +99,7 @@ export class Attributes {
8999

90100
this.base.element.setAttribute('class', updatedClassNames)
91101
} catch (error) {
92-
if (!this.base.isExists()) return
93-
throw error
102+
this._handleError(':class', error)
94103
}
95104
}
96105

@@ -101,54 +110,55 @@ export class Attributes {
101110
try {
102111
const newText = await this.base._interpret(textExpr)
103112

104-
if (newText || newText == '') this.base.element.innerText = newText
113+
if (newText || newText == '') this.base.element.textContent = newText
105114
} catch (error) {
106-
if (!this.base.isExists()) return
107-
throw error
115+
this._handleError(':text', error)
108116
}
109117
}
110118

111119
async evaluateValue() {
120+
const valueExpr = this.base.element.getAttribute(':value')
121+
if (!valueExpr) return
112122
try {
113-
const valueExpr = this.base.element.getAttribute(':value')
114-
115-
if (valueExpr) {
116-
const newValue = await this.base._interpret(valueExpr)
123+
const newValue = await this.base._interpret(valueExpr)
117124

118-
if (this.base.element.value !== newValue && newValue != null)
119-
this.base.element.value = newValue
120-
}
125+
if (this.base.element.value !== newValue && newValue != null)
126+
this.base.element.value = newValue
127+
} catch (error) {
128+
this._handleError(':value', error)
129+
}
130+
}
121131

122-
const checkedExpr = this.base.element.getAttribute(':checked')
132+
async evaluateChecked() {
133+
const checkedExpr = this.base.element.getAttribute(':checked')
134+
if (!checkedExpr) return
123135

124-
if (checkedExpr) {
125-
const newValue = await this.base._interpret(checkedExpr)
136+
try {
137+
const isChecked = await this.base._interpret(checkedExpr)
126138

127-
if (newValue) this.base.element.checked = newValue
128-
}
139+
if (this.base.element.checked !== isChecked && isChecked != null)
140+
this.base.element.checked = isChecked
129141
} catch (error) {
130-
if (!this.base.isExists()) return
131-
throw error
142+
this._handleError(':checked', error)
132143
}
133144
}
134145

135146
async evaluateOtherAttributes() {
136-
try {
137-
for (const attr of this.dynamicAttributes) {
138-
if (Attributes.CUSTOM_ATTRIBUTES.includes(attr)) continue
147+
for (const attr of this.dynamicAttributes) {
148+
if (Attributes.CUSTOM_ATTRIBUTES.includes(attr)) continue
139149

140-
const expr = this.base.element.getAttribute(attr)
141-
if (!expr) return
150+
const expr = this.base.element.getAttribute(attr)
151+
if (!expr) return
142152

153+
try {
143154
const newValue = await this.base._interpret(expr)
144155
const nativeAttr = attr.slice(1)
145156

146157
if (this.base.element[nativeAttr] !== newValue && newValue != null)
147158
this.base.element[nativeAttr] = newValue
159+
} catch (error) {
160+
this._handleError(attr, error)
148161
}
149-
} catch (error) {
150-
if (!this.base.isExists()) return
151-
throw error
152162
}
153163
}
154164

@@ -159,19 +169,24 @@ export class Attributes {
159169

160170
const [args, iterable] = eachExpr.split(' in ')
161171
const [variable, indexName] = args.split(',').map((v) => v.trim())
162-
const items = await this.base._interpret(iterable)
163-
this.childClone ||= this.base.element.innerHTML
164172

165-
let newHTML = ''
173+
try {
174+
const items = await this.base._interpret(iterable)
175+
this.childClone ||= this.base.element.innerHTML
166176

167-
items.forEach((item, index) => {
168-
// TODO: Use the lexer to replace the variables
169-
newHTML += this.childClone
170-
.replaceAll(indexName, index)
171-
.replaceAll(variable, `'${escapeHTML(item)}'`)
172-
})
177+
let newHTML = ''
173178

174-
// ObserveDOM will be called for updated DOM to initialize the entities
175-
this.base.element.innerHTML = newHTML
179+
items.forEach((item, index) => {
180+
// TODO: Use the lexer to replace the variables
181+
newHTML += this.childClone
182+
.replaceAll(indexName, index)
183+
.replaceAll(variable, `'${escapeHTML(item)}'`)
184+
})
185+
186+
// ObserveDOM will be called for updated DOM to initialize the entities
187+
this.base.element.innerHTML = newHTML
188+
} catch (error) {
189+
this._handleError(':each', error)
190+
}
176191
}
177192
}

lib/entity/events.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ export class Events {
7070
)
7171
}
7272

73+
_handleError(attr, error) {
74+
if (!this.base.isExists()) return
75+
console.error(
76+
`Failed to evaluate ${attr} for Entity#${this.base.id}:`,
77+
error
78+
)
79+
}
80+
7381
apply() {
7482
this.dispose()
7583
this.evaluate(':load')
@@ -240,7 +248,11 @@ export class Events {
240248
MiniJS.state.attachVariableHelpers(elVariables, this.base.id)
241249
}
242250

243-
await this.base._interpret(value)
251+
try {
252+
await this.base._interpret(value)
253+
} catch (error) {
254+
this._handleError(attr, error)
255+
}
244256
}
245257

246258
disposeEvent(attr) {

lib/main.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import Entity from './entity'
1+
import { Entity } from './entity'
22
import { Lexer } from './generators/lexer'
33
import { observeDOM } from './generators/observer'
44
import { State } from './state'

0 commit comments

Comments
 (0)