From 1d85fcbd35bd581bbf157326930078277d7de0eb Mon Sep 17 00:00:00 2001 From: fergaldoyle Date: Wed, 4 Nov 2015 15:12:01 +0000 Subject: [PATCH 1/2] IE should prefer all bound props other than class --- package.json | 1 + src/compiler/compile-props.js | 43 ++++++++++++++++++++++++++++------- test/unit/specs/misc_spec.js | 9 +++++++- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 2ace33e465b..bd480f71abc 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "karma-commonjs": "^0.0.13", "karma-coverage": "^0.5.0", "karma-firefox-launcher": "^0.1.6", + "karma-ie-launcher": "^0.2.0", "karma-jasmine": "^0.3.6", "karma-phantomjs-launcher": "^0.2.1", "karma-safari-launcher": "^0.1.1", diff --git a/src/compiler/compile-props.js b/src/compiler/compile-props.js index 266d4760b2f..cecbd553b62 100644 --- a/src/compiler/compile-props.js +++ b/src/compiler/compile-props.js @@ -8,6 +8,15 @@ var empty = {} var identRE = require('../parsers/path').identRE var settablePathRE = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*|\[[^\[\]]+\])*$/ +// feature detect browsers (IE) that have trouble +// with binding syntax on certain attributes +var div, preferBinding +if (_.inBrowser) { + div = document.createElement('div') + div.setAttribute(':title', '') + preferBinding = div.getAttribute('title') !== null +} + /** * Compile props on a root element and return * a props link function. @@ -21,7 +30,7 @@ module.exports = function compileProps (el, propOptions) { var props = [] var names = Object.keys(propOptions) var i = names.length - var options, name, attr, value, path, parsed, prop, isTitleBinding + var options, name, attr, value, path, parsed, prop, hasBinding while (i--) { name = names[i] options = propOptions[name] || empty @@ -50,16 +59,12 @@ module.exports = function compileProps (el, propOptions) { mode: propBindingModes.ONE_WAY } - // IE title issues - isTitleBinding = false - if (name === 'title' && (el.getAttribute(':title') || el.getAttribute('v-bind:title'))) { - isTitleBinding = true - } + attr = _.hyphenate(name) + hasBinding = preferBinding && checkBindingAttr(el, attr) !== null // first check literal version - attr = _.hyphenate(name) value = prop.raw = _.attr(el, attr) - if (value === null || isTitleBinding) { + if (value === null || hasBinding) { // then check dynamic version if ((value = _.getBindAttr(el, attr)) === null) { if ((value = _.getBindAttr(el, attr + '.sync')) !== null) { @@ -119,6 +124,28 @@ module.exports = function compileProps (el, propOptions) { return makePropsLinkFn(props) } +/** + * Check existance of an attribute with binding syntax. + * + * @param {Element} el + * @return {String} attr + */ + +function checkBindingAttr (el, attr) { + if (attr === 'class') { + return null + } + + return ( + el.getAttribute(':' + attr) || + el.getAttribute(':' + attr + '.once') || + el.getAttribute(':' + attr + '.sync') || + el.getAttribute('v-bind:' + attr) || + el.getAttribute('v-bind:' + attr + '.once') || + el.getAttribute('v-bind:' + attr + '.sync') + ) +} + /** * Build a function that applies props to a vm. * diff --git a/test/unit/specs/misc_spec.js b/test/unit/specs/misc_spec.js index dce78e904e3..46a401ce91d 100644 --- a/test/unit/specs/misc_spec.js +++ b/test/unit/specs/misc_spec.js @@ -270,7 +270,7 @@ describe('Misc', function () { expect(hasWarned(__, 'Unknown custom element')).toBe(true) }) - it('prefer bound title over static title', function (done) { + it('prefer bound attributes over static attributes', function (done) { var el = document.createElement('div') var count = 0 var expected = [ @@ -289,6 +289,13 @@ describe('Misc', function () { } document.body.appendChild(el) + + el.setAttribute(':title', '') + if(el.getAttribute('title') === null) { + // this browser does not need this test + done() + return + } new Vue({ el: el, From ccec91519288ab80a09832189dd702a3f89a7582 Mon Sep 17 00:00:00 2001 From: fergaldoyle Date: Wed, 4 Nov 2015 19:49:12 +0000 Subject: [PATCH 2/2] preferBinding moved to util, use hasAttribute, no need to check for modifiers --- src/compiler/compile-props.js | 23 +++++------------------ src/util/env.js | 11 +++++++++++ 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/compiler/compile-props.js b/src/compiler/compile-props.js index 59671b17780..8173d2935b8 100644 --- a/src/compiler/compile-props.js +++ b/src/compiler/compile-props.js @@ -8,15 +8,6 @@ var empty = {} var identRE = require('../parsers/path').identRE var settablePathRE = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*|\[[^\[\]]+\])*$/ -// feature detect browsers (IE) that have trouble -// with binding syntax on certain attributes -var div, preferBinding -if (_.inBrowser) { - div = document.createElement('div') - div.setAttribute(':title', '') - preferBinding = div.getAttribute('title') !== null -} - /** * Compile props on a root element and return * a props link function. @@ -60,7 +51,7 @@ module.exports = function compileProps (el, propOptions) { } attr = _.hyphenate(name) - hasBinding = preferBinding && checkBindingAttr(el, attr) !== null + hasBinding = _.preferBinding && hasBindingAttr(el, attr) // first check literal version value = prop.raw = _.attr(el, attr) @@ -131,18 +122,14 @@ module.exports = function compileProps (el, propOptions) { * @return {String} attr */ -function checkBindingAttr (el, attr) { +function hasBindingAttr (el, attr) { if (attr === 'class') { - return null + return false } return ( - el.getAttribute(':' + attr) || - el.getAttribute(':' + attr + '.once') || - el.getAttribute(':' + attr + '.sync') || - el.getAttribute('v-bind:' + attr) || - el.getAttribute('v-bind:' + attr + '.once') || - el.getAttribute('v-bind:' + attr + '.sync') + el.hasAttribute(':' + attr) || + el.hasAttribute('v-bind:' + attr) ) } diff --git a/src/util/env.js b/src/util/env.js index 065ba465434..f804eadda25 100644 --- a/src/util/env.js +++ b/src/util/env.js @@ -83,3 +83,14 @@ exports.nextTick = (function () { timerFunc(nextTickHandler, 0) } })() + +// feature detect browsers (IE) that have trouble +// with binding syntax on certain attributes +var div +var preferBinding = false +if (inBrowser) { + div = document.createElement('div') + div.setAttribute(':title', '') + preferBinding = div.getAttribute('title') !== null +} +exports.preferBinding = preferBinding