Skip to content
This repository has been archived by the owner on Sep 22, 2020. It is now read-only.

Commit

Permalink
Rebuilt components on acorn
Browse files Browse the repository at this point in the history
  • Loading branch information
shnhrrsn committed Dec 2, 2017
1 parent ebe5e58 commit e9b86c2
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 0 deletions.
79 changes: 79 additions & 0 deletions src/Stone/Parsers/Components.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
export function parseComponentDirective(node, args) {
args = this._flattenArgs(args)

if(args.length === 0) {
this.raise(this.start, '`@component` must contain at least 1 argument')
}

node.view = args.shift()

if(args.length > 1) {
this.raise(this.start, '`@component` cannot contain more than 2 arguments')
} else if(args.length === 1) {
node.context = args.pop()
}

(this._currentComponent = (this._currentComponent || [ ])).push(node)

const output = this.startNode()
output.params = args
output.body = this.parseUntilEndDirective('endcomponent')
node.output = this.finishNode(output, 'StoneOutputBlock')

return this.finishNode(node, 'StoneComponent')
}

/**
* Ends the current component and returns output
* @return {string} Output from the component
*/
export function parseEndcomponentDirective(node) {
if(!this._currentComponent || this._currentComponent.length === 0) {
this.raise(this.start, '`@endcomponent` outside of `@component`')
}

this._currentComponent.pop()

return this.finishNode(node, 'Directive')
}

export function parseSlotDirective(node, args) {
args = this._flattenArgs(args)

if(args.length === 0) {
this.raise(this.start, '`@slot` must contain at least 1 argument')
}

node.id = args.shift()

if(args.length > 1) {
this.raise(this.start, '`@slot` cannot contain more than 2 arguments')
} else if(args.length === 1) {
node.output = args.pop()
node.inline = true
this.next()
} else {
(this._currentSlot = (this._currentSlot || [ ])).push(node)

const output = this.startNode()
output.params = args
output.body = this.parseUntilEndDirective('endslot')
node.output = this.finishNode(output, 'StoneOutputBlock')
}

return this.finishNode(node, 'StoneSlot')
}

/**
* Ends the current slot and returns output
* @return {string} Output from the slot
*/
export function parseEndslotDirective(node) {
if(!this._currentSlot || this._currentSlot.length === 0) {
this.raise(this.start, '`@endslot` outside of `@slot`')
}

this._currentSlot.pop()

return this.finishNode(node, 'Directive')
}
1 change: 1 addition & 0 deletions src/Stone/Parsers/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export const Parsers = {
...require('./Components'),
...require('./Conditionals'),
...require('./Includes'),
...require('./Layouts'),
Expand Down
56 changes: 56 additions & 0 deletions src/Stone/Types/StoneComponent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { make } from '../Support/MakeNode'

export function generate(node, state) {
node.output.assignments = node.output.assignments || [ ]

node.output.assignments.push({
kind: 'const',
left: make.identifier('__componentView'),
right: node.view
})

node.output.assignments.push({
kind: 'const',
left: make.identifier('__componentContext'),
right: !node.context.isNil ? node.context : make.object()
})

node.output.return = {
type: 'CallExpression',
callee: {
type: 'MemberExpression',
object: {
type: 'MemberExpression',
object: make.identifier('_'),
property: make.identifier('$stone'),
},
property: make.identifier('include'),
},
arguments: [
make.identifier('_'),
make.null(),
make.identifier('_templatePathname'),
make.identifier('__componentView'),
make.object([
make.property('slot', make.new('HtmlString', 'output')),
make.spread('__componentContext')
])
]
}

state.write('output += (')
this[node.output.type](node.output, state)
state.write(')();')
}

export function walk(node, st, c) {

}

export function scope(node, scope) {
node.scope = new Set(scope)
node.scope.add('__componentView')
node.scope.add('__componentContext')

this._scope(node.output, node.scope)
}
29 changes: 29 additions & 0 deletions src/Stone/Types/StoneSlot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export function generate(node, state) {
state.write('__componentContext[')
this[node.id.type](node.id, state)
state.write('] = ')

if(node.inline) {
this.StoneOutputExpression({ safe: true, value: node.output }, state)
} else {
state.write('(')
this[node.output.type](node.output, state)
state.write(')()')
}

state.write(';')
}

export function walk(node, st, c) {
c(node.id, st, 'Pattern')

if(node.inline) {
return
}

c(node.output, st, 'Expression')
}

export function scope(node, scope) {
this._scope(node.output, scope)
}
2 changes: 2 additions & 0 deletions src/Stone/Types/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export const Types = {
StoneComponent: require('./StoneComponent'),
StoneDump: require('./StoneDump'),
StoneEach: require('./StoneEach'),
StoneEmptyExpression: require('./StoneEmptyExpression'),
Expand All @@ -11,6 +12,7 @@ export const Types = {
StoneOutputBlock: require('./StoneOutputBlock'),
StoneOutputExpression: require('./StoneOutputExpression'),
StoneSection: require('./StoneSection'),
StoneSlot: require('./StoneSlot'),
StoneSuper: require('./StoneSuper'),
StoneTemplate: require('./StoneTemplate'),
StoneYield: require('./StoneYield'),
Expand Down

0 comments on commit e9b86c2

Please sign in to comment.