Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor: Rename :group to :scope #22

Merged
merged 1 commit into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -342,26 +342,26 @@ If you want to use the variable across an element's attributes and events, you c

Like the example above, `:load` can be used to set the initial value of the variable.

### Group Variables
### Scope Variables

Adding a `:group` attribute to an element will allow you to access its variables from its children using `group.` variables.
Adding a `:scope` attribute to an element will allow you to access its variables from its children using `scope.` variables.

```html
<!-- Group Element -->
<div id="accordion" class="accordion" :group>
<!-- Scope Element -->
<div id="accordion" class="accordion" :scope>
<!-- Children Elements -->
<section
class="grid transition-all border-gray-300 border border-b-0 rounded hover:bg-gray-100"
>
<button
:click="group.activeSection = 'about'"
:click="scope.activeSection = 'about'"
class="cursor-pointer font-bold p-4"
>
About Us
</button>
<div
class="p-4 pt-2 overflow-hidden hidden"
:class="group.activeSection =='about' ? 'block' : 'hidden'"
:class="scope.activeSection =='about' ? 'block' : 'hidden'"
>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
eirmod.
Expand All @@ -372,14 +372,14 @@ Adding a `:group` attribute to an element will allow you to access its variables
class="grid transition-all border-gray-300 border border-b-0 rounded hover:bg-gray-100"
>
<button
:click="group.activeSection = 'contact'"
:click="scope.activeSection = 'contact'"
class="cursor-pointer font-bold p-4"
>
Contact Us
</button>
<div
class="p-4 pt-2 overflow-hidden"
:class="group.activeSection =='contact' ? 'block' : 'hidden'"
:class="scope.activeSection =='contact' ? 'block' : 'hidden'"
>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
eirmod.
Expand All @@ -388,17 +388,17 @@ Adding a `:group` attribute to an element will allow you to access its variables

<section
class="grid transition-all border-gray-300 border rounded hover:bg-gray-100"
:class="group.activeSection =='team' ? 'active' : ''"
:class="scope.activeSection =='team' ? 'active' : ''"
>
<button
:click="group.activeSection = 'team'"
:click="scope.activeSection = 'team'"
class="cursor-pointer font-bold p-4"
>
Team 3
</button>
<div
class="p-4 pt-2 overflow-hidden"
:class="group.activeSection =='team' ? 'block' : 'hidden'"
:class="scope.activeSection =='team' ? 'block' : 'hidden'"
>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
eirmod.
Expand All @@ -407,10 +407,10 @@ Adding a `:group` attribute to an element will allow you to access its variables
</div>
```

You can set the default value of the group variables in the `:group` directive:
You can set the default value of the scope variables in the `:scope` directive:

```html
<div id="accordion" class="accordion" :group="activeSection = 'about'">
<div id="accordion" class="accordion" :scope="activeSection = 'about'">
<!-- ... -->
</div>
```
Expand Down
20 changes: 10 additions & 10 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1472,15 +1472,15 @@ <h3 class="font-bold font-mono">Multi Select:</h3>
grid-template-rows: 0fr 1fr;
}
</style>
<div class="accordion" :group="activeSection = 'about'">
<div class="accordion" :scope="activeSection = 'about'">
<section
class="grid transition-all border-gray-300 border border-b-0 rounded hover:bg-gray-100"
:class="group.activeSection == 'about' ? 'active' : ''"
:class="scope.activeSection == 'about' ? 'active' : ''"
>
<a
:click="group.activeSection = 'about'"
:click="scope.activeSection = 'about'"
class="cursor-pointer font-bold p-4"
:aria-expanded="group.activeSection == 'about'"
:aria-expanded="scope.activeSection == 'about'"
>
About Us
</a>
Expand All @@ -1494,12 +1494,12 @@ <h3 class="font-bold font-mono">Multi Select:</h3>

<section
class="grid transition-all border-gray-300 border border-b-0 rounded hover:bg-gray-100"
:class="group.activeSection =='contact' ? 'active' : ''"
:class="scope.activeSection =='contact' ? 'active' : ''"
>
<a
:click="group.activeSection = 'contact'"
:click="scope.activeSection = 'contact'"
class="cursor-pointer font-bold p-4"
:aria-expanded="group.activeSection == 'contact'"
:aria-expanded="scope.activeSection == 'contact'"
>
Contact Us
</a>
Expand All @@ -1513,11 +1513,11 @@ <h3 class="font-bold font-mono">Multi Select:</h3>

