Skip to content

Commit 628c42c

Browse files
committed
component refactor
1 parent e04553a commit 628c42c

17 files changed

+112
-258
lines changed

component.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
"src/directives/if.js",
2525
"src/directives/repeat.js",
2626
"src/directives/on.js",
27-
"src/directives/model.js"
27+
"src/directives/model.js",
28+
"src/directives/component.js"
2829
],
2930
"dependencies": {
3031
"component/emitter": "*"

src/compiler.js

Lines changed: 30 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,9 @@ function Compiler (vm, options) {
7171

7272
// set parent VM
7373
// and register child id on parent
74-
var childId = utils.attr(el, 'id')
74+
var childId = utils.attr(el, 'component-id')
7575
if (parent) {
76+
parent.childCompilers.push(compiler)
7677
def(vm, '$parent', parent.vm)
7778
if (childId) {
7879
compiler.childId = childId
@@ -217,18 +218,20 @@ CompilerProto.setupObserver = function () {
217218
*/
218219
CompilerProto.compile = function (node, root) {
219220

220-
var compiler = this
221+
var compiler = this,
222+
nodeType = node.nodeType,
223+
tagName = node.tagName
221224

222-
if (node.nodeType === 1) { // a normal node
225+
if (nodeType === 1 && tagName !== 'SCRIPT') { // a normal node
223226

224227
// skip anything with v-pre
225228
if (utils.attr(node, 'pre') !== null) return
226229

227230
// special attributes to check
228231
var repeatExp,
229-
componentId,
232+
componentExp,
230233
partialId,
231-
customElementFn = compiler.getOption('elements', node.tagName.toLowerCase())
234+
directive
232235

233236
// It is important that we access these attributes
234237
// procedurally because the order matters.
@@ -242,21 +245,25 @@ CompilerProto.compile = function (node, root) {
242245
if (repeatExp = utils.attr(node, 'repeat')) {
243246

244247
// repeat block cannot have v-id at the same time.
245-
var directive = Directive.parse(config.attrs.repeat, repeatExp, compiler, node)
248+
directive = Directive.parse(config.attrs.repeat, repeatExp, compiler, node)
246249
if (directive) {
247250
compiler.bindDirective(directive)
248251
}
249252

250-
// custom elements has 2nd highest priority
251-
} else if (!root && customElementFn) {
252-
253-
addChild(customElementFn)
254-
255-
// v-component has 3rd highest priority
256-
} else if (!root && (componentId = utils.attr(node, 'component'))) {
253+
// v-component has 2nd highest priority
254+
} else if (!root && (componentExp = utils.attr(node, 'component'))) {
257255

258-
var ChildVM = compiler.getOption('components', componentId)
259-
if (ChildVM) addChild(ChildVM)
256+
directive = Directive.parse(config.attrs.component, componentExp, compiler, node)
257+
if (directive) {
258+
// component directive is a bit different from the others.
259+
// when it has no argument, it should be treated as a
260+
// simple directive with its key as the argument.
261+
if (componentExp.indexOf(':') === -1) {
262+
directive.isSimple = true
263+
directive.arg = directive.key
264+
}
265+
compiler.bindDirective(directive)
266+
}
260267

261268
} else {
262269

@@ -277,27 +284,12 @@ CompilerProto.compile = function (node, root) {
277284
compiler.compileNode(node)
278285
}
279286

280-
} else if (node.nodeType === 3) { // text node
287+
} else if (nodeType === 3) { // text node
281288

282289
compiler.compileTextNode(node)
283290

284291
}
285292

286-
function addChild (Ctor) {
287-
if (utils.isConstructor(Ctor)) {
288-
var child = new Ctor({
289-
el: node,
290-
child: true,
291-
compilerOptions: {
292-
parentCompiler: compiler
293-
}
294-
})
295-
compiler.childCompilers.push(child.$compiler)
296-
} else {
297-
// simply call the function
298-
Ctor(node)
299-
}
300-
}
301293
}
302294

303295
/**
@@ -412,13 +404,13 @@ CompilerProto.bindDirective = function (directive) {
412404
binding.instances.push(directive)
413405
directive.binding = binding
414406

415-
var value = binding.value
416407
// invoke bind hook if exists
417408
if (directive.bind) {
418-
directive.bind(value)
409+
directive.bind()
419410
}
420411

421412
// set initial value
413+
var value = binding.value
422414
if (value !== undefined) {
423415
if (binding.isComputed) {
424416
directive.refresh(value)
@@ -454,11 +446,11 @@ CompilerProto.createBinding = function (key, isExp, isFn) {
454446
bindings[key] = binding
455447
// make sure the key exists in the object so it can be observed
456448
// by the Observer!
457-
Observer.ensurePath(compiler.vm, key)
458449
if (binding.root) {
459450
// this is a root level binding. we need to define getter/setters for it.
460451
compiler.define(key, binding)
461452
} else {
453+
Observer.ensurePath(compiler.vm, key)
462454
var parentKey = key.slice(0, key.lastIndexOf('.'))
463455
if (!hasOwn.call(bindings, parentKey)) {
464456
// this is a nested value binding, but the binding for its parent
@@ -488,9 +480,10 @@ CompilerProto.define = function (key, binding) {
488480
// computed property
489481
compiler.markComputed(binding)
490482
} else if (type === 'Object' || type === 'Array') {
491-
// observe objects later, becase there might be more keys
492-
// to be added to it. we also want to emit all the set events
493-
// after all values are available.
483+
// observe objects later, because there might be more keys
484+
// to be added to it during Observer.ensurePath().
485+
// we also want to emit all the set events after all values
486+
// are available.
494487
compiler.observables.push(binding)
495488
}
496489

src/deps-parser.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ var Emitter = require('./emitter'),
99
function catchDeps (binding) {
1010
if (binding.isFn) return
1111
utils.log('\n─ ' + binding.key)
12-
var depsHash = utils.hash()
12+
var has = []
1313
observer.on('get', function (dep) {
14-
if (depsHash[dep.key]) return
15-
depsHash[dep.key] = 1
14+
if (has.indexOf(dep) > -1) return
15+
has.push(dep)
1616
utils.log(' └─ ' + dep.key)
1717
binding.deps.push(dep)
1818
dep.subs.push(binding)

src/directives/component.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
var utils = require('../utils')
2+
3+
module.exports = {
4+
5+
bind: function () {
6+
if (this.isSimple) {
7+
this.build()
8+
}
9+
},
10+
11+
update: function (value) {
12+
if (!this.component) {
13+
this.build(value)
14+
} else {
15+
this.component.model = value
16+
}
17+
},
18+
19+
build: function (value) {
20+
var Ctor = this.compiler.getOption('components', this.arg)
21+
if (!Ctor) utils.warn('unknown component: ' + this.arg)
22+
var options = {
23+
el: this.el,
24+
compilerOptions: {
25+
parentCompiler: this.compiler
26+
}
27+
}
28+
if (value) {
29+
options.scope = {
30+
model: value
31+
}
32+
}
33+
this.component = new Ctor(options)
34+
},
35+
36+
unbind: function () {
37+
this.component.$destroy()
38+
}
39+
40+
}

src/directives/index.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ var utils = require('../utils'),
33

44
module.exports = {
55

6-
on : require('./on'),
7-
repeat : require('./repeat'),
8-
model : require('./model'),
9-
'if' : require('./if'),
6+
on : require('./on'),
7+
repeat : require('./repeat'),
8+
model : require('./model'),
9+
'if' : require('./if'),
10+
component : require('./component'),
1011

1112
attr: function (value) {
1213
this.el.setAttribute(this.arg, value)

src/main.js

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,6 @@ ViewModel.component = function (id, Ctor) {
4242
return this
4343
}
4444

45-
/**
46-
* Allows user to register/retrieve a Custom element constructor
47-
*/
48-
ViewModel.element = function (id, Ctor) {
49-
if (!Ctor) return utils.elements[id]
50-
utils.elements[id] = utils.toConstructor(Ctor)
51-
return this
52-
}
53-
5445
/**
5546
* Allows user to register/retrieve a template partial
5647
*/
@@ -141,12 +132,12 @@ function inheritOptions (child, parent, topLevel) {
141132
* that are used in compilation.
142133
*/
143134
var specialAttributes = [
144-
'id',
145135
'pre',
146136
'text',
147137
'repeat',
148138
'partial',
149139
'component',
140+
'component-id',
150141
'transition'
151142
]
152143

src/observer.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,10 +214,12 @@ function ensurePath (obj, key) {
214214
if (!obj[sec]) obj[sec] = {}
215215
obj = obj[sec]
216216
}
217-
if (typeOf(obj) === 'Object') {
217+
var type = typeOf(obj)
218+
if (type === 'Object' || type === 'Array') {
218219
sec = path[i]
219220
if (!(sec in obj)) obj[sec] = undefined
220221
}
222+
return obj[sec]
221223
}
222224

223225
module.exports = {

src/utils.js

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ var utils = module.exports = {
2222
components : makeHash(),
2323
partials : makeHash(),
2424
transitions : makeHash(),
25-
elements : makeHash(),
2625

2726
/**
2827
* get an attribute and remove it.
@@ -141,30 +140,19 @@ var utils = module.exports = {
141140
: null
142141
},
143142

144-
isConstructor: function (obj) {
145-
ViewModel = ViewModel || require('./viewmodel')
146-
return obj.prototype instanceof ViewModel || obj === ViewModel
147-
},
148-
149143
/**
150144
* convert certain option values to the desired format.
151145
*/
152146
processOptions: function (options) {
153147
var components = options.components,
154148
partials = options.partials,
155149
template = options.template,
156-
elements = options.elements,
157150
key
158151
if (components) {
159152
for (key in components) {
160153
components[key] = utils.toConstructor(components[key])
161154
}
162155
}
163-
if (elements) {
164-
for (key in elements) {
165-
elements[key] = utils.toConstructor(elements[key])
166-
}
167-
}
168156
if (partials) {
169157
for (key in partials) {
170158
partials[key] = utils.toFragment(partials[key])
@@ -185,11 +173,11 @@ var utils = module.exports = {
185173
},
186174

187175
/**
188-
* warnings, thrown in all cases
176+
* warnings, traces by default
177+
* can be suppressed by `silent` option.
189178
*/
190179
warn: function() {
191180
if (!config.silent && console) {
192-
console.trace()
193181
console.warn(join.call(arguments, ' '))
194182
}
195183
}

test/functional/fixtures/custom-element.html

Lines changed: 0 additions & 40 deletions
This file was deleted.

0 commit comments

Comments
 (0)