var _ = require('../util') var mergeOptions = require('../util/merge-option') /** * Expose useful internals */ exports.util = _ exports.nextTick = _.nextTick exports.config = require('../config') exports.compiler = { compile: require('../compiler/compile'), transclude: require('../compiler/transclude') } exports.parsers = { path: require('../parsers/path'), text: require('../parsers/text'), template: require('../parsers/template'), directive: require('../parsers/directive'), expression: require('../parsers/expression') } /** * Each instance constructor, including Vue, has a unique * cid. This enables us to create wrapped "child * constructors" for prototypal inheritance and cache them. */ exports.cid = 0 var cid = 1 /** * Class inehritance * * @param {Object} extendOptions */ exports.extend = function (extendOptions) { extendOptions = extendOptions || {} var Super = this var Sub = createClass(extendOptions.name || 'VueComponent') Sub.prototype = Object.create(Super.prototype) Sub.prototype.constructor = Sub Sub.cid = cid++ Sub.options = mergeOptions( Super.options, extendOptions ) Sub['super'] = Super // allow further extension Sub.extend = Super.extend // create asset registers, so extended classes // can have their private assets too. createAssetRegisters(Sub) return Sub } /** * A function that returns a sub-class constructor with the * given name. This gives us much nicer output when * logging instances in the console. * * @param {String} name * @return {Function} */ function createClass (name) { return new Function( 'return function ' + _.camelize(name, true) + ' (options) { this._init(options) }' )() } /** * Plugin system * * @param {Object} plugin */ exports.use = function (plugin) { // additional parameters var args = _.toArray(arguments, 1) args.unshift(this) if (typeof plugin.install === 'function') { plugin.install.apply(plugin, args) } else { plugin.apply(null, args) } return this } /** * Define asset registration methods on a constructor. * * @param {Function} Constructor */ var assetTypes = [ 'directive', 'filter', 'partial', 'transition' ] function createAssetRegisters (Constructor) { /* Asset registration methods share the same signature: * * @param {String} id * @param {*} definition */ assetTypes.forEach(function (type) { Constructor[type] = function (id, definition) { if (!definition) { return this.options[type + 's'][id] } else { this.options[type + 's'][id] = definition } } }) /** * Component registration needs to automatically invoke * Vue.extend on object values. * * @param {String} id * @param {Object|Function} definition */ Constructor.component = function (id, definition) { if (!definition) { return this.options.components[id] } else { if (_.isPlainObject(definition)) { definition.name = id definition = _.Vue.extend(definition) } this.options.components[id] = definition } } } createAssetRegisters(exports)