<section
class="grid transition-all border-gray-300 border rounded hover:bg-gray-100"
:class="group.activeSection == 'team' ? 'active' : ''"
:class="scope.activeSection == 'team' ? 'active' : ''"
>
<a
:click="group.activeSection = 'team'"
:aria-expanded="group.activeSection == 'team'"
:click="scope.activeSection = 'team'"
:aria-expanded="scope.activeSection == 'team'"
class="cursor-pointer font-bold p-4"
>
Team 3
Expand Down
18 changes: 9 additions & 9 deletions lib/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,18 @@ export class Entity {

if (this.base.debug) this.element.dataset.entityId = this.id

this.setAsGroup()
this.setAsScope()
}

setAsGroup() {
if (!this.element.hasAttribute(':group')) return
if (this.isGroup()) return
setAsScope() {
if (!this.element.hasAttribute(':scope')) return
if (this.isScope()) return

this.uuid = this.id
this.element.dataset['mini.uuid'] = this.uuid
}

isGroup() {
isScope() {
return !!this.uuid
}

Expand Down Expand Up @@ -92,14 +92,14 @@ export class Entity {
this.data.init()
}

getGroup() {
const groupNode = this.getClosestEl('data-mini.uuid')
getScope() {
const scopeNode = this.getClosestEl('data-mini.uuid')

if (groupNode == null) return { id: 'EntityDocument' }
if (scopeNode == null) return { id: 'EntityDocument' }

const entities = Array.from(this.base.state.entities.values())
const entity = entities.find(
(e) => e.uuid == groupNode.dataset['mini.uuid']
(e) => e.uuid == scopeNode.dataset['mini.uuid']
)

return entity
Expand Down
28 changes: 14 additions & 14 deletions lib/entity/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class Attributes {
':checked',
':each',
':each.item',
':group',
':scope',
]
static FORBIDDEN_ATTRIBUTES = [':innerHTML', ':innerText']

Expand Down Expand Up @@ -64,9 +64,9 @@ export class Attributes {
const ids = {
$: 'document-querySelector',
el: `proxyWindow['${this.entity.id}${State.DISABLE_RE_RENDER_KEY}']`,
group: this.entity.group
? `proxyWindow['${this.entity.group.id}${
!options.isGroup ? State.DISABLE_RE_RENDER_KEY : ''
scope: this.entity.scope
? `proxyWindow['${this.entity.scope.id}${
!options.isScope ? State.DISABLE_RE_RENDER_KEY : ''
}']`
: undefined,
...(options.ids || {}),
Expand All @@ -93,7 +93,7 @@ export class Attributes {
}

async evaluate() {
await this.evaluateAttribute(':group')
await this.evaluateAttribute(':scope')
await this.evaluateClass()
await this.evaluateText()
await this.evaluateValue()
Expand All @@ -109,7 +109,7 @@ export class Attributes {

async evaluateAttribute(attr) {
if (!Attributes.isValidAttribute(attr, this.entity.element)) return
if (attr === ':group') await this.evaluateGroup()
if (attr === ':scope') await this.evaluateScope()
else if (attr === ':class') await this.evaluateClass()
else if (attr === ':text') await this.evaluateText()
else if (attr === ':value') await this.evaluateValue()
Expand Down Expand Up @@ -148,29 +148,29 @@ export class Attributes {
}

/*
:group is a special attribute that acts as an :load event
:scope is a special attribute that acts as an :load event
when it has a given expr. Unlike other attributes, state updates
inside :group will trigger re-renders.
inside :scope will trigger re-renders.

NOTE: This should NOT be used in this.evaluate() because it will
trigger an infinite loop.
*/
async evaluateGroup() {
if (!this.entity.isGroup()) return
async evaluateScope() {
if (!this.entity.isScope()) return

const expr = this.entity.element.getAttribute(':group')
const expr = this.entity.element.getAttribute(':scope')
if (!expr) return

const ids = {}

this.entity.data.groupVariables.forEach((variable) => {
this.entity.data.scopeVariables.forEach((variable) => {
ids[variable] = `proxyWindow['${this.entity.id}'].${variable}`
})

try {
await this._interpret(expr, { isGroup: true, ids })
await this._interpret(expr, { isScope: true, ids })
} catch (error) {
this._handleError(':group', expr, error)
this._handleError(':scope', expr, error)
}
}

Expand Down
32 changes: 16 additions & 16 deletions lib/entity/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class Data {
this.entity = entity
this._variables = new Map() // key: variable, value: attributes
this._attributes = new Map() // key: attribute, value: variables
this.groupVariables = []
this.scopeVariables = []
}

get variables() {
Expand Down Expand Up @@ -54,15 +54,15 @@ export class Data {
}

const lexer = new Lexer(expr)
const isGroupAttr = attr === ':group'
const isScopeAttr = attr === ':scope'

lexer.identifiers.forEach((variable) => {
if (IGNORED_IDS.includes(variable)) return

const object = variable.split('.')[0]
if (object in this.entity.state) return

if (isGroupAttr) this.groupVariables.push(variable)
if (isScopeAttr) this.scopeVariables.push(variable)
else this.add(variable, attr)
})
}
Expand Down Expand Up @@ -107,7 +107,7 @@ export class Data {

this.variables.forEach((variable) => {
if (State.isElState(variable)) {
this.entity.setAsGroup()
this.entity.setAsScope()

if (window[entityID] == null)
window[entityID] = state.create({}, entityID)
Expand All @@ -118,25 +118,25 @@ export class Data {
const [_, varName] = variable.split('.')
state.addEntityVariable(entityID, varName, entityID)
}
} else if (State.isGroupState(variable)) {
if (this.entity.group == null)
this.entity.group = this.entity.getGroup()
} else if (State.isScopeState(variable)) {
if (this.entity.scope == null)
this.entity.scope = this.entity.getScope()

// Cases where group is not found:
// - an each item with a :group directive being removed due to re-evaluation of :each attribute
if (this.entity.group == null) return
// Cases where scope is not found:
// - an each item with a :scope directive being removed due to re-evaluation of :each attribute
if (this.entity.scope == null) return

const groupID = this.entity.group?.id
const scopeID = this.entity.scope?.id

if (window[groupID] == null) {
window[groupID] = state.create({}, groupID)
if (window[scopeID] == null) {
window[scopeID] = state.create({}, scopeID)
}

state.addVariable(groupID, entityID)
state.addVariable(scopeID, entityID)

if (variable !== State.GROUP_STATE) {
if (variable !== State.SCOPE_STATE) {
const [_, varName] = variable.split('.')
state.addEntityVariable(groupID, varName, entityID)
state.addEntityVariable(scopeID, varName, entityID)
}
} else if (typeof window[variable] === 'function') {
this.deleteVariable(variable)
Expand Down
12 changes: 6 additions & 6 deletions lib/entity/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -440,13 +440,13 @@ export class Events {
_attachVariableHelpers(attr) {
const variables = []
const elVariables = []
const groupVariables = []
const scopeVariables = []

this.entity.data.getAttributeVariables(attr).forEach((variable) => {
const [_, object] = variable.split('.')

if (State.isElState(variable)) elVariables.push(object)
else if (State.isGroupState(variable)) groupVariables.push(object)
else if (State.isScopeState(variable)) scopeVariables.push(object)
else variables.push(variable)
})

Expand All @@ -455,8 +455,8 @@ export class Events {
state.attachVariableHelpers(variables)
state.attachVariableHelpers(elVariables, this.entity.id)

if (this.entity.group)
state.attachVariableHelpers(groupVariables, this.entity.group.id)
if (this.entity.scope)
state.attachVariableHelpers(scopeVariables, this.entity.scope.id)
}

async _interpret(expr) {
Expand All @@ -467,10 +467,10 @@ export class Events {
// "this" is set under the interpreter as bind context
}

if (this.entity.group) ids.group = `proxyWindow['${this.entity.group.id}']`
if (this.entity.scope) ids.scope = `proxyWindow['${this.entity.scope.id}']`

this.entity.data.variables.forEach((variable) => {
if (State.isElState(variable) || State.isGroupState(variable)) return
if (State.isElState(variable) || State.isScopeState(variable)) return

ids[variable] = `proxyWindow-${variable}`
})
Expand Down
2 changes: 1 addition & 1 deletion lib/generators/lexer.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ function getVariables(node) {
export class Lexer {
static debug = false
static IGNORED_KEYS = ['event', 'window', 'document', 'console', 'Math']
static ENTITY_KEYS = ['el', 'group']
static ENTITY_KEYS = ['el', 'scope']

constructor(code) {
this._code = code
Expand Down
Loading
Loading