Ver código fonte

add elementDirectives

Evan You 11 anos atrás
pai
commit
78271e5f8a

+ 1 - 1
src/api/global.js

@@ -103,8 +103,8 @@ exports.use = function (plugin) {
 
 var assetTypes = [
   'directive',
+  'elementDirective',
   'filter',
-  'partial',
   'transition'
 ]
 

+ 22 - 3
src/compiler/compile.js

@@ -194,8 +194,10 @@ function compileElement (el, options) {
   }
   var linkFn
   var hasAttrs = el.hasAttributes()
+  // check element directives
+  linkFn = checkElementDirectives(el, options)
   // check terminal direcitves (repeat & if)
-  if (hasAttrs) {
+  if (!linkFn && hasAttrs) {
     linkFn = checkTerminalDirectives(el, options)
   }
   // check component
@@ -444,6 +446,22 @@ function makePropsLinkFn (props) {
   }
 }
 
+/**
+ * Check for element directives (custom elements that should
+ * be resovled as terminal directives).
+ *
+ * @param {Element} el
+ * @param {Object} options
+ */
+
+function checkElementDirectives (el, options) {
+  var tag = el.tagName.toLowerCase()
+  var def = options.elementDirectives[tag]
+  if (def) {
+    return makeTerminalNodeLinkFn(el, tag, '', options, def)
+  }
+}
+
 /**
  * Check if an element is a component. If yes, return
  * a component link function.
@@ -503,12 +521,13 @@ skip.terminal = true
  * @param {String} dirName
  * @param {String} value
  * @param {Object} options
+ * @param {Object} [def]
  * @return {Function} terminalLinkFn
  */
 
-function makeTerminalNodeLinkFn (el, dirName, value, options) {
+function makeTerminalNodeLinkFn (el, dirName, value, options, def) {
   var descriptor = dirParser.parse(value)[0]
-  var def = options.directives[dirName]
+  def = def || options.directives[dirName]
   var fn = function terminalNodeLinkFn (vm, el, host) {
     vm._bindDir(dirName, el, descriptor, def, host)
   }

+ 0 - 1
src/directives/component.js

@@ -3,7 +3,6 @@ var templateParser = require('../parsers/template')
 
 module.exports = {
 
-  _internal: true,
   isLiteral: true,
 
   /**

+ 0 - 2
src/directives/prop.js

@@ -4,8 +4,6 @@ var expParser = require('../parsers/expression')
 
 module.exports = {
 
-  _internal: true,
-
   bind: function () {
 
     var child = this.vm

+ 2 - 2
src/util/merge-option.js

@@ -133,9 +133,9 @@ strats.props = function (parentVal, childVal) {
 
 strats.directives =
 strats.filters =
-strats.partials =
 strats.transitions =
-strats.components = function (parentVal, childVal, vm, key) {
+strats.components =
+strats.elementDirectives = function (parentVal, childVal, vm, key) {
   var ret = Object.create(
     vm && vm.$parent
       ? vm.$parent.$options[key]

+ 2 - 2
src/vue.js

@@ -37,9 +37,9 @@ extend(Vue, require('./api/global'))
 Vue.options = {
   directives  : require('./directives'),
   filters     : require('./filters'),
-  partials    : {},
   transitions : {},
-  components  : {}
+  components  : {},
+  elementDirectives: {}
 }
 
 /**

+ 2 - 2
test/unit/specs/api/global_spec.js

@@ -61,11 +61,11 @@ describe('Global API', function () {
 
     var Test = Vue.extend()
     
-    it('directive / filter / partial / transition', function () {
+    it('directive / elementDirective / filter / transition', function () {
       [
         'directive',
+        'elementDirective',
         'filter',
-        'partial',
         'transition'
       ].forEach(function (type) {
         var def = {}

+ 16 - 0
test/unit/specs/compiler/compile_spec.js

@@ -352,5 +352,21 @@ if (_.inBrowser) {
       })
     })
 
+    it('element directive', function () {
+      var vm = new Vue({
+        el: el,
+        template: '<test>{{a}}</test>',
+        elementDirectives: {
+          test: {
+            bind: function () {
+              this.el.setAttribute('test', '1')
+            }
+          }
+        }
+      })
+      // should be terminal
+      expect(el.innerHTML).toBe('<test test="1">{{a}}</test>')
+    })
+
   })
 }