/* Vue.js v0.8.2 (c) 2014 Evan You License: MIT */ ;(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, val) { if (typeof opts === 'string') { if (val === undefined) { return config[opts] } else { config[opts] = val } } else { utils.extend(config, opts) } 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 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 ViewModel.nextTick = utils.nextTick /** * 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, asParent) { if (!asParent) { opts = inheritOptions(opts, options, true) } ParentVM.call(this, opts, true) } // inherit prototype props var proto = ExtendedVM.prototype = Object.create(ParentVM.prototype) utils.defProtected(proto, 'constructor', ExtendedVM) // copy prototype props var methods = options.methods if (methods) { for (var key in methods) { if ( !(key in ViewModel.prototype) && typeof methods[key] === 'function' ) { proto[key] = methods[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 `data`, `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 === 'methods') continue var val = child[key], parentVal = parent[key], type = utils.typeOf(val) if (topLevel && type === 'Function' && parentVal) { // merge hook functions child[key] = mergeHook(val, parentVal) } else if (topLevel && type === 'Object') { // merge toplevel object options inheritOptions(val, parentVal) } else if (val === undefined) { // inherit if child doesn't override child[key] = parentVal } } return child } /** * Merge hook functions * so parent hooks also get called */ function mergeHook (fn, parentFn) { return function (opts) { parentFn.call(this, opts) fn.call(this, opts) } } 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){ var prefix = 'v', specialAttributes = [ 'pre', 'text', 'repeat', 'partial', 'with', 'component', 'component-id', 'transition' ], config = module.exports = { debug : false, silent : false, enterClass : 'v-enter', leaveClass : 'v-leave', attrs : {}, get prefix () { return prefix }, set prefix (val) { prefix = val updatePrefix() } } function updatePrefix () { specialAttributes.forEach(function (attr) { config.attrs[attr] = prefix + '-' + attr }) } updatePrefix() }); 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 var defer = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.setTimeout /** * 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(), /** * 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 }, /** * convert certain option values to the desired format. */ processOptions: function (options) { var components = options.components, partials = options.partials, template = options.template, key if (components) { for (key in components) { components[key] = utils.toConstructor(components[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, traces by default * can be suppressed by `silent` option. */ warn: function() { if (!config.silent && console) { console.warn(join.call(arguments, ' ')) if (config.debug) { console.trace() } } }, /** * used to defer batch updates */ nextTick: function (cb) { defer(cb, 0) } } }); 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'), // cache methods slice = Array.prototype.slice, log = utils.log, makeHash = utils.hash, extend = utils.extend, 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 // process and extend options options = compiler.options = options || makeHash() utils.processOptions(options) // copy data, methods & compiler options var data = compiler.data = options.data || {} extend(vm, data, true) extend(vm, options.methods, true) extend(compiler, options.compilerOptions) // initialize element var el = compiler.setupElement(options) log('\nnew VM instance:', el.tagName, '\n') // set compiler properties compiler.vm = vm compiler.bindings = makeHash() compiler.dirs = [] compiler.deferred = [] compiler.exps = [] compiler.computed = [] compiler.childCompilers = [] compiler.emitter = new Emitter() // set inenumerable VM properties def(vm, '$', makeHash()) def(vm, '$el', el) def(vm, '$compiler', compiler) def(vm, '$root', getRoot(compiler).vm) // set parent VM // and register child id on parent var parent = compiler.parentCompiler, childId = utils.attr(el, 'component-id') if (parent) { parent.childCompilers.push(compiler) def(vm, '$parent', parent.vm) if (childId) { compiler.childId = childId parent.vm.$[childId] = vm } } // setup observer compiler.setupObserver() // create bindings for computed properties var computed = options.computed if (computed) { for (var key in computed) { compiler.createBinding(key) } } // beforeCompile hook compiler.execHook('beforeCompile', 'created') // the user might have set some props on the vm // so copy it back to the data... extend(data, vm) // observe the data Observer.observe(data, '', compiler.observer) // for repeated items, create an index binding // which should be inenumerable but configurable if (compiler.repeat) { //data.$index = compiler.repeatIndex def(data, '$index', compiler.repeatIndex, false, true) compiler.createBinding('$index') } // allow the $data object to be swapped Object.defineProperty(vm, '$data', { enumerable: false, get: function () { return compiler.data }, set: function (newData) { var oldData = compiler.data Observer.unobserve(oldData, '', compiler.observer) compiler.data = newData Observer.copyPaths(newData, oldData) Observer.observe(newData, '', compiler.observer) } }) // now parse the DOM, during which we will create necessary bindings // and bind the parsed directives compiler.compile(el, true) // bind deferred directives (child components) for (var i = 0, l = compiler.deferred.length; i < l; i++) { compiler.bindDirective(compiler.deferred[i]) } // extract dependencies for computed properties compiler.parseDeps() // done! compiler.init = false // post compile / ready hook compiler.execHook('afterCompile', 'ready') } 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) DepsParser.catcher.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, nodeType = node.nodeType, tagName = node.tagName if (nodeType === 1 && tagName !== 'SCRIPT') { // a normal node // skip anything with v-pre if (utils.attr(node, 'pre') !== null) return // special attributes to check var repeatExp, withKey, partialId, directive, componentId = utils.attr(node, 'component') || tagName.toLowerCase(), componentCtor = compiler.getOption('components', componentId) // 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. directive = Directive.parse('repeat', repeatExp, compiler, node) if (directive) { directive.Ctor = componentCtor // defer child component compilation // so by the time they are compiled, the parent // would have collected all bindings compiler.deferred.push(directive) } // v-with has 2nd highest priority } else if (!root && ((withKey = utils.attr(node, 'with')) || componentCtor)) { directive = Directive.parse('with', withKey || '', compiler, node) if (directive) { directive.Ctor = componentCtor compiler.deferred.push(directive) } } 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 (nodeType === 3) { // text node compiler.compileTextNode(node) } } /** * Compile a normal node */ CompilerProto.compileNode = function (node) { var i, j, attrs = node.attributes, prefix = config.prefix + '-' // parse if has attributes if (attrs && attrs.length) { var attr, isDirective, exps, exp, directive // loop through all attributes i = attrs.length while (i--) { attr = attrs[i] isDirective = false if (attr.name.indexOf(prefix) === 0) { // a directive - split, parse and bind it. isDirective = true exps = Directive.split(attr.value) // loop through clauses (separated by ",") // inside each attribute j = exps.length while (j--) { exp = exps[j] directive = Directive.parse(attr.name.slice(prefix.length), exp, this, node) if (directive) { this.bindDirective(directive) } } } else { // non directive attribute, check interpolation tags exp = TextParser.parseAttr(attr.value) if (exp) { directive = Directive.parse('attr', attr.name + ':' + exp, this, node) if (directive) { this.bindDirective(directive) } } } if (isDirective) 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 el, token, directive, partial, partialId, partialNodes 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 partialId = token.key.slice(1).trim() partial = this.getOption('partials', partialId) if (partial) { el = partial.cloneNode(true) // save an Array reference of the partial's nodes // so we can compile them AFTER appending the fragment partialNodes = slice.call(el.childNodes) } } else { // a real binding el = document.createTextNode('') directive = Directive.parse('text', token.key, this, el) if (directive) { this.bindDirective(directive) } } } else { // a plain string el = document.createTextNode(token) } // insert node node.parentNode.insertBefore(el, node) // compile partial after appending, because its children's parentNode // will change from the fragment to the correct parentNode. // This could affect directives that need access to its element's parentNode. if (partialNodes) { for (var j = 0, k = partialNodes.length; j < k; j++) { this.compile(partialNodes[j]) } partialNodes = null } } 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.isEmpty) { if (directive.bind) directive.bind() return } // otherwise, we got more work to do... var binding, compiler = this, key = directive.key if (directive.isExp) { // expression bindings are always created on current compiler binding = compiler.createBinding(key, true, directive.isFn) } else { // recursively locate which compiler owns the binding while (compiler) { if (compiler.hasKey(key)) { break } else { compiler = compiler.parentCompiler } } compiler = compiler || this binding = compiler.bindings[key] || compiler.createBinding(key) } binding.instances.push(directive) directive.binding = binding // invoke bind hook if exists if (directive.bind) { directive.bind() } // set initial value directive.update(binding.val(), true) } /** * Create binding and attach getter/setter for a key to the viewmodel object */ CompilerProto.createBinding = function (key, isExp, isFn) { log(' created binding: ' + key) var compiler = this, bindings = compiler.bindings, computed = compiler.options.computed, binding = new Binding(compiler, key, isExp, isFn) if (isExp) { // expression bindings are anonymous compiler.defineExp(key, binding) } else { bindings[key] = binding if (binding.root) { // this is a root level binding. we need to define getter/setters for it. if (computed && computed[key]) { // computed property compiler.defineComputed(key, binding, computed[key]) } else { // normal property compiler.defineProp(key, binding) } } else { // ensure path in data so it can be observed Observer.ensurePath(compiler.data, key) var parentKey = key.slice(0, key.lastIndexOf('.')) if (!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 } /** * Define the getter/setter for a root-level property on the VM * and observe the initial value */ CompilerProto.defineProp = function (key, binding) { var compiler = this, data = compiler.data, ob = data.__observer__ // make sure the key is present in data // so it can be observed if (!(key in data)) { data[key] = undefined } // if the data object is already observed, but the key // is not observed, we need to add it to the observed keys. if (ob && !(key in ob.values)) { Observer.convert(data, key) } binding.value = data[key] Object.defineProperty(compiler.vm, key, { get: function () { return compiler.data[key] }, set: function (val) { compiler.data[key] = val } }) } /** * Define an expression binding, which is essentially * an anonymous computed property */ CompilerProto.defineExp = function (key, binding) { var getter = ExpParser.parse(key, this) if (getter) { this.markComputed(binding, getter) this.exps.push(binding) } } /** * Define a computed property on the VM */ CompilerProto.defineComputed = function (key, binding, value) { this.markComputed(binding, value) var def = { get: binding.value.$get, set: binding.value.$set } Object.defineProperty(this.vm, key, def) } /** * Process a computed property binding * so its getter/setter are bound to proper context */ CompilerProto.markComputed = function (binding, value) { binding.isComputed = true // bind the accessors to the vm if (binding.isFn) { binding.value = value } else { if (typeof value === 'function') { value = { $get: value } } binding.value = { $get: utils.bind(value.$get, this.vm), $set: value.$set ? utils.bind(value.$set, this.vm) : undefined } } // 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, parent = this.parentCompiler return (opts[type] && opts[type][id]) || ( parent ? parent.getOption(type, id) : utils[type] && utils[type][id] ) } /** * Execute a user hook */ CompilerProto.execHook = function (id, alt) { var opts = this.options, hook = opts[id] || opts[alt] if (hook) { hook.call(this.vm, opts) } } /** * Check if a compiler's data contains a keypath */ CompilerProto.hasKey = function (key) { var baseKey = key.split('.')[0] return hasOwn.call(this.data, baseKey) || hasOwn.call(this.vm, baseKey) } /** * Collect dependencies for computed properties */ CompilerProto.parseDeps = function () { if (!this.computed.length) return DepsParser.parse(this.computed) } /** * Unbind and remove element */ CompilerProto.destroy = function () { var compiler = this, i, key, dir, instances, binding, vm = compiler.vm, el = compiler.el, directives = compiler.dirs, exps = compiler.exps, bindings = compiler.bindings compiler.execHook('beforeDestroy') // 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.isEmpty && 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) { binding = bindings[key] if (binding) { 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 { vm.$remove() } compiler.execHook('afterDestroy') } // Helpers -------------------------------------------------------------------- /** * shorthand for getting root compiler */ function getRoot (compiler) { while (compiler.parentCompiler) { compiler = compiler.parentCompiler } return compiler } module.exports = Compiler }); require.register("vue/src/viewmodel.js", function(exports, require, module){ var Compiler = require('./compiler'), utils = require('./utils'), transition = require('./transition'), def = utils.defProtected, nextTick = utils.nextTick /** * 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) { var self = this function on () { var args = arguments utils.nextTick(function () { callback.apply(self, args) }) } callback._fn = on self.$compiler.observer.on('change:' + key, on) }) /** * 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._fn) 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, '$dispatch', function () { var compiler = this.$compiler, emitter = compiler.emitter, parent = compiler.parentCompiler emitter.emit.apply(emitter, arguments) if (parent) { parent.vm.$dispatch.apply(parent.vm, arguments) } }) /** * delegate on/off/once to the compiler's emitter */ ;['emit', 'on', 'off', 'once'].forEach(function (method) { def(VMProto, '$' + method, function () { var emitter = this.$compiler.emitter emitter[method].apply(emitter, arguments) }) }) // DOM convenience methods def(VMProto, '$appendTo', function (target, cb) { target = query(target) var el = this.$el transition(el, 1, function () { target.appendChild(el) if (cb) nextTick(cb) }, this.$compiler) }) def(VMProto, '$remove', function (cb) { var el = this.$el, parent = el.parentNode if (!parent) return transition(el, -1, function () { parent.removeChild(el) if (cb) nextTick(cb) }, this.$compiler) }) def(VMProto, '$before', function (target, cb) { target = query(target) var el = this.$el, parent = target.parentNode if (!parent) return transition(el, 1, function () { parent.insertBefore(el, target) if (cb) nextTick(cb) }, this.$compiler) }) def(VMProto, '$after', function (target, cb) { target = query(target) var el = this.$el, parent = target.parentNode, next = target.nextSibling if (!parent) return transition(el, 1, function () { if (next) { parent.insertBefore(el, next) } else { parent.appendChild(el) } if (cb) nextTick(cb) }, this.$compiler) }) function query (el) { return typeof el === 'string' ? document.querySelector(el) : el } /** * 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){ var batcher = require('./batcher'), id = 0 /** * 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.id = id++ 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 = [] this.unbound = false } var BindingProto = Binding.prototype /** * Update value and queue instance updates. */ BindingProto.update = function (value) { if (!this.isComputed || this.isFn) { this.value = value } batcher.queue(this) } /** * Actually update the instances. */ BindingProto._update = function () { var i = this.instances.length, value = this.val() while (i--) { this.instances[i].update(value) } this.pub() } /** * Return the valuated value regardless * of whether it is computed or not */ BindingProto.val = function () { return this.isComputed && !this.isFn ? this.value.$get() : this.value } /** * Notify computed properties that depend on this binding * to update themselves */ BindingProto.pub = function () { var i = this.subs.length while (i--) { this.subs[i].update() } } /** * Unbind the binding, remove itself from all of its dependencies */ BindingProto.unbind = function () { // Indicate this has been unbound. // It's possible this binding will be in // the batcher's flush queue when its owner // compiler has already been destroyed. this.unbound = true 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'), // cache methods typeOf = utils.typeOf, def = utils.defProtected, slice = Array.prototype.slice, // types OBJECT = 'Object', ARRAY = 'Array', // 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__, // lazy load ViewModel // 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, recursive. */ function watchObject (obj) { for (var key in obj) { convert(obj, key) } } /** * Watch an Array, overload mutation methods * and add augmentations by intercepting the prototype chain */ function watchArray (arr, path) { var observer = arr.__observer__ if (!observer) { observer = new Emitter() 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 convert (obj, key) { var keyPrefix = key.charAt(0) if ((keyPrefix === '$' || keyPrefix === '_') && key !== '$index') { return } // emit set on bind // this means when an object is observed it will emit // a first batch of set events. var observer = obj.__observer__, values = observer.values, val = values[key] = obj[key] observer.emit('set', key, val) if (Array.isArray(val)) { observer.emit('set', key + '.length', val.length) } Object.defineProperty(obj, key, { get: function () { var value = values[key] // only emit get on tip values if (pub.shouldGet && typeOf(value) !== OBJECT) { observer.emit('get', key) } return value }, set: function (newVal) { var oldVal = values[key] unobserve(oldVal, key, observer) values[key] = newVal copyPaths(newVal, oldVal) observer.emit('set', key, newVal) observe(newVal, key, observer) } }) observe(val, key, observer) } /** * Check if a value is watchable */ function isWatchable (obj) { ViewModel = ViewModel || require('./viewmodel') var type = typeOf(obj) return (type === OBJECT || type === ARRAY) && !(obj instanceof ViewModel) } /** * 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) { var type = typeOf(obj), emitter = obj && obj.__observer__ if (type === ARRAY) { emitter.emit('set', 'length', obj.length) } else if (type === OBJECT) { var key, val for (key in obj) { val = obj[key] emitter.emit('set', key, val) emitSet(val) } } } /** * Make sure all the paths in an old object exists * in a new object. * So when an object changes, all missing keys will * emit a set event with undefined value. */ function copyPaths (newObj, oldObj) { if (typeOf(oldObj) !== OBJECT || typeOf(newObj) !== OBJECT) { return } var path, type, oldVal, newVal for (path in oldObj) { if (!(path in newObj)) { oldVal = oldObj[path] type = typeOf(oldVal) if (type === OBJECT) { newVal = newObj[path] = {} copyPaths(newVal, oldVal) } else if (type === ARRAY) { newObj[path] = [] } else { newObj[path] = undefined } } } } /** * walk along a path and make sure it can be accessed * and enumerated in that object */ function ensurePath (obj, key) { var path = key.split('.'), sec for (var i = 0, d = path.length - 1; i < d; i++) { sec = path[i] if (!obj[sec]) { obj[sec] = {} if (obj.__observer__) convert(obj, sec) } obj = obj[sec] } if (typeOf(obj) === OBJECT) { sec = path[i] if (!(sec in obj)) { obj[sec] = undefined if (obj.__observer__) convert(obj, sec) } } } /** * Observe an object with a given path, * and proxy get/set/mutate events to the provided observer. */ function observe (obj, rawPath, observer) { if (!isWatchable(obj)) return var path = rawPath ? rawPath + '.' : '', ob, alreadyConverted = !!obj.__observer__ if (!alreadyConverted) { def(obj, '__observer__', new Emitter()) } ob = obj.__observer__ ob.values = ob.values || utils.hash() observer.proxies = observer.proxies || {} 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) } else { var type = typeOf(obj) if (type === OBJECT) { watchObject(obj) } else if (type === ARRAY) { watchArray(obj) } } } /** * Cancel observation, turn off the listeners. */ function unobserve (obj, path, observer) { if (!obj || !obj.__observer__) return path = path ? path + '.' : '' var proxies = observer.proxies[path] if (!proxies) return obj.__observer__ .off('get', proxies.get) .off('set', proxies.set) .off('mutate', proxies.mutate) observer.proxies[path] = null } var pub = module.exports = { // whether to emit get events // only enabled during dependency parsing shouldGet : false, observe : observe, unobserve : unobserve, ensurePath : ensurePath, convert : convert, copyPaths : copyPaths, watchArray : watchArray } }); require.register("vue/src/directive.js", function(exports, require, module){ var 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 = /^\$(parent|root)\./, 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 isEmpty = expression === '' // mix in properties from the directive definition if (typeof definition === 'function') { this[isEmpty ? '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 (isEmpty) { this.isEmpty = true return } this.expression = expression.trim() this.rawKey = rawKey parseKey(this, rawKey) this.isExp = !SINGLE_VAR_RE.test(this.key) || NESTING_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 } 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 if (this._update) { 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 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'), stringSaveRE = /"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g, stringRestoreRE = /"(\d+)"/g // 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 = '', dist = 0, self = compiler while (compiler) { if (compiler.hasKey(path)) { break } else { compiler = compiler.parentCompiler dist++ } } if (compiler) { while (dist--) { rel += '$parent.' } if (!compiler.bindings[path] && path.charAt(0) !== '$') { compiler.createBinding(path) } } else { self.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 data 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 = '', has = utils.hash(), strings = [], // 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(stringSaveRE, saveStrings) .replace(pathRE, replacePath) .replace(stringRestoreRE, restoreStrings) body = accessors + body function saveStrings (str) { var i = strings.length strings[i] = str return '"' + i + '"' } function replacePath (path) { // keep track of the first char var c = path.charAt(0) path = path.slice(1) var val = 'this.' + getRel(path, compiler) + path if (!has[path]) { accessors += val + ';' has[path] = 1 } // don't forget to put that first char back return c + val } function restoreStrings (str, i) { return strings[i] } return makeGetter(body, exp) } } }); require.register("vue/src/text-parser.js", function(exports, require, module){ var BINDING_RE = /\{\{(.+?)\}\}/ /** * Parse a piece of text, return an array of tokens */ function parse (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 } /** * Parse an attribute value with possible interpolation tags * return a Directive-friendly expression */ function parseAttr (attr) { var tokens = parse(attr) if (!tokens) return null var res = [], token for (var i = 0, l = tokens.length; i < l; i++) { token = tokens[i] res.push(token.key || ('"' + token + '"')) } return res.join('+') } exports.parse = parse exports.parseAttr = parseAttr }); require.register("vue/src/deps-parser.js", function(exports, require, module){ var Emitter = require('./emitter'), utils = require('./utils'), Observer = require('./observer'), catcher = 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 got = utils.hash() binding.deps = [] catcher.on('get', function (dep) { var has = got[dep.key] if (has && has.compiler === dep.compiler) return got[dep.key] = dep utils.log(' - ' + dep.key) binding.deps.push(dep) dep.subs.push(binding) }) binding.value.$get() catcher.off('get') } module.exports = { /** * the observer that catches events triggered by getters */ catcher: catcher, /** * parse a list of computed property bindings */ parse: function (bindings) { utils.log('\nparsing dependencies...') Observer.shouldGet = true var i = bindings.length while (i--) { catchDeps(bindings[i]) } Observer.shouldGet = 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'), // 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, cb, compiler) { var changeState = function () { cb() compiler.execHook(stage > 0 ? 'enteredView' : 'leftView') } 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(config.enterClass) // append changeState() // force a layout so transition can be triggered /* jshint unused: false */ var forceLayout = el.clientHeight // trigger transition classList.remove(config.enterClass) return codes.CSS_E } else { // leave // trigger hide transition classList.add(config.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(config.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/batcher.js", function(exports, require, module){ var utils = require('./utils'), queue, has, waiting reset() exports.queue = function (binding) { if (!has[binding.id]) { queue.push(binding) has[binding.id] = true if (!waiting) { waiting = true utils.nextTick(flush) } } } function flush () { for (var i = 0; i < queue.length; i++) { var b = queue[i] if (b.unbound) continue b._update() has[b.id] = false } reset() } function reset () { queue = [] has = utils.hash() waiting = false } }); 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'), 'with' : require('./with'), 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) }, 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 } } } } }); 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 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.$data === 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') self.Ctor = self.Ctor || 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.key) ctn.insertBefore(self.ref, el) ctn.removeChild(el) self.initiated = false self.collection = null self.vms = null self.mutationListener = function (path, arr, mutation) { var method = mutation.method mutationHandlers[method].call(self, mutation) if (method !== 'push' && method !== 'pop') { self.updateIndexes() } if (method === 'push' || method === 'unshift' || method === 'splice') { self.changed() } } }, update: function (collection, init) { var self = this self.unbind(true) // attach an object to container to hold handlers self.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 (!self.initiated && (!collection || !collection.length)) { self.buildItem() self.initiated = true } collection = self.collection = collection || [] self.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', self.mutationListener) // create child-vms and append to DOM if (collection.length) { for (var i = 0, l = collection.length; i < l; i++) { self.buildItem(collection[i], i) } if (!init) self.changed() } }, /** * Notify parent compiler that new items * have been added to the collection, it needs * to re-calculate computed property dependencies. * Batched to ensure it's called only once every event loop. */ changed: function () { var self = this if (self.queued) return self.queued = true setTimeout(function () { self.compiler.parseDeps() self.queued = false }, 0) }, /** * 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, 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) } item = new this.Ctor({ el: node, data: data, compilerOptions: { repeat: true, repeatIndex: index, repeatCollection: this.collection, 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].$data.$index = i } }, 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, isExp = this.binding.isExp, 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.targetVM = target.vue_viewmodel handler.call(isExp ? e.targetVM : 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.targetVM = vm 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, tag = el.tagName self.lock = false // determine what event to listen to self.event = (self.compiler.options.lazy || tag === 'SELECT' || type === 'checkbox' || type === 'radio') ? 'change' : 'input' // determine the attribute to change when updating var attr = self.attr = type === 'checkbox' ? 'checked' : (tag === 'INPUT' || tag === 'SELECT' || tag === 'TEXTAREA') ? 'value' : 'innerHTML' var compositionLock = false this.cLock = function () { compositionLock = true } this.cUnlock = function () { compositionLock = false } el.addEventListener('compositionstart', this.cLock) el.addEventListener('compositionend', this.cUnlock) // attach listener self.set = self.filters ? function () { if (compositionLock) return // 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) {} self.vm.$set(self.key, el[attr]) // since updates are async // we need to reset cursor position async too utils.nextTick(function () { if (cursorPos !== undefined) { el.setSelectionRange(cursorPos, cursorPos) } }) } : function () { if (compositionLock) return // no filters, don't let it trigger update() self.lock = true self.vm.$set(self.key, el[attr]) utils.nextTick(function () { 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 utils.nextTick(function () { self.set() }) } 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