Skip to content

Commit a9af6c0

Browse files
committed
implement scope-wise directive priority
1 parent f4af9f6 commit a9af6c0

File tree

10 files changed

+63
-40
lines changed

10 files changed

+63
-40
lines changed

src/compiler/compile.js

Lines changed: 19 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -87,29 +87,26 @@ function linkAndCapture (linker, vm) {
8787
var originalDirCount = vm._directives.length
8888
linker()
8989
var dirs = vm._directives.slice(originalDirCount)
90-
var dir
90+
dirs.sort(directiveComparator)
9191
for (var i = 0, l = dirs.length; i < l; i++) {
92-
dir = dirs[i]
93-
if (dir.name === 'if' ||
94-
dir.name === 'for' ||
95-
dir.name === 'repeat') {
96-
dir._bind()
97-
}
98-
}
99-
for (var i = 0, l = dirs.length; i < l; i++) {
100-
dir = dirs[i]
101-
if (dir.name === 'component' ||
102-
dir.name === 'el') {
103-
dir._bind()
104-
}
105-
}
106-
for (var i = 0, l = dirs.length; i < l; i++) {
107-
dir = dirs[i]
108-
if (!dir._bound) dir._bind()
92+
dirs[i]._bind()
10993
}
11094
return dirs
11195
}
11296

97+
/**
98+
* Directive priority sort comparator
99+
*
100+
* @param {Object} a
101+
* @param {Object} b
102+
*/
103+
104+
function directiveComparator (a, b) {
105+
a = a._def.priority || 0
106+
b = b._def.priority || 0
107+
return a > b ? -1 : a === b ? 0 : 1
108+
}
109+
113110
/**
114111
* Linker functions return an unlink function that
115112
* tearsdown all directives instances generated during
@@ -264,8 +261,10 @@ function compileElement (el, options) {
264261
// textarea treats its text content as the initial value.
265262
// just bind it as a v-attr directive for value.
266263
if (el.tagName === 'TEXTAREA') {
267-
if (textParser.parse(el.value)) {
268-
el.setAttribute('value', el.value)
264+
var tokens = textParser.parse(el.value)
265+
if (tokens) {
266+
el.setAttribute('bind-value', textParser.tokensToExp(tokens))
267+
el.value = ''
269268
}
270269
}
271270
var linkFn
@@ -629,7 +628,6 @@ function compileDirectives (attrs, options) {
629628
}
630629
// sort by priority, LOW to HIGH
631630
if (dirs.length) {
632-
dirs.sort(directiveComparator)
633631
return makeNodeLinkFn(dirs)
634632
}
635633
}
@@ -717,16 +715,3 @@ function collectAttrDirective (name, value, options) {
717715
}
718716
}
719717
}
720-
721-
/**
722-
* Directive priority sort comparator
723-
*
724-
* @param {Object} a
725-
* @param {Object} b
726-
*/
727-
728-
function directiveComparator (a, b) {
729-
a = a.def.priority || 0
730-
b = b.def.priority || 0
731-
return a > b ? 1 : -1
732-
}

src/directives/component.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ var templateParser = require('../parsers/template')
55
module.exports = {
66

77
isLiteral: true,
8+
priority: 1500,
89

910
/**
1011
* Setup. Two possible usages:

src/directives/el.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ var _ = require('../util')
33
module.exports = {
44

55
isLiteral: true,
6-
priority: 1000,
6+
priority: 1500,
77

88
bind: function () {
99
var scope = this._scope || this.vm

src/directives/for.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ var uid = 0
77

88
module.exports = {
99

10+
priority: 2000,
11+
1012
bind: function () {
1113

1214
// some helpful tips...

src/directives/if.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ var FragmentFactory = require('../fragment/factory')
33

44
module.exports = {
55

6+
priority: 2000,
7+
68
bind: function () {
79
var el = this.el
810
if (!el.__vue__) {

src/directives/repeat.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ var ABORTED = 3
1717

1818
module.exports = {
1919

20+
priority: 2000,
21+
2022
/**
2123
* Setup.
2224
*/

src/element-directives/partial.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ var vIf = require('../directives/if')
55

66
module.exports = {
77

8+
priority: 1750,
9+
810
bind: function () {
911
var el = this.el
1012
this.anchor = _.createAnchor('v-partial')

src/element-directives/slot.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ var templateParser = require('../parsers/template')
99

1010
module.exports = {
1111

12+
priority: 1750,
13+
1214
bind: function () {
1315

1416
this.isSlot = this.el.tagName === 'SLOT'

test/unit/specs/compiler/compile_spec.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,13 @@ if (_.inBrowser) {
1919
vm = {
2020
_data: {},
2121
_directives: [],
22-
_bindDir: function (name) {
22+
_bindDir: function (name, node, desc, def) {
2323
this._directives.push({
2424
name: name,
25-
_bind: directiveBind,
25+
_def: def,
26+
_bind: function () {
27+
directiveBind(this.name)
28+
},
2629
_teardown: directiveTeardown
2730
})
2831
},
@@ -68,8 +71,11 @@ if (_.inBrowser) {
6871
expect(vm._bindDir).toHaveBeenCalledWith('b', el.firstChild, descriptorB, defB, undefined, undefined, undefined, undefined)
6972
expect(vm._bindDir).toHaveBeenCalledWith('b', el.lastChild, descriptorB, defB, undefined, undefined, undefined, undefined)
7073
// check the priority sorting
71-
// the "b" on the firstNode should be called first!
72-
expect(vm._bindDir.calls.argsFor(1)[0]).toBe('b')
74+
// the "b"s should be called first!
75+
expect(directiveBind.calls.argsFor(0)[0]).toBe('b')
76+
expect(directiveBind.calls.argsFor(1)[0]).toBe('b')
77+
expect(directiveBind.calls.argsFor(2)[0]).toBe('a')
78+
expect(directiveBind.calls.argsFor(3)[0]).toBe('a')
7379
})
7480

7581
it('bind- syntax', function () {

test/unit/specs/directives/el_spec.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,35 @@ if (_.inBrowser) {
1313
it('normal', function () {
1414
var vm = new Vue({
1515
el: el,
16-
template: '<div el="test" id="test"></div>'
16+
template: '<div v-el="test" id="test"></div>'
1717
})
1818
expect(vm.$$.test).toBeTruthy()
1919
expect(vm.$$.test.id).toBe('test')
2020
vm._directives[0]._teardown()
2121
expect(vm.$$.test).toBeNull()
2222
})
2323

24+
it('normal (new syntax)', function (done) {
25+
var vm = new Vue({
26+
el: el,
27+
data: {
28+
ok: true
29+
},
30+
template: '<div v-if="ok" el="test" id="test"></div>'
31+
})
32+
expect(vm.$$.test).toBeTruthy()
33+
expect(vm.$$.test.id).toBe('test')
34+
vm.ok = false
35+
_.nextTick(function () {
36+
expect(vm.$$.test).toBeNull()
37+
vm.ok = true
38+
_.nextTick(function () {
39+
expect(vm.$$.test.id).toBe('test')
40+
done()
41+
})
42+
})
43+
})
44+
2445
it('with v-repeat', function (done) {
2546
var vm = new Vue({
2647
el: el,

0 commit comments

Comments
 (0)