Przeglądaj źródła

component attr should take higher priority than placeholder attr with same name (fix #828)

Evan You 11 lat temu
rodzic
commit
e5054181aa

+ 29 - 1
src/compiler/transclude.js

@@ -89,7 +89,7 @@ function transcludeTemplate (el, options) {
         return frag
       } else {
         var replacer = frag.firstChild
-        _.copyAttributes(el, replacer)
+        copyAttrs(el, replacer, options)
         transcludeContent(replacer, rawContent)
         return replacer
       }
@@ -211,4 +211,32 @@ function extractAttrs (attrs) {
     if (name !== vwith) res[name] = true
   }
   return res
+}
+
+/**
+ * Copy attributes from one element to another.
+ *
+ * @param {Element} from
+ * @param {Element} to
+ * @param {Object} options
+ */
+
+function copyAttrs (from, to, options) {
+  if (from.hasAttributes()) {
+    var attrs = from.attributes
+    for (var i = 0, l = attrs.length; i < l; i++) {
+      var attr = attrs[i]
+      var name = attr.name
+      var value = attr.value
+      // do not overwrite
+      if (!to.hasAttribute(name)) {
+        to.setAttribute(name, value)
+      } else if (options._transcludedAttrs) {
+        // a parent container attribute is replaced by
+        // the replacer's attribute, we need to remove it
+        // from the list of transcluded attributes.
+        options._transcludedAttrs[name] = false
+      }
+    }
+  }
 }

+ 0 - 17
src/util/dom.js

@@ -104,23 +104,6 @@ exports.replace = function (target, el) {
   }
 }
 
-/**
- * Copy attributes from one element to another.
- *
- * @param {Element} from
- * @param {Element} to
- */
-
-exports.copyAttributes = function (from, to) {
-  if (from.hasAttributes()) {
-    var attrs = from.attributes
-    for (var i = 0, l = attrs.length; i < l; i++) {
-      var attr = attrs[i]
-      to.setAttribute(attr.name, attr.value)
-    }
-  }
-}
-
 /**
  * Add event listener shorthand.
  *

+ 10 - 0
test/unit/specs/compiler/transclude_spec.js

@@ -119,5 +119,15 @@ if (_.inBrowser) {
       expect(res.lastChild.textContent).toBe('fallback c')
     })
 
+    it('replacer attr should overwrite container attr of same name', function () {
+      el.setAttribute('class', 'test')
+      options.template = '<div class="other"></div>'
+      options.replace = true
+      options._asComponent = true
+      var res = transclude(el, options)
+      expect(res.getAttribute('class')).toBe('other')
+      expect(options._transcludedAttrs['class']).toBe(false)
+    })
+
   })
 }

+ 0 - 9
test/unit/specs/util/dom_spec.js

@@ -77,15 +77,6 @@ if (_.inBrowser) {
       expect(parent.firstChild).toBe(target)
     })
 
-    it('copyAttributes', function () {
-      parent.setAttribute('test1', 1)
-      parent.setAttribute('test2', 2)
-      _.copyAttributes(parent, target)
-      expect(target.attributes.length).toBe(2)
-      expect(target.getAttribute('test1')).toBe('1')
-      expect(target.getAttribute('test2')).toBe('2')
-    })
-
     it('on/off', function () {
       // IE requires element to be in document to fire events
       document.body.appendChild(target)