Skip to content

Commit 35883fa

Browse files
committed
Merge pull request #2564 from kazupon/fix/terminal-directive-compilation-loop
Fix terminal directive compilation loop
2 parents 01fe821 + 381469a commit 35883fa

File tree

2 files changed

+59
-16
lines changed

2 files changed

+59
-16
lines changed

src/compiler/compile.js

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -586,15 +586,17 @@ function checkTerminalDirectives (el, attrs, options) {
586586
}
587587
}
588588

589-
var attr, name, value, matched, dirName, arg, def, termDef
589+
var attr, name, value, modifiers, matched, dirName, rawName, arg, def, termDef
590590
for (var i = 0, j = attrs.length; i < j; i++) {
591591
attr = attrs[i]
592-
if ((matched = attr.name.match(dirAttrRE))) {
592+
modifiers = parseModifiers(attr.name)
593+
name = attr.name.replace(modifierRE, '')
594+
if ((matched = name.match(dirAttrRE))) {
593595
def = resolveAsset(options, 'directives', matched[1])
594596
if (def && def.terminal) {
595597
if (!termDef || ((def.priority || DEFAULT_TERMINAL_PRIORITY) > termDef.priority)) {
596598
termDef = def
597-
name = attr.name
599+
rawName = attr.name
598600
value = attr.value
599601
dirName = matched[1]
600602
arg = matched[2]
@@ -604,7 +606,7 @@ function checkTerminalDirectives (el, attrs, options) {
604606
}
605607

606608
if (termDef) {
607-
return makeTerminalNodeLinkFn(el, dirName, value, options, termDef, name, arg)
609+
return makeTerminalNodeLinkFn(el, dirName, value, options, termDef, rawName, arg, modifiers)
608610
}
609611
}
610612

@@ -622,28 +624,24 @@ skip.terminal = true
622624
* @param {String} value
623625
* @param {Object} options
624626
* @param {Object} def
625-
* @param {String} [attrName]
627+
* @param {String} [rawName]
626628
* @param {String} [arg]
629+
* @param {Object} [modifiers]
627630
* @return {Function} terminalLinkFn
628631
*/
629632

630-
function makeTerminalNodeLinkFn (el, dirName, value, options, def, attrName, arg) {
633+
function makeTerminalNodeLinkFn (el, dirName, value, options, def, rawName, arg, modifiers) {
631634
var parsed = parseDirective(value)
632635
var descriptor = {
633636
name: dirName,
637+
arg: arg,
634638
expression: parsed.expression,
635639
filters: parsed.filters,
636640
raw: value,
637-
rawName: attrName,
641+
attr: rawName,
642+
modifiers: modifiers,
638643
def: def
639644
}
640-
if (attrName) {
641-
descriptor.rawName = attrName
642-
descriptor.modifiers = parseModifiers(attrName)
643-
}
644-
if (arg) {
645-
descriptor.arg = arg.replace(modifierRE, '')
646-
}
647645
// check ref for v-for and router-view
648646
if (dirName === 'for' || dirName === 'router-view') {
649647
descriptor.ref = findRef(el)

test/unit/specs/compiler/compile_spec.js

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
var Vue = require('src')
22
var _ = require('src/util')
3+
var FragmentFactory = require('src/fragment/factory')
34
var compiler = require('src/compiler')
45
var compile = compiler.compile
56
var publicDirectives = require('src/directives/public')
@@ -264,7 +265,7 @@ describe('Compile', function () {
264265
var args = vm._bindDir.calls.argsFor(0)
265266
expect(args[0].name).toBe('term')
266267
expect(args[0].expression).toBe('foo')
267-
expect(args[0].rawName).toBe('v-term:arg1.modifier1.modifier2')
268+
expect(args[0].attr).toBe('v-term:arg1.modifier1.modifier2')
268269
expect(args[0].arg).toBe('arg1')
269270
expect(args[0].modifiers.modifier1).toBe(true)
270271
expect(args[0].modifiers.modifier2).toBe(true)
@@ -286,7 +287,7 @@ describe('Compile', function () {
286287
var args = vm._bindDir.calls.argsFor(0)
287288
expect(args[0].name).toBe('term')
288289
expect(args[0].expression).toBe('')
289-
expect(args[0].rawName).toBe('v-term:arg1')
290+
expect(args[0].attr).toBe('v-term:arg1')
290291
expect(args[0].arg).toBe('arg1')
291292
expect(args[0].def).toBe(defTerminal)
292293
})
@@ -669,4 +670,48 @@ describe('Compile', function () {
669670
expect(el.textContent).toBe('worked!')
670671
expect(getWarnCount()).toBe(0)
671672
})
673+
674+
// #xxx
675+
it('should compile build-in terminal directive wihtout loop', function (done) {
676+
var vm = new Vue({
677+
el: el,
678+
data: { show: false },
679+
template: '<p v-if:arg1.modifier1="show">hello world</p>'
680+
})
681+
vm.show = true
682+
_.nextTick(function () {
683+
expect(el.textContent).toBe('hello world')
684+
done()
685+
})
686+
})
687+
688+
it('should compile custom terminal directive wihtout loop', function (done) {
689+
var vm = new Vue({
690+
el: el,
691+
data: { show: false },
692+
template: '<p v-if="show" v-inject:modal.modifier1="foo">hello world</p>',
693+
directives: {
694+
inject: {
695+
terminal: true,
696+
priority: Vue.options.directives.if.priority + 1,
697+
bind: function () {
698+
this.anchor = _.createAnchor('v-inject')
699+
_.replace(this.el, this.anchor)
700+
var factory = new FragmentFactory(this.vm, this.el)
701+
this.frag = factory.create(this._host, this._scope, this._frag)
702+
this.frag.before(this.anchor)
703+
},
704+
unbind: function () {
705+
this.frag.remove()
706+
_.replace(this.anchor, this.el)
707+
}
708+
}
709+
}
710+
})
711+
vm.show = true
712+
_.nextTick(function () {
713+
expect(el.textContent).toBe('hello world')
714+
done()
715+
})
716+
})
672717
})

0 commit comments

Comments
 (0)