mirror of https://github.com/vuejs/vue.git
3181 lines
84 KiB
JavaScript
3181 lines
84 KiB
JavaScript
;(function(){
|
|
|
|
/**
|
|
* Require the given path.
|
|
*
|
|
* @param {String} path
|
|
* @return {Object} exports
|
|
* @api public
|
|
*/
|
|
|
|
function require(path, parent, orig) {
|
|
var resolved = require.resolve(path);
|
|
|
|
// lookup failed
|
|
if (null == resolved) {
|
|
orig = orig || path;
|
|
parent = parent || 'root';
|
|
var err = new Error('Failed to require "' + orig + '" from "' + parent + '"');
|
|
err.path = orig;
|
|
err.parent = parent;
|
|
err.require = true;
|
|
throw err;
|
|
}
|
|
|
|
var module = require.modules[resolved];
|
|
|
|
// perform real require()
|
|
// by invoking the module's
|
|
// registered function
|
|
if (!module._resolving && !module.exports) {
|
|
var mod = {};
|
|
mod.exports = {};
|
|
mod.client = mod.component = true;
|
|
module._resolving = true;
|
|
module.call(this, mod.exports, require.relative(resolved), mod);
|
|
delete module._resolving;
|
|
module.exports = mod.exports;
|
|
}
|
|
|
|
return module.exports;
|
|
}
|
|
|
|
/**
|
|
* Registered modules.
|
|
*/
|
|
|
|
require.modules = {};
|
|
|
|
/**
|
|
* Registered aliases.
|
|
*/
|
|
|
|
require.aliases = {};
|
|
|
|
/**
|
|
* Resolve `path`.
|
|
*
|
|
* Lookup:
|
|
*
|
|
* - PATH/index.js
|
|
* - PATH.js
|
|
* - PATH
|
|
*
|
|
* @param {String} path
|
|
* @return {String} path or null
|
|
* @api private
|
|
*/
|
|
|
|
require.resolve = function(path) {
|
|
if (path.charAt(0) === '/') path = path.slice(1);
|
|
|
|
var paths = [
|
|
path,
|
|
path + '.js',
|
|
path + '.json',
|
|
path + '/index.js',
|
|
path + '/index.json'
|
|
];
|
|
|
|
for (var i = 0; i < paths.length; i++) {
|
|
var path = paths[i];
|
|
if (require.modules.hasOwnProperty(path)) return path;
|
|
if (require.aliases.hasOwnProperty(path)) return require.aliases[path];
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Normalize `path` relative to the current path.
|
|
*
|
|
* @param {String} curr
|
|
* @param {String} path
|
|
* @return {String}
|
|
* @api private
|
|
*/
|
|
|
|
require.normalize = function(curr, path) {
|
|
var segs = [];
|
|
|
|
if ('.' != path.charAt(0)) return path;
|
|
|
|
curr = curr.split('/');
|
|
path = path.split('/');
|
|
|
|
for (var i = 0; i < path.length; ++i) {
|
|
if ('..' == path[i]) {
|
|
curr.pop();
|
|
} else if ('.' != path[i] && '' != path[i]) {
|
|
segs.push(path[i]);
|
|
}
|
|
}
|
|
|
|
return curr.concat(segs).join('/');
|
|
};
|
|
|
|
/**
|
|
* Register module at `path` with callback `definition`.
|
|
*
|
|
* @param {String} path
|
|
* @param {Function} definition
|
|
* @api private
|
|
*/
|
|
|
|
require.register = function(path, definition) {
|
|
require.modules[path] = definition;
|
|
};
|
|
|
|
/**
|
|
* Alias a module definition.
|
|
*
|
|
* @param {String} from
|
|
* @param {String} to
|
|
* @api private
|
|
*/
|
|
|
|
require.alias = function(from, to) {
|
|
if (!require.modules.hasOwnProperty(from)) {
|
|
throw new Error('Failed to alias "' + from + '", it does not exist');
|
|
}
|
|
require.aliases[to] = from;
|
|
};
|
|
|
|
/**
|
|
* Return a require function relative to the `parent` path.
|
|
*
|
|
* @param {String} parent
|
|
* @return {Function}
|
|
* @api private
|
|
*/
|
|
|
|
require.relative = function(parent) {
|
|
var p = require.normalize(parent, '..');
|
|
|
|
/**
|
|
* lastIndexOf helper.
|
|
*/
|
|
|
|
function lastIndexOf(arr, obj) {
|
|
var i = arr.length;
|
|
while (i--) {
|
|
if (arr[i] === obj) return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* The relative require() itself.
|
|
*/
|
|
|
|
function localRequire(path) {
|
|
var resolved = localRequire.resolve(path);
|
|
return require(resolved, parent, path);
|
|
}
|
|
|
|
/**
|
|
* Resolve relative to the parent.
|
|
*/
|
|
|
|
localRequire.resolve = function(path) {
|
|
var c = path.charAt(0);
|
|
if ('/' == c) return path.slice(1);
|
|
if ('.' == c) return require.normalize(p, path);
|
|
|
|
// resolve deps by returning
|
|
// the dep in the nearest "deps"
|
|
// directory
|
|
var segs = parent.split('/');
|
|
var i = lastIndexOf(segs, 'deps') + 1;
|
|
if (!i) i = 0;
|
|
path = segs.slice(0, i + 1).join('/') + '/deps/' + path;
|
|
return path;
|
|
};
|
|
|
|
/**
|
|
* Check if module is defined at `path`.
|
|
*/
|
|
|
|
localRequire.exists = function(path) {
|
|
return require.modules.hasOwnProperty(localRequire.resolve(path));
|
|
};
|
|
|
|
return localRequire;
|
|
};
|
|
require.register("component-emitter/index.js", function(exports, require, module){
|
|
|
|
/**
|
|
* Expose `Emitter`.
|
|
*/
|
|
|
|
module.exports = Emitter;
|
|
|
|
/**
|
|
* Initialize a new `Emitter`.
|
|
*
|
|
* @api public
|
|
*/
|
|
|
|
function Emitter(obj) {
|
|
if (obj) return mixin(obj);
|
|
};
|
|
|
|
/**
|
|
* Mixin the emitter properties.
|
|
*
|
|
* @param {Object} obj
|
|
* @return {Object}
|
|
* @api private
|
|
*/
|
|
|
|
function mixin(obj) {
|
|
for (var key in Emitter.prototype) {
|
|
obj[key] = Emitter.prototype[key];
|
|
}
|
|
return obj;
|
|
}
|
|
|
|
/**
|
|
* Listen on the given `event` with `fn`.
|
|
*
|
|
* @param {String} event
|
|
* @param {Function} fn
|
|
* @return {Emitter}
|
|
* @api public
|
|
*/
|
|
|
|
Emitter.prototype.on =
|
|
Emitter.prototype.addEventListener = function(event, fn){
|
|
this._callbacks = this._callbacks || {};
|
|
(this._callbacks[event] = this._callbacks[event] || [])
|
|
.push(fn);
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Adds an `event` listener that will be invoked a single
|
|
* time then automatically removed.
|
|
*
|
|
* @param {String} event
|
|
* @param {Function} fn
|
|
* @return {Emitter}
|
|
* @api public
|
|
*/
|
|
|
|
Emitter.prototype.once = function(event, fn){
|
|
var self = this;
|
|
this._callbacks = this._callbacks || {};
|
|
|
|
function on() {
|
|
self.off(event, on);
|
|
fn.apply(this, arguments);
|
|
}
|
|
|
|
on.fn = fn;
|
|
this.on(event, on);
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Remove the given callback for `event` or all
|
|
* registered callbacks.
|
|
*
|
|
* @param {String} event
|
|
* @param {Function} fn
|
|
* @return {Emitter}
|
|
* @api public
|
|
*/
|
|
|
|
Emitter.prototype.off =
|
|
Emitter.prototype.removeListener =
|
|
Emitter.prototype.removeAllListeners =
|
|
Emitter.prototype.removeEventListener = function(event, fn){
|
|
this._callbacks = this._callbacks || {};
|
|
|
|
// all
|
|
if (0 == arguments.length) {
|
|
this._callbacks = {};
|
|
return this;
|
|
}
|
|
|
|
// specific event
|
|
var callbacks = this._callbacks[event];
|
|
if (!callbacks) return this;
|
|
|
|
// remove all handlers
|
|
if (1 == arguments.length) {
|
|
delete this._callbacks[event];
|
|
return this;
|
|
}
|
|
|
|
// remove specific handler
|
|
var cb;
|
|
for (var i = 0; i < callbacks.length; i++) {
|
|
cb = callbacks[i];
|
|
if (cb === fn || cb.fn === fn) {
|
|
callbacks.splice(i, 1);
|
|
break;
|
|
}
|
|
}
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Emit `event` with the given args.
|
|
*
|
|
* @param {String} event
|
|
* @param {Mixed} ...
|
|
* @return {Emitter}
|
|
*/
|
|
|
|
Emitter.prototype.emit = function(event){
|
|
this._callbacks = this._callbacks || {};
|
|
var args = [].slice.call(arguments, 1)
|
|
, callbacks = this._callbacks[event];
|
|
|
|
if (callbacks) {
|
|
callbacks = callbacks.slice(0);
|
|
for (var i = 0, len = callbacks.length; i < len; ++i) {
|
|
callbacks[i].apply(this, args);
|
|
}
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Return array of callbacks for `event`.
|
|
*
|
|
* @param {String} event
|
|
* @return {Array}
|
|
* @api public
|
|
*/
|
|
|
|
Emitter.prototype.listeners = function(event){
|
|
this._callbacks = this._callbacks || {};
|
|
return this._callbacks[event] || [];
|
|
};
|
|
|
|
/**
|
|
* Check if this emitter has `event` handlers.
|
|
*
|
|
* @param {String} event
|
|
* @return {Boolean}
|
|
* @api public
|
|
*/
|
|
|
|
Emitter.prototype.hasListeners = function(event){
|
|
return !! this.listeners(event).length;
|
|
};
|
|
|
|
});
|
|
require.register("vue/src/main.js", function(exports, require, module){
|
|
var config = require('./config'),
|
|
ViewModel = require('./viewmodel'),
|
|
directives = require('./directives'),
|
|
filters = require('./filters'),
|
|
utils = require('./utils')
|
|
|
|
/**
|
|
* Set config options
|
|
*/
|
|
ViewModel.config = function (opts) {
|
|
if (opts) {
|
|
utils.extend(config, opts)
|
|
if (opts.prefix) updatePrefix()
|
|
}
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Allows user to register/retrieve a directive definition
|
|
*/
|
|
ViewModel.directive = function (id, fn) {
|
|
if (!fn) return directives[id]
|
|
directives[id] = fn
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Allows user to register/retrieve a filter function
|
|
*/
|
|
ViewModel.filter = function (id, fn) {
|
|
if (!fn) return filters[id]
|
|
filters[id] = fn
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Allows user to register/retrieve a ViewModel constructor
|
|
*/
|
|
ViewModel.component = function (id, Ctor) {
|
|
if (!Ctor) return utils.components[id]
|
|
utils.components[id] = utils.toConstructor(Ctor)
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Allows user to register/retrieve a Custom element constructor
|
|
*/
|
|
ViewModel.element = function (id, Ctor) {
|
|
if (!Ctor) return utils.elements[id]
|
|
utils.elements[id] = utils.toConstructor(Ctor)
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Allows user to register/retrieve a template partial
|
|
*/
|
|
ViewModel.partial = function (id, partial) {
|
|
if (!partial) return utils.partials[id]
|
|
utils.partials[id] = utils.toFragment(partial)
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Allows user to register/retrieve a transition definition object
|
|
*/
|
|
ViewModel.transition = function (id, transition) {
|
|
if (!transition) return utils.transitions[id]
|
|
utils.transitions[id] = transition
|
|
return this
|
|
}
|
|
|
|
ViewModel.extend = extend
|
|
|
|
/**
|
|
* Expose the main ViewModel class
|
|
* and add extend method
|
|
*/
|
|
function extend (options) {
|
|
|
|
var ParentVM = this
|
|
|
|
// inherit options
|
|
options = inheritOptions(options, ParentVM.options, true)
|
|
utils.processOptions(options)
|
|
|
|
var ExtendedVM = function (opts) {
|
|
opts = inheritOptions(opts, options, true)
|
|
ParentVM.call(this, opts)
|
|
}
|
|
|
|
// inherit prototype props
|
|
var proto = ExtendedVM.prototype = Object.create(ParentVM.prototype)
|
|
utils.defProtected(proto, 'constructor', ExtendedVM)
|
|
|
|
// copy prototype props
|
|
var protoMixins = options.proto
|
|
if (protoMixins) {
|
|
for (var key in protoMixins) {
|
|
if (!(key in ViewModel.prototype)) {
|
|
proto[key] = protoMixins[key]
|
|
}
|
|
}
|
|
}
|
|
|
|
// allow extended VM to be further extended
|
|
ExtendedVM.extend = extend
|
|
ExtendedVM.super = ParentVM
|
|
ExtendedVM.options = options
|
|
return ExtendedVM
|
|
}
|
|
|
|
/**
|
|
* Inherit options
|
|
*
|
|
* For options such as `scope`, `vms`, `directives`, 'partials',
|
|
* they should be further extended. However extending should only
|
|
* be done at top level.
|
|
*
|
|
* `proto` is an exception because it's handled directly on the
|
|
* prototype.
|
|
*
|
|
* `el` is an exception because it's not allowed as an
|
|
* extension option, but only as an instance option.
|
|
*/
|
|
function inheritOptions (child, parent, topLevel) {
|
|
child = child || utils.hash()
|
|
if (!parent) return child
|
|
for (var key in parent) {
|
|
if (key === 'el' || key === 'proto') continue
|
|
if (!child[key]) { // child has priority
|
|
child[key] = parent[key]
|
|
} else if (topLevel && utils.typeOf(child[key]) === 'Object') {
|
|
inheritOptions(child[key], parent[key], false)
|
|
}
|
|
}
|
|
return child
|
|
}
|
|
|
|
/**
|
|
* Update prefix for some special directives
|
|
* that are used in compilation.
|
|
*/
|
|
var specialAttributes = [
|
|
'id',
|
|
'pre',
|
|
'text',
|
|
'repeat',
|
|
'partial',
|
|
'component',
|
|
'transition'
|
|
]
|
|
|
|
function updatePrefix () {
|
|
specialAttributes.forEach(setPrefix)
|
|
}
|
|
|
|
function setPrefix (attr) {
|
|
config.attrs[attr] = config.prefix + '-' + attr
|
|
}
|
|
|
|
updatePrefix()
|
|
module.exports = ViewModel
|
|
});
|
|
require.register("vue/src/emitter.js", function(exports, require, module){
|
|
// shiv to make this work for Component, Browserify and Node at the same time.
|
|
var Emitter,
|
|
componentEmitter = 'emitter'
|
|
|
|
try {
|
|
// Requiring without a string literal will make browserify
|
|
// unable to parse the dependency, thus preventing it from
|
|
// stopping the compilation after a failed lookup.
|
|
Emitter = require(componentEmitter)
|
|
} catch (e) {
|
|
Emitter = require('events').EventEmitter
|
|
Emitter.prototype.off = function () {
|
|
var method = arguments.length > 1
|
|
? this.removeListener
|
|
: this.removeAllListeners
|
|
return method.apply(this, arguments)
|
|
}
|
|
}
|
|
|
|
module.exports = Emitter
|
|
});
|
|
require.register("vue/src/config.js", function(exports, require, module){
|
|
module.exports = {
|
|
|
|
prefix : 'v',
|
|
debug : false,
|
|
silent : false,
|
|
enterClass : 'v-enter',
|
|
leaveClass : 'v-leave',
|
|
attrs : {}
|
|
|
|
}
|
|
});
|
|
require.register("vue/src/utils.js", function(exports, require, module){
|
|
var config = require('./config'),
|
|
attrs = config.attrs,
|
|
toString = Object.prototype.toString,
|
|
join = Array.prototype.join,
|
|
console = window.console,
|
|
ViewModel // late def
|
|
|
|
/**
|
|
* Create a prototype-less object
|
|
* which is a better hash/map
|
|
*/
|
|
function makeHash () {
|
|
return Object.create(null)
|
|
}
|
|
|
|
var utils = module.exports = {
|
|
|
|
hash: makeHash,
|
|
|
|
// global storage for user-registered
|
|
// vms, partials and transitions
|
|
components : makeHash(),
|
|
partials : makeHash(),
|
|
transitions : makeHash(),
|
|
elements : makeHash(),
|
|
|
|
/**
|
|
* get an attribute and remove it.
|
|
*/
|
|
attr: function (el, type, noRemove) {
|
|
var attr = attrs[type],
|
|
val = el.getAttribute(attr)
|
|
if (!noRemove && val !== null) el.removeAttribute(attr)
|
|
return val
|
|
},
|
|
|
|
/**
|
|
* Define an ienumerable property
|
|
* This avoids it being included in JSON.stringify
|
|
* or for...in loops.
|
|
*/
|
|
defProtected: function (obj, key, val, enumerable, configurable) {
|
|
if (obj.hasOwnProperty(key)) return
|
|
Object.defineProperty(obj, key, {
|
|
value : val,
|
|
enumerable : !!enumerable,
|
|
configurable : !!configurable
|
|
})
|
|
},
|
|
|
|
/**
|
|
* Accurate type check
|
|
* internal use only, so no need to check for NaN
|
|
*/
|
|
typeOf: function (obj) {
|
|
return toString.call(obj).slice(8, -1)
|
|
},
|
|
|
|
/**
|
|
* Most simple bind
|
|
* enough for the usecase and fast than native bind()
|
|
*/
|
|
bind: function (fn, ctx) {
|
|
return function (arg) {
|
|
return fn.call(ctx, arg)
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Make sure only strings and numbers are output to html
|
|
* output empty string is value is not string or number
|
|
*/
|
|
toText: function (value) {
|
|
/* jshint eqeqeq: false */
|
|
return (typeof value === 'string' ||
|
|
typeof value === 'boolean' ||
|
|
(typeof value === 'number' && value == value)) // deal with NaN
|
|
? value
|
|
: ''
|
|
},
|
|
|
|
/**
|
|
* simple extend
|
|
*/
|
|
extend: function (obj, ext, protective) {
|
|
for (var key in ext) {
|
|
if (protective && obj[key]) continue
|
|
obj[key] = ext[key]
|
|
}
|
|
},
|
|
|
|
/**
|
|
* filter an array with duplicates into uniques
|
|
*/
|
|
unique: function (arr) {
|
|
var hash = utils.hash(),
|
|
i = arr.length,
|
|
key, res = []
|
|
while (i--) {
|
|
key = arr[i]
|
|
if (hash[key]) continue
|
|
hash[key] = 1
|
|
res.push(key)
|
|
}
|
|
return res
|
|
},
|
|
|
|
/**
|
|
* Convert a string template to a dom fragment
|
|
*/
|
|
toFragment: function (template) {
|
|
if (typeof template !== 'string') {
|
|
return template
|
|
}
|
|
if (template.charAt(0) === '#') {
|
|
var templateNode = document.getElementById(template.slice(1))
|
|
if (!templateNode) return
|
|
template = templateNode.innerHTML
|
|
}
|
|
var node = document.createElement('div'),
|
|
frag = document.createDocumentFragment(),
|
|
child
|
|
node.innerHTML = template.trim()
|
|
/* jshint boss: true */
|
|
while (child = node.firstChild) {
|
|
frag.appendChild(child)
|
|
}
|
|
return frag
|
|
},
|
|
|
|
/**
|
|
* Convert the object to a ViewModel constructor
|
|
* if it is not already one
|
|
*/
|
|
toConstructor: function (obj) {
|
|
ViewModel = ViewModel || require('./viewmodel')
|
|
return utils.typeOf(obj) === 'Object'
|
|
? ViewModel.extend(obj)
|
|
: typeof obj === 'function'
|
|
? obj
|
|
: null
|
|
},
|
|
|
|
isConstructor: function (obj) {
|
|
ViewModel = ViewModel || require('./viewmodel')
|
|
return obj.prototype instanceof ViewModel || obj === ViewModel
|
|
},
|
|
|
|
/**
|
|
* convert certain option values to the desired format.
|
|
*/
|
|
processOptions: function (options) {
|
|
var components = options.components,
|
|
partials = options.partials,
|
|
template = options.template,
|
|
elements = options.elements,
|
|
key
|
|
if (components) {
|
|
for (key in components) {
|
|
components[key] = utils.toConstructor(components[key])
|
|
}
|
|
}
|
|
if (elements) {
|
|
for (key in elements) {
|
|
elements[key] = utils.toConstructor(elements[key])
|
|
}
|
|
}
|
|
if (partials) {
|
|
for (key in partials) {
|
|
partials[key] = utils.toFragment(partials[key])
|
|
}
|
|
}
|
|
if (template) {
|
|
options.template = utils.toFragment(template)
|
|
}
|
|
},
|
|
|
|
/**
|
|
* log for debugging
|
|
*/
|
|
log: function () {
|
|
if (config.debug && console) {
|
|
console.log(join.call(arguments, ' '))
|
|
}
|
|
},
|
|
|
|
/**
|
|
* warnings, thrown in all cases
|
|
*/
|
|
warn: function() {
|
|
if (!config.silent && console) {
|
|
console.trace()
|
|
console.warn(join.call(arguments, ' '))
|
|
}
|
|
}
|
|
}
|
|
});
|
|
require.register("vue/src/compiler.js", function(exports, require, module){
|
|
var Emitter = require('./emitter'),
|
|
Observer = require('./observer'),
|
|
config = require('./config'),
|
|
utils = require('./utils'),
|
|
Binding = require('./binding'),
|
|
Directive = require('./directive'),
|
|
TextParser = require('./text-parser'),
|
|
DepsParser = require('./deps-parser'),
|
|
ExpParser = require('./exp-parser'),
|
|
transition = require('./transition'),
|
|
// cache deps ob
|
|
depsOb = DepsParser.observer,
|
|
// cache methods
|
|
slice = Array.prototype.slice,
|
|
log = utils.log,
|
|
makeHash = utils.hash,
|
|
def = utils.defProtected,
|
|
hasOwn = Object.prototype.hasOwnProperty
|
|
|
|
/**
|
|
* The DOM compiler
|
|
* scans a DOM node and compile bindings for a ViewModel
|
|
*/
|
|
function Compiler (vm, options) {
|
|
|
|
var compiler = this
|
|
|
|
// indicate that we are intiating this instance
|
|
// so we should not run any transitions
|
|
compiler.init = true
|
|
|
|
// extend options
|
|
options = compiler.options = options || makeHash()
|
|
utils.processOptions(options)
|
|
utils.extend(compiler, options.compilerOptions)
|
|
|
|
// initialize element
|
|
var el = compiler.setupElement(options)
|
|
log('\nnew VM instance:', el.tagName, '\n')
|
|
|
|
// copy scope properties to vm
|
|
var scope = options.scope
|
|
if (scope) utils.extend(vm, scope, true)
|
|
|
|
compiler.vm = vm
|
|
def(vm, '$', makeHash())
|
|
def(vm, '$el', el)
|
|
def(vm, '$compiler', compiler)
|
|
|
|
// keep track of directives and expressions
|
|
// so they can be unbound during destroy()
|
|
compiler.dirs = []
|
|
compiler.exps = []
|
|
compiler.childCompilers = [] // keep track of child compilers
|
|
compiler.emitter = new Emitter() // the emitter used for nested VM communication
|
|
|
|
// Store things during parsing to be processed afterwards,
|
|
// because we want to have created all bindings before
|
|
// observing values / parsing dependencies.
|
|
var observables = compiler.observables = [],
|
|
computed = compiler.computed = []
|
|
|
|
// prototypal inheritance of bindings
|
|
var parent = compiler.parentCompiler
|
|
compiler.bindings = parent
|
|
? Object.create(parent.bindings)
|
|
: makeHash()
|
|
compiler.rootCompiler = parent
|
|
? getRoot(parent)
|
|
: compiler
|
|
|
|
// set parent VM
|
|
// and register child id on parent
|
|
var childId = utils.attr(el, 'id')
|
|
if (parent) {
|
|
def(vm, '$parent', parent.vm)
|
|
if (childId) {
|
|
compiler.childId = childId
|
|
parent.vm.$[childId] = vm
|
|
}
|
|
}
|
|
|
|
// setup observer
|
|
compiler.setupObserver()
|
|
|
|
// call user init. this will capture some initial values.
|
|
if (options.init) {
|
|
options.init.apply(vm, options.args || [])
|
|
}
|
|
|
|
// create bindings for keys set on the vm by the user
|
|
var key, keyPrefix
|
|
for (key in vm) {
|
|
keyPrefix = key.charAt(0)
|
|
if (keyPrefix !== '$' && keyPrefix !== '_') {
|
|
compiler.createBinding(key)
|
|
}
|
|
}
|
|
|
|
// for repeated items, create an index binding
|
|
// which should be inenumerable but configurable
|
|
if (compiler.repeat) {
|
|
vm.$index = compiler.repeatIndex
|
|
def(vm, '$collection', compiler.repeatCollection)
|
|
compiler.createBinding('$index')
|
|
}
|
|
|
|
// now parse the DOM, during which we will create necessary bindings
|
|
// and bind the parsed directives
|
|
compiler.compile(el, true)
|
|
|
|
// observe root values so that they emit events when
|
|
// their nested values change (for an Object)
|
|
// or when they mutate (for an Array)
|
|
var i = observables.length, binding
|
|
while (i--) {
|
|
binding = observables[i]
|
|
Observer.observe(binding.value, binding.key, compiler.observer)
|
|
}
|
|
// extract dependencies for computed properties
|
|
if (computed.length) DepsParser.parse(computed)
|
|
|
|
// done!
|
|
compiler.init = false
|
|
}
|
|
|
|
var CompilerProto = Compiler.prototype
|
|
|
|
/**
|
|
* Initialize the VM/Compiler's element.
|
|
* Fill it in with the template if necessary.
|
|
*/
|
|
CompilerProto.setupElement = function (options) {
|
|
// create the node first
|
|
var el = this.el = typeof options.el === 'string'
|
|
? document.querySelector(options.el)
|
|
: options.el || document.createElement(options.tagName || 'div')
|
|
|
|
var template = options.template
|
|
if (template) {
|
|
// replace option: use the first node in
|
|
// the template directly
|
|
if (options.replace && template.childNodes.length === 1) {
|
|
var replacer = template.childNodes[0].cloneNode(true)
|
|
if (el.parentNode) {
|
|
el.parentNode.insertBefore(replacer, el)
|
|
el.parentNode.removeChild(el)
|
|
}
|
|
el = replacer
|
|
} else {
|
|
el.innerHTML = ''
|
|
el.appendChild(template.cloneNode(true))
|
|
}
|
|
}
|
|
|
|
// apply element options
|
|
if (options.id) el.id = options.id
|
|
if (options.className) el.className = options.className
|
|
var attrs = options.attributes
|
|
if (attrs) {
|
|
for (var attr in attrs) {
|
|
el.setAttribute(attr, attrs[attr])
|
|
}
|
|
}
|
|
|
|
return el
|
|
}
|
|
|
|
/**
|
|
* Setup observer.
|
|
* The observer listens for get/set/mutate events on all VM
|
|
* values/objects and trigger corresponding binding updates.
|
|
*/
|
|
CompilerProto.setupObserver = function () {
|
|
|
|
var compiler = this,
|
|
bindings = compiler.bindings,
|
|
observer = compiler.observer = new Emitter()
|
|
|
|
// a hash to hold event proxies for each root level key
|
|
// so they can be referenced and removed later
|
|
observer.proxies = makeHash()
|
|
|
|
// add own listeners which trigger binding updates
|
|
observer
|
|
.on('get', function (key) {
|
|
check(key)
|
|
depsOb.emit('get', bindings[key])
|
|
})
|
|
.on('set', function (key, val) {
|
|
observer.emit('change:' + key, val)
|
|
check(key)
|
|
bindings[key].update(val)
|
|
})
|
|
.on('mutate', function (key, val, mutation) {
|
|
observer.emit('change:' + key, val, mutation)
|
|
check(key)
|
|
bindings[key].pub()
|
|
})
|
|
|
|
function check (key) {
|
|
if (!bindings[key]) {
|
|
compiler.createBinding(key)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Compile a DOM node (recursive)
|
|
*/
|
|
CompilerProto.compile = function (node, root) {
|
|
|
|
var compiler = this
|
|
|
|
if (node.nodeType === 1) { // a normal node
|
|
|
|
// skip anything with v-pre
|
|
if (utils.attr(node, 'pre') !== null) return
|
|
|
|
// special attributes to check
|
|
var repeatExp,
|
|
componentId,
|
|
partialId,
|
|
customElementFn = compiler.getOption('elements', node.tagName.toLowerCase())
|
|
|
|
// It is important that we access these attributes
|
|
// procedurally because the order matters.
|
|
//
|
|
// `utils.attr` removes the attribute once it gets the
|
|
// value, so we should not access them all at once.
|
|
|
|
// v-repeat has the highest priority
|
|
// and we need to preserve all other attributes for it.
|
|
/* jshint boss: true */
|
|
if (repeatExp = utils.attr(node, 'repeat')) {
|
|
|
|
// repeat block cannot have v-id at the same time.
|
|
var directive = Directive.parse(config.attrs.repeat, repeatExp, compiler, node)
|
|
if (directive) {
|
|
compiler.bindDirective(directive)
|
|
}
|
|
|
|
// custom elements has 2nd highest priority
|
|
} else if (!root && customElementFn) {
|
|
|
|
addChild(customElementFn)
|
|
|
|
// v-component has 3rd highest priority
|
|
} else if (!root && (componentId = utils.attr(node, 'component'))) {
|
|
|
|
var ChildVM = compiler.getOption('components', componentId)
|
|
if (ChildVM) addChild(ChildVM)
|
|
|
|
} else {
|
|
|
|
// check transition property
|
|
node.vue_trans = utils.attr(node, 'transition')
|
|
|
|
// replace innerHTML with partial
|
|
partialId = utils.attr(node, 'partial')
|
|
if (partialId) {
|
|
var partial = compiler.getOption('partials', partialId)
|
|
if (partial) {
|
|
node.innerHTML = ''
|
|
node.appendChild(partial.cloneNode(true))
|
|
}
|
|
}
|
|
|
|
// finally, only normal directives left!
|
|
compiler.compileNode(node)
|
|
}
|
|
|
|
} else if (node.nodeType === 3) { // text node
|
|
|
|
compiler.compileTextNode(node)
|
|
|
|
}
|
|
|
|
function addChild (Ctor) {
|
|
if (utils.isConstructor(Ctor)) {
|
|
var child = new Ctor({
|
|
el: node,
|
|
child: true,
|
|
compilerOptions: {
|
|
parentCompiler: compiler
|
|
}
|
|
})
|
|
compiler.childCompilers.push(child.$compiler)
|
|
} else {
|
|
// simply call the function
|
|
Ctor(node)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Compile a normal node
|
|
*/
|
|
CompilerProto.compileNode = function (node) {
|
|
var i, j, attrs = node.attributes
|
|
// parse if has attributes
|
|
if (attrs && attrs.length) {
|
|
var attr, valid, exps, exp
|
|
// loop through all attributes
|
|
i = attrs.length
|
|
while (i--) {
|
|
attr = attrs[i]
|
|
valid = false
|
|
exps = Directive.split(attr.value)
|
|
// loop through clauses (separated by ",")
|
|
// inside each attribute
|
|
j = exps.length
|
|
while (j--) {
|
|
exp = exps[j]
|
|
var directive = Directive.parse(attr.name, exp, this, node)
|
|
if (directive) {
|
|
valid = true
|
|
this.bindDirective(directive)
|
|
}
|
|
}
|
|
if (valid) node.removeAttribute(attr.name)
|
|
}
|
|
}
|
|
// recursively compile childNodes
|
|
if (node.childNodes.length) {
|
|
var nodes = slice.call(node.childNodes)
|
|
for (i = 0, j = nodes.length; i < j; i++) {
|
|
this.compile(nodes[i])
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Compile a text node
|
|
*/
|
|
CompilerProto.compileTextNode = function (node) {
|
|
var tokens = TextParser.parse(node.nodeValue)
|
|
if (!tokens) return
|
|
var dirname = config.attrs.text,
|
|
el, token, directive
|
|
for (var i = 0, l = tokens.length; i < l; i++) {
|
|
token = tokens[i]
|
|
if (token.key) { // a binding
|
|
if (token.key.charAt(0) === '>') { // a partial
|
|
var partialId = token.key.slice(1).trim(),
|
|
partial = this.getOption('partials', partialId)
|
|
if (partial) {
|
|
el = partial.cloneNode(true)
|
|
this.compileNode(el)
|
|
}
|
|
} else { // a binding
|
|
el = document.createTextNode('')
|
|
directive = Directive.parse(dirname, token.key, this, el)
|
|
if (directive) {
|
|
this.bindDirective(directive)
|
|
}
|
|
}
|
|
} else { // a plain string
|
|
el = document.createTextNode(token)
|
|
}
|
|
node.parentNode.insertBefore(el, node)
|
|
}
|
|
node.parentNode.removeChild(node)
|
|
}
|
|
|
|
/**
|
|
* Add a directive instance to the correct binding & viewmodel
|
|
*/
|
|
CompilerProto.bindDirective = function (directive) {
|
|
|
|
// keep track of it so we can unbind() later
|
|
this.dirs.push(directive)
|
|
|
|
// for a simple directive, simply call its bind() or _update()
|
|
// and we're done.
|
|
if (directive.isSimple) {
|
|
if (directive.bind) directive.bind()
|
|
return
|
|
}
|
|
|
|
// otherwise, we got more work to do...
|
|
var binding,
|
|
compiler = this,
|
|
key = directive.key,
|
|
baseKey = key.split('.')[0],
|
|
ownerCompiler = traceOwnerCompiler(directive, compiler)
|
|
|
|
if (directive.isExp) {
|
|
// expression bindings are always created on current compiler
|
|
binding = compiler.createBinding(key, true, directive.isFn)
|
|
} else if (ownerCompiler.vm.hasOwnProperty(baseKey)) {
|
|
// If the directive's owner compiler's VM has the key,
|
|
// it belongs there. Create the binding if it's not already
|
|
// created, and return it.
|
|
binding = hasOwn.call(ownerCompiler.bindings, key)
|
|
? ownerCompiler.bindings[key]
|
|
: ownerCompiler.createBinding(key)
|
|
} else {
|
|
// due to prototypal inheritance of bindings, if a key doesn't exist
|
|
// on the owner compiler's VM, then it doesn't exist in the whole
|
|
// prototype chain. In this case we create the new binding at the root level.
|
|
binding = ownerCompiler.bindings[key] || compiler.rootCompiler.createBinding(key)
|
|
}
|
|
|
|
binding.instances.push(directive)
|
|
directive.binding = binding
|
|
|
|
var value = binding.value
|
|
// invoke bind hook if exists
|
|
if (directive.bind) {
|
|
directive.bind(value)
|
|
}
|
|
|
|
// set initial value
|
|
if (value !== undefined) {
|
|
if (binding.isComputed) {
|
|
directive.refresh(value)
|
|
} else {
|
|
directive.update(value, true)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create binding and attach getter/setter for a key to the viewmodel object
|
|
*/
|
|
CompilerProto.createBinding = function (key, isExp, isFn) {
|
|
|
|
var compiler = this,
|
|
bindings = compiler.bindings,
|
|
binding = new Binding(compiler, key, isExp, isFn)
|
|
|
|
if (isExp) {
|
|
// a complex expression binding
|
|
// we need to generate an anonymous computed property for it
|
|
var getter = ExpParser.parse(key, compiler)
|
|
if (getter) {
|
|
log(' created expression binding: ' + key)
|
|
binding.value = isFn
|
|
? getter
|
|
: { $get: getter }
|
|
compiler.markComputed(binding)
|
|
compiler.exps.push(binding)
|
|
}
|
|
} else {
|
|
log(' created binding: ' + key)
|
|
bindings[key] = binding
|
|
// make sure the key exists in the object so it can be observed
|
|
// by the Observer!
|
|
Observer.ensurePath(compiler.vm, key)
|
|
if (binding.root) {
|
|
// this is a root level binding. we need to define getter/setters for it.
|
|
compiler.define(key, binding)
|
|
} else {
|
|
var parentKey = key.slice(0, key.lastIndexOf('.'))
|
|
if (!hasOwn.call(bindings, parentKey)) {
|
|
// this is a nested value binding, but the binding for its parent
|
|
// has not been created yet. We better create that one too.
|
|
compiler.createBinding(parentKey)
|
|
}
|
|
}
|
|
}
|
|
return binding
|
|
}
|
|
|
|
/**
|
|
* Defines the getter/setter for a root-level binding on the VM
|
|
* and observe the initial value
|
|
*/
|
|
CompilerProto.define = function (key, binding) {
|
|
|
|
log(' defined root binding: ' + key)
|
|
|
|
var compiler = this,
|
|
vm = compiler.vm,
|
|
ob = compiler.observer,
|
|
value = binding.value = vm[key], // save the value before redefinening it
|
|
type = utils.typeOf(value)
|
|
|
|
if (type === 'Object' && value.$get) {
|
|
// computed property
|
|
compiler.markComputed(binding)
|
|
} else if (type === 'Object' || type === 'Array') {
|
|
// observe objects later, becase there might be more keys
|
|
// to be added to it. we also want to emit all the set events
|
|
// after all values are available.
|
|
compiler.observables.push(binding)
|
|
}
|
|
|
|
Object.defineProperty(vm, key, {
|
|
enumerable: true,
|
|
get: function () {
|
|
var value = binding.value
|
|
if (depsOb.active && (!binding.isComputed && (!value || !value.__observer__)) ||
|
|
Array.isArray(value)) {
|
|
// only emit non-computed, non-observed (primitive) values, or Arrays.
|
|
// because these are the cleanest dependencies
|
|
ob.emit('get', key)
|
|
}
|
|
return binding.isComputed
|
|
? value.$get()
|
|
: value
|
|
},
|
|
set: function (newVal) {
|
|
var value = binding.value
|
|
if (binding.isComputed) {
|
|
if (value.$set) {
|
|
value.$set(newVal)
|
|
}
|
|
} else if (newVal !== value) {
|
|
// unwatch the old value
|
|
Observer.unobserve(value, key, ob)
|
|
// set new value
|
|
binding.value = newVal
|
|
ob.emit('set', key, newVal)
|
|
Observer.ensurePaths(key, newVal, compiler.bindings)
|
|
// now watch the new value, which in turn emits 'set'
|
|
// for all its nested values
|
|
Observer.observe(newVal, key, ob)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Process a computed property binding
|
|
*/
|
|
CompilerProto.markComputed = function (binding) {
|
|
var value = binding.value,
|
|
vm = this.vm
|
|
binding.isComputed = true
|
|
// bind the accessors to the vm
|
|
if (binding.isFn) {
|
|
binding.value = utils.bind(value, vm)
|
|
} else {
|
|
value.$get = utils.bind(value.$get, vm)
|
|
if (value.$set) {
|
|
value.$set = utils.bind(value.$set, vm)
|
|
}
|
|
}
|
|
// keep track for dep parsing later
|
|
this.computed.push(binding)
|
|
}
|
|
|
|
/**
|
|
* Retrive an option from the compiler
|
|
*/
|
|
CompilerProto.getOption = function (type, id) {
|
|
var opts = this.options
|
|
return (opts[type] && opts[type][id]) || (utils[type] && utils[type][id])
|
|
}
|
|
|
|
/**
|
|
* Unbind and remove element
|
|
*/
|
|
CompilerProto.destroy = function () {
|
|
|
|
var compiler = this,
|
|
i, key, dir, instances, binding,
|
|
el = compiler.el,
|
|
directives = compiler.dirs,
|
|
exps = compiler.exps,
|
|
bindings = compiler.bindings,
|
|
teardown = compiler.options.teardown
|
|
|
|
// call user teardown first
|
|
if (teardown) teardown()
|
|
|
|
// unwatch
|
|
compiler.observer.off()
|
|
compiler.emitter.off()
|
|
|
|
// unbind all direcitves
|
|
i = directives.length
|
|
while (i--) {
|
|
dir = directives[i]
|
|
// if this directive is an instance of an external binding
|
|
// e.g. a directive that refers to a variable on the parent VM
|
|
// we need to remove it from that binding's instances
|
|
if (!dir.isSimple && dir.binding.compiler !== compiler) {
|
|
instances = dir.binding.instances
|
|
if (instances) instances.splice(instances.indexOf(dir), 1)
|
|
}
|
|
dir.unbind()
|
|
}
|
|
|
|
// unbind all expressions (anonymous bindings)
|
|
i = exps.length
|
|
while (i--) {
|
|
exps[i].unbind()
|
|
}
|
|
|
|
// unbind/unobserve all own bindings
|
|
for (key in bindings) {
|
|
if (hasOwn.call(bindings, key)) {
|
|
binding = bindings[key]
|
|
if (binding.root) {
|
|
Observer.unobserve(binding.value, binding.key, compiler.observer)
|
|
}
|
|
binding.unbind()
|
|
}
|
|
}
|
|
|
|
// remove self from parentCompiler
|
|
var parent = compiler.parentCompiler,
|
|
childId = compiler.childId
|
|
if (parent) {
|
|
parent.childCompilers.splice(parent.childCompilers.indexOf(compiler), 1)
|
|
if (childId) {
|
|
delete parent.vm.$[childId]
|
|
}
|
|
}
|
|
|
|
// finally remove dom element
|
|
if (el === document.body) {
|
|
el.innerHTML = ''
|
|
} else if (el.parentNode) {
|
|
transition(el, -1, function () {
|
|
el.parentNode.removeChild(el)
|
|
}, this)
|
|
}
|
|
}
|
|
|
|
// Helpers --------------------------------------------------------------------
|
|
|
|
/**
|
|
* determine which viewmodel a key belongs to based on nesting symbols
|
|
*/
|
|
function traceOwnerCompiler (key, compiler) {
|
|
if (key.nesting) {
|
|
var levels = key.nesting
|
|
while (compiler.parentCompiler && levels--) {
|
|
compiler = compiler.parentCompiler
|
|
}
|
|
} else if (key.root) {
|
|
while (compiler.parentCompiler) {
|
|
compiler = compiler.parentCompiler
|
|
}
|
|
}
|
|
return compiler
|
|
}
|
|
|
|
/**
|
|
* shorthand for getting root compiler
|
|
*/
|
|
function getRoot (compiler) {
|
|
return traceOwnerCompiler({ root: true }, compiler)
|
|
}
|
|
|
|
module.exports = Compiler
|
|
});
|
|
require.register("vue/src/viewmodel.js", function(exports, require, module){
|
|
var Compiler = require('./compiler'),
|
|
def = require('./utils').defProtected
|
|
|
|
/**
|
|
* ViewModel exposed to the user that holds data,
|
|
* computed properties, event handlers
|
|
* and a few reserved methods
|
|
*/
|
|
function ViewModel (options) {
|
|
// just compile. options are passed directly to compiler
|
|
new Compiler(this, options)
|
|
}
|
|
|
|
// All VM prototype methods are inenumerable
|
|
// so it can be stringified/looped through as raw data
|
|
var VMProto = ViewModel.prototype
|
|
|
|
/**
|
|
* Convenience function to set an actual nested value
|
|
* from a flat key string. Used in directives.
|
|
*/
|
|
def(VMProto, '$set', function (key, value) {
|
|
var path = key.split('.'),
|
|
obj = getTargetVM(this, path)
|
|
if (!obj) return
|
|
for (var d = 0, l = path.length - 1; d < l; d++) {
|
|
obj = obj[path[d]]
|
|
}
|
|
obj[path[d]] = value
|
|
})
|
|
|
|
/**
|
|
* watch a key on the viewmodel for changes
|
|
* fire callback with new value
|
|
*/
|
|
def(VMProto, '$watch', function (key, callback) {
|
|
this.$compiler.observer.on('change:' + key, callback)
|
|
})
|
|
|
|
/**
|
|
* unwatch a key
|
|
*/
|
|
def(VMProto, '$unwatch', function (key, callback) {
|
|
// workaround here
|
|
// since the emitter module checks callback existence
|
|
// by checking the length of arguments
|
|
var args = ['change:' + key],
|
|
ob = this.$compiler.observer
|
|
if (callback) args.push(callback)
|
|
ob.off.apply(ob, args)
|
|
})
|
|
|
|
/**
|
|
* unbind everything, remove everything
|
|
*/
|
|
def(VMProto, '$destroy', function () {
|
|
this.$compiler.destroy()
|
|
})
|
|
|
|
/**
|
|
* broadcast an event to all child VMs recursively.
|
|
*/
|
|
def(VMProto, '$broadcast', function () {
|
|
var children = this.$compiler.childCompilers,
|
|
i = children.length,
|
|
child
|
|
while (i--) {
|
|
child = children[i]
|
|
child.emitter.emit.apply(child.emitter, arguments)
|
|
child.vm.$broadcast.apply(child.vm, arguments)
|
|
}
|
|
})
|
|
|
|
/**
|
|
* emit an event that propagates all the way up to parent VMs.
|
|
*/
|
|
def(VMProto, '$emit', function () {
|
|
var compiler = this.$compiler,
|
|
emitter = compiler.emitter,
|
|
parent = compiler.parentCompiler
|
|
emitter.emit.apply(emitter, arguments)
|
|
if (parent) {
|
|
parent.emitter.emit.apply(parent.emitter, arguments)
|
|
parent.vm.$emit.apply(parent.vm, arguments)
|
|
}
|
|
})
|
|
|
|
/**
|
|
* delegate on/off/once to the compiler's emitter
|
|
*/
|
|
;['on', 'off', 'once'].forEach(function (method) {
|
|
def(VMProto, '$' + method, function () {
|
|
var emitter = this.$compiler.emitter
|
|
emitter[method].apply(emitter, arguments)
|
|
})
|
|
})
|
|
|
|
/**
|
|
* If a VM doesn't contain a path, go up the prototype chain
|
|
* to locate the ancestor that has it.
|
|
*/
|
|
function getTargetVM (vm, path) {
|
|
var baseKey = path[0],
|
|
binding = vm.$compiler.bindings[baseKey]
|
|
return binding
|
|
? binding.compiler.vm
|
|
: null
|
|
}
|
|
|
|
module.exports = ViewModel
|
|
});
|
|
require.register("vue/src/binding.js", function(exports, require, module){
|
|
/**
|
|
* Binding class.
|
|
*
|
|
* each property on the viewmodel has one corresponding Binding object
|
|
* which has multiple directive instances on the DOM
|
|
* and multiple computed property dependents
|
|
*/
|
|
function Binding (compiler, key, isExp, isFn) {
|
|
this.value = undefined
|
|
this.isExp = !!isExp
|
|
this.isFn = isFn
|
|
this.root = !this.isExp && key.indexOf('.') === -1
|
|
this.compiler = compiler
|
|
this.key = key
|
|
this.instances = []
|
|
this.subs = []
|
|
this.deps = []
|
|
}
|
|
|
|
var BindingProto = Binding.prototype
|
|
|
|
/**
|
|
* Process the value, then trigger updates on all dependents
|
|
*/
|
|
BindingProto.update = function (value) {
|
|
this.value = value
|
|
var i = this.instances.length
|
|
while (i--) {
|
|
this.instances[i].update(value)
|
|
}
|
|
this.pub()
|
|
}
|
|
|
|
/**
|
|
* -- computed property only --
|
|
* Force all instances to re-evaluate themselves
|
|
*/
|
|
BindingProto.refresh = function () {
|
|
var i = this.instances.length
|
|
while (i--) {
|
|
this.instances[i].refresh()
|
|
}
|
|
this.pub()
|
|
}
|
|
|
|
/**
|
|
* Notify computed properties that depend on this binding
|
|
* to update themselves
|
|
*/
|
|
BindingProto.pub = function () {
|
|
var i = this.subs.length
|
|
while (i--) {
|
|
this.subs[i].refresh()
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Unbind the binding, remove itself from all of its dependencies
|
|
*/
|
|
BindingProto.unbind = function () {
|
|
var i = this.instances.length
|
|
while (i--) {
|
|
this.instances[i].unbind()
|
|
}
|
|
i = this.deps.length
|
|
var subs
|
|
while (i--) {
|
|
subs = this.deps[i].subs
|
|
subs.splice(subs.indexOf(this), 1)
|
|
}
|
|
}
|
|
|
|
module.exports = Binding
|
|
});
|
|
require.register("vue/src/observer.js", function(exports, require, module){
|
|
/* jshint proto:true */
|
|
|
|
var Emitter = require('./emitter'),
|
|
utils = require('./utils'),
|
|
depsOb = require('./deps-parser').observer,
|
|
|
|
// cache methods
|
|
typeOf = utils.typeOf,
|
|
def = utils.defProtected,
|
|
slice = Array.prototype.slice,
|
|
|
|
// Array mutation methods to wrap
|
|
methods = ['push','pop','shift','unshift','splice','sort','reverse'],
|
|
|
|
// fix for IE + __proto__ problem
|
|
// define methods as inenumerable if __proto__ is present,
|
|
// otherwise enumerable so we can loop through and manually
|
|
// attach to array instances
|
|
hasProto = ({}).__proto__
|
|
|
|
// The proxy prototype to replace the __proto__ of
|
|
// an observed array
|
|
var ArrayProxy = Object.create(Array.prototype)
|
|
|
|
// Define mutation interceptors so we can emit the mutation info
|
|
methods.forEach(function (method) {
|
|
def(ArrayProxy, method, function () {
|
|
var result = Array.prototype[method].apply(this, arguments)
|
|
this.__observer__.emit('mutate', this.__observer__.path, this, {
|
|
method: method,
|
|
args: slice.call(arguments),
|
|
result: result
|
|
})
|
|
return result
|
|
}, !hasProto)
|
|
})
|
|
|
|
// Augment it with several convenience methods
|
|
var extensions = {
|
|
remove: function (index) {
|
|
if (typeof index === 'function') {
|
|
var i = this.length,
|
|
removed = []
|
|
while (i--) {
|
|
if (index(this[i])) {
|
|
removed.push(this.splice(i, 1)[0])
|
|
}
|
|
}
|
|
return removed.reverse()
|
|
} else {
|
|
if (typeof index !== 'number') {
|
|
index = this.indexOf(index)
|
|
}
|
|
if (index > -1) {
|
|
return this.splice(index, 1)[0]
|
|
}
|
|
}
|
|
},
|
|
replace: function (index, data) {
|
|
if (typeof index === 'function') {
|
|
var i = this.length,
|
|
replaced = [],
|
|
replacer
|
|
while (i--) {
|
|
replacer = index(this[i])
|
|
if (replacer !== undefined) {
|
|
replaced.push(this.splice(i, 1, replacer)[0])
|
|
}
|
|
}
|
|
return replaced.reverse()
|
|
} else {
|
|
if (typeof index !== 'number') {
|
|
index = this.indexOf(index)
|
|
}
|
|
if (index > -1) {
|
|
return this.splice(index, 1, data)[0]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (var method in extensions) {
|
|
def(ArrayProxy, method, extensions[method], !hasProto)
|
|
}
|
|
|
|
/**
|
|
* Watch an object based on type
|
|
*/
|
|
function watch (obj, path, observer) {
|
|
var type = typeOf(obj)
|
|
if (type === 'Object') {
|
|
watchObject(obj, path, observer)
|
|
} else if (type === 'Array') {
|
|
watchArray(obj, path, observer)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Watch an Object, recursive.
|
|
*/
|
|
function watchObject (obj, path, observer) {
|
|
for (var key in obj) {
|
|
var keyPrefix = key.charAt(0)
|
|
if (keyPrefix !== '$' && keyPrefix !== '_') {
|
|
bind(obj, key, path, observer)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Watch an Array, overload mutation methods
|
|
* and add augmentations by intercepting the prototype chain
|
|
*/
|
|
function watchArray (arr, path, observer) {
|
|
def(arr, '__observer__', observer)
|
|
observer.path = path
|
|
if (hasProto) {
|
|
arr.__proto__ = ArrayProxy
|
|
} else {
|
|
for (var key in ArrayProxy) {
|
|
def(arr, key, ArrayProxy[key])
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Define accessors for a property on an Object
|
|
* so it emits get/set events.
|
|
* Then watch the value itself.
|
|
*/
|
|
function bind (obj, key, path, observer) {
|
|
var val = obj[key],
|
|
watchable = isWatchable(val),
|
|
values = observer.values,
|
|
fullKey = (path ? path + '.' : '') + key
|
|
values[fullKey] = val
|
|
// emit set on bind
|
|
// this means when an object is observed it will emit
|
|
// a first batch of set events.
|
|
observer.emit('set', fullKey, val)
|
|
Object.defineProperty(obj, key, {
|
|
enumerable: true,
|
|
get: function () {
|
|
// only emit get on tip values
|
|
if (depsOb.active && !watchable) {
|
|
observer.emit('get', fullKey)
|
|
}
|
|
return values[fullKey]
|
|
},
|
|
set: function (newVal) {
|
|
values[fullKey] = newVal
|
|
ensurePaths(key, newVal, values)
|
|
observer.emit('set', fullKey, newVal)
|
|
watch(newVal, fullKey, observer)
|
|
}
|
|
})
|
|
watch(val, fullKey, observer)
|
|
}
|
|
|
|
/**
|
|
* Check if a value is watchable
|
|
*/
|
|
function isWatchable (obj) {
|
|
var type = typeOf(obj)
|
|
return type === 'Object' || type === 'Array'
|
|
}
|
|
|
|
/**
|
|
* When a value that is already converted is
|
|
* observed again by another observer, we can skip
|
|
* the watch conversion and simply emit set event for
|
|
* all of its properties.
|
|
*/
|
|
function emitSet (obj, observer, set) {
|
|
if (typeOf(obj) === 'Array') {
|
|
set('length', obj.length)
|
|
} else {
|
|
var key, val, values = observer.values
|
|
for (key in observer.values) {
|
|
val = values[key]
|
|
set(key, val)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sometimes when a binding is found in the template, the value might
|
|
* have not been set on the VM yet. To ensure computed properties and
|
|
* dependency extraction can work, we have to create a dummy value for
|
|
* any given path.
|
|
*/
|
|
function ensurePaths (key, val, paths) {
|
|
key += '.'
|
|
for (var path in paths) {
|
|
if (!path.indexOf(key)) {
|
|
ensurePath(val, path.replace(key, ''))
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* walk along a path and make sure it can be accessed
|
|
* and enumerated in that object
|
|
*/
|
|
function ensurePath (obj, key) {
|
|
if (typeOf(obj) !== 'Object') return
|
|
var path = key.split('.'), sec
|
|
for (var i = 0, d = path.length - 1; i < d; i++) {
|
|
sec = path[i]
|
|
if (!obj[sec]) obj[sec] = {}
|
|
obj = obj[sec]
|
|
}
|
|
if (typeOf(obj) === 'Object') {
|
|
sec = path[i]
|
|
if (!(sec in obj)) obj[sec] = undefined
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
|
|
// used in v-repeat
|
|
watchArray: watchArray,
|
|
ensurePath: ensurePath,
|
|
ensurePaths: ensurePaths,
|
|
|
|
/**
|
|
* Observe an object with a given path,
|
|
* and proxy get/set/mutate events to the provided observer.
|
|
*/
|
|
observe: function (obj, rawPath, observer) {
|
|
if (isWatchable(obj)) {
|
|
var path = rawPath + '.',
|
|
ob, alreadyConverted = !!obj.__observer__
|
|
if (!alreadyConverted) {
|
|
def(obj, '__observer__', new Emitter())
|
|
}
|
|
ob = obj.__observer__
|
|
ob.values = ob.values || utils.hash()
|
|
var proxies = observer.proxies[path] = {
|
|
get: function (key) {
|
|
observer.emit('get', path + key)
|
|
},
|
|
set: function (key, val) {
|
|
observer.emit('set', path + key, val)
|
|
},
|
|
mutate: function (key, val, mutation) {
|
|
// if the Array is a root value
|
|
// the key will be null
|
|
var fixedPath = key ? path + key : rawPath
|
|
observer.emit('mutate', fixedPath, val, mutation)
|
|
// also emit set for Array's length when it mutates
|
|
var m = mutation.method
|
|
if (m !== 'sort' && m !== 'reverse') {
|
|
observer.emit('set', fixedPath + '.length', val.length)
|
|
}
|
|
}
|
|
}
|
|
ob
|
|
.on('get', proxies.get)
|
|
.on('set', proxies.set)
|
|
.on('mutate', proxies.mutate)
|
|
if (alreadyConverted) {
|
|
emitSet(obj, ob, proxies.set)
|
|
} else {
|
|
watch(obj, null, ob)
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Cancel observation, turn off the listeners.
|
|
*/
|
|
unobserve: function (obj, path, observer) {
|
|
if (!obj || !obj.__observer__) return
|
|
path = path + '.'
|
|
var proxies = observer.proxies[path]
|
|
obj.__observer__
|
|
.off('get', proxies.get)
|
|
.off('set', proxies.set)
|
|
.off('mutate', proxies.mutate)
|
|
observer.proxies[path] = null
|
|
}
|
|
}
|
|
});
|
|
require.register("vue/src/directive.js", function(exports, require, module){
|
|
var config = require('./config'),
|
|
utils = require('./utils'),
|
|
directives = require('./directives'),
|
|
filters = require('./filters'),
|
|
|
|
// Regexes!
|
|
|
|
// regex to split multiple directive expressions
|
|
// split by commas, but ignore commas within quotes, parens and escapes.
|
|
SPLIT_RE = /(?:['"](?:\\.|[^'"])*['"]|\((?:\\.|[^\)])*\)|\\.|[^,])+/g,
|
|
|
|
// match up to the first single pipe, ignore those within quotes.
|
|
KEY_RE = /^(?:['"](?:\\.|[^'"])*['"]|\\.|[^\|]|\|\|)+/,
|
|
|
|
ARG_RE = /^([\w- ]+):(.+)$/,
|
|
FILTERS_RE = /\|[^\|]+/g,
|
|
FILTER_TOKEN_RE = /[^\s']+|'[^']+'/g,
|
|
NESTING_RE = /^\^+/,
|
|
SINGLE_VAR_RE = /^[\w\.\$]+$/
|
|
|
|
/**
|
|
* Directive class
|
|
* represents a single directive instance in the DOM
|
|
*/
|
|
function Directive (definition, expression, rawKey, compiler, node) {
|
|
|
|
this.compiler = compiler
|
|
this.vm = compiler.vm
|
|
this.el = node
|
|
|
|
var isSimple = expression === ''
|
|
|
|
// mix in properties from the directive definition
|
|
if (typeof definition === 'function') {
|
|
this[isSimple ? 'bind' : '_update'] = definition
|
|
} else {
|
|
for (var prop in definition) {
|
|
if (prop === 'unbind' || prop === 'update') {
|
|
this['_' + prop] = definition[prop]
|
|
} else {
|
|
this[prop] = definition[prop]
|
|
}
|
|
}
|
|
}
|
|
|
|
// empty expression, we're done.
|
|
if (isSimple) {
|
|
this.isSimple = true
|
|
return
|
|
}
|
|
|
|
this.expression = expression.trim()
|
|
this.rawKey = rawKey
|
|
|
|
parseKey(this, rawKey)
|
|
|
|
this.isExp = !SINGLE_VAR_RE.test(this.key)
|
|
|
|
var filterExps = this.expression.slice(rawKey.length).match(FILTERS_RE)
|
|
if (filterExps) {
|
|
this.filters = []
|
|
var i = 0, l = filterExps.length, filter
|
|
for (; i < l; i++) {
|
|
filter = parseFilter(filterExps[i], this.compiler)
|
|
if (filter) this.filters.push(filter)
|
|
}
|
|
if (!this.filters.length) this.filters = null
|
|
} else {
|
|
this.filters = null
|
|
}
|
|
}
|
|
|
|
var DirProto = Directive.prototype
|
|
|
|
/**
|
|
* parse a key, extract argument and nesting/root info
|
|
*/
|
|
function parseKey (dir, rawKey) {
|
|
|
|
var key = rawKey
|
|
if (rawKey.indexOf(':') > -1) {
|
|
var argMatch = rawKey.match(ARG_RE)
|
|
key = argMatch
|
|
? argMatch[2].trim()
|
|
: key
|
|
dir.arg = argMatch
|
|
? argMatch[1].trim()
|
|
: null
|
|
}
|
|
|
|
// nesting
|
|
var firstChar = key.charAt(0)
|
|
dir.root = firstChar === '*'
|
|
dir.nesting = firstChar === '^'
|
|
? key.match(NESTING_RE)[0].length
|
|
: false
|
|
|
|
if (dir.nesting) {
|
|
key = key.slice(dir.nesting)
|
|
} else if (dir.root) {
|
|
key = key.slice(1)
|
|
}
|
|
|
|
dir.key = key
|
|
}
|
|
|
|
/**
|
|
* parse a filter expression
|
|
*/
|
|
function parseFilter (filter, compiler) {
|
|
|
|
var tokens = filter.slice(1).match(FILTER_TOKEN_RE)
|
|
if (!tokens) return
|
|
tokens = tokens.map(function (token) {
|
|
return token.replace(/'/g, '').trim()
|
|
})
|
|
|
|
var name = tokens[0],
|
|
apply = compiler.getOption('filters', name) || filters[name]
|
|
if (!apply) {
|
|
utils.warn('Unknown filter: ' + name)
|
|
return
|
|
}
|
|
|
|
return {
|
|
name : name,
|
|
apply : apply,
|
|
args : tokens.length > 1
|
|
? tokens.slice(1)
|
|
: null
|
|
}
|
|
}
|
|
|
|
/**
|
|
* called when a new value is set
|
|
* for computed properties, this will only be called once
|
|
* during initialization.
|
|
*/
|
|
DirProto.update = function (value, init) {
|
|
if (!init && value === this.value) return
|
|
this.value = value
|
|
this.apply(value)
|
|
}
|
|
|
|
/**
|
|
* -- computed property only --
|
|
* called when a dependency has changed
|
|
*/
|
|
DirProto.refresh = function (value) {
|
|
// pass element and viewmodel info to the getter
|
|
// enables context-aware bindings
|
|
if (value) this.value = value
|
|
|
|
if (this.isFn) {
|
|
value = this.value
|
|
} else {
|
|
value = this.value.$get()
|
|
if (value !== undefined && value === this.computedValue) return
|
|
this.computedValue = value
|
|
}
|
|
this.apply(value)
|
|
}
|
|
|
|
/**
|
|
* Actually invoking the _update from the directive's definition
|
|
*/
|
|
DirProto.apply = function (value) {
|
|
this._update(
|
|
this.filters
|
|
? this.applyFilters(value)
|
|
: value
|
|
)
|
|
}
|
|
|
|
/**
|
|
* pipe the value through filters
|
|
*/
|
|
DirProto.applyFilters = function (value) {
|
|
var filtered = value, filter
|
|
for (var i = 0, l = this.filters.length; i < l; i++) {
|
|
filter = this.filters[i]
|
|
filtered = filter.apply.call(this.vm, filtered, filter.args)
|
|
}
|
|
return filtered
|
|
}
|
|
|
|
/**
|
|
* Unbind diretive
|
|
* @ param {Boolean} update
|
|
* Sometimes we call unbind before an update (i.e. not destroy)
|
|
* just to teardown previous stuff, in that case we do not want
|
|
* to null everything.
|
|
*/
|
|
DirProto.unbind = function (update) {
|
|
// this can be called before the el is even assigned...
|
|
if (!this.el) return
|
|
if (this._unbind) this._unbind(update)
|
|
if (!update) this.vm = this.el = this.binding = this.compiler = null
|
|
}
|
|
|
|
// exposed methods ------------------------------------------------------------
|
|
|
|
/**
|
|
* split a unquoted-comma separated expression into
|
|
* multiple clauses
|
|
*/
|
|
Directive.split = function (exp) {
|
|
return exp.indexOf(',') > -1
|
|
? exp.match(SPLIT_RE) || ['']
|
|
: [exp]
|
|
}
|
|
|
|
/**
|
|
* make sure the directive and expression is valid
|
|
* before we create an instance
|
|
*/
|
|
Directive.parse = function (dirname, expression, compiler, node) {
|
|
|
|
var prefix = config.prefix + '-'
|
|
if (dirname.indexOf(prefix) !== 0) return
|
|
dirname = dirname.slice(prefix.length)
|
|
|
|
var dir = compiler.getOption('directives', dirname) || directives[dirname]
|
|
if (!dir) return utils.warn('unknown directive: ' + dirname)
|
|
|
|
var rawKey
|
|
if (expression.indexOf('|') > -1) {
|
|
var keyMatch = expression.match(KEY_RE)
|
|
if (keyMatch) {
|
|
rawKey = keyMatch[0].trim()
|
|
}
|
|
} else {
|
|
rawKey = expression.trim()
|
|
}
|
|
|
|
// have a valid raw key, or be an empty directive
|
|
return (rawKey || expression === '')
|
|
? new Directive(dir, expression, rawKey, compiler, node)
|
|
: utils.warn('invalid directive expression: ' + expression)
|
|
}
|
|
|
|
module.exports = Directive
|
|
});
|
|
require.register("vue/src/exp-parser.js", function(exports, require, module){
|
|
var utils = require('./utils'),
|
|
hasOwn = Object.prototype.hasOwnProperty
|
|
|
|
// Variable extraction scooped from https://github.com/RubyLouvre/avalon
|
|
|
|
var KEYWORDS =
|
|
// keywords
|
|
'break,case,catch,continue,debugger,default,delete,do,else,false' +
|
|
',finally,for,function,if,in,instanceof,new,null,return,switch,this' +
|
|
',throw,true,try,typeof,var,void,while,with,undefined' +
|
|
// reserved
|
|
',abstract,boolean,byte,char,class,const,double,enum,export,extends' +
|
|
',final,float,goto,implements,import,int,interface,long,native' +
|
|
',package,private,protected,public,short,static,super,synchronized' +
|
|
',throws,transient,volatile' +
|
|
// ECMA 5 - use strict
|
|
',arguments,let,yield' +
|
|
// allow using Math in expressions
|
|
',Math',
|
|
|
|
KEYWORDS_RE = new RegExp(["\\b" + KEYWORDS.replace(/,/g, '\\b|\\b') + "\\b"].join('|'), 'g'),
|
|
REMOVE_RE = /\/\*(?:.|\n)*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|'[^']*'|"[^"]*"|[\s\t\n]*\.[\s\t\n]*[$\w\.]+/g,
|
|
SPLIT_RE = /[^\w$]+/g,
|
|
NUMBER_RE = /\b\d[^,]*/g,
|
|
BOUNDARY_RE = /^,+|,+$/g
|
|
|
|
/**
|
|
* Strip top level variable names from a snippet of JS expression
|
|
*/
|
|
function getVariables (code) {
|
|
code = code
|
|
.replace(REMOVE_RE, '')
|
|
.replace(SPLIT_RE, ',')
|
|
.replace(KEYWORDS_RE, '')
|
|
.replace(NUMBER_RE, '')
|
|
.replace(BOUNDARY_RE, '')
|
|
return code
|
|
? code.split(/,+/)
|
|
: []
|
|
}
|
|
|
|
/**
|
|
* A given path could potentially exist not on the
|
|
* current compiler, but up in the parent chain somewhere.
|
|
* This function generates an access relationship string
|
|
* that can be used in the getter function by walking up
|
|
* the parent chain to check for key existence.
|
|
*
|
|
* It stops at top parent if no vm in the chain has the
|
|
* key. It then creates any missing bindings on the
|
|
* final resolved vm.
|
|
*/
|
|
function getRel (path, compiler) {
|
|
var rel = '',
|
|
vm = compiler.vm,
|
|
dot = path.indexOf('.'),
|
|
key = dot > -1
|
|
? path.slice(0, dot)
|
|
: path
|
|
while (true) {
|
|
if (hasOwn.call(vm, key)) {
|
|
break
|
|
} else {
|
|
if (vm.$parent) {
|
|
vm = vm.$parent
|
|
rel += '$parent.'
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
compiler = vm.$compiler
|
|
if (
|
|
!hasOwn.call(compiler.bindings, path) &&
|
|
path.charAt(0) !== '$'
|
|
) {
|
|
compiler.createBinding(path)
|
|
}
|
|
return rel
|
|
}
|
|
|
|
/**
|
|
* Create a function from a string...
|
|
* this looks like evil magic but since all variables are limited
|
|
* to the VM's scope it's actually properly sandboxed
|
|
*/
|
|
function makeGetter (exp, raw) {
|
|
/* jshint evil: true */
|
|
var fn
|
|
try {
|
|
fn = new Function(exp)
|
|
} catch (e) {
|
|
utils.warn('Invalid expression: ' + raw)
|
|
}
|
|
return fn
|
|
}
|
|
|
|
/**
|
|
* Escape a leading dollar sign for regex construction
|
|
*/
|
|
function escapeDollar (v) {
|
|
return v.charAt(0) === '$'
|
|
? '\\' + v
|
|
: v
|
|
}
|
|
|
|
module.exports = {
|
|
|
|
/**
|
|
* Parse and return an anonymous computed property getter function
|
|
* from an arbitrary expression, together with a list of paths to be
|
|
* created as bindings.
|
|
*/
|
|
parse: function (exp, compiler) {
|
|
// extract variable names
|
|
var vars = getVariables(exp)
|
|
if (!vars.length) {
|
|
return makeGetter('return ' + exp, exp)
|
|
}
|
|
vars = utils.unique(vars)
|
|
var accessors = '',
|
|
// construct a regex to extract all valid variable paths
|
|
// ones that begin with "$" are particularly tricky
|
|
// because we can't use \b for them
|
|
pathRE = new RegExp(
|
|
"[^$\\w\\.](" +
|
|
vars.map(escapeDollar).join('|') +
|
|
")[$\\w\\.]*\\b", 'g'
|
|
),
|
|
body = ('return ' + exp).replace(pathRE, function (path) {
|
|
// keep track of the first char
|
|
var c = path.charAt(0)
|
|
path = path.slice(1)
|
|
var val = 'this.' + getRel(path, compiler) + path
|
|
accessors += val + ';'
|
|
// don't forget to put that first char back
|
|
return c + val
|
|
})
|
|
body = accessors + body
|
|
return makeGetter(body, exp)
|
|
}
|
|
}
|
|
});
|
|
require.register("vue/src/text-parser.js", function(exports, require, module){
|
|
var BINDING_RE = /\{\{(.+?)\}\}/
|
|
|
|
module.exports = {
|
|
|
|
/**
|
|
* Parse a piece of text, return an array of tokens
|
|
*/
|
|
parse: function (text) {
|
|
if (!BINDING_RE.test(text)) return null
|
|
var m, i, tokens = []
|
|
/* jshint boss: true */
|
|
while (m = text.match(BINDING_RE)) {
|
|
i = m.index
|
|
if (i > 0) tokens.push(text.slice(0, i))
|
|
tokens.push({ key: m[1].trim() })
|
|
text = text.slice(i + m[0].length)
|
|
}
|
|
if (text.length) tokens.push(text)
|
|
return tokens
|
|
}
|
|
|
|
}
|
|
});
|
|
require.register("vue/src/deps-parser.js", function(exports, require, module){
|
|
var Emitter = require('./emitter'),
|
|
utils = require('./utils'),
|
|
observer = new Emitter()
|
|
|
|
/**
|
|
* Auto-extract the dependencies of a computed property
|
|
* by recording the getters triggered when evaluating it.
|
|
*/
|
|
function catchDeps (binding) {
|
|
if (binding.isFn) return
|
|
utils.log('\n─ ' + binding.key)
|
|
var depsHash = utils.hash()
|
|
observer.on('get', function (dep) {
|
|
if (depsHash[dep.key]) return
|
|
depsHash[dep.key] = 1
|
|
utils.log(' └─ ' + dep.key)
|
|
binding.deps.push(dep)
|
|
dep.subs.push(binding)
|
|
})
|
|
binding.value.$get()
|
|
observer.off('get')
|
|
}
|
|
|
|
module.exports = {
|
|
|
|
/**
|
|
* the observer that catches events triggered by getters
|
|
*/
|
|
observer: observer,
|
|
|
|
/**
|
|
* parse a list of computed property bindings
|
|
*/
|
|
parse: function (bindings) {
|
|
utils.log('\nparsing dependencies...')
|
|
observer.active = true
|
|
bindings.forEach(catchDeps)
|
|
observer.active = false
|
|
utils.log('\ndone.')
|
|
}
|
|
|
|
}
|
|
});
|
|
require.register("vue/src/filters.js", function(exports, require, module){
|
|
var keyCodes = {
|
|
enter : 13,
|
|
tab : 9,
|
|
'delete' : 46,
|
|
up : 38,
|
|
left : 37,
|
|
right : 39,
|
|
down : 40,
|
|
esc : 27
|
|
}
|
|
|
|
module.exports = {
|
|
|
|
/**
|
|
* 'abc' => 'Abc'
|
|
*/
|
|
capitalize: function (value) {
|
|
if (!value && value !== 0) return ''
|
|
value = value.toString()
|
|
return value.charAt(0).toUpperCase() + value.slice(1)
|
|
},
|
|
|
|
/**
|
|
* 'abc' => 'ABC'
|
|
*/
|
|
uppercase: function (value) {
|
|
return (value || value === 0)
|
|
? value.toString().toUpperCase()
|
|
: ''
|
|
},
|
|
|
|
/**
|
|
* 'AbC' => 'abc'
|
|
*/
|
|
lowercase: function (value) {
|
|
return (value || value === 0)
|
|
? value.toString().toLowerCase()
|
|
: ''
|
|
},
|
|
|
|
/**
|
|
* 12345 => $12,345.00
|
|
*/
|
|
currency: function (value, args) {
|
|
if (!value && value !== 0) return ''
|
|
var sign = (args && args[0]) || '$',
|
|
s = Math.floor(value).toString(),
|
|
i = s.length % 3,
|
|
h = i > 0 ? (s.slice(0, i) + (s.length > 3 ? ',' : '')) : '',
|
|
f = '.' + value.toFixed(2).slice(-2)
|
|
return sign + h + s.slice(i).replace(/(\d{3})(?=\d)/g, '$1,') + f
|
|
},
|
|
|
|
/**
|
|
* args: an array of strings corresponding to
|
|
* the single, double, triple ... forms of the word to
|
|
* be pluralized. When the number to be pluralized
|
|
* exceeds the length of the args, it will use the last
|
|
* entry in the array.
|
|
*
|
|
* e.g. ['single', 'double', 'triple', 'multiple']
|
|
*/
|
|
pluralize: function (value, args) {
|
|
return args.length > 1
|
|
? (args[value - 1] || args[args.length - 1])
|
|
: (args[value - 1] || args[0] + 's')
|
|
},
|
|
|
|
/**
|
|
* A special filter that takes a handler function,
|
|
* wraps it so it only gets triggered on specific keypresses.
|
|
*/
|
|
key: function (handler, args) {
|
|
if (!handler) return
|
|
var code = keyCodes[args[0]]
|
|
if (!code) {
|
|
code = parseInt(args[0], 10)
|
|
}
|
|
return function (e) {
|
|
if (e.keyCode === code) {
|
|
handler.call(this, e)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
require.register("vue/src/transition.js", function(exports, require, module){
|
|
var endEvent = sniffTransitionEndEvent(),
|
|
config = require('./config'),
|
|
enterClass = config.enterClass,
|
|
leaveClass = config.leaveClass,
|
|
// exit codes for testing
|
|
codes = {
|
|
CSS_E : 1,
|
|
CSS_L : 2,
|
|
JS_E : 3,
|
|
JS_L : 4,
|
|
CSS_SKIP : -1,
|
|
JS_SKIP : -2,
|
|
JS_SKIP_E : -3,
|
|
JS_SKIP_L : -4,
|
|
INIT : -5,
|
|
SKIP : -6
|
|
}
|
|
|
|
/**
|
|
* stage:
|
|
* 1 = enter
|
|
* 2 = leave
|
|
*/
|
|
var transition = module.exports = function (el, stage, changeState, compiler) {
|
|
|
|
if (compiler.init) {
|
|
changeState()
|
|
return codes.INIT
|
|
}
|
|
|
|
var transitionId = el.vue_trans
|
|
|
|
if (transitionId) {
|
|
return applyTransitionFunctions(
|
|
el,
|
|
stage,
|
|
changeState,
|
|
transitionId,
|
|
compiler
|
|
)
|
|
} else if (transitionId === '') {
|
|
return applyTransitionClass(
|
|
el,
|
|
stage,
|
|
changeState
|
|
)
|
|
} else {
|
|
changeState()
|
|
return codes.SKIP
|
|
}
|
|
|
|
}
|
|
|
|
transition.codes = codes
|
|
|
|
/**
|
|
* Togggle a CSS class to trigger transition
|
|
*/
|
|
function applyTransitionClass (el, stage, changeState) {
|
|
|
|
if (!endEvent) {
|
|
changeState()
|
|
return codes.CSS_SKIP
|
|
}
|
|
|
|
var classList = el.classList,
|
|
lastLeaveCallback = el.vue_trans_cb
|
|
|
|
if (stage > 0) { // enter
|
|
|
|
// cancel unfinished leave transition
|
|
if (lastLeaveCallback) {
|
|
el.removeEventListener(endEvent, lastLeaveCallback)
|
|
el.vue_trans_cb = null
|
|
}
|
|
|
|
// set to hidden state before appending
|
|
classList.add(enterClass)
|
|
// append
|
|
changeState()
|
|
// force a layout so transition can be triggered
|
|
/* jshint unused: false */
|
|
var forceLayout = el.clientHeight
|
|
// trigger transition
|
|
classList.remove(enterClass)
|
|
return codes.CSS_E
|
|
|
|
} else { // leave
|
|
|
|
// trigger hide transition
|
|
classList.add(leaveClass)
|
|
var onEnd = function (e) {
|
|
if (e.target === el) {
|
|
el.removeEventListener(endEvent, onEnd)
|
|
el.vue_trans_cb = null
|
|
// actually remove node here
|
|
changeState()
|
|
classList.remove(leaveClass)
|
|
}
|
|
}
|
|
// attach transition end listener
|
|
el.addEventListener(endEvent, onEnd)
|
|
el.vue_trans_cb = onEnd
|
|
return codes.CSS_L
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function applyTransitionFunctions (el, stage, changeState, functionId, compiler) {
|
|
|
|
var funcs = compiler.getOption('transitions', functionId)
|
|
if (!funcs) {
|
|
changeState()
|
|
return codes.JS_SKIP
|
|
}
|
|
|
|
var enter = funcs.enter,
|
|
leave = funcs.leave
|
|
|
|
if (stage > 0) { // enter
|
|
if (typeof enter !== 'function') {
|
|
changeState()
|
|
return codes.JS_SKIP_E
|
|
}
|
|
enter(el, changeState)
|
|
return codes.JS_E
|
|
} else { // leave
|
|
if (typeof leave !== 'function') {
|
|
changeState()
|
|
return codes.JS_SKIP_L
|
|
}
|
|
leave(el, changeState)
|
|
return codes.JS_L
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Sniff proper transition end event name
|
|
*/
|
|
function sniffTransitionEndEvent () {
|
|
var el = document.createElement('vue'),
|
|
defaultEvent = 'transitionend',
|
|
events = {
|
|
'transition' : defaultEvent,
|
|
'MozTransition' : defaultEvent,
|
|
'WebkitTransition' : 'webkitTransitionEnd'
|
|
}
|
|
for (var name in events) {
|
|
if (el.style[name] !== undefined) {
|
|
return events[name]
|
|
}
|
|
}
|
|
}
|
|
});
|
|
require.register("vue/src/directives/index.js", function(exports, require, module){
|
|
var utils = require('../utils'),
|
|
transition = require('../transition')
|
|
|
|
module.exports = {
|
|
|
|
on : require('./on'),
|
|
repeat : require('./repeat'),
|
|
model : require('./model'),
|
|
'if' : require('./if'),
|
|
|
|
attr: function (value) {
|
|
this.el.setAttribute(this.arg, value)
|
|
},
|
|
|
|
text: function (value) {
|
|
this.el.textContent = utils.toText(value)
|
|
},
|
|
|
|
html: function (value) {
|
|
this.el.innerHTML = utils.toText(value)
|
|
},
|
|
|
|
visible: function (value) {
|
|
this.el.style.visibility = value ? '' : 'hidden'
|
|
},
|
|
|
|
show: function (value) {
|
|
var el = this.el,
|
|
target = value ? '' : 'none',
|
|
change = function () {
|
|
el.style.display = target
|
|
}
|
|
transition(el, value ? 1 : -1, change, this.compiler)
|
|
},
|
|
|
|
'class': function (value) {
|
|
if (this.arg) {
|
|
this.el.classList[value ? 'add' : 'remove'](this.arg)
|
|
} else {
|
|
if (this.lastVal) {
|
|
this.el.classList.remove(this.lastVal)
|
|
}
|
|
if (value) {
|
|
this.el.classList.add(value)
|
|
this.lastVal = value
|
|
}
|
|
}
|
|
},
|
|
|
|
style: {
|
|
bind: function () {
|
|
this.arg = convertCSSProperty(this.arg)
|
|
},
|
|
update: function (value) {
|
|
this.el.style[this.arg] = value
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* convert hyphen style CSS property to Camel style
|
|
*/
|
|
var CONVERT_RE = /-(.)/g
|
|
function convertCSSProperty (prop) {
|
|
if (prop.charAt(0) === '-') prop = prop.slice(1)
|
|
return prop.replace(CONVERT_RE, function (m, char) {
|
|
return char.toUpperCase()
|
|
})
|
|
}
|
|
});
|
|
require.register("vue/src/directives/if.js", function(exports, require, module){
|
|
var config = require('../config'),
|
|
transition = require('../transition')
|
|
|
|
module.exports = {
|
|
|
|
bind: function () {
|
|
this.parent = this.el.parentNode
|
|
this.ref = document.createComment(config.prefix + '-if-' + this.key)
|
|
this.el.vue_ref = this.ref
|
|
},
|
|
|
|
update: function (value) {
|
|
|
|
var el = this.el
|
|
|
|
if (!this.parent) { // the node was detached when bound
|
|
if (!el.parentNode) {
|
|
return
|
|
} else {
|
|
this.parent = el.parentNode
|
|
}
|
|
}
|
|
|
|
// should always have this.parent if we reach here
|
|
var parent = this.parent,
|
|
ref = this.ref,
|
|
compiler = this.compiler
|
|
|
|
if (!value) {
|
|
transition(el, -1, remove, compiler)
|
|
} else {
|
|
transition(el, 1, insert, compiler)
|
|
}
|
|
|
|
function remove () {
|
|
if (!el.parentNode) return
|
|
// insert the reference node
|
|
var next = el.nextSibling
|
|
if (next) {
|
|
parent.insertBefore(ref, next)
|
|
} else {
|
|
parent.appendChild(ref)
|
|
}
|
|
parent.removeChild(el)
|
|
}
|
|
|
|
function insert () {
|
|
if (el.parentNode) return
|
|
parent.insertBefore(el, ref)
|
|
parent.removeChild(ref)
|
|
}
|
|
},
|
|
|
|
unbind: function () {
|
|
this.el.vue_ref = null
|
|
}
|
|
}
|
|
});
|
|
require.register("vue/src/directives/repeat.js", function(exports, require, module){
|
|
var Observer = require('../observer'),
|
|
Emitter = require('../emitter'),
|
|
utils = require('../utils'),
|
|
config = require('../config'),
|
|
transition = require('../transition'),
|
|
ViewModel // lazy def to avoid circular dependency
|
|
|
|
/**
|
|
* Mathods that perform precise DOM manipulation
|
|
* based on mutator method triggered
|
|
*/
|
|
var mutationHandlers = {
|
|
|
|
push: function (m) {
|
|
var i, l = m.args.length,
|
|
base = this.collection.length - l
|
|
for (i = 0; i < l; i++) {
|
|
this.buildItem(m.args[i], base + i)
|
|
}
|
|
},
|
|
|
|
pop: function () {
|
|
var vm = this.vms.pop()
|
|
if (vm) vm.$destroy()
|
|
},
|
|
|
|
unshift: function (m) {
|
|
var i, l = m.args.length
|
|
for (i = 0; i < l; i++) {
|
|
this.buildItem(m.args[i], i)
|
|
}
|
|
},
|
|
|
|
shift: function () {
|
|
var vm = this.vms.shift()
|
|
if (vm) vm.$destroy()
|
|
},
|
|
|
|
splice: function (m) {
|
|
var i, l,
|
|
index = m.args[0],
|
|
removed = m.args[1],
|
|
added = m.args.length - 2,
|
|
removedVMs = this.vms.splice(index, removed)
|
|
for (i = 0, l = removedVMs.length; i < l; i++) {
|
|
removedVMs[i].$destroy()
|
|
}
|
|
for (i = 0; i < added; i++) {
|
|
this.buildItem(m.args[i + 2], index + i)
|
|
}
|
|
},
|
|
|
|
sort: function () {
|
|
var key = this.arg,
|
|
vms = this.vms,
|
|
col = this.collection,
|
|
l = col.length,
|
|
sorted = new Array(l),
|
|
i, j, vm, data
|
|
for (i = 0; i < l; i++) {
|
|
data = col[i]
|
|
for (j = 0; j < l; j++) {
|
|
vm = vms[j]
|
|
if (vm[key] === data) {
|
|
sorted[i] = vm
|
|
break
|
|
}
|
|
}
|
|
}
|
|
for (i = 0; i < l; i++) {
|
|
this.container.insertBefore(sorted[i].$el, this.ref)
|
|
}
|
|
this.vms = sorted
|
|
},
|
|
|
|
reverse: function () {
|
|
var vms = this.vms
|
|
vms.reverse()
|
|
for (var i = 0, l = vms.length; i < l; i++) {
|
|
this.container.insertBefore(vms[i].$el, this.ref)
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
|
|
bind: function () {
|
|
|
|
var self = this,
|
|
el = self.el,
|
|
ctn = self.container = el.parentNode
|
|
|
|
// extract child VM information, if any
|
|
ViewModel = ViewModel || require('../viewmodel')
|
|
var componentId = utils.attr(el, 'component')
|
|
self.ChildVM = self.compiler.getOption('components', componentId) || ViewModel
|
|
|
|
// extract transition information
|
|
self.hasTrans = el.hasAttribute(config.attrs.transition)
|
|
|
|
// create a comment node as a reference node for DOM insertions
|
|
self.ref = document.createComment(config.prefix + '-repeat-' + self.arg)
|
|
ctn.insertBefore(self.ref, el)
|
|
ctn.removeChild(el)
|
|
|
|
self.initiated = false
|
|
self.collection = null
|
|
self.vms = null
|
|
self.mutationListener = function (path, arr, mutation) {
|
|
self.detach()
|
|
var method = mutation.method
|
|
mutationHandlers[method].call(self, mutation)
|
|
if (method !== 'push' && method !== 'pop') {
|
|
self.updateIndexes()
|
|
}
|
|
self.retach()
|
|
}
|
|
|
|
},
|
|
|
|
update: function (collection) {
|
|
|
|
this.unbind(true)
|
|
// attach an object to container to hold handlers
|
|
this.container.vue_dHandlers = utils.hash()
|
|
// if initiating with an empty collection, we need to
|
|
// force a compile so that we get all the bindings for
|
|
// dependency extraction.
|
|
if (!this.initiated && (!collection || !collection.length)) {
|
|
this.buildItem()
|
|
this.initiated = true
|
|
}
|
|
collection = this.collection = collection || []
|
|
this.vms = []
|
|
|
|
// listen for collection mutation events
|
|
// the collection has been augmented during Binding.set()
|
|
if (!collection.__observer__) Observer.watchArray(collection, null, new Emitter())
|
|
collection.__observer__.on('mutate', this.mutationListener)
|
|
|
|
// create child-vms and append to DOM
|
|
if (collection.length) {
|
|
this.detach()
|
|
for (var i = 0, l = collection.length; i < l; i++) {
|
|
this.buildItem(collection[i], i)
|
|
}
|
|
this.retach()
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Create a new child VM from a data object
|
|
* passing along compiler options indicating this
|
|
* is a v-repeat item.
|
|
*/
|
|
buildItem: function (data, index) {
|
|
|
|
var node = this.el.cloneNode(true),
|
|
ctn = this.container,
|
|
scope = {},
|
|
ref, item
|
|
|
|
// append node into DOM first
|
|
// so v-if can get access to parentNode
|
|
if (data) {
|
|
ref = this.vms.length > index
|
|
? this.vms[index].$el
|
|
: this.ref
|
|
// make sure it works with v-if
|
|
if (!ref.parentNode) ref = ref.vue_ref
|
|
// process transition info before appending
|
|
node.vue_trans = utils.attr(node, 'transition', true)
|
|
transition(node, 1, function () {
|
|
ctn.insertBefore(node, ref)
|
|
}, this.compiler)
|
|
}
|
|
|
|
// set data on scope and compile
|
|
scope[this.arg] = data || {}
|
|
item = new this.ChildVM({
|
|
el: node,
|
|
scope: scope,
|
|
compilerOptions: {
|
|
repeat: true,
|
|
repeatIndex: index,
|
|
repeatCollection: this.collection,
|
|
repeatPrefix: this.arg,
|
|
parentCompiler: this.compiler,
|
|
delegator: ctn
|
|
}
|
|
})
|
|
|
|
if (!data) {
|
|
// this is a forced compile for an empty collection.
|
|
// let's remove it...
|
|
item.$destroy()
|
|
} else {
|
|
this.vms.splice(index, 0, item)
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Update index of each item after a mutation
|
|
*/
|
|
updateIndexes: function () {
|
|
var i = this.vms.length
|
|
while (i--) {
|
|
this.vms[i].$index = i
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Detach/retach the container from the DOM before mutation
|
|
* so that batch DOM updates are done in-memory and faster
|
|
*/
|
|
detach: function () {
|
|
if (this.hasTrans) return
|
|
var c = this.container,
|
|
p = this.parent = c.parentNode
|
|
this.next = c.nextSibling
|
|
if (p) p.removeChild(c)
|
|
},
|
|
|
|
retach: function () {
|
|
if (this.hasTrans) return
|
|
var n = this.next,
|
|
p = this.parent,
|
|
c = this.container
|
|
if (!p) return
|
|
if (n) {
|
|
p.insertBefore(c, n)
|
|
} else {
|
|
p.appendChild(c)
|
|
}
|
|
},
|
|
|
|
unbind: function () {
|
|
if (this.collection) {
|
|
this.collection.__observer__.off('mutate', this.mutationListener)
|
|
var i = this.vms.length
|
|
while (i--) {
|
|
this.vms[i].$destroy()
|
|
}
|
|
}
|
|
var ctn = this.container,
|
|
handlers = ctn.vue_dHandlers
|
|
for (var key in handlers) {
|
|
ctn.removeEventListener(handlers[key].event, handlers[key])
|
|
}
|
|
ctn.vue_dHandlers = null
|
|
}
|
|
}
|
|
});
|
|
require.register("vue/src/directives/on.js", function(exports, require, module){
|
|
var utils = require('../utils')
|
|
|
|
function delegateCheck (el, root, identifier) {
|
|
while (el && el !== root) {
|
|
if (el[identifier]) return el
|
|
el = el.parentNode
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
|
|
isFn: true,
|
|
|
|
bind: function () {
|
|
if (this.compiler.repeat) {
|
|
// attach an identifier to the el
|
|
// so it can be matched during event delegation
|
|
this.el[this.expression] = true
|
|
// attach the owner viewmodel of this directive
|
|
this.el.vue_viewmodel = this.vm
|
|
}
|
|
},
|
|
|
|
update: function (handler) {
|
|
this.unbind(true)
|
|
if (typeof handler !== 'function') {
|
|
return utils.warn('Directive "on" expects a function value.')
|
|
}
|
|
|
|
var compiler = this.compiler,
|
|
event = this.arg,
|
|
ownerVM = this.binding.compiler.vm
|
|
|
|
if (compiler.repeat &&
|
|
// do not delegate if the repeat is combined with an extended VM
|
|
!this.vm.constructor.super &&
|
|
// blur and focus events do not bubble
|
|
event !== 'blur' && event !== 'focus') {
|
|
|
|
// for each blocks, delegate for better performance
|
|
// focus and blur events dont bubble so exclude them
|
|
var delegator = compiler.delegator,
|
|
identifier = this.expression,
|
|
dHandler = delegator.vue_dHandlers[identifier]
|
|
|
|
if (dHandler) return
|
|
|
|
// the following only gets run once for the entire each block
|
|
dHandler = delegator.vue_dHandlers[identifier] = function (e) {
|
|
var target = delegateCheck(e.target, delegator, identifier)
|
|
if (target) {
|
|
e.el = target
|
|
e.vm = target.vue_viewmodel
|
|
e.item = e.vm[compiler.repeatPrefix]
|
|
handler.call(ownerVM, e)
|
|
}
|
|
}
|
|
dHandler.event = event
|
|
delegator.addEventListener(event, dHandler)
|
|
|
|
} else {
|
|
|
|
// a normal, single element handler
|
|
var vm = this.vm
|
|
this.handler = function (e) {
|
|
e.el = e.currentTarget
|
|
e.vm = vm
|
|
if (compiler.repeat) {
|
|
e.item = vm[compiler.repeatPrefix]
|
|
}
|
|
handler.call(ownerVM, e)
|
|
}
|
|
this.el.addEventListener(event, this.handler)
|
|
|
|
}
|
|
},
|
|
|
|
unbind: function (update) {
|
|
this.el.removeEventListener(this.arg, this.handler)
|
|
this.handler = null
|
|
if (!update) this.el.vue_viewmodel = null
|
|
}
|
|
}
|
|
});
|
|
require.register("vue/src/directives/model.js", function(exports, require, module){
|
|
var utils = require('../utils'),
|
|
isIE9 = navigator.userAgent.indexOf('MSIE 9.0') > 0
|
|
|
|
module.exports = {
|
|
|
|
bind: function () {
|
|
|
|
var self = this,
|
|
el = self.el,
|
|
type = el.type
|
|
|
|
self.lock = false
|
|
|
|
// determine what event to listen to
|
|
self.event =
|
|
(self.compiler.options.lazy ||
|
|
el.tagName === 'SELECT' ||
|
|
type === 'checkbox' ||
|
|
type === 'radio')
|
|
? 'change'
|
|
: 'input'
|
|
|
|
// determin the attribute to change when updating
|
|
var attr = type === 'checkbox'
|
|
? 'checked'
|
|
: 'value'
|
|
|
|
// attach listener
|
|
self.set = self.filters
|
|
? function () {
|
|
// if this directive has filters
|
|
// we need to let the vm.$set trigger
|
|
// update() so filters are applied.
|
|
// therefore we have to record cursor position
|
|
// so that after vm.$set changes the input
|
|
// value we can put the cursor back at where it is
|
|
var cursorPos
|
|
try {
|
|
cursorPos = el.selectionStart
|
|
} catch (e) {}
|
|
// `input` event has weird updating issue with
|
|
// International (e.g. Chinese) input methods,
|
|
// have to use a Timeout to hack around it...
|
|
setTimeout(function () {
|
|
self.vm.$set(self.key, el[attr])
|
|
if (cursorPos !== undefined) {
|
|
el.setSelectionRange(cursorPos, cursorPos)
|
|
}
|
|
}, 0)
|
|
}
|
|
: function () {
|
|
// no filters, don't let it trigger update()
|
|
self.lock = true
|
|
self.vm.$set(self.key, el[attr])
|
|
self.lock = false
|
|
}
|
|
el.addEventListener(self.event, self.set)
|
|
|
|
// fix shit for IE9
|
|
// since it doesn't fire input on backspace / del / cut
|
|
if (isIE9) {
|
|
self.onCut = function () {
|
|
// cut event fires before the value actually changes
|
|
setTimeout(function () {
|
|
self.set()
|
|
}, 0)
|
|
}
|
|
self.onDel = function (e) {
|
|
if (e.keyCode === 46 || e.keyCode === 8) {
|
|
self.set()
|
|
}
|
|
}
|
|
el.addEventListener('cut', self.onCut)
|
|
el.addEventListener('keyup', self.onDel)
|
|
}
|
|
},
|
|
|
|
update: function (value) {
|
|
if (this.lock) return
|
|
/* jshint eqeqeq: false */
|
|
var self = this,
|
|
el = self.el
|
|
if (el.tagName === 'SELECT') { // select dropdown
|
|
// setting <select>'s value in IE9 doesn't work
|
|
var o = el.options,
|
|
i = o.length,
|
|
index = -1
|
|
while (i--) {
|
|
if (o[i].value == value) {
|
|
index = i
|
|
break
|
|
}
|
|
}
|
|
o.selectedIndex = index
|
|
} else if (el.type === 'radio') { // radio button
|
|
el.checked = value == el.value
|
|
} else if (el.type === 'checkbox') { // checkbox
|
|
el.checked = !!value
|
|
} else {
|
|
el.value = utils.toText(value)
|
|
}
|
|
},
|
|
|
|
unbind: function () {
|
|
this.el.removeEventListener(this.event, this.set)
|
|
if (isIE9) {
|
|
this.el.removeEventListener('cut', this.onCut)
|
|
this.el.removeEventListener('keyup', this.onDel)
|
|
}
|
|
}
|
|
}
|
|
});
|
|
require.alias("component-emitter/index.js", "vue/deps/emitter/index.js");
|
|
require.alias("component-emitter/index.js", "emitter/index.js");
|
|
|
|
require.alias("vue/src/main.js", "vue/index.js");if (typeof exports == "object") {
|
|
module.exports = require("vue");
|
|
} else if (typeof define == "function" && define.amd) {
|
|
define(function(){ return require("vue"); });
|
|
} else {
|
|
this["Vue"] = require("vue");
|
|
}})(); |