Comparing version 0.12.12 to 1.0.0-alpha.1
{ | ||
"name": "vue", | ||
"version": "0.12.12", | ||
"version": "1.0.0-alpha.1", | ||
"author": "Evan You <yyx990803@gmail.com>", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -17,4 +17,6 @@ var _ = require('../util') | ||
opts = opts || {} | ||
var ChildVue | ||
var parent = this | ||
var ChildVue | ||
// transclusion context | ||
var context = opts._context || parent | ||
var inherit = opts.inherit !== undefined | ||
@@ -24,3 +26,3 @@ ? opts.inherit | ||
if (inherit) { | ||
var ctors = parent._childCtors | ||
var ctors = context._childCtors | ||
ChildVue = ctors[BaseCtor.cid] | ||
@@ -39,5 +41,3 @@ if (!ChildVue) { | ||
ChildVue.linker = BaseCtor.linker | ||
// important: transcluded inline repeaters should | ||
// inherit from outer scope rather than host | ||
ChildVue.prototype = opts._context || this | ||
ChildVue.prototype = context | ||
ctors[BaseCtor.cid] = ChildVue | ||
@@ -44,0 +44,0 @@ } |
@@ -41,3 +41,3 @@ var Watcher = require('../watcher') | ||
/** | ||
* Add a property on the VM | ||
* Add a property on the VM (deorecated) | ||
* | ||
@@ -49,3 +49,6 @@ * @param {String} key | ||
exports.$add = function (key, val) { | ||
this._data.$add(key, val) | ||
this._data.$set(key, val) | ||
if (process.env.NODE_ENV !== 'production') { | ||
require('../util').deprecation.ADD() | ||
} | ||
} | ||
@@ -52,0 +55,0 @@ |
@@ -90,20 +90,17 @@ var _ = require('../util') | ||
exports.$emit = function (event) { | ||
this._eventCancelled = false | ||
this._shouldPropagate = false | ||
var cbs = this._events[event] | ||
if (cbs) { | ||
// avoid leaking arguments: | ||
// http://jsperf.com/closure-with-arguments | ||
var i = arguments.length - 1 | ||
var args = new Array(i) | ||
while (i--) { | ||
args[i] = arguments[i + 1] | ||
} | ||
i = 0 | ||
cbs = cbs.length > 1 | ||
? _.toArray(cbs) | ||
: cbs | ||
for (var l = cbs.length; i < l; i++) { | ||
if (cbs[i].apply(this, args) === false) { | ||
this._eventCancelled = true | ||
var args = _.toArray(arguments, 1) | ||
for (var i = 0, l = cbs.length; i < l; i++) { | ||
var res = cbs[i].apply(this, args) | ||
if (res === true) { | ||
this._shouldPropagate = true | ||
} | ||
if (process.env.NODE_ENV !== 'production' && res === false) { | ||
_.deprecation.PROPAGATION(event) | ||
} | ||
} | ||
@@ -129,3 +126,3 @@ } | ||
child.$emit.apply(child, arguments) | ||
if (!child._eventCancelled) { | ||
if (child._shouldPropagate) { | ||
child.$broadcast.apply(child, arguments) | ||
@@ -148,5 +145,5 @@ } | ||
parent.$emit.apply(parent, arguments) | ||
parent = parent._eventCancelled | ||
? null | ||
: parent.$parent | ||
parent = parent._shouldPropagate | ||
? parent.$parent | ||
: null | ||
} | ||
@@ -153,0 +150,0 @@ return this |
@@ -39,7 +39,4 @@ var _ = require('../util') | ||
var Super = this | ||
var Sub = createClass( | ||
extendOptions.name || | ||
Super.options.name || | ||
'VueComponent' | ||
) | ||
var name = extendOptions.name || Super.options.name | ||
var Sub = createClass(name || 'VueComponent') | ||
Sub.prototype = Object.create(Super.prototype) | ||
@@ -60,2 +57,6 @@ Sub.prototype.constructor = Sub | ||
}) | ||
// enable recursive self-lookup | ||
if (name) { | ||
Sub.options.components[name] = Sub | ||
} | ||
return Sub | ||
@@ -62,0 +63,0 @@ } |
@@ -66,4 +66,6 @@ var _ = require('../util') | ||
exports.$compile = function (el, host) { | ||
return compiler.compile(el, this.$options, true)(this, el, host) | ||
exports.$compile = function (el, host, scope, frag) { | ||
return compiler.compile(el, this.$options, true)( | ||
this, el, host, scope, frag | ||
) | ||
} |
@@ -13,3 +13,3 @@ var _ = require('../util') | ||
/** | ||
* Compile param attributes on a root element and return | ||
* Compile props on a root element and return | ||
* a props link function. | ||
@@ -22,2 +22,5 @@ * | ||
// TODO: 1.0.0 we can just loop through el.attributes and | ||
// check for prop- prefixes. | ||
module.exports = function compileProps (el, propOptions) { | ||
@@ -30,2 +33,9 @@ var props = [] | ||
name = options.name | ||
if (process.env.NODE_ENV !== 'production') { | ||
if (name === '$data') { | ||
_.deprecation.DATA_AS_PROP() | ||
} | ||
} | ||
// props could contain dashes, which will be | ||
@@ -44,6 +54,17 @@ // interpreted as minus calculations by the parser | ||
value = el.getAttribute(attr) | ||
if (value !== null && process.env.NODE_ENV !== 'production') { | ||
_.deprecation.PROPS(attr, value) | ||
} | ||
if (value === null) { | ||
attr = 'data-' + attr | ||
value = el.getAttribute(attr) | ||
value = el.getAttribute('data-' + attr) | ||
if (value !== null) { | ||
attr = 'data-' + attr | ||
if (process.env.NODE_ENV !== 'production') { | ||
_.deprecation.PROPS(attr, value) | ||
} | ||
} | ||
} | ||
// create a prop descriptor | ||
@@ -84,13 +105,44 @@ prop = { | ||
} | ||
if ( | ||
process.env.NODE_ENV !== 'production' && | ||
options.twoWay && | ||
prop.mode !== propBindingModes.TWO_WAY | ||
) { | ||
_.warn( | ||
'Prop "' + name + '" expects a two-way binding type.' | ||
) | ||
} | ||
} else { | ||
// new prop- syntax | ||
attr = 'prop-' + attr | ||
value = prop.raw = el.getAttribute(attr) | ||
if (value !== null) { | ||
el.removeAttribute(attr) | ||
// check binding type | ||
if (literalValueRE.test(value)) { | ||
prop.mode = propBindingModes.ONE_TIME | ||
} else if (value.charAt(0) === '*') { | ||
prop.mode = propBindingModes.ONE_TIME | ||
value = value.slice(1) | ||
} else if (value.charAt(0) === '@') { | ||
value = value.slice(1) | ||
if (settablePathRE.test(value)) { | ||
prop.mode = propBindingModes.TWO_WAY | ||
} else { | ||
process.env.NODE_ENV !== 'production' && _.warn( | ||
'Cannot bind two-way prop with non-settable ' + | ||
'parent path: ' + value | ||
) | ||
} | ||
} | ||
} | ||
} else if (options && options.required) { | ||
prop.dynamic = true | ||
prop.parentPath = value | ||
} | ||
// warn required two-way | ||
if ( | ||
process.env.NODE_ENV !== 'production' && | ||
options.twoWay && | ||
prop.mode !== propBindingModes.TWO_WAY | ||
) { | ||
_.warn( | ||
'Prop "' + name + '" expects a two-way binding type.' | ||
) | ||
} | ||
// warn missing required | ||
if (value === null && options && options.required) { | ||
process.env.NODE_ENV !== 'production' && _.warn( | ||
@@ -100,2 +152,4 @@ 'Missing required prop: ' + name | ||
} | ||
// push prop | ||
props.push(prop) | ||
@@ -114,3 +168,3 @@ } | ||
function makePropsLinkFn (props) { | ||
return function propsLinkFn (vm, el) { | ||
return function propsLinkFn (vm, scope) { | ||
// store resolved props info | ||
@@ -133,7 +187,7 @@ vm._props = {} | ||
// one time binding | ||
value = vm._context.$get(prop.parentPath) | ||
value = (scope || vm._context).$get(prop.parentPath) | ||
_.initProp(vm, prop, value) | ||
} else { | ||
// dynamic binding | ||
vm._bindDir('prop', el, prop, propDef) | ||
vm._bindDir('prop', null, prop, propDef, null, scope) | ||
} | ||
@@ -140,0 +194,0 @@ } else { |
@@ -6,2 +6,3 @@ var _ = require('../util') | ||
var dirParser = require('../parsers/directive') | ||
var newDirParser = require('../parsers/directive-new') | ||
var templateParser = require('../parsers/template') | ||
@@ -11,5 +12,11 @@ var resolveAsset = _.resolveAsset | ||
// special binding prefixes | ||
var propRE = /^prop-/ | ||
var bindRE = /^bind-/ | ||
var onRE = /^on-/ | ||
// terminal directives | ||
var terminalDirectives = [ | ||
'repeat', | ||
'for', | ||
'if' | ||
@@ -56,12 +63,14 @@ ] | ||
* @param {Vue} [host] - host vm of transcluded content | ||
* @param {Object} [scope] - v-for scope | ||
* @param {Fragment} [frag] - link context fragment | ||
* @return {Function|undefined} | ||
*/ | ||
return function compositeLinkFn (vm, el, host) { | ||
return function compositeLinkFn (vm, el, host, scope, frag) { | ||
// cache childNodes before linking parent, fix #657 | ||
var childNodes = _.toArray(el.childNodes) | ||
// link | ||
var dirs = linkAndCapture(function () { | ||
if (nodeLinkFn) nodeLinkFn(vm, el, host) | ||
if (childLinkFn) childLinkFn(vm, childNodes, host) | ||
var dirs = linkAndCapture(function compositeLinkCapturer () { | ||
if (nodeLinkFn) nodeLinkFn(vm, el, host, scope, frag) | ||
if (childLinkFn) childLinkFn(vm, childNodes, host, scope, frag) | ||
}, vm) | ||
@@ -83,6 +92,24 @@ return makeUnlinkFn(vm, dirs) | ||
linker() | ||
return vm._directives.slice(originalDirCount) | ||
var dirs = vm._directives.slice(originalDirCount) | ||
dirs.sort(directiveComparator) | ||
for (var i = 0, l = dirs.length; i < l; i++) { | ||
dirs[i]._bind() | ||
} | ||
return dirs | ||
} | ||
/** | ||
* Directive priority sort comparator | ||
* | ||
* @param {Object} a | ||
* @param {Object} b | ||
*/ | ||
function directiveComparator (a, b) { | ||
a = a._def.priority || 0 | ||
b = b._def.priority || 0 | ||
return a > b ? -1 : a === b ? 0 : 1 | ||
} | ||
/** | ||
* Linker functions return an unlink function that | ||
@@ -134,10 +161,11 @@ * tearsdown all directives instances generated during | ||
* @param {Element} el | ||
* @param {Object} options | ||
* @param {Object} props | ||
* @param {Object} [scope] | ||
* @return {Function} | ||
*/ | ||
exports.compileAndLinkProps = function (vm, el, props) { | ||
exports.compileAndLinkProps = function (vm, el, props, scope) { | ||
var propsLinkFn = compileProps(el, props) | ||
var propDirs = linkAndCapture(function () { | ||
propsLinkFn(vm, null) | ||
propsLinkFn(vm, scope) | ||
}, vm) | ||
@@ -187,3 +215,3 @@ return makeUnlinkFn(vm, propDirs) | ||
return function rootLinkFn (vm, el) { | ||
return function rootLinkFn (vm, el, scope) { | ||
// link context scope dirs | ||
@@ -194,3 +222,3 @@ var context = vm._context | ||
contextDirs = linkAndCapture(function () { | ||
contextLinkFn(context, el) | ||
contextLinkFn(context, el, null, scope) | ||
}, context) | ||
@@ -220,2 +248,7 @@ } | ||
function compileNode (node, options) { | ||
/* istanbul ignore if */ | ||
if (process.env.NODE_ENV !== 'production' && !config.interpolate) { | ||
_.deprecation.INTERPOLATE() | ||
} | ||
var type = node.nodeType | ||
@@ -244,4 +277,6 @@ if (type === 1 && node.tagName !== 'SCRIPT') { | ||
if (el.tagName === 'TEXTAREA') { | ||
if (textParser.parse(el.value)) { | ||
el.setAttribute('value', el.value) | ||
var tokens = textParser.parse(el.value) | ||
if (tokens) { | ||
el.setAttribute('bind-value', textParser.tokensToExp(tokens)) | ||
el.value = '' | ||
} | ||
@@ -335,3 +370,3 @@ } | ||
function makeTextNodeLinkFn (tokens, frag) { | ||
return function textNodeLinkFn (vm, el) { | ||
return function textNodeLinkFn (vm, el, host, scope) { | ||
var fragClone = frag.cloneNode(true) | ||
@@ -346,3 +381,3 @@ var childNodes = _.toArray(fragClone.childNodes) | ||
if (token.oneTime) { | ||
value = vm.$eval(value) | ||
value = (scope || vm).$eval(value) | ||
if (token.html) { | ||
@@ -355,3 +390,3 @@ _.replace(node, templateParser.parse(value, true)) | ||
vm._bindDir(token.type, node, | ||
token.descriptor, token.def) | ||
token.descriptor, token.def, host, scope) | ||
} | ||
@@ -399,3 +434,3 @@ } | ||
function makeChildLinkFn (linkFns) { | ||
return function childLinkFn (vm, nodes, host) { | ||
return function childLinkFn (vm, nodes, host, scope, frag) { | ||
var node, nodeLinkFn, childrenLinkFn | ||
@@ -409,6 +444,6 @@ for (var i = 0, n = 0, l = linkFns.length; i < l; n++) { | ||
if (nodeLinkFn) { | ||
nodeLinkFn(vm, node, host) | ||
nodeLinkFn(vm, node, host, scope, frag) | ||
} | ||
if (childrenLinkFn) { | ||
childrenLinkFn(vm, childNodes, host) | ||
childrenLinkFn(vm, childNodes, host, scope, frag) | ||
} | ||
@@ -449,6 +484,6 @@ } | ||
if (componentId) { | ||
var componentLinkFn = function (vm, el, host) { | ||
var componentLinkFn = function (vm, el, host, scope, frag) { | ||
vm._bindDir('component', el, { | ||
expression: componentId | ||
}, componentDef, host) | ||
}, componentDef, host, scope, frag) | ||
} | ||
@@ -504,4 +539,4 @@ componentLinkFn.terminal = true | ||
def = def || options.directives[dirName] | ||
var fn = function terminalNodeLinkFn (vm, el, host) { | ||
vm._bindDir(dirName, el, descriptor, def, host) | ||
var fn = function terminalNodeLinkFn (vm, el, host, scope, frag) { | ||
vm._bindDir(dirName, el, descriptor, def, host, scope, frag) | ||
} | ||
@@ -523,3 +558,3 @@ fn.terminal = true | ||
var dirs = [] | ||
var attr, name, value, dir, dirName, dirDef | ||
var attr, name, value, dir, dirName, dirDef, arg | ||
while (i--) { | ||
@@ -529,2 +564,3 @@ attr = attrs[i] | ||
value = attr.value | ||
// Core directive | ||
if (name.indexOf(config.prefix) === 0) { | ||
@@ -535,2 +571,18 @@ dirName = name.slice(config.prefix.length) | ||
_.assertAsset(dirDef, 'directive', dirName) | ||
// deprecations | ||
if (dirName === 'transition') { | ||
_.deprecation.V_TRANSITION() | ||
} else if (dirName === 'class') { | ||
_.deprecation.V_CLASS() | ||
} else if (dirName === 'style') { | ||
_.deprecation.V_STYLE() | ||
} else if (dirName === 'on') { | ||
_.deprecation.V_ON() | ||
} else if (dirName === 'attr') { | ||
_.deprecation.V_ATTR() | ||
} else if (dirName === 'el') { | ||
_.deprecation.V_EL() | ||
} | ||
} | ||
@@ -544,3 +596,53 @@ if (dirDef) { | ||
} | ||
} else if (config.interpolate) { | ||
} else | ||
// speical case for el | ||
if (name === 'el' || name === 'bind-el') { | ||
dirs.push({ | ||
name: 'el', | ||
arg: bindRE.test(name), | ||
descriptors: [newDirParser.parse(value)], | ||
def: options.directives.el | ||
}) | ||
} else | ||
// attribute bindings | ||
if (bindRE.test(name)) { | ||
var attributeName = name.replace(bindRE, '') | ||
if (attributeName === 'style' || attributeName === 'class') { | ||
dirName = attributeName | ||
arg = undefined | ||
} else { | ||
dirName = 'attr' | ||
arg = attributeName | ||
} | ||
dirs.push({ | ||
name: dirName, | ||
arg: arg, | ||
descriptors: [newDirParser.parse(value)], | ||
def: options.directives[dirName] | ||
}) | ||
} else | ||
// event handlers | ||
if (onRE.test(name)) { | ||
dirs.push({ | ||
name: 'on', | ||
arg: name.replace(onRE, ''), | ||
descriptors: [newDirParser.parse(value)], | ||
def: options.directives.on | ||
}) | ||
} else | ||
// should not see props here | ||
/* istanbul ignore if */ | ||
if (process.env.NODE_ENV !== 'production' && propRE.test(name)) { | ||
_.warn( | ||
name + '="' + value + '" is not compiled. The prop is either not declared ' + | ||
'on the child component, or is used on a non-component element.' | ||
) | ||
} else | ||
// TODO: remove this in 1.0.0 | ||
if (config.interpolate) { | ||
dir = collectAttrDirective(name, value, options) | ||
@@ -554,3 +656,2 @@ if (dir) { | ||
if (dirs.length) { | ||
dirs.sort(directiveComparator) | ||
return makeNodeLinkFn(dirs) | ||
@@ -568,3 +669,3 @@ } | ||
function makeNodeLinkFn (directives) { | ||
return function nodeLinkFn (vm, el, host) { | ||
return function nodeLinkFn (vm, el, host, scope, frag) { | ||
// reverse apply because it's sorted low to high | ||
@@ -577,8 +678,11 @@ var i = directives.length | ||
// custom link fn | ||
dir._link(vm, el) | ||
dir._link(vm, el, scope) | ||
} else { | ||
// TODO: no need for loop here in 1.0.0 | ||
// also, we can just pass in the dir object to _bindDir, | ||
// which is going to be much simpler. | ||
k = dir.descriptors.length | ||
for (j = 0; j < k; j++) { | ||
vm._bindDir(dir.name, el, | ||
dir.descriptors[j], dir.def, host) | ||
dir.descriptors[j], dir.def, host, scope, frag, dir.arg) | ||
} | ||
@@ -608,2 +712,7 @@ } | ||
if (tokens) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
_.deprecation.ATTR_INTERPOLATION(name, value) | ||
} | ||
var dirName = isClass ? 'class' : 'attr' | ||
@@ -622,7 +731,7 @@ var def = options.directives[dirName] | ||
_link: allOneTime | ||
? function (vm, el) { | ||
el.setAttribute(name, vm.$interpolate(value)) | ||
? function (vm, el, scope) { | ||
el.setAttribute(name, (scope || vm).$interpolate(value)) | ||
} | ||
: function (vm, el) { | ||
var exp = textParser.tokensToExp(tokens, vm) | ||
: function (vm, el, scope) { | ||
var exp = textParser.tokensToExp(tokens, (scope || vm)) | ||
var desc = isClass | ||
@@ -634,3 +743,3 @@ ? dirParser.parse(exp)[0] | ||
} | ||
vm._bindDir(dirName, el, desc, def) | ||
vm._bindDir(dirName, el, desc, def, undefined, scope) | ||
} | ||
@@ -640,14 +749,1 @@ } | ||
} | ||
/** | ||
* Directive priority sort comparator | ||
* | ||
* @param {Object} a | ||
* @param {Object} b | ||
*/ | ||
function directiveComparator (a, b) { | ||
a = a.def.priority || 0 | ||
b = b.def.priority || 0 | ||
return a > b ? 1 : -1 | ||
} |
@@ -33,3 +33,3 @@ var _ = require('../util') | ||
if (options._asComponent && !options.template) { | ||
options.template = '<content></content>' | ||
options.template = '<slot></slot>' | ||
} | ||
@@ -36,0 +36,0 @@ if (options.template) { |
@@ -21,7 +21,11 @@ var _ = require('./util') | ||
* @param {Object} def - directive definition object | ||
* @param {Vue|undefined} host - transclusion host target | ||
* @param {Vue} [host] - transclusion host component | ||
* @param {Object} [scope] - v-for scope | ||
* @param {Fragment} [frag] - owner fragment | ||
* @constructor | ||
*/ | ||
function Directive (name, el, vm, descriptor, def, host) { | ||
// TODO: 1.0.0 cleanup the arguments | ||
function Directive (name, el, vm, descriptor, def, host, scope, frag, arg) { | ||
// public | ||
@@ -32,14 +36,15 @@ this.name = name | ||
// copy descriptor props | ||
this.raw = descriptor.raw | ||
this.expression = descriptor.expression | ||
this.arg = descriptor.arg | ||
this.arg = arg || descriptor.arg | ||
this.filters = descriptor.filters | ||
// private | ||
this._def = def | ||
this._descriptor = descriptor | ||
this._host = host | ||
this._locked = false | ||
this._bound = false | ||
this._listeners = null | ||
// init | ||
this._bind(def) | ||
// link context | ||
this._host = host | ||
this._scope = scope | ||
this._frag = frag | ||
} | ||
@@ -55,8 +60,21 @@ | ||
Directive.prototype._bind = function (def) { | ||
Directive.prototype._bind = function () { | ||
var def = this._def | ||
var name = this.name | ||
if ( | ||
(this.name !== 'cloak' || this.vm._isCompiled) && | ||
(name !== 'cloak' || this.vm._isCompiled) && | ||
this.el && this.el.removeAttribute | ||
) { | ||
this.el.removeAttribute(config.prefix + this.name) | ||
// 1.0.0: remove bind/on | ||
// TODO simplify this | ||
if (name === 'attr') { | ||
this.el.removeAttribute('bind-' + this.arg) | ||
} else if (name === 'class' || name === 'style') { | ||
this.el.removeAttribute('bind-' + name) | ||
} else if (name === 'on') { | ||
this.el.removeAttribute('on-' + this.arg) | ||
} else if (name === 'transition') { | ||
this.el.removeAttribute(name) | ||
} | ||
} | ||
@@ -99,3 +117,4 @@ if (typeof def === 'function') { | ||
deep: this.deep, | ||
preProcess: preProcess | ||
preProcess: preProcess, | ||
scope: this._scope | ||
} | ||
@@ -118,2 +137,3 @@ ) | ||
// TODO: we shouldn't need this in 1.0.0. | ||
Directive.prototype._checkDynamicLiteral = function () { | ||
@@ -150,8 +170,8 @@ var expression = this.expression | ||
var fn = expParser.parse(expression).get | ||
var vm = this.vm | ||
var scope = this._scope || this.vm | ||
var handler = function () { | ||
fn.call(vm, vm) | ||
fn.call(scope, scope) | ||
} | ||
if (this.filters) { | ||
handler = vm._applyFilters(handler, null, this.filters) | ||
handler = this.vm._applyFilters(handler, null, this.filters) | ||
} | ||
@@ -170,7 +190,17 @@ this.update(handler) | ||
Directive.prototype._checkParam = function (name) { | ||
Directive.prototype.param = function (name) { | ||
var param = this.el.getAttribute(name) | ||
if (param !== null) { | ||
if (param != null) { | ||
this.el.removeAttribute(name) | ||
param = this.vm.$interpolate(param) | ||
param = (this._scope || this.vm).$interpolate(param) | ||
} else { | ||
param = this.el.getAttribute('bind-' + name) | ||
if (param != null) { | ||
this.el.removeAttribute('bind-' + name) | ||
param = (this._scope || this.vm).$eval(param) | ||
process.env.NODE_ENV !== 'production' && _.log( | ||
'You are using bind- syntax on "' + name + '", which ' + | ||
'is a directive param. It will be evaluated only once.' | ||
) | ||
} | ||
} | ||
@@ -177,0 +207,0 @@ return param |
// xlink | ||
var xlinkNS = 'http://www.w3.org/1999/xlink' | ||
var xlinkRE = /^xlink:/ | ||
// these input element attributes should also set their | ||
// corresponding properties | ||
var inputProps = { | ||
@@ -10,2 +13,10 @@ value: 1, | ||
// these attributes should set a hidden property for | ||
// binding v-model to object values | ||
var modelProps = { | ||
value: '_value', | ||
'true-value': '_trueValue', | ||
'false-value': '_falseValue' | ||
} | ||
module.exports = { | ||
@@ -19,2 +30,3 @@ | ||
} else if (typeof value === 'object') { | ||
// TODO no longer need to support object in 1.0.0 | ||
this.objectHandler(value) | ||
@@ -60,3 +72,8 @@ } | ||
} | ||
// set model props | ||
var modelProp = modelProps[attr] | ||
if (modelProp) { | ||
this.el[modelProp] = value | ||
} | ||
} | ||
} |
@@ -7,2 +7,4 @@ var _ = require('../util') | ||
// TODO: remove unnecessary logic in 1.0.0 | ||
bind: function () { | ||
@@ -31,2 +33,4 @@ // interpolations like class="{{abc}}" are converted | ||
this.handleObject(value) | ||
} else if (_.isArray(value)) { | ||
this.handleArray(value) | ||
} else { | ||
@@ -51,2 +55,10 @@ this.cleanup() | ||
handleArray: function (value) { | ||
this.cleanup(value) | ||
for (var i = 0, l = value.length; i < l; i++) { | ||
addClass(this.el, value[i]) | ||
} | ||
this.prevKeys = value | ||
}, | ||
cleanup: function (value) { | ||
@@ -57,3 +69,3 @@ if (this.prevKeys) { | ||
var key = this.prevKeys[i] | ||
if (!value || !value.hasOwnProperty(key)) { | ||
if (!value || !contains(value, key)) { | ||
removeClass(this.el, key) | ||
@@ -75,1 +87,7 @@ } | ||
} | ||
function contains (value, key) { | ||
return _.isArray(value) | ||
? value.indexOf(key) > -1 | ||
: value.hasOwnProperty(key) | ||
} |
@@ -8,2 +8,3 @@ var _ = require('../util') | ||
isLiteral: true, | ||
priority: 1500, | ||
@@ -22,5 +23,2 @@ /** | ||
if (!this.el.__vue__) { | ||
// create a ref anchor | ||
this.anchor = _.createAnchor('v-component') | ||
_.replace(this.el, this.anchor) | ||
// check keep-alive options. | ||
@@ -31,7 +29,25 @@ // If yes, instead of destroying the active vm when | ||
// cache object, with its constructor id as the key. | ||
this.keepAlive = this._checkParam('keep-alive') != null | ||
this.keepAlive = this.param('keep-alive') != null | ||
// wait for event before insertion | ||
this.waitForEvent = this._checkParam('wait-for') | ||
this.waitForEvent = this.param('wait-for') | ||
if (process.env.NODE_ENV !== 'production') { | ||
if (this.waitForEvent) { | ||
_.deprecation.WAIT_FOR() | ||
} | ||
} | ||
// check ref | ||
this.refID = this._checkParam(config.prefix + 'ref') | ||
// TODO: only check ref in 1.0.0 | ||
var ref = this.param(config.prefix + 'ref') | ||
/* istanbul ignore if */ | ||
if (process.env.NODE_ENV !== 'production' && ref) { | ||
_.deprecation.V_REF() | ||
} | ||
this.ref = ref || this.param('ref') | ||
var refs = (this._scope || this.vm).$ | ||
if (this.ref && !refs.hasOwnProperty(this.ref)) { | ||
_.defineReactive(refs, this.ref, null) | ||
} | ||
if (this.keepAlive) { | ||
@@ -41,5 +57,5 @@ this.cache = {} | ||
// check inline-template | ||
if (this._checkParam('inline-template') !== null) { | ||
if (this.param('inline-template') !== null) { | ||
// extract inline template as a DocumentFragment | ||
this.template = _.extractContent(this.el, true) | ||
this.inlineTemplate = _.extractContent(this.el, true) | ||
} | ||
@@ -57,3 +73,6 @@ // component resolution related state | ||
// check dynamic component params | ||
this.transMode = this._checkParam('transition-mode') | ||
// create a ref anchor | ||
this.anchor = _.createAnchor('v-component') | ||
_.replace(this.el, this.anchor) | ||
this.transMode = this.param('transition-mode') | ||
} | ||
@@ -74,11 +93,10 @@ } else { | ||
// wait-for | ||
var anchor = this.anchor | ||
var anchor = this.el | ||
var options | ||
var waitFor = this.waitForEvent | ||
var activateHook = this.Component.options.activate | ||
if (waitFor) { | ||
options = { | ||
created: function () { | ||
this.$once(waitFor, function () { | ||
this.$before(anchor) | ||
}) | ||
this.$once(waitFor, insert) | ||
} | ||
@@ -90,4 +108,15 @@ } | ||
if (!this.waitForEvent) { | ||
child.$before(anchor) | ||
if (activateHook) { | ||
activateHook.call(child, insert) | ||
} else { | ||
child.$before(anchor) | ||
_.remove(anchor) | ||
} | ||
} | ||
function insert () { | ||
// TODO: no need to fallback to this in 1.0.0 | ||
// once wait-for is removed | ||
(child || this).$before(anchor) | ||
_.remove(anchor) | ||
} | ||
}, | ||
@@ -130,9 +159,7 @@ | ||
var waitFor = this.waitForEvent | ||
var activateHook = this.Component.options.activate | ||
if (waitFor) { | ||
options = { | ||
created: function () { | ||
this.$once(waitFor, function () { | ||
self.waitingFor = null | ||
self.transition(this, cb) | ||
}) | ||
this.$once(waitFor, insert) | ||
} | ||
@@ -143,7 +170,17 @@ } | ||
var newComponent = this.build(options) | ||
if (!waitFor || cached) { | ||
if ((!waitFor && !activateHook) || cached) { | ||
this.transition(newComponent, cb) | ||
} else { | ||
this.waitingFor = newComponent | ||
if (activateHook) { | ||
activateHook.call(newComponent, insert) | ||
} | ||
} | ||
function insert () { | ||
self.waitingFor = null | ||
// TODO: no need to fallback to this in 1.0.0 | ||
// once wait-for is removed | ||
self.transition((newComponent || this), cb) | ||
} | ||
}, this)) | ||
@@ -198,9 +235,22 @@ } | ||
el: templateParser.clone(this.el), | ||
template: this.template, | ||
template: this.inlineTemplate, | ||
// if no inline-template, then the compiled | ||
// linker can be cached for better performance. | ||
_linkerCachable: !this.template, | ||
_linkerCachable: !this.inlineTemplate, | ||
_asComponent: true, | ||
_isRouterView: this._isRouterView, | ||
_context: this.vm | ||
// if this is a transcluded component, context | ||
// will be the common parent vm of this instance | ||
// and its host. | ||
_context: this.vm, | ||
// if this is inside an inline v-repeat, the scope | ||
// will be the intermediate scope created for this | ||
// repeat fragment. this is used for linking props | ||
// and container directives. | ||
_scope: this._scope, | ||
// pass in the owner fragment of this component. | ||
// this is necessary so that the fragment can keep | ||
// track of its contained components in order to | ||
// call attach/detach hooks for them. | ||
_frag: this._frag | ||
} | ||
@@ -216,2 +266,11 @@ // extra options | ||
} | ||
/* istanbul ignore if */ | ||
if (process.env.NODE_ENV !== 'production' && | ||
this.el.hasAttribute('transition') && | ||
child._isFragment) { | ||
_.warn( | ||
'Transitions will not work on a fragment instance. ' + | ||
'Template: ' + child.$options.template | ||
) | ||
} | ||
return child | ||
@@ -319,5 +378,5 @@ } | ||
this.childVM = child | ||
var refID = child._refID || this.refID | ||
if (refID) { | ||
this.vm.$[refID] = child | ||
var ref = child._refId || this.ref | ||
if (ref) { | ||
(this._scope || this.vm).$[ref] = child | ||
} | ||
@@ -333,5 +392,5 @@ }, | ||
this.childVM = null | ||
var refID = (child && child._refID) || this.refID | ||
if (refID) { | ||
this.vm.$[refID] = null | ||
var ref = (child && child._refId) || this.ref | ||
if (ref) { | ||
(this._scope || this.vm).$[ref] = null | ||
} | ||
@@ -338,0 +397,0 @@ }, |
@@ -0,12 +1,32 @@ | ||
var _ = require('../util') | ||
module.exports = { | ||
isLiteral: true, | ||
priority: 1500, | ||
bind: function () { | ||
this.vm.$$[this.expression] = this.el | ||
var scope = this._scope || this.vm | ||
var refs = scope.$$ | ||
var id = this.id = this.arg // bind-el ? | ||
? scope.$eval(this.expression) | ||
: this.expression | ||
if (process.env.NODE_ENV !== 'production' && this.arg) { | ||
_.log( | ||
'You are using bind- syntax on "el", which is a special ' + | ||
'attribute. It will be evaluated only once.' | ||
) | ||
} | ||
if (refs.hasOwnProperty(id)) { | ||
refs[id] = this.el | ||
} else { | ||
_.defineReactive(refs, id, this.el) | ||
} | ||
}, | ||
unbind: function () { | ||
delete this.vm.$$[this.expression] | ||
(this._scope || this.vm).$$[this.id] = null | ||
} | ||
} |
var _ = require('../util') | ||
var compiler = require('../compiler') | ||
var templateParser = require('../parsers/template') | ||
var transition = require('../transition') | ||
var Cache = require('../cache') | ||
var cache = new Cache(1000) | ||
var FragmentFactory = require('../fragment/factory') | ||
module.exports = { | ||
priority: 2000, | ||
bind: function () { | ||
var el = this.el | ||
if (!el.__vue__) { | ||
this.start = _.createAnchor('v-if-start') | ||
this.end = _.createAnchor('v-if-end') | ||
_.replace(el, this.end) | ||
_.before(this.start, this.end) | ||
if (_.isTemplate(el)) { | ||
this.template = templateParser.parse(el, true) | ||
} else { | ||
this.template = document.createDocumentFragment() | ||
this.template.appendChild(templateParser.clone(el)) | ||
} | ||
// compile the nested partial | ||
var cacheId = (this.vm.constructor.cid || '') + el.outerHTML | ||
this.linker = cache.get(cacheId) | ||
if (!this.linker) { | ||
this.linker = compiler.compile( | ||
this.template, | ||
this.vm.$options, | ||
true // partial | ||
) | ||
cache.put(cacheId, this.linker) | ||
} | ||
this.anchor = _.createAnchor('v-if') | ||
_.replace(el, this.anchor) | ||
this.factory = new FragmentFactory(this.vm, el) | ||
} else { | ||
@@ -46,81 +26,27 @@ process.env.NODE_ENV !== 'production' && _.warn( | ||
if (value) { | ||
// avoid duplicate compiles, since update() can be | ||
// called with different truthy values | ||
if (!this.unlink) { | ||
this.link( | ||
templateParser.clone(this.template), | ||
this.linker | ||
) | ||
if (!this.frag) { | ||
this.insert() | ||
} | ||
} else { | ||
this.teardown() | ||
this.remove() | ||
} | ||
}, | ||
link: function (frag, linker) { | ||
var vm = this.vm | ||
this.unlink = linker(vm, frag, this._host /* important */) | ||
transition.blockAppend(frag, this.end, vm) | ||
// call attached for all the child components created | ||
// during the compilation | ||
if (_.inDoc(vm.$el)) { | ||
var children = this.getContainedComponents() | ||
if (children) children.forEach(callAttach) | ||
} | ||
insert: function () { | ||
this.frag = this.factory.create(this._host, this._scope, this._frag) | ||
this.frag.before(this.anchor) | ||
}, | ||
teardown: function () { | ||
if (!this.unlink) return | ||
// collect children beforehand | ||
var children | ||
if (_.inDoc(this.vm.$el)) { | ||
children = this.getContainedComponents() | ||
} | ||
transition.blockRemove(this.start, this.end, this.vm) | ||
if (children) children.forEach(callDetach) | ||
this.unlink() | ||
this.unlink = null | ||
remove: function () { | ||
if (!this.frag) return | ||
this.frag.remove() | ||
this.frag.destroy() | ||
this.frag = null | ||
}, | ||
getContainedComponents: function () { | ||
var vm = this.vm | ||
var start = this.start.nextSibling | ||
var end = this.end | ||
function contains (c) { | ||
var cur = start | ||
var next | ||
while (next !== end) { | ||
next = cur.nextSibling | ||
if ( | ||
cur === c.$el || | ||
cur.contains && cur.contains(c.$el) | ||
) { | ||
return true | ||
} | ||
cur = next | ||
} | ||
return false | ||
unbind: function () { | ||
if (this.frag) { | ||
this.frag.destroy() | ||
} | ||
return vm.$children.length && | ||
vm.$children.filter(contains) | ||
}, | ||
unbind: function () { | ||
if (this.unlink) this.unlink() | ||
} | ||
} | ||
function callAttach (child) { | ||
if (!child._isAttached) { | ||
child._callHook('attached') | ||
} | ||
} | ||
function callDetach (child) { | ||
if (child._isAttached) { | ||
child._callHook('detached') | ||
} | ||
} |
@@ -0,1 +1,3 @@ | ||
// TODO: only expose core in 1.0.0 | ||
// manipulation directives | ||
@@ -19,2 +21,3 @@ exports.text = require('./text') | ||
exports.repeat = require('./repeat') | ||
exports['for'] = require('./for') | ||
exports['if'] = require('./if') | ||
@@ -21,0 +24,0 @@ |
@@ -8,8 +8,15 @@ var _ = require('../../util') | ||
var el = this.el | ||
var trueExp = this._checkParam('true-exp') | ||
var falseExp = this._checkParam('false-exp') | ||
var trueExp = this.param('true-exp') | ||
var falseExp = this.param('false-exp') | ||
var scope = this._scope || this.vm | ||
if (process.env.NODE_ENV !== 'production' && (trueExp || falseExp)) { | ||
_.deprecation.MODEL_EXP(this.expression) | ||
} | ||
this._matchValue = function (value) { | ||
if (trueExp !== null) { | ||
return _.looseEqual(value, self.vm.$eval(trueExp)) | ||
if (el.hasOwnProperty('_trueValue')) { | ||
return _.looseEqual(value, el._trueValue) | ||
} else if (trueExp !== null) { | ||
return _.looseEqual(value, scope.$eval(trueExp)) | ||
} else { | ||
@@ -22,7 +29,13 @@ return !!value | ||
var val = el.checked | ||
if (val && el.hasOwnProperty('_trueValue')) { | ||
return el._trueValue | ||
} | ||
if (!val && el.hasOwnProperty('_falseValue')) { | ||
return el._falseValue | ||
} | ||
if (val && trueExp !== null) { | ||
val = self.vm.$eval(trueExp) | ||
val = scope.$eval(trueExp) | ||
} | ||
if (!val && falseExp !== null) { | ||
val = self.vm.$eval(falseExp) | ||
val = scope.$eval(falseExp) | ||
} | ||
@@ -29,0 +42,0 @@ return val |
@@ -53,5 +53,6 @@ var _ = require('../../util') | ||
} | ||
el.__v_model = this | ||
handler.bind.call(this) | ||
this.update = handler.update | ||
this.unbind = handler.unbind | ||
this._unbind = handler.unbind | ||
}, | ||
@@ -76,3 +77,8 @@ | ||
} | ||
}, | ||
unbind: function () { | ||
this.el.__v_model = null | ||
this._unbind && this._unbind() | ||
} | ||
} |
@@ -8,6 +8,15 @@ var _ = require('../../util') | ||
var el = this.el | ||
var number = this._checkParam('number') != null | ||
var expression = this._checkParam('exp') | ||
var number = this.param('number') != null | ||
var expression = this.param('exp') | ||
var scope = this._scope || this.vm | ||
if (process.env.NODE_ENV !== 'production' && expression) { | ||
_.deprecation.MODEL_EXP(this.expression) | ||
} | ||
this.getValue = function () { | ||
// value overwrite via bind-value | ||
if (el.hasOwnProperty('_value')) { | ||
return el._value | ||
} | ||
var val = el.value | ||
@@ -17,3 +26,3 @@ if (number) { | ||
} else if (expression !== null) { | ||
val = self.vm.$eval(expression) | ||
val = scope.$eval(expression) | ||
} | ||
@@ -20,0 +29,0 @@ return val |
@@ -19,7 +19,10 @@ var _ = require('../../util') | ||
// check options param | ||
var optionsParam = this._checkParam('options') | ||
var optionsParam = this.param('options') | ||
if (optionsParam) { | ||
initOptions.call(this, optionsParam) | ||
if (process.env.NODE_ENV !== 'production') { | ||
_.deprecation.SELECT_OPTIONS() | ||
} | ||
} | ||
this.number = this._checkParam('number') != null | ||
this.number = this.param('number') != null | ||
this.multiple = el.hasAttribute('multiple') | ||
@@ -26,0 +29,0 @@ |
@@ -12,7 +12,7 @@ var _ = require('../../util') | ||
// - lazy: update model on "change" instead of "input" | ||
var lazy = this._checkParam('lazy') != null | ||
var lazy = this.param('lazy') != null | ||
// - number: cast value into number when updating model. | ||
var number = this._checkParam('number') != null | ||
var number = this.param('number') != null | ||
// - debounce: debounce the input listener | ||
var debounce = parseInt(this._checkParam('debounce'), 10) | ||
var debounce = parseInt(this.param('debounce'), 10) | ||
@@ -19,0 +19,0 @@ // handle composition events. |
var _ = require('../util') | ||
var keyFilter = require('../filters').key | ||
@@ -9,2 +10,22 @@ module.exports = { | ||
bind: function () { | ||
// 1.0.0 key filter | ||
var rawArg = this.arg | ||
var keyIndex = rawArg.indexOf(':') | ||
if (keyIndex > -1) { | ||
this.arg = rawArg.slice(0, keyIndex) | ||
this.key = rawArg.slice(keyIndex + 1) | ||
} | ||
// warn old usage | ||
if (process.env.NODE_ENV !== 'production') { | ||
if (this.filters) { | ||
var hasKeyFilter = this.filters.some(function (f) { | ||
return f.name === 'key' | ||
}) | ||
if (hasKeyFilter) { | ||
_.deprecation.KEY_FILTER() | ||
} | ||
} | ||
} | ||
// deal with iframes | ||
@@ -32,9 +53,13 @@ if ( | ||
} | ||
if (this.key) { | ||
handler = keyFilter(handler, this.key) | ||
} | ||
this.reset() | ||
var vm = this.vm | ||
var scope = this._scope || this.vm | ||
this.handler = function (e) { | ||
e.targetVM = vm | ||
vm.$event = e | ||
scope.$event = e | ||
var res = handler(e) | ||
vm.$event = null | ||
scope.$event = null | ||
return res | ||
@@ -41,0 +66,0 @@ } |
@@ -28,3 +28,8 @@ // NOTE: the prop internal directive is compiled and linked | ||
} | ||
}, { sync: true } | ||
}, { | ||
sync: true, | ||
// important: props need to be observed on the | ||
// repeat scope if present | ||
scope: this._scope | ||
} | ||
) | ||
@@ -31,0 +36,0 @@ |
@@ -20,4 +20,8 @@ var _ = require('../util') | ||
// if any. | ||
vm._refID = this.expression | ||
vm._refId = this.expression | ||
if (process.env.NODE_ENV !== 'production') { | ||
_.deprecation.REF_IN_CHILD() | ||
} | ||
} | ||
} |
@@ -5,2 +5,3 @@ var _ = require('../util') | ||
var isPlainObject = _.isPlainObject | ||
var transition = require('../transition') | ||
var textParser = require('../parsers/text') | ||
@@ -25,2 +26,21 @@ var expParser = require('../parsers/expression') | ||
bind: function () { | ||
// some helpful tips... | ||
/* istanbul ignore if */ | ||
if ( | ||
process.env.NODE_ENV !== 'production' && | ||
this.el.tagName === 'OPTION' && | ||
this.el.parentNode && this.el.parentNode.__v_model | ||
) { | ||
_.warn( | ||
'Don\'t use v-repeat for v-model options; ' + | ||
'use the `options` param instead: ' + | ||
'http://vuejs.org/guide/forms.html#Dynamic_Select_Options' | ||
) | ||
} | ||
if (process.env.NODE_ENV !== 'production') { | ||
_.deprecation.REPEAT() | ||
} | ||
// support for item in array syntax | ||
@@ -47,12 +67,18 @@ var inMatch = this.expression.match(/(.*) in (.*)/) | ||
// check for trackby param | ||
this.idKey = this._checkParam('track-by') | ||
this.idKey = this.param('track-by') | ||
// check for transition stagger | ||
var stagger = +this._checkParam('stagger') | ||
this.enterStagger = +this._checkParam('enter-stagger') || stagger | ||
this.leaveStagger = +this._checkParam('leave-stagger') || stagger | ||
var stagger = +this.param('stagger') | ||
this.enterStagger = +this.param('enter-stagger') || stagger | ||
this.leaveStagger = +this.param('leave-stagger') || stagger | ||
// check for v-ref/v-el | ||
this.refID = this._checkParam(config.prefix + 'ref') | ||
this.elID = this._checkParam(config.prefix + 'el') | ||
this.refId = this.param(config.prefix + 'ref') | ||
this.elID = this.param(config.prefix + 'el') | ||
if (process.env.NODE_ENV !== 'production') { | ||
if (this.refId) _.deprecation.V_REF() | ||
if (this.elID) _.deprecation.V_EL() | ||
} | ||
this.refId = this.refId || this.param('ref') | ||
// check other directives that need to be handled | ||
@@ -65,15 +91,2 @@ // at v-repeat level | ||
this.cache = Object.create(null) | ||
// some helpful tips... | ||
/* istanbul ignore if */ | ||
if ( | ||
process.env.NODE_ENV !== 'production' && | ||
this.el.tagName === 'OPTION' | ||
) { | ||
_.warn( | ||
'Don\'t use v-repeat for v-model options; ' + | ||
'use the `options` param instead: ' + | ||
'http://vuejs.org/guide/forms.html#Dynamic_Select_Options' | ||
) | ||
} | ||
}, | ||
@@ -119,3 +132,3 @@ | ||
// check inline-template | ||
if (this._checkParam('inline-template') !== null) { | ||
if (this.param('inline-template') !== null) { | ||
// extract inline template as a DocumentFragment | ||
@@ -223,4 +236,4 @@ this.inlineTemplate = _.extractContent(this.el, true) | ||
// update v-ref | ||
if (this.refID) { | ||
this.vm.$[this.refID] = this.converted | ||
if (this.refId) { | ||
this.vm.$[this.refId] = this.converted | ||
? toRefObject(this.vms) | ||
@@ -272,2 +285,10 @@ : this.vms | ||
if (vm) { // reusable instance | ||
if (process.env.NODE_ENV !== 'production' && vm._reused) { | ||
_.warn( | ||
'Duplicate objects found in v-repeat="' + this.expression + '": ' + | ||
JSON.stringify(raw) | ||
) | ||
} | ||
vm._reused = true | ||
@@ -389,3 +410,5 @@ vm.$index = i // update $index | ||
// transclusion content owner | ||
_context: this.vm | ||
_context: this.vm, | ||
// cotnext fragment | ||
_frag: this._frag | ||
}, Component) | ||
@@ -428,4 +451,4 @@ // cache instance | ||
this.componentState = ABORTED | ||
if (this.refID) { | ||
this.vm.$[this.refID] = null | ||
if (this.refId) { | ||
this.vm.$[this.refId] = null | ||
} | ||
@@ -472,3 +495,3 @@ if (this.vms) { | ||
process.env.NODE_ENV !== 'production' && _.warn( | ||
'Duplicate track-by key in v-repeat: ' + id | ||
'Duplicate objects with the same track-by key in v-repeat: ' + id | ||
) | ||
@@ -483,4 +506,4 @@ } | ||
process.env.NODE_ENV !== 'production' && _.warn( | ||
'Duplicate objects are not supported in v-repeat ' + | ||
'when using components or transitions.' | ||
'Duplicate objects found in v-repeat="' + this.expression + '": ' + | ||
JSON.stringify(data) | ||
) | ||
@@ -640,4 +663,4 @@ } | ||
type = type + 'Stagger' | ||
var transition = vm.$el.__v_trans | ||
var hooks = transition && transition.hooks | ||
var trans = transition.get(vm.$el, vm) | ||
var hooks = trans && trans.hooks | ||
var hook = hooks && (hooks[type] || hooks.stagger) | ||
@@ -644,0 +667,0 @@ return hook |
@@ -0,1 +1,3 @@ | ||
// TODO: remove in 1.0.0 | ||
var _ = require('../util') | ||
@@ -17,6 +19,7 @@ var Transition = require('../transition/transition') | ||
var el = this.el | ||
var vm = this.el.__vue__ || this.vm | ||
var hooks = _.resolveAsset(vm.$options, 'transitions', id) | ||
// resolve on owner vm | ||
var hooks = _.resolveAsset(this.vm.$options, 'transitions', id) | ||
id = id || 'v' | ||
el.__v_trans = new Transition(el, id, hooks, vm) | ||
// apply on closest vm | ||
el.__v_trans = new Transition(el, id, hooks, this.el.__vue__ || this.vm) | ||
if (oldId) { | ||
@@ -23,0 +26,0 @@ _.removeClass(el, oldId + '-transition') |
@@ -1,2 +0,2 @@ | ||
exports.content = require('./content') | ||
exports.slot = exports.content = require('./slot') | ||
exports.partial = require('./partial') |
var _ = require('../util') | ||
var templateParser = require('../parsers/template') | ||
var textParser = require('../parsers/text') | ||
var compiler = require('../compiler') | ||
var Cache = require('../cache') | ||
var cache = new Cache(1000) | ||
// v-partial reuses logic from v-if | ||
var FragmentFactory = require('../fragment/factory') | ||
var vIf = require('../directives/if') | ||
@@ -13,32 +8,38 @@ | ||
link: vIf.link, | ||
teardown: vIf.teardown, | ||
getContainedComponents: vIf.getContainedComponents, | ||
priority: 1750, | ||
bind: function () { | ||
var el = this.el | ||
this.start = _.createAnchor('v-partial-start') | ||
this.end = _.createAnchor('v-partial-end') | ||
_.replace(el, this.end) | ||
_.before(this.start, this.end) | ||
this.anchor = _.createAnchor('v-partial') | ||
_.replace(el, this.anchor) | ||
var id = el.getAttribute('name') | ||
var tokens = textParser.parse(id) | ||
if (tokens) { | ||
// dynamic partial | ||
this.setupDynamic(tokens) | ||
if (id != null) { | ||
var tokens = textParser.parse(id) | ||
if (tokens) { | ||
// dynamic partial | ||
this.setupDynamic(textParser.tokensToExp(tokens)) | ||
if (process.env.NODE_ENV !== 'production') { | ||
_.deprecation.PARTIAL_NAME(id) | ||
} | ||
} else { | ||
// static partial | ||
this.insert(id) | ||
} | ||
} else { | ||
// static partial | ||
this.insert(id) | ||
id = el.getAttribute('bind-name') | ||
if (id) { | ||
this.setupDynamic(id) | ||
} | ||
} | ||
}, | ||
setupDynamic: function (tokens) { | ||
setupDynamic: function (exp) { | ||
var self = this | ||
var exp = textParser.tokensToExp(tokens) | ||
this.unwatch = this.vm.$watch(exp, function (value) { | ||
self.teardown() | ||
vIf.remove.call(self) | ||
self.insert(value) | ||
}, { | ||
immediate: true, | ||
user: false | ||
user: false, | ||
scope: this._scope | ||
}) | ||
@@ -53,23 +54,11 @@ }, | ||
if (partial) { | ||
var frag = templateParser.parse(partial, true) | ||
// cache partials based on constructor id. | ||
var cacheId = (this.vm.constructor.cid || '') + partial | ||
var linker = this.compile(frag, cacheId) | ||
// this is provided by v-if | ||
this.link(frag, linker) | ||
this.factory = new FragmentFactory(this.vm, partial) | ||
vIf.insert.call(this) | ||
} | ||
}, | ||
compile: function (frag, cacheId) { | ||
var hit = cache.get(cacheId) | ||
if (hit) return hit | ||
var linker = compiler.compile(frag, this.vm.$options, true) | ||
cache.put(cacheId, linker) | ||
return linker | ||
}, | ||
unbind: function () { | ||
if (this.unlink) this.unlink() | ||
if (this.frag) this.frag.destroy() | ||
if (this.unwatch) this.unwatch() | ||
} | ||
} |
@@ -58,5 +58,5 @@ var _ = require('../util') | ||
return arr.slice().sort(function (a, b) { | ||
if (sortKey !== '$key' && sortKey !== '$value') { | ||
if (a && '$value' in a) a = a.$value | ||
if (b && '$value' in b) b = b.$value | ||
if (sortKey !== '$key') { | ||
if (_.isObject(a) && '$value' in a) a = a.$value | ||
if (_.isObject(b) && '$value' in b) b = b.$value | ||
} | ||
@@ -63,0 +63,0 @@ a = _.isObject(a) ? Path.get(a, sortKey) : a |
@@ -110,2 +110,3 @@ var _ = require('../util') | ||
enter: 13, | ||
space: 32, | ||
'delete': 46, | ||
@@ -112,0 +113,0 @@ up: 38, |
@@ -34,3 +34,3 @@ var mergeOptions = require('../util').mergeOptions | ||
this._eventsCount = {} // for $broadcast optimization | ||
this._eventCancelled = false // for event cancellation | ||
this._shouldPropagate = false // for event propagation | ||
@@ -50,9 +50,24 @@ // fragment instance properties | ||
// context: the scope in which the component was used, | ||
// and the scope in which props and contents of this | ||
// instance should be compiled in. | ||
this._context = | ||
options._context || | ||
options._parent | ||
// context: | ||
// if this is a transcluded component, context | ||
// will be the common parent vm of this instance | ||
// and its host. | ||
this._context = options._context || options._parent | ||
// scope: | ||
// if this is inside an inline v-repeat, the scope | ||
// will be the intermediate scope created for this | ||
// repeat fragment. this is used for linking props | ||
// and container directives. | ||
this._scope = options._scope | ||
// fragment: | ||
// if this instance is compiled inside a Fragment, it | ||
// needs to reigster itself as a child of that fragment | ||
// for attach/detach to work properly. | ||
this._frag = options._frag | ||
if (this._frag) { | ||
this._frag.children.push(this) | ||
} | ||
// push self into parent / transclusion host | ||
@@ -79,3 +94,3 @@ if (this.$parent) { | ||
// initialize data observation and scope inheritance. | ||
this._initScope() | ||
this._initState() | ||
@@ -82,0 +97,0 @@ // setup event system and option events. |
@@ -55,3 +55,3 @@ var _ = require('../util') | ||
} else if ( | ||
_.isObject(value) && | ||
(_.isArray(value) || _.isPlainObject(value)) && | ||
!Object.isFrozen(value) && | ||
@@ -61,2 +61,9 @@ !value._isVue | ||
ob = new Observer(value) | ||
} else if (process.env.NODE_ENV !== 'production') { | ||
if (_.isObject(value) && !_.isArray(value) && !_.isPlainObject(value)) { | ||
_.warn( | ||
'Unobservable object found in data: ' + | ||
Object.prototype.toString.call(value) | ||
) | ||
} | ||
} | ||
@@ -74,4 +81,3 @@ if (ob && vm) { | ||
* getter/setters. This method should only be called when | ||
* value type is Object. Properties prefixed with `$` or `_` | ||
* and accessor properties are ignored. | ||
* value type is Object. | ||
* | ||
@@ -78,0 +84,0 @@ * @param {Object} obj |
@@ -5,5 +5,22 @@ var _ = require('../util') | ||
/** | ||
* $add deprecation warning | ||
*/ | ||
_.define( | ||
objProto, | ||
'$add', | ||
function (key, val) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
_.deprecation.ADD() | ||
} | ||
add(this, key, val) | ||
} | ||
) | ||
/** | ||
* Add a new property to an observed object | ||
* and emits corresponding event | ||
* and emits corresponding event. This is internal and | ||
* no longer exposed as of 1.0. | ||
* | ||
* @param {Object} obj | ||
* @param {String} key | ||
@@ -14,24 +31,26 @@ * @param {*} val | ||
_.define( | ||
objProto, | ||
'$add', | ||
function $add (key, val) { | ||
if (this.hasOwnProperty(key)) return | ||
var ob = this.__ob__ | ||
if (!ob || _.isReserved(key)) { | ||
this[key] = val | ||
return | ||
var add = exports.add = function (obj, key, val) { | ||
if (obj.hasOwnProperty(key)) { | ||
return | ||
} | ||
if (obj._isVue) { | ||
add(obj._data, key, val) | ||
return | ||
} | ||
var ob = obj.__ob__ | ||
if (!ob || _.isReserved(key)) { | ||
obj[key] = val | ||
return | ||
} | ||
ob.convert(key, val) | ||
ob.dep.notify() | ||
if (ob.vms) { | ||
var i = ob.vms.length | ||
while (i--) { | ||
var vm = ob.vms[i] | ||
vm._proxy(key) | ||
vm._digest() | ||
} | ||
ob.convert(key, val) | ||
ob.dep.notify() | ||
if (ob.vms) { | ||
var i = ob.vms.length | ||
while (i--) { | ||
var vm = ob.vms[i] | ||
vm._proxy(key) | ||
vm._digest() | ||
} | ||
} | ||
} | ||
) | ||
} | ||
@@ -51,3 +70,3 @@ /** | ||
function $set (key, val) { | ||
this.$add(key, val) | ||
add(this, key, val) | ||
this[key] = val | ||
@@ -54,0 +73,0 @@ } |
@@ -146,2 +146,7 @@ var _ = require('../util') | ||
dir.arg = _.stripQuotes(arg) || arg | ||
if (process.env.NODE_ENV !== 'production') { | ||
_.deprecation.DIR_ARGS(str) | ||
} | ||
} | ||
@@ -180,3 +185,8 @@ } else if ( | ||
cache.put(s, dirs) | ||
if (dirs.length > 1) { | ||
_.deprecation.MUTI_CLAUSES() | ||
} | ||
return dirs | ||
} |
var _ = require('../util') | ||
var add = require('../observer/object').add | ||
var Cache = require('../cache') | ||
@@ -158,3 +159,2 @@ var pathCache = new Cache(1000) | ||
* Parse a string path into an array of segments | ||
* Todo implement cache | ||
* | ||
@@ -299,2 +299,18 @@ * @param {String} path | ||
/** | ||
* Warn against setting non-existent root path on a vm. | ||
*/ | ||
var warnNonExistent | ||
if (process.env.NODE_ENV !== 'production') { | ||
warnNonExistent = function (path) { | ||
_.warn( | ||
'You are setting a non-existent path "' + path.raw + '" ' + | ||
'on a vm instance. Consider pre-initializing the property ' + | ||
'with the "data" option for more reliable reactivity ' + | ||
'and better performance.' | ||
) | ||
} | ||
} | ||
/** | ||
* Set on an object from a path | ||
@@ -325,5 +341,7 @@ * | ||
if (!_.isObject(obj)) { | ||
warnNonExistent(path) | ||
obj = {} | ||
last.$add(key, obj) | ||
if (process.env.NODE_ENV !== 'production' && last._isVue) { | ||
warnNonExistent(path) | ||
} | ||
add(last, key, obj) | ||
} | ||
@@ -336,4 +354,6 @@ } else { | ||
} else { | ||
warnNonExistent(path) | ||
obj.$add(key, val) | ||
if (process.env.NODE_ENV !== 'production' && obj._isVue) { | ||
warnNonExistent(path) | ||
} | ||
add(obj, key, val) | ||
} | ||
@@ -344,10 +364,1 @@ } | ||
} | ||
function warnNonExistent (path) { | ||
process.env.NODE_ENV !== 'production' && _.warn( | ||
'You are setting a non-existent path "' + path.raw + '" ' + | ||
'on a vm instance. Consider pre-initializing the property ' + | ||
'with the "data" option for more reliable reactivity ' + | ||
'and better performance.' | ||
) | ||
} |
var _ = require('../util') | ||
var Transition = require('./transition') | ||
@@ -64,35 +65,2 @@ /** | ||
/** | ||
* Append the childNodes of a fragment to target. | ||
* | ||
* @param {DocumentFragment} block | ||
* @param {Node} target | ||
* @param {Vue} vm | ||
*/ | ||
exports.blockAppend = function (block, target, vm) { | ||
var nodes = _.toArray(block.childNodes) | ||
for (var i = 0, l = nodes.length; i < l; i++) { | ||
exports.before(nodes[i], target, vm) | ||
} | ||
} | ||
/** | ||
* Remove a block of nodes between two edge nodes. | ||
* | ||
* @param {Node} start | ||
* @param {Node} end | ||
* @param {Vue} vm | ||
*/ | ||
exports.blockRemove = function (start, end, vm) { | ||
var node = start.nextSibling | ||
var next | ||
while (node !== end) { | ||
next = node.nextSibling | ||
exports.remove(node, vm) | ||
node = next | ||
} | ||
} | ||
/** | ||
* Apply transitions with an operation callback. | ||
@@ -110,3 +78,3 @@ * | ||
var apply = exports.apply = function (el, direction, op, vm, cb) { | ||
var transition = el.__v_trans | ||
var transition = exports.get(el, vm) | ||
if ( | ||
@@ -131,1 +99,26 @@ !transition || | ||
} | ||
/** | ||
* Get the transition object from an element, will create | ||
* one if it has the "transition" attribute but doesn't have | ||
* a transition object, or if the current transition object's | ||
* id doesn't match the desired id. | ||
* | ||
* @param {Element} el | ||
* @param {Vue} vm | ||
* @return {Transition|undefined} | ||
*/ | ||
exports.get = function (el, vm) { | ||
var transition = el.__v_trans | ||
var id = el.getAttribute && el.getAttribute('transition') | ||
// create new transition object if | ||
// 1. element has "transition" attribute | ||
// 2. current transition object's id doesn't match | ||
if (id != null && (!transition || transition.id !== id)) { | ||
var hooks = _.resolveAsset(vm.$options, 'transitions', id) | ||
id = id || 'v' | ||
transition = el.__v_trans = new Transition(el, id, hooks, el.__vue__ || vm) | ||
} | ||
return transition | ||
} |
@@ -13,4 +13,2 @@ var _ = require('../util') | ||
var uid = 0 | ||
/** | ||
@@ -27,3 +25,3 @@ * A Transition object that encapsulates the state and logic | ||
function Transition (el, id, hooks, vm) { | ||
this.id = uid++ | ||
this.id = id | ||
this.el = el | ||
@@ -30,0 +28,0 @@ this.enterClass = id + '-enter' |
@@ -12,3 +12,3 @@ var _ = require('./index') | ||
exports.commonTagRE = /^(div|p|span|img|a|br|ul|ol|li|h1|h2|h3|h4|h5|code|pre)$/ | ||
exports.commonTagRE = /^(div|p|span|img|a|b|i|br|ul|ol|li|h1|h2|h3|h4|h5|h6|code|pre|table|th|td|tr|form|label|input|select|option)$/ | ||
exports.checkComponent = function (el, options) { | ||
@@ -19,11 +19,32 @@ var tag = el.tagName.toLowerCase() | ||
var exp = el.getAttribute('is') | ||
el.removeAttribute('is') | ||
if (exp != null) { | ||
if (process.env.NODE_ENV !== 'production' && /{{.*}}/.test(exp)) { | ||
_.deprecation.BIND_IS() | ||
} | ||
el.removeAttribute('is') | ||
} else { | ||
exp = el.getAttribute('bind-is') | ||
if (exp != null) { | ||
// leverage literal dynamic for now. | ||
// TODO: make this cleaner | ||
exp = '{{' + exp + '}}' | ||
el.removeAttribute('bind-is') | ||
} | ||
} | ||
return exp | ||
} else if ( | ||
!exports.commonTagRE.test(tag) && | ||
_.resolveAsset(options, 'components', tag) | ||
) { | ||
return tag | ||
} else if (!exports.commonTagRE.test(tag)) { | ||
if (_.resolveAsset(options, 'components', tag)) { | ||
return tag | ||
} else if (process.env.NODE_ENV !== 'production') { | ||
if (tag.indexOf('-') > -1 || | ||
/HTMLUnknownElement/.test(Object.prototype.toString.call(el))) { | ||
_.warn( | ||
'Unknown custom element: <' + tag + '> - did you ' + | ||
'register the component correctly?' | ||
) | ||
} | ||
} | ||
} | ||
/* eslint-disable no-cond-assign */ | ||
} else if (tag = _.attr(el, 'component')) { | ||
if (tag = _.attr(el, 'component')) { | ||
/* eslint-enable no-cond-assign */ | ||
@@ -30,0 +51,0 @@ return tag |
@@ -11,2 +11,8 @@ /** | ||
/** | ||
* Load deprecation warning functions | ||
*/ | ||
exports.deprecations = require('../deprecations') | ||
/** | ||
* Log a message. | ||
@@ -44,19 +50,2 @@ * | ||
exports.assertAsset = function (val, type, id) { | ||
/* istanbul ignore if */ | ||
if (type === 'directive') { | ||
if (id === 'with') { | ||
exports.warn( | ||
'v-with has been deprecated in ^0.12.0. ' + | ||
'Use props instead.' | ||
) | ||
return | ||
} | ||
if (id === 'events') { | ||
exports.warn( | ||
'v-events has been deprecated in ^0.12.0. ' + | ||
'Pass down methods as callback props instead.' | ||
) | ||
return | ||
} | ||
} | ||
if (!val) { | ||
@@ -63,0 +52,0 @@ exports.warn('Failed to resolve ' + type + ': ' + id) |
@@ -185,2 +185,5 @@ var _ = require('./index') | ||
} | ||
if (!el.className) { | ||
el.removeAttribute('class') | ||
} | ||
} | ||
@@ -187,0 +190,0 @@ |
@@ -0,1 +1,3 @@ | ||
var Dep = require('../observer/dep') | ||
/** | ||
@@ -194,4 +196,5 @@ * Check is a string starts with $ or _ | ||
var toString = Object.prototype.toString | ||
var OBJECT_STRING = '[object Object]' | ||
exports.isPlainObject = function (obj) { | ||
return toString.call(obj) === '[object Object]' | ||
return toString.call(obj) === OBJECT_STRING | ||
} | ||
@@ -227,2 +230,28 @@ | ||
/** | ||
* Define a reactive property. | ||
* | ||
* @param {Object} obj | ||
* @param {String} key | ||
* @param {*} val | ||
*/ | ||
exports.defineReactive = function (obj, key, val) { | ||
var dep = new Dep() | ||
Object.defineProperty(obj, key, { | ||
get: function metaGetter () { | ||
if (Dep.target) { | ||
dep.depend() | ||
} | ||
return val | ||
}, | ||
set: function metaSetter (newVal) { | ||
if (val !== newVal) { | ||
val = newVal | ||
dep.notify() | ||
} | ||
} | ||
}) | ||
} | ||
/** | ||
* Debounce a function so it only gets called after the | ||
@@ -229,0 +258,0 @@ * input stops arriving after the given wait period. |
@@ -29,3 +29,3 @@ var _ = require('./index') | ||
if (!to.hasOwnProperty(key)) { | ||
to.$add(key, fromVal) | ||
to.$set(key, fromVal) | ||
} else if (_.isObject(toVal) && _.isObject(fromVal)) { | ||
@@ -308,2 +308,9 @@ mergeData(toVal, fromVal) | ||
exports.mergeOptions = function merge (parent, child, vm) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
if (child.inherit && !child._repeat) { | ||
_.deprecation.INHERIT() | ||
} | ||
} | ||
guardComponents(child) | ||
@@ -349,2 +356,6 @@ guardProps(child) | ||
var asset = assets[id] || assets[camelizedId] || assets[pascalizedId] | ||
// for deprecation check | ||
var localAsset = asset | ||
while ( | ||
@@ -359,3 +370,10 @@ !asset && | ||
} | ||
if (process.env.NODE_ENV !== 'production') { | ||
if (asset && !localAsset && !config.strict) { | ||
_.deprecation.STRICT_MODE(type, id) | ||
} | ||
} | ||
return asset | ||
} |
@@ -75,4 +75,4 @@ var _ = require('./util') | ||
extend(p, require('./instance/events')) | ||
extend(p, require('./instance/scope')) | ||
extend(p, require('./instance/compile')) | ||
extend(p, require('./instance/state')) | ||
extend(p, require('./instance/lifecycle')) | ||
extend(p, require('./instance/misc')) | ||
@@ -90,2 +90,3 @@ | ||
Vue.version = '1.0.0-alpha' | ||
module.exports = _.Vue = Vue |
@@ -41,3 +41,3 @@ var _ = require('./util') | ||
this.deps = [] | ||
this.newDeps = null | ||
this.newDeps = [] | ||
this.prevError = null // for async error stacks | ||
@@ -88,5 +88,6 @@ // parse expression for getter/setter | ||
var vm = this.vm | ||
var scope = this.scope || vm | ||
var value | ||
try { | ||
value = this.getter.call(vm, vm) | ||
value = this.getter.call(scope, scope) | ||
} catch (e) { | ||
@@ -130,2 +131,3 @@ if ( | ||
var vm = this.vm | ||
var scope = this.scope || vm | ||
if (this.filters) { | ||
@@ -136,3 +138,3 @@ value = vm._applyFilters( | ||
try { | ||
this.setter.call(vm, vm, value) | ||
this.setter.call(scope, scope, value) | ||
} catch (e) { | ||
@@ -149,2 +151,21 @@ if ( | ||
} | ||
// two-way sync for v-for alias | ||
var forContext = scope.$forContext | ||
if (forContext && forContext.alias === this.expression) { | ||
if (forContext.filters) { | ||
process.env.NODE_ENV !== 'production' && _.warn( | ||
'It seems you are using two-way binding on ' + | ||
'a v-for alias, and the v-for has filters. ' + | ||
'This will not work properly. Either remove the ' + | ||
'filters or use an array of objects and bind to ' + | ||
'object properties instead.' | ||
) | ||
return | ||
} | ||
if (scope.$key) { // original is an object | ||
forContext.rawValue[scope.$key] = value | ||
} else { | ||
forContext.rawValue.$set(scope.$index, value) | ||
} | ||
} | ||
} | ||
@@ -158,3 +179,2 @@ | ||
Dep.target = this | ||
this.newDeps = [] | ||
} | ||
@@ -168,5 +188,6 @@ | ||
Dep.target = null | ||
var i = this.deps.length | ||
var oldDeps = this.deps | ||
var i = oldDeps.length | ||
while (i--) { | ||
var dep = this.deps[i] | ||
var dep = oldDeps[i] | ||
if (dep) { | ||
@@ -177,3 +198,4 @@ dep.removeSub(this) | ||
this.deps = this.newDeps | ||
this.newDeps = null | ||
this.newDeps = oldDeps | ||
oldDeps.length = 0 // reuse old dep array | ||
} | ||
@@ -180,0 +202,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
637094
77
20794
91