diff --git a/app/DataMapper/DefaultSettings.php b/app/DataMapper/DefaultSettings.php new file mode 100644 index 000000000000..89a8a6bff6a8 --- /dev/null +++ b/app/DataMapper/DefaultSettings.php @@ -0,0 +1,40 @@ + self::clientSettings(), + ]; + } + + private static function clientSettings() : \stdClass + { + + return (object)[ + 'datatable' => (object) [ + 'per_page' => self::$per_page, + 'column_visibility' => (object)[ + '__checkbox' => true, + 'name' => true, + 'contact' => true, + 'email' => true, + 'client_created_at' => true, + 'last_login' => true, + 'balance' => true, + '__component:client-actions' => true + ] + ] + ]; + + } + +} \ No newline at end of file diff --git a/app/Datatables/ClientDatatable.php b/app/Datatables/ClientDatatable.php index 52f5464a3190..1e1e6178333d 100644 --- a/app/Datatables/ClientDatatable.php +++ b/app/Datatables/ClientDatatable.php @@ -6,6 +6,7 @@ use App\Models\Client; use App\Utils\Traits\MakesHash; use App\Utils\Traits\UserSessionAttributes; use Illuminate\Http\Request; +use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; @@ -157,8 +158,11 @@ class ClientDatatable extends EntityDatatable } - public function buildOptions() + public function buildOptions() : Collection { + + $visible = auth()->user()->getColumnVisibility(Client::class); + return collect([ 'per_page' => 20, 'sort_order' => [ @@ -170,53 +174,59 @@ class ClientDatatable extends EntityDatatable ], 'fields' => [ [ - 'name' => '__checkbox', // <---- + 'name' => '__checkbox', 'title' => '', 'titleClass' => 'center aligned', + 'visible' => $visible->__checkbox, 'dataClass' => 'center aligned' ], [ 'name' => 'name', 'title' => trans('texts.name'), 'sortField' => 'name', - 'visible' => false, + 'visible' => $visible->name, 'dataClass' => 'center aligned' ], [ 'name' => 'contact', 'title' => trans('texts.contact'), 'sortField' => 'contact', - 'visible' => false, + 'visible' => $visible->contact, 'dataClass' => 'center aligned' ], [ 'name' => 'email', 'title' => trans('texts.email'), 'sortField' => 'email', + 'visible' => $visible->email, 'dataClass' => 'center aligned' ], [ 'name' => 'client_created_at', 'title' => trans('texts.date_created'), 'sortField' => 'client_created_at', + 'visible' => $visible->client_created_at, 'dataClass' => 'center aligned' ], [ 'name' => 'last_login', 'title' => trans('texts.last_login'), 'sortField' => 'last_login', + 'visible' => $visible->last_login, 'dataClass' => 'center aligned' ], [ 'name' => 'balance', 'title' => trans('texts.balance'), 'sortField' => 'balance', + 'visible' => $visible->balance, 'dataClass' => 'center aligned' ], [ 'name' => '__component:client-actions', 'title' => '', 'titleClass' => 'center aligned', + 'visible' => true, 'dataClass' => 'center aligned' ] ] diff --git a/app/Models/CompanyUser.php b/app/Models/CompanyUser.php index f0e7291ba746..de5121a60ad3 100644 --- a/app/Models/CompanyUser.php +++ b/app/Models/CompanyUser.php @@ -6,6 +6,16 @@ class CompanyUser extends BaseModel { protected $guarded = ['id']; + + /** + * The attributes that should be cast to native types. + * + * @var array + */ + protected $casts = [ + 'settings' => 'collection', + ]; + public function account() { return $this->hasOne(Account::class); @@ -13,11 +23,11 @@ class CompanyUser extends BaseModel public function user() { - return $this->hasOne(User::class)->withPivot('permissions'); + return $this->hasOne(User::class)->withPivot('permissions', 'settings'); } public function company() { - return $this->hasOne(Company::class)->withPivot('permissions'); + return $this->hasOne(Company::class)->withPivot('permissions', 'settings'); } } diff --git a/app/Models/User.php b/app/Models/User.php index d41306d46a5c..6ed1563346be 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -5,6 +5,7 @@ namespace App\Models; use App\Models\Traits\UserTrait; use App\Utils\Traits\MakesHash; use App\Utils\Traits\UserSessionAttributes; +use App\Utils\Traits\UserSettings; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Foundation\Auth\User as Authenticatable; @@ -18,7 +19,8 @@ class User extends Authenticatable implements MustVerifyEmail use PresentableTrait; use MakesHash; use UserSessionAttributes; - + use UserSettings; + protected $guard = 'user'; protected $dates = ['deleted_at']; @@ -55,16 +57,31 @@ class User extends Authenticatable implements MustVerifyEmail 'slack_webhook_url', ]; + /** + * Returns all companies a user has access to. + * + * @return Collection + */ public function companies() { - return $this->belongsToMany(Company::class)->withPivot('permissions'); + return $this->belongsToMany(Company::class)->withPivot('permissions','settings'); } + /** + * Returns the current company + * + * @return Collection + */ public function company() { return $this->companies()->where('company_id', $this->getCurrentCompanyId())->first(); } + /** + * Returns a object of user permissions + * + * @return stdClass + */ public function permissions() { @@ -76,26 +93,63 @@ class User extends Authenticatable implements MustVerifyEmail return $permissions; } + /** + * Returns a object of User Settings + * + * @return stdClass + */ + public function settings() + { + return json_decode($this->company()->pivot->settings); + } + + /** + * Returns a boolean of the administrator status of the user + * + * @return bool + */ public function is_admin() { return $this->company()->pivot->is_admin; } + /** + * Returns all user created contacts + * + * @return Collection + */ public function contacts() { return $this->hasMany(Contact::class); } + /** + * Returns a boolean value if the user owns the current Entity + * + * @param string Entity + * @return bool + */ public function owns($entity) : bool { return ! empty($entity->user_id) && $entity->user_id == $this->id; } + /** + * Flattens a stdClass representation of the User Permissions + * into a Collection + * + * @return Collection + */ public function permissionsFlat() { return collect($this->permissions())->flatten(); } + /** + * Returns a array of permission for the mobile application + * + * @return array + */ public function permissionsMap() { @@ -104,4 +158,5 @@ class User extends Authenticatable implements MustVerifyEmail return array_combine($keys, $values); } + } diff --git a/composer.lock b/composer.lock index 71ddd1e7e438..0a1ce42f8c0c 100644 --- a/composer.lock +++ b/composer.lock @@ -1761,16 +1761,16 @@ }, { "name": "opis/closure", - "version": "3.1.3", + "version": "3.1.5", "source": { "type": "git", "url": "https://github.com/opis/closure.git", - "reference": "5e9095ce871a425ab87a854b285b7766de38a7d9" + "reference": "41f5da65d75cf473e5ee582df8fc7f2c733ce9d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opis/closure/zipball/5e9095ce871a425ab87a854b285b7766de38a7d9", - "reference": "5e9095ce871a425ab87a854b285b7766de38a7d9", + "url": "https://api.github.com/repos/opis/closure/zipball/41f5da65d75cf473e5ee582df8fc7f2c733ce9d6", + "reference": "41f5da65d75cf473e5ee582df8fc7f2c733ce9d6", "shasum": "" }, "require": { @@ -1818,7 +1818,7 @@ "serialization", "serialize" ], - "time": "2019-01-06T22:07:38+00:00" + "time": "2019-01-14T14:45:33+00:00" }, { "name": "paragonie/random_compat", diff --git a/config/app.php b/config/app.php index f57e17cfef04..a6deae9f9a10 100644 --- a/config/app.php +++ b/config/app.php @@ -227,7 +227,6 @@ return [ 'URL' => Illuminate\Support\Facades\URL::class, 'Validator' => Illuminate\Support\Facades\Validator::class, 'View' => Illuminate\Support\Facades\View::class, - 'Datatables' => Yajra\Datatables\Facades\Datatables::class, /* * Dependency Facades diff --git a/database/migrations/2014_10_13_000000_create_users_table.php b/database/migrations/2014_10_13_000000_create_users_table.php index 5d0e8d459365..68dcbe023385 100644 --- a/database/migrations/2014_10_13_000000_create_users_table.php +++ b/database/migrations/2014_10_13_000000_create_users_table.php @@ -151,6 +151,12 @@ class CreateUsersTable extends Migration $table->string('custom_label2')->nullable(); $table->string('custom_value2')->nullable(); + $table->string('custom_label3')->nullable(); + $table->string('custom_value3')->nullable(); + + $table->string('custom_label4')->nullable(); + $table->string('custom_value4')->nullable(); + $table->string('custom_client_label1')->nullable(); $table->string('custom_client_label2')->nullable(); @@ -191,6 +197,7 @@ class CreateUsersTable extends Migration $table->unsignedInteger('account_id'); $table->unsignedInteger('user_id')->index(); $table->text('permissions'); + $table->text('settings'); $table->boolean('is_owner')->default(false); $table->boolean('is_admin'); $table->boolean('is_locked')->default(false); // locks user out of account diff --git a/database/seeds/UsersTableSeeder.php b/database/seeds/UsersTableSeeder.php index 854da855f6c9..433e3939a4ce 100644 --- a/database/seeds/UsersTableSeeder.php +++ b/database/seeds/UsersTableSeeder.php @@ -1,5 +1,6 @@ companies()->attach($company->id, [ 'account_id' => $account->id, 'is_owner' => 1, 'is_admin' => 1, 'permissions' => $userPermissions->toJson(), + 'settings' => json_encode($userSettings), 'is_locked' => 0, ]); diff --git a/public/js/client_create.js b/public/js/client_create.js index e634a94d16aa..e980e5bf029f 100644 --- a/public/js/client_create.js +++ b/public/js/client_create.js @@ -3964,7 +3964,7 @@ if(false) { "use strict"; /* WEBPACK VAR INJECTION */(function(global, setImmediate) {/*! - * Vue.js v2.5.17 + * Vue.js v2.5.21 * (c) 2014-2018 Evan You * Released under the MIT License. */ @@ -3974,8 +3974,8 @@ if(false) { var emptyObject = Object.freeze({}); -// these helpers produces better vm code in JS engines due to their -// explicitness and function inlining +// These helpers produce better VM code in JS engines due to their +// explicitness and function inlining. function isUndef (v) { return v === undefined || v === null } @@ -3993,7 +3993,7 @@ function isFalse (v) { } /** - * Check if value is primitive + * Check if value is primitive. */ function isPrimitive (value) { return ( @@ -4015,7 +4015,7 @@ function isObject (obj) { } /** - * Get the raw type string of a value e.g. [object Object] + * Get the raw type string of a value, e.g., [object Object]. */ var _toString = Object.prototype.toString; @@ -4055,7 +4055,7 @@ function toString (val) { } /** - * Convert a input value to a number for persistence. + * Convert an input value to a number for persistence. * If the conversion fails, return original string. */ function toNumber (val) { @@ -4087,12 +4087,12 @@ function makeMap ( var isBuiltInTag = makeMap('slot,component', true); /** - * Check if a attribute is a reserved attribute. + * Check if an attribute is a reserved attribute. */ var isReservedAttribute = makeMap('key,ref,slot,slot-scope,is'); /** - * Remove an item from an array + * Remove an item from an array. */ function remove (arr, item) { if (arr.length) { @@ -4104,7 +4104,7 @@ function remove (arr, item) { } /** - * Check whether the object has the property. + * Check whether an object has the property. */ var hasOwnProperty = Object.prototype.hasOwnProperty; function hasOwn (obj, key) { @@ -4146,11 +4146,11 @@ var hyphenate = cached(function (str) { }); /** - * Simple bind polyfill for environments that do not support it... e.g. - * PhantomJS 1.x. Technically we don't need this anymore since native bind is - * now more performant in most browsers, but removing it would be breaking for - * code that was able to run in PhantomJS 1.x, so this must be kept for - * backwards compatibility. + * Simple bind polyfill for environments that do not support it, + * e.g., PhantomJS 1.x. Technically, we don't need this anymore + * since native bind is now performant enough in most browsers. + * But removing it would mean breaking code that was able to run in + * PhantomJS 1.x, so this must be kept for backward compatibility. */ /* istanbul ignore next */ @@ -4212,10 +4212,12 @@ function toObject (arr) { return res } +/* eslint-disable no-unused-vars */ + /** * Perform no operation. * Stubbing args to make Flow happy without leaving useless transpiled code - * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/) + * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/). */ function noop (a, b, c) {} @@ -4224,13 +4226,15 @@ function noop (a, b, c) {} */ var no = function (a, b, c) { return false; }; +/* eslint-enable no-unused-vars */ + /** - * Return same value + * Return the same value. */ var identity = function (_) { return _; }; /** - * Generate a static keys string from compiler modules. + * Generate a string containing static keys from compiler modules. */ function genStaticKeys (modules) { return modules.reduce(function (keys, m) { @@ -4254,6 +4258,8 @@ function looseEqual (a, b) { return a.length === b.length && a.every(function (e, i) { return looseEqual(e, b[i]) }) + } else if (a instanceof Date && b instanceof Date) { + return a.getTime() === b.getTime() } else if (!isArrayA && !isArrayB) { var keysA = Object.keys(a); var keysB = Object.keys(b); @@ -4275,6 +4281,11 @@ function looseEqual (a, b) { } } +/** + * Return the first index at which a loosely equal value can be + * found in the array (if value is a plain object, the array must + * contain an object of the same shape), or -1 if it is not present. + */ function looseIndexOf (arr, val) { for (var i = 0; i < arr.length; i++) { if (looseEqual(arr[i], val)) { return i } @@ -4319,6 +4330,8 @@ var LIFECYCLE_HOOKS = [ /* */ + + var config = ({ /** * Option merge strategies (used in core/util/options) @@ -4401,11 +4414,17 @@ var config = ({ */ mustUseProp: no, + /** + * Perform updates asynchronously. Intended to be used by Vue Test Utils + * This will significantly reduce performance if set to false. + */ + async: true, + /** * Exposed for legacy reasons */ _lifecycleHooks: LIFECYCLE_HOOKS -}) +}); /* */ @@ -4490,7 +4509,7 @@ var isServerRendering = function () { if (!inBrowser && !inWeex && typeof global !== 'undefined') { // detect presence of vue-server-renderer and avoid // Webpack shimming the process - _isServer = global['process'].env.VUE_ENV === 'server'; + _isServer = global['process'] && global['process'].env.VUE_ENV === 'server'; } else { _isServer = false; } @@ -4517,7 +4536,7 @@ if (typeof Set !== 'undefined' && isNative(Set)) { _Set = Set; } else { // a non-standard Set polyfill that only works with primitive keys. - _Set = (function () { + _Set = /*@__PURE__*/(function () { function Set () { this.set = Object.create(null); } @@ -4631,7 +4650,6 @@ if (true) { /* */ - var uid = 0; /** @@ -4660,6 +4678,12 @@ Dep.prototype.depend = function depend () { Dep.prototype.notify = function notify () { // stabilize the subscriber list first var subs = this.subs.slice(); + if ("development" !== 'production' && !config.async) { + // subs aren't sorted in scheduler if not running async + // we need to sort them now to make sure they fire in correct + // order + subs.sort(function (a, b) { return a.id - b.id; }); + } for (var i = 0, l = subs.length; i < l; i++) { subs[i].update(); } @@ -4671,13 +4695,14 @@ Dep.prototype.notify = function notify () { Dep.target = null; var targetStack = []; -function pushTarget (_target) { - if (Dep.target) { targetStack.push(Dep.target); } - Dep.target = _target; +function pushTarget (target) { + targetStack.push(target); + Dep.target = target; } function popTarget () { - Dep.target = targetStack.pop(); + targetStack.pop(); + Dep.target = targetStack[targetStack.length - 1]; } /* */ @@ -4748,7 +4773,10 @@ function cloneVNode (vnode) { var cloned = new VNode( vnode.tag, vnode.data, - vnode.children, + // #7975 + // clone children array to avoid mutating original in case of cloning + // a child. + vnode.children && vnode.children.slice(), vnode.text, vnode.elm, vnode.context, @@ -4762,6 +4790,7 @@ function cloneVNode (vnode) { cloned.fnContext = vnode.fnContext; cloned.fnOptions = vnode.fnOptions; cloned.fnScopeId = vnode.fnScopeId; + cloned.asyncMeta = vnode.asyncMeta; cloned.isCloned = true; return cloned } @@ -4839,10 +4868,11 @@ var Observer = function Observer (value) { this.vmCount = 0; def(value, '__ob__', this); if (Array.isArray(value)) { - var augment = hasProto - ? protoAugment - : copyAugment; - augment(value, arrayMethods, arrayKeys); + if (hasProto) { + protoAugment(value, arrayMethods); + } else { + copyAugment(value, arrayMethods, arrayKeys); + } this.observeArray(value); } else { this.walk(value); @@ -4850,14 +4880,14 @@ var Observer = function Observer (value) { }; /** - * Walk through each property and convert them into + * Walk through all properties and convert them into * getter/setters. This method should only be called when * value type is Object. */ Observer.prototype.walk = function walk (obj) { var keys = Object.keys(obj); for (var i = 0; i < keys.length; i++) { - defineReactive(obj, keys[i]); + defineReactive$$1(obj, keys[i]); } }; @@ -4873,17 +4903,17 @@ Observer.prototype.observeArray = function observeArray (items) { // helpers /** - * Augment an target Object or Array by intercepting + * Augment a target Object or Array by intercepting * the prototype chain using __proto__ */ -function protoAugment (target, src, keys) { +function protoAugment (target, src) { /* eslint-disable no-proto */ target.__proto__ = src; /* eslint-enable no-proto */ } /** - * Augment an target Object or Array by defining + * Augment a target Object or Array by defining * hidden properties. */ /* istanbul ignore next */ @@ -4924,7 +4954,7 @@ function observe (value, asRootData) { /** * Define a reactive property on an Object. */ -function defineReactive ( +function defineReactive$$1 ( obj, key, val, @@ -4940,10 +4970,10 @@ function defineReactive ( // cater for pre-defined getter/setters var getter = property && property.get; - if (!getter && arguments.length === 2) { + var setter = property && property.set; + if ((!getter || setter) && arguments.length === 2) { val = obj[key]; } - var setter = property && property.set; var childOb = !shallow && observe(val); Object.defineProperty(obj, key, { @@ -4972,6 +5002,8 @@ function defineReactive ( if ("development" !== 'production' && customSetter) { customSetter(); } + // #7981: for accessor properties without setter + if (getter && !setter) { return } if (setter) { setter.call(obj, newVal); } else { @@ -5015,7 +5047,7 @@ function set (target, key, val) { target[key] = val; return val } - defineReactive(ob.value, key, val); + defineReactive$$1(ob.value, key, val); ob.dep.notify(); return val } @@ -5102,7 +5134,11 @@ function mergeData (to, from) { fromVal = from[key]; if (!hasOwn(to, key)) { set(to, key, fromVal); - } else if (isPlainObject(toVal) && isPlainObject(fromVal)) { + } else if ( + toVal !== fromVal && + isPlainObject(toVal) && + isPlainObject(fromVal) + ) { mergeData(toVal, fromVal); } } @@ -5425,15 +5461,22 @@ function mergeOptions ( normalizeProps(child, vm); normalizeInject(child, vm); normalizeDirectives(child); - var extendsFrom = child.extends; - if (extendsFrom) { - parent = mergeOptions(parent, extendsFrom, vm); - } - if (child.mixins) { - for (var i = 0, l = child.mixins.length; i < l; i++) { - parent = mergeOptions(parent, child.mixins[i], vm); + + // Apply extends and mixins on the child options, + // but only if it is a raw options object that isn't + // the result of another mergeOptions call. + // Only merged options has the _base property. + if (!child._base) { + if (child.extends) { + parent = mergeOptions(parent, child.extends, vm); + } + if (child.mixins) { + for (var i = 0, l = child.mixins.length; i < l; i++) { + parent = mergeOptions(parent, child.mixins[i], vm); + } } } + var options = {}; var key; for (key in parent) { @@ -5486,6 +5529,8 @@ function resolveAsset ( /* */ + + function validateProp ( key, propOptions, @@ -5593,11 +5638,10 @@ function assertProp ( valid = assertedType.valid; } } + if (!valid) { warn( - "Invalid prop: type check failed for prop \"" + name + "\"." + - " Expected " + (expectedTypes.map(capitalize).join(', ')) + - ", got " + (toRawType(value)) + ".", + getInvalidTypeMessage(name, value, expectedTypes), vm ); return @@ -5664,6 +5708,49 @@ function getTypeIndex (type, expectedTypes) { return -1 } +function getInvalidTypeMessage (name, value, expectedTypes) { + var message = "Invalid prop: type check failed for prop \"" + name + "\"." + + " Expected " + (expectedTypes.map(capitalize).join(', ')); + var expectedType = expectedTypes[0]; + var receivedType = toRawType(value); + var expectedValue = styleValue(value, expectedType); + var receivedValue = styleValue(value, receivedType); + // check if we need to specify expected value + if (expectedTypes.length === 1 && + isExplicable(expectedType) && + !isBoolean(expectedType, receivedType)) { + message += " with value " + expectedValue; + } + message += ", got " + receivedType + " "; + // check if we need to specify received value + if (isExplicable(receivedType)) { + message += "with value " + receivedValue + "."; + } + return message +} + +function styleValue (value, type) { + if (type === 'String') { + return ("\"" + value + "\"") + } else if (type === 'Number') { + return ("" + (Number(value))) + } else { + return ("" + value) + } +} + +function isExplicable (value) { + var explicitTypes = ['string', 'number', 'boolean']; + return explicitTypes.some(function (elem) { return value.toLowerCase() === elem; }) +} + +function isBoolean () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + return args.some(function (elem) { return elem.toLowerCase() === 'boolean'; }) +} + /* */ function handleError (err, vm, info) { @@ -5710,7 +5797,6 @@ function logError (err, vm, info) { } /* */ -/* globals MessageChannel */ var callbacks = []; var pending = false; @@ -5788,9 +5874,11 @@ if (typeof Promise !== 'undefined' && isNative(Promise)) { function withMacroTask (fn) { return fn._withTask || (fn._withTask = function () { useMacroTask = true; - var res = fn.apply(null, arguments); - useMacroTask = false; - return res + try { + return fn.apply(null, arguments) + } finally { + useMacroTask = false; + } }) } @@ -5871,6 +5959,16 @@ if (true) { ); }; + var warnReservedPrefix = function (target, key) { + warn( + "Property \"" + key + "\" must be accessed with \"$data." + key + "\" because " + + 'properties starting with "$" or "_" are not proxied in the Vue instance to ' + + 'prevent conflicts with Vue internals' + + 'See: https://vuejs.org/v2/api/#data', + target + ); + }; + var hasProxy = typeof Proxy !== 'undefined' && isNative(Proxy); @@ -5892,9 +5990,11 @@ if (true) { var hasHandler = { has: function has (target, key) { var has = key in target; - var isAllowed = allowedGlobals(key) || key.charAt(0) === '_'; + var isAllowed = allowedGlobals(key) || + (typeof key === 'string' && key.charAt(0) === '_' && !(key in target.$data)); if (!has && !isAllowed) { - warnNonPresent(target, key); + if (key in target.$data) { warnReservedPrefix(target, key); } + else { warnNonPresent(target, key); } } return has || !isAllowed } @@ -5903,7 +6003,8 @@ if (true) { var getHandler = { get: function get (target, key) { if (typeof key === 'string' && !(key in target)) { - warnNonPresent(target, key); + if (key in target.$data) { warnReservedPrefix(target, key); } + else { warnNonPresent(target, key); } } return target[key] } @@ -6001,14 +6102,14 @@ function updateListeners ( oldOn, add, remove$$1, + createOnceHandler, vm ) { - var name, def, cur, old, event; + var name, def$$1, cur, old, event; for (name in on) { - def = cur = on[name]; + def$$1 = cur = on[name]; old = oldOn[name]; event = normalizeEvent(name); - /* istanbul ignore if */ if (isUndef(cur)) { "development" !== 'production' && warn( "Invalid handler for event \"" + (event.name) + "\": got " + String(cur), @@ -6018,7 +6119,10 @@ function updateListeners ( if (isUndef(cur.fns)) { cur = on[name] = createFnInvoker(cur); } - add(event.name, cur, event.once, event.capture, event.passive, event.params); + if (isTrue(event.once)) { + cur = on[name] = createOnceHandler(event.name, cur, event.capture); + } + add(event.name, cur, event.capture, event.passive, event.params); } else if (cur !== old) { old.fns = cur; on[name] = old; @@ -6273,10 +6377,14 @@ function resolveAsyncComponent ( var contexts = factory.contexts = [context]; var sync = true; - var forceRender = function () { + var forceRender = function (renderCompleted) { for (var i = 0, l = contexts.length; i < l; i++) { contexts[i].$forceUpdate(); } + + if (renderCompleted) { + contexts.length = 0; + } }; var resolve = once(function (res) { @@ -6285,7 +6393,7 @@ function resolveAsyncComponent ( // invoke callbacks only if this is not a synchronous resolve // (async resolves are shimmed as synchronous during SSR) if (!sync) { - forceRender(); + forceRender(true); } }); @@ -6296,7 +6404,7 @@ function resolveAsyncComponent ( ); if (isDef(factory.errorComp)) { factory.error = true; - forceRender(); + forceRender(true); } }); @@ -6323,7 +6431,7 @@ function resolveAsyncComponent ( setTimeout(function () { if (isUndef(factory.resolved) && isUndef(factory.error)) { factory.loading = true; - forceRender(); + forceRender(false); } }, res.delay || 200); } @@ -6386,37 +6494,41 @@ function initEvents (vm) { var target; -function add (event, fn, once) { - if (once) { - target.$once(event, fn); - } else { - target.$on(event, fn); - } +function add (event, fn) { + target.$on(event, fn); } function remove$1 (event, fn) { target.$off(event, fn); } +function createOnceHandler (event, fn) { + var _target = target; + return function onceHandler () { + var res = fn.apply(null, arguments); + if (res !== null) { + _target.$off(event, onceHandler); + } + } +} + function updateComponentListeners ( vm, listeners, oldListeners ) { target = vm; - updateListeners(listeners, oldListeners || {}, add, remove$1, vm); + updateListeners(listeners, oldListeners || {}, add, remove$1, createOnceHandler, vm); target = undefined; } function eventsMixin (Vue) { var hookRE = /^hook:/; Vue.prototype.$on = function (event, fn) { - var this$1 = this; - var vm = this; if (Array.isArray(event)) { for (var i = 0, l = event.length; i < l; i++) { - this$1.$on(event[i], fn); + vm.$on(event[i], fn); } } else { (vm._events[event] || (vm._events[event] = [])).push(fn); @@ -6441,8 +6553,6 @@ function eventsMixin (Vue) { }; Vue.prototype.$off = function (event, fn) { - var this$1 = this; - var vm = this; // all if (!arguments.length) { @@ -6452,7 +6562,7 @@ function eventsMixin (Vue) { // array of events if (Array.isArray(event)) { for (var i = 0, l = event.length; i < l; i++) { - this$1.$off(event[i], fn); + vm.$off(event[i], fn); } return vm } @@ -6581,6 +6691,14 @@ function resolveScopedSlots ( var activeInstance = null; var isUpdatingChildComponent = false; +function setActiveInstance(vm) { + var prevActiveInstance = activeInstance; + activeInstance = vm; + return function () { + activeInstance = prevActiveInstance; + } +} + function initLifecycle (vm) { var options = vm.$options; @@ -6610,31 +6728,20 @@ function initLifecycle (vm) { function lifecycleMixin (Vue) { Vue.prototype._update = function (vnode, hydrating) { var vm = this; - if (vm._isMounted) { - callHook(vm, 'beforeUpdate'); - } var prevEl = vm.$el; var prevVnode = vm._vnode; - var prevActiveInstance = activeInstance; - activeInstance = vm; + var restoreActiveInstance = setActiveInstance(vm); vm._vnode = vnode; // Vue.prototype.__patch__ is injected in entry points // based on the rendering backend used. if (!prevVnode) { // initial render - vm.$el = vm.__patch__( - vm.$el, vnode, hydrating, false /* removeOnly */, - vm.$options._parentElm, - vm.$options._refElm - ); - // no need for the ref nodes after initial patch - // this prevents keeping a detached DOM tree in memory (#5851) - vm.$options._parentElm = vm.$options._refElm = null; + vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */); } else { // updates vm.$el = vm.__patch__(prevVnode, vnode); } - activeInstance = prevActiveInstance; + restoreActiveInstance(); // update __vue__ reference if (prevEl) { prevEl.__vue__ = null; @@ -6757,7 +6864,13 @@ function mountComponent ( // we set this to vm._watcher inside the watcher's constructor // since the watcher's initial patch may call $forceUpdate (e.g. inside child // component's mounted hook), which relies on vm._watcher being already defined - new Watcher(vm, updateComponent, noop, null, true /* isRenderWatcher */); + new Watcher(vm, updateComponent, noop, { + before: function before () { + if (vm._isMounted && !vm._isDestroyed) { + callHook(vm, 'beforeUpdate'); + } + } + }, true /* isRenderWatcher */); hydrating = false; // manually mounted instance, call mounted on self @@ -6897,7 +7010,6 @@ function callHook (vm, hook) { /* */ - var MAX_UPDATE_COUNT = 100; var queue = []; @@ -6941,6 +7053,9 @@ function flushSchedulerQueue () { // as we run existing watchers for (index = 0; index < queue.length; index++) { watcher = queue[index]; + if (watcher.before) { + watcher.before(); + } id = watcher.id; has[id] = null; watcher.run(); @@ -6983,7 +7098,7 @@ function callUpdatedHooks (queue) { while (i--) { var watcher = queue[i]; var vm = watcher.vm; - if (vm._watcher === watcher && vm._isMounted) { + if (vm._watcher === watcher && vm._isMounted && !vm._isDestroyed) { callHook(vm, 'updated'); } } @@ -7030,6 +7145,11 @@ function queueWatcher (watcher) { // queue the flush if (!waiting) { waiting = true; + + if ("development" !== 'production' && !config.async) { + flushSchedulerQueue(); + return + } nextTick(flushSchedulerQueue); } } @@ -7037,6 +7157,8 @@ function queueWatcher (watcher) { /* */ + + var uid$1 = 0; /** @@ -7062,6 +7184,7 @@ var Watcher = function Watcher ( this.user = !!options.user; this.lazy = !!options.lazy; this.sync = !!options.sync; + this.before = options.before; } else { this.deep = this.user = this.lazy = this.sync = false; } @@ -7082,7 +7205,7 @@ var Watcher = function Watcher ( } else { this.getter = parsePath(expOrFn); if (!this.getter) { - this.getter = function () {}; + this.getter = noop; "development" !== 'production' && warn( "Failed watching path: \"" + expOrFn + "\" " + 'Watcher only accepts simple dot-delimited paths. ' + @@ -7141,13 +7264,11 @@ Watcher.prototype.addDep = function addDep (dep) { * Clean up for dependency collection. */ Watcher.prototype.cleanupDeps = function cleanupDeps () { - var this$1 = this; - var i = this.deps.length; while (i--) { - var dep = this$1.deps[i]; - if (!this$1.newDepIds.has(dep.id)) { - dep.removeSub(this$1); + var dep = this.deps[i]; + if (!this.newDepIds.has(dep.id)) { + dep.removeSub(this); } } var tmp = this.depIds; @@ -7219,11 +7340,9 @@ Watcher.prototype.evaluate = function evaluate () { * Depend on all deps collected by this watcher. */ Watcher.prototype.depend = function depend () { - var this$1 = this; - var i = this.deps.length; while (i--) { - this$1.deps[i].depend(); + this.deps[i].depend(); } }; @@ -7231,8 +7350,6 @@ Watcher.prototype.depend = function depend () { * Remove self from all dependencies' subscriber list. */ Watcher.prototype.teardown = function teardown () { - var this$1 = this; - if (this.active) { // remove self from vm's watcher list // this is a somewhat expensive operation so we skip it @@ -7242,7 +7359,7 @@ Watcher.prototype.teardown = function teardown () { } var i = this.deps.length; while (i--) { - this$1.deps[i].removeSub(this$1); + this.deps[i].removeSub(this); } this.active = false; } @@ -7307,8 +7424,8 @@ function initProps (vm, propsOptions) { vm ); } - defineReactive(props, key, value, function () { - if (vm.$parent && !isUpdatingChildComponent) { + defineReactive$$1(props, key, value, function () { + if (!isRoot && !isUpdatingChildComponent) { warn( "Avoid mutating a prop directly since the value will be " + "overwritten whenever the parent component re-renders. " + @@ -7319,7 +7436,7 @@ function initProps (vm, propsOptions) { } }); } else { - defineReactive(props, key, value); + defineReactive$$1(props, key, value); } // static props are already proxied on the component's prototype // during Vue.extend(). We only need to proxy props defined at @@ -7440,17 +7557,15 @@ function defineComputed ( if (typeof userDef === 'function') { sharedPropertyDefinition.get = shouldCache ? createComputedGetter(key) - : userDef; + : createGetterInvoker(userDef); sharedPropertyDefinition.set = noop; } else { sharedPropertyDefinition.get = userDef.get ? shouldCache && userDef.cache !== false ? createComputedGetter(key) - : userDef.get - : noop; - sharedPropertyDefinition.set = userDef.set - ? userDef.set + : createGetterInvoker(userDef.get) : noop; + sharedPropertyDefinition.set = userDef.set || noop; } if ("development" !== 'production' && sharedPropertyDefinition.set === noop) { @@ -7479,13 +7594,19 @@ function createComputedGetter (key) { } } +function createGetterInvoker(fn) { + return function computedGetter () { + return fn.call(this, this) + } +} + function initMethods (vm, methods) { var props = vm.$options.props; for (var key in methods) { if (true) { - if (methods[key] == null) { + if (typeof methods[key] !== 'function') { warn( - "Method \"" + key + "\" has an undefined value in the component definition. " + + "Method \"" + key + "\" has type \"" + (typeof methods[key]) + "\" in the component definition. " + "Did you reference the function correctly?", vm ); @@ -7503,7 +7624,7 @@ function initMethods (vm, methods) { ); } } - vm[key] = methods[key] == null ? noop : bind(methods[key], vm); + vm[key] = typeof methods[key] !== 'function' ? noop : bind(methods[key], vm); } } @@ -7545,7 +7666,7 @@ function stateMixin (Vue) { var propsDef = {}; propsDef.get = function () { return this._props }; if (true) { - dataDef.set = function (newData) { + dataDef.set = function () { warn( 'Avoid replacing instance root $data. ' + 'Use nested data properties instead.', @@ -7575,7 +7696,11 @@ function stateMixin (Vue) { options.user = true; var watcher = new Watcher(vm, expOrFn, cb, options); if (options.immediate) { - cb.call(vm, watcher.value); + try { + cb.call(vm, watcher.value); + } catch (error) { + handleError(error, vm, ("callback for immediate watcher \"" + (watcher.expression) + "\"")); + } } return function unwatchFn () { watcher.teardown(); @@ -7601,7 +7726,7 @@ function initInjections (vm) { Object.keys(result).forEach(function (key) { /* istanbul ignore else */ if (true) { - defineReactive(vm, key, result[key], function () { + defineReactive$$1(vm, key, result[key], function () { warn( "Avoid mutating an injected value directly since the changes will be " + "overwritten whenever the provided component re-renders. " + @@ -7610,7 +7735,7 @@ function initInjections (vm) { ); }); } else { - defineReactive(vm, key, result[key]); + defineReactive$$1(vm, key, result[key]); } }); toggleObserving(true); @@ -7682,9 +7807,10 @@ function renderList ( ret[i] = render(val[key], key, i); } } - if (isDef(ret)) { - (ret)._isVList = true; + if (!isDef(ret)) { + ret = []; } + (ret)._isVList = true; return ret } @@ -7714,19 +7840,7 @@ function renderSlot ( } nodes = scopedSlotFn(props) || fallback; } else { - var slotNodes = this.$slots[name]; - // warn duplicate slot usage - if (slotNodes) { - if ("development" !== 'production' && slotNodes._rendered) { - warn( - "Duplicate presence of slot \"" + name + "\" found in the same render tree " + - "- this will likely cause render errors.", - this - ); - } - slotNodes._rendered = true; - } - nodes = slotNodes || fallback; + nodes = this.$slots[name] || fallback; } var target = props && props.slot; @@ -7814,12 +7928,13 @@ function bindObjectProps ( ? data.domProps || (data.domProps = {}) : data.attrs || (data.attrs = {}); } - if (!(key in hash)) { + var camelizedKey = camelize(key); + if (!(key in hash) && !(camelizedKey in hash)) { hash[key] = value[key]; if (isSync) { var on = data.on || (data.on = {}); - on[("update:" + key)] = function ($event) { + on[("update:" + camelizedKey)] = function ($event) { value[key] = $event; }; } @@ -8025,24 +8140,27 @@ function createFunctionalComponent ( var vnode = options.render.call(null, renderContext._c, renderContext); if (vnode instanceof VNode) { - return cloneAndMarkFunctionalResult(vnode, data, renderContext.parent, options) + return cloneAndMarkFunctionalResult(vnode, data, renderContext.parent, options, renderContext) } else if (Array.isArray(vnode)) { var vnodes = normalizeChildren(vnode) || []; var res = new Array(vnodes.length); for (var i = 0; i < vnodes.length; i++) { - res[i] = cloneAndMarkFunctionalResult(vnodes[i], data, renderContext.parent, options); + res[i] = cloneAndMarkFunctionalResult(vnodes[i], data, renderContext.parent, options, renderContext); } return res } } -function cloneAndMarkFunctionalResult (vnode, data, contextVm, options) { +function cloneAndMarkFunctionalResult (vnode, data, contextVm, options, renderContext) { // #7817 clone node before setting fnContext, otherwise if the node is reused // (e.g. it was from a cached normal slot) the fnContext causes named slots // that should not be matched to match. var clone = cloneVNode(vnode); clone.fnContext = contextVm; clone.fnOptions = options; + if (true) { + (clone.devtoolsMeta = clone.devtoolsMeta || {}).renderContext = renderContext; + } if (data.slot) { (clone.data || (clone.data = {})).slot = data.slot; } @@ -8057,33 +8175,15 @@ function mergeProps (to, from) { /* */ - - - -// Register the component hook to weex native render engine. -// The hook will be triggered by native, not javascript. - - -// Updates the state of the component to weex native render engine. - /* */ -// https://github.com/Hanks10100/weex-native-directive/tree/master/component - -// listening on native callback - /* */ /* */ // inline hooks to be invoked on component VNodes during patch var componentVNodeHooks = { - init: function init ( - vnode, - hydrating, - parentElm, - refElm - ) { + init: function init (vnode, hydrating) { if ( vnode.componentInstance && !vnode.componentInstance._isDestroyed && @@ -8095,9 +8195,7 @@ var componentVNodeHooks = { } else { var child = vnode.componentInstance = createComponentInstanceForVnode( vnode, - activeInstance, - parentElm, - refElm + activeInstance ); child.$mount(hydrating ? vnode.elm : undefined, hydrating); } @@ -8246,25 +8344,17 @@ function createComponent ( asyncFactory ); - // Weex specific: invoke recycle-list optimized @render function for - // extracting cell-slot template. - // https://github.com/Hanks10100/weex-native-directive/tree/master/component - /* istanbul ignore if */ return vnode } function createComponentInstanceForVnode ( vnode, // we know it's MountedComponentVNode but flow doesn't - parent, // activeInstance in lifecycle state - parentElm, - refElm + parent // activeInstance in lifecycle state ) { var options = { _isComponent: true, - parent: parent, _parentVnode: vnode, - _parentElm: parentElm || null, - _refElm: refElm || null + parent: parent }; // check inline-template render functions var inlineTemplate = vnode.data.inlineTemplate; @@ -8279,20 +8369,43 @@ function installComponentHooks (data) { var hooks = data.hook || (data.hook = {}); for (var i = 0; i < hooksToMerge.length; i++) { var key = hooksToMerge[i]; - hooks[key] = componentVNodeHooks[key]; + var existing = hooks[key]; + var toMerge = componentVNodeHooks[key]; + if (existing !== toMerge && !(existing && existing._merged)) { + hooks[key] = existing ? mergeHook$1(toMerge, existing) : toMerge; + } } } +function mergeHook$1 (f1, f2) { + var merged = function (a, b) { + // flow complains about extra args which is why we use any + f1(a, b); + f2(a, b); + }; + merged._merged = true; + return merged +} + // transform component v-model info (value and callback) into // prop and event handler respectively. function transformModel (options, data) { var prop = (options.model && options.model.prop) || 'value'; - var event = (options.model && options.model.event) || 'input';(data.props || (data.props = {}))[prop] = data.model.value; + var event = (options.model && options.model.event) || 'input' + ;(data.props || (data.props = {}))[prop] = data.model.value; var on = data.on || (data.on = {}); - if (isDef(on[event])) { - on[event] = [data.model.callback].concat(on[event]); + var existing = on[event]; + var callback = data.model.callback; + if (isDef(existing)) { + if ( + Array.isArray(existing) + ? existing.indexOf(callback) === -1 + : existing !== callback + ) { + on[event] = [callback].concat(existing); + } } else { - on[event] = data.model.callback; + on[event] = callback; } } @@ -8380,7 +8493,7 @@ function _createElement ( config.parsePlatformTagName(tag), data, children, undefined, undefined, context ); - } else if (isDef(Ctor = resolveAsset(context.$options, 'components', tag))) { + } else if ((!data || !data.pre) && isDef(Ctor = resolveAsset(context.$options, 'components', tag))) { // component vnode = createComponent(Ctor, data, context, children, tag); } else { @@ -8462,15 +8575,15 @@ function initRender (vm) { /* istanbul ignore else */ if (true) { - defineReactive(vm, '$attrs', parentData && parentData.attrs || emptyObject, function () { + defineReactive$$1(vm, '$attrs', parentData && parentData.attrs || emptyObject, function () { !isUpdatingChildComponent && warn("$attrs is readonly.", vm); }, true); - defineReactive(vm, '$listeners', options._parentListeners || emptyObject, function () { + defineReactive$$1(vm, '$listeners', options._parentListeners || emptyObject, function () { !isUpdatingChildComponent && warn("$listeners is readonly.", vm); }, true); } else { - defineReactive(vm, '$attrs', parentData && parentData.attrs || emptyObject, null, true); - defineReactive(vm, '$listeners', options._parentListeners || emptyObject, null, true); + defineReactive$$1(vm, '$attrs', parentData && parentData.attrs || emptyObject, null, true); + defineReactive$$1(vm, '$listeners', options._parentListeners || emptyObject, null, true); } } @@ -8488,14 +8601,6 @@ function renderMixin (Vue) { var render = ref.render; var _parentVnode = ref._parentVnode; - // reset _rendered flag on slots for duplicate slot check - if (true) { - for (var key in vm.$slots) { - // $flow-disable-line - vm.$slots[key]._rendered = false; - } - } - if (_parentVnode) { vm.$scopedSlots = _parentVnode.data.scopedSlots || emptyObject; } @@ -8512,15 +8617,11 @@ function renderMixin (Vue) { // return error render result, // or previous vnode to prevent render error causing blank component /* istanbul ignore else */ - if (true) { - if (vm.$options.renderError) { - try { - vnode = vm.$options.renderError.call(vm._renderProxy, vm.$createElement, e); - } catch (e) { - handleError(e, vm, "renderError"); - vnode = vm._vnode; - } - } else { + if ("development" !== 'production' && vm.$options.renderError) { + try { + vnode = vm.$options.renderError.call(vm._renderProxy, vm.$createElement, e); + } catch (e) { + handleError(e, vm, "renderError"); vnode = vm._vnode; } } else { @@ -8613,8 +8714,6 @@ function initInternalComponent (vm, options) { var parentVnode = options._parentVnode; opts.parent = options.parent; opts._parentVnode = parentVnode; - opts._parentElm = options._parentElm; - opts._refElm = options._refElm; var vnodeComponentOptions = parentVnode.componentOptions; opts.propsData = vnodeComponentOptions.propsData; @@ -8857,6 +8956,8 @@ function initAssetRegisters (Vue) { /* */ + + function getComponentName (opts) { return opts && (opts.Ctor.options.name || opts.tag) } @@ -8920,10 +9021,8 @@ var KeepAlive = { }, destroyed: function destroyed () { - var this$1 = this; - - for (var key in this$1.cache) { - pruneCacheEntry(this$1.cache, key, this$1.keys); + for (var key in this.cache) { + pruneCacheEntry(this.cache, key, this.keys); } }, @@ -8983,11 +9082,11 @@ var KeepAlive = { } return vnode || (slot && slot[0]) } -} +}; var builtInComponents = { KeepAlive: KeepAlive -} +}; /* */ @@ -9011,7 +9110,7 @@ function initGlobalAPI (Vue) { warn: warn, extend: extend, mergeOptions: mergeOptions, - defineReactive: defineReactive + defineReactive: defineReactive$$1 }; Vue.set = set; @@ -9053,7 +9152,7 @@ Object.defineProperty(Vue, 'FunctionalRenderContext', { value: FunctionalRenderContext }); -Vue.version = '2.5.17'; +Vue.version = '2.5.21'; /* */ @@ -9331,20 +9430,19 @@ function setStyleScope (node, scopeId) { node.setAttribute(scopeId, ''); } - -var nodeOps = Object.freeze({ - createElement: createElement$1, - createElementNS: createElementNS, - createTextNode: createTextNode, - createComment: createComment, - insertBefore: insertBefore, - removeChild: removeChild, - appendChild: appendChild, - parentNode: parentNode, - nextSibling: nextSibling, - tagName: tagName, - setTextContent: setTextContent, - setStyleScope: setStyleScope +var nodeOps = /*#__PURE__*/Object.freeze({ + createElement: createElement$1, + createElementNS: createElementNS, + createTextNode: createTextNode, + createComment: createComment, + insertBefore: insertBefore, + removeChild: removeChild, + appendChild: appendChild, + parentNode: parentNode, + nextSibling: nextSibling, + tagName: tagName, + setTextContent: setTextContent, + setStyleScope: setStyleScope }); /* */ @@ -9362,7 +9460,7 @@ var ref = { destroy: function destroy (vnode) { registerRef(vnode, true); } -} +}; function registerRef (vnode, isRemoval) { var key = vnode.data.ref; @@ -9463,13 +9561,13 @@ function createPatchFunction (backend) { } function createRmCb (childElm, listeners) { - function remove () { - if (--remove.listeners === 0) { + function remove$$1 () { + if (--remove$$1.listeners === 0) { removeNode(childElm); } } - remove.listeners = listeners; - return remove + remove$$1.listeners = listeners; + return remove$$1 } function removeNode (el) { @@ -9570,7 +9668,7 @@ function createPatchFunction (backend) { if (isDef(i)) { var isReactivated = isDef(vnode.componentInstance) && i.keepAlive; if (isDef(i = i.hook) && isDef(i = i.init)) { - i(vnode, false /* hydrating */, parentElm, refElm); + i(vnode, false /* hydrating */); } // after calling the init hook, if the vnode is a child component // it should've created a child instance and mounted it. the child @@ -9578,6 +9676,7 @@ function createPatchFunction (backend) { // in that case we can just return the element and be done. if (isDef(vnode.componentInstance)) { initComponent(vnode, insertedVnodeQueue); + insert(parentElm, vnode.elm, refElm); if (isTrue(isReactivated)) { reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm); } @@ -9629,7 +9728,7 @@ function createPatchFunction (backend) { function insert (parent, elm, ref$$1) { if (isDef(parent)) { if (isDef(ref$$1)) { - if (ref$$1.parentNode === parent) { + if (nodeOps.parentNode(ref$$1) === parent) { nodeOps.insertBefore(parent, elm, ref$$1); } } else { @@ -9784,20 +9883,20 @@ function createPatchFunction (backend) { } else if (isUndef(oldEndVnode)) { oldEndVnode = oldCh[--oldEndIdx]; } else if (sameVnode(oldStartVnode, newStartVnode)) { - patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue); + patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue, newCh, newStartIdx); oldStartVnode = oldCh[++oldStartIdx]; newStartVnode = newCh[++newStartIdx]; } else if (sameVnode(oldEndVnode, newEndVnode)) { - patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue); + patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue, newCh, newEndIdx); oldEndVnode = oldCh[--oldEndIdx]; newEndVnode = newCh[--newEndIdx]; } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right - patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue); + patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue, newCh, newEndIdx); canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm)); oldStartVnode = oldCh[++oldStartIdx]; newEndVnode = newCh[--newEndIdx]; } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left - patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue); + patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue, newCh, newStartIdx); canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm); oldEndVnode = oldCh[--oldEndIdx]; newStartVnode = newCh[++newStartIdx]; @@ -9811,7 +9910,7 @@ function createPatchFunction (backend) { } else { vnodeToMove = oldCh[idxInOld]; if (sameVnode(vnodeToMove, newStartVnode)) { - patchVnode(vnodeToMove, newStartVnode, insertedVnodeQueue); + patchVnode(vnodeToMove, newStartVnode, insertedVnodeQueue, newCh, newStartIdx); oldCh[idxInOld] = undefined; canMove && nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm); } else { @@ -9855,11 +9954,23 @@ function createPatchFunction (backend) { } } - function patchVnode (oldVnode, vnode, insertedVnodeQueue, removeOnly) { + function patchVnode ( + oldVnode, + vnode, + insertedVnodeQueue, + ownerArray, + index, + removeOnly + ) { if (oldVnode === vnode) { return } + if (isDef(vnode.elm) && isDef(ownerArray)) { + // clone reused vnode + vnode = ownerArray[index] = cloneVNode(vnode); + } + var elm = vnode.elm = oldVnode.elm; if (isTrue(oldVnode.isAsyncPlaceholder)) { @@ -9900,6 +10011,9 @@ function createPatchFunction (backend) { if (isDef(oldCh) && isDef(ch)) { if (oldCh !== ch) { updateChildren(elm, oldCh, ch, insertedVnodeQueue, removeOnly); } } else if (isDef(ch)) { + if (true) { + checkDuplicateKeys(ch); + } if (isDef(oldVnode.text)) { nodeOps.setTextContent(elm, ''); } addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue); } else if (isDef(oldCh)) { @@ -10041,7 +10155,7 @@ function createPatchFunction (backend) { } } - return function patch (oldVnode, vnode, hydrating, removeOnly, parentElm, refElm) { + return function patch (oldVnode, vnode, hydrating, removeOnly) { if (isUndef(vnode)) { if (isDef(oldVnode)) { invokeDestroyHook(oldVnode); } return @@ -10053,12 +10167,12 @@ function createPatchFunction (backend) { if (isUndef(oldVnode)) { // empty mount (likely as component), create new root element isInitialPatch = true; - createElm(vnode, insertedVnodeQueue, parentElm, refElm); + createElm(vnode, insertedVnodeQueue); } else { var isRealElement = isDef(oldVnode.nodeType); if (!isRealElement && sameVnode(oldVnode, vnode)) { // patch existing root node - patchVnode(oldVnode, vnode, insertedVnodeQueue, removeOnly); + patchVnode(oldVnode, vnode, insertedVnodeQueue, null, null, removeOnly); } else { if (isRealElement) { // mounting to a real element @@ -10089,7 +10203,7 @@ function createPatchFunction (backend) { // replacing existing element var oldElm = oldVnode.elm; - var parentElm$1 = nodeOps.parentNode(oldElm); + var parentElm = nodeOps.parentNode(oldElm); // create new node createElm( @@ -10098,7 +10212,7 @@ function createPatchFunction (backend) { // extremely rare edge case: do not insert if old element is in a // leaving transition. Only happens when combining transition + // keep-alive + HOCs. (#4590) - oldElm._leaveCb ? null : parentElm$1, + oldElm._leaveCb ? null : parentElm, nodeOps.nextSibling(oldElm) ); @@ -10133,8 +10247,8 @@ function createPatchFunction (backend) { } // destroy old node - if (isDef(parentElm$1)) { - removeVnodes(parentElm$1, [oldVnode], 0, 0); + if (isDef(parentElm)) { + removeVnodes(parentElm, [oldVnode], 0, 0); } else if (isDef(oldVnode.tag)) { invokeDestroyHook(oldVnode); } @@ -10154,7 +10268,7 @@ var directives = { destroy: function unbindDirectives (vnode) { updateDirectives(vnode, emptyNode); } -} +}; function updateDirectives (oldVnode, vnode) { if (oldVnode.data.directives || vnode.data.directives) { @@ -10265,7 +10379,7 @@ function callHook$1 (dir, hook, vnode, oldVnode, isDestroy) { var baseModules = [ ref, directives -] +]; /* */ @@ -10349,7 +10463,7 @@ function baseSetAttr (el, key, value) { /* istanbul ignore if */ if ( isIE && !isIE9 && - el.tagName === 'TEXTAREA' && + (el.tagName === 'TEXTAREA' || el.tagName === 'INPUT') && key === 'placeholder' && !el.__ieph ) { var blocker = function (e) { @@ -10367,7 +10481,7 @@ function baseSetAttr (el, key, value) { var attrs = { create: updateAttrs, update: updateAttrs -} +}; /* */ @@ -10405,7 +10519,7 @@ function updateClass (oldVnode, vnode) { var klass = { create: updateClass, update: updateClass -} +}; /* */ @@ -10569,6 +10683,18 @@ function addHandler ( ); } + // normalize click.right and click.middle since they don't actually fire + // this is technically browser-specific, but at least for now browsers are + // the only target envs that have right/middle clicks. + if (name === 'click') { + if (modifiers.right) { + name = 'contextmenu'; + delete modifiers.right; + } else if (modifiers.middle) { + name = 'mouseup'; + } + } + // check capture modifier if (modifiers.capture) { delete modifiers.capture; @@ -10584,18 +10710,6 @@ function addHandler ( name = '&' + name; // mark the event as passive } - // normalize click.right and click.middle since they don't actually fire - // this is technically browser-specific, but at least for now browsers are - // the only target envs that have right/middle clicks. - if (name === 'click') { - if (modifiers.right) { - name = 'contextmenu'; - delete modifiers.right; - } else if (modifiers.middle) { - name = 'mouseup'; - } - } - var events; if (modifiers.native) { delete modifiers.native; @@ -10696,7 +10810,7 @@ function genComponentModel ( el.model = { value: ("(" + value + ")"), - expression: ("\"" + value + "\""), + expression: JSON.stringify(value), callback: ("function (" + baseValueExpression + ") {" + assignment + "}") }; } @@ -10731,12 +10845,7 @@ function genAssignmentCode ( * */ -var len; -var str; -var chr; -var index$1; -var expressionPos; -var expressionEndPos; +var len, str, chr, index$1, expressionPos, expressionEndPos; @@ -11017,7 +11126,7 @@ function normalizeEvents (on) { var target$1; -function createOnceHandler (handler, event, capture) { +function createOnceHandler$1 (event, handler, capture) { var _target = target$1; // save current target element in closure return function onceHandler () { var res = handler.apply(null, arguments); @@ -11030,12 +11139,10 @@ function createOnceHandler (handler, event, capture) { function add$1 ( event, handler, - once$$1, capture, passive ) { handler = withMacroTask(handler); - if (once$$1) { handler = createOnceHandler(handler, event, capture); } target$1.addEventListener( event, handler, @@ -11066,14 +11173,14 @@ function updateDOMListeners (oldVnode, vnode) { var oldOn = oldVnode.data.on || {}; target$1 = vnode.elm; normalizeEvents(on); - updateListeners(on, oldOn, add$1, remove$2, vnode.context); + updateListeners(on, oldOn, add$1, remove$2, createOnceHandler$1, vnode.context); target$1 = undefined; } var events = { create: updateDOMListeners, update: updateDOMListeners -} +}; /* */ @@ -11167,7 +11274,7 @@ function isDirtyWithModifiers (elm, newVal) { var domProps = { create: updateDOMProps, update: updateDOMProps -} +}; /* */ @@ -11328,10 +11435,12 @@ function updateStyle (oldVnode, vnode) { var style = { create: updateStyle, update: updateStyle -} +}; /* */ +var whitespaceRE = /\s+/; + /** * Add class with compatibility for SVG since classList is not supported on * SVG elements in IE @@ -11345,7 +11454,7 @@ function addClass (el, cls) { /* istanbul ignore else */ if (el.classList) { if (cls.indexOf(' ') > -1) { - cls.split(/\s+/).forEach(function (c) { return el.classList.add(c); }); + cls.split(whitespaceRE).forEach(function (c) { return el.classList.add(c); }); } else { el.classList.add(cls); } @@ -11370,7 +11479,7 @@ function removeClass (el, cls) { /* istanbul ignore else */ if (el.classList) { if (cls.indexOf(' ') > -1) { - cls.split(/\s+/).forEach(function (c) { return el.classList.remove(c); }); + cls.split(whitespaceRE).forEach(function (c) { return el.classList.remove(c); }); } else { el.classList.remove(cls); } @@ -11394,20 +11503,20 @@ function removeClass (el, cls) { /* */ -function resolveTransition (def) { - if (!def) { +function resolveTransition (def$$1) { + if (!def$$1) { return } /* istanbul ignore else */ - if (typeof def === 'object') { + if (typeof def$$1 === 'object') { var res = {}; - if (def.css !== false) { - extend(res, autoCssTransition(def.name || 'v')); + if (def$$1.css !== false) { + extend(res, autoCssTransition(def$$1.name || 'v')); } - extend(res, def); + extend(res, def$$1); return res - } else if (typeof def === 'string') { - return autoCssTransition(def) + } else if (typeof def$$1 === 'string') { + return autoCssTransition(def$$1) } } @@ -11510,11 +11619,12 @@ var transformRE = /\b(transform|all)(,|$)/; function getTransitionInfo (el, expectedType) { var styles = window.getComputedStyle(el); - var transitionDelays = styles[transitionProp + 'Delay'].split(', '); - var transitionDurations = styles[transitionProp + 'Duration'].split(', '); + // JSDOM may return undefined for transition properties + var transitionDelays = (styles[transitionProp + 'Delay'] || '').split(', '); + var transitionDurations = (styles[transitionProp + 'Duration'] || '').split(', '); var transitionTimeout = getTimeout(transitionDelays, transitionDurations); - var animationDelays = styles[animationProp + 'Delay'].split(', '); - var animationDurations = styles[animationProp + 'Duration'].split(', '); + var animationDelays = (styles[animationProp + 'Delay'] || '').split(', '); + var animationDurations = (styles[animationProp + 'Duration'] || '').split(', '); var animationTimeout = getTimeout(animationDelays, animationDurations); var type; @@ -11568,8 +11678,12 @@ function getTimeout (delays, durations) { })) } +// Old versions of Chromium (below 61.0.3163.100) formats floating pointer numbers +// in a locale-dependent way, using a comma instead of a dot. +// If comma is not replaced with a dot, the input will be rounded down (i.e. acting +// as a floor function) causing unexpected behaviors function toMs (s) { - return Number(s.slice(0, -1)) * 1000 + return Number(s.slice(0, -1).replace(',', '.')) * 1000 } /* */ @@ -11801,7 +11915,7 @@ function leave (vnode, rm) { return } // record leaving element - if (!vnode.data.show) { + if (!vnode.data.show && el.parentNode) { (el.parentNode._pending || (el.parentNode._pending = {}))[(vnode.key)] = vnode; } beforeLeave && beforeLeave(el); @@ -11890,7 +12004,7 @@ var transition = inBrowser ? { rm(); } } -} : {} +} : {}; var platformModules = [ attrs, @@ -11899,7 +12013,7 @@ var platformModules = [ domProps, style, transition -] +]; /* */ @@ -12110,18 +12224,15 @@ var show = { el.style.display = el.__vOriginalDisplay; } } -} +}; var platformDirectives = { model: directive, show: show -} +}; /* */ -// Provides transition support for a single element/component. -// supports transition mode (out-in / in-out) - var transitionProps = { name: String, appear: Boolean, @@ -12187,6 +12298,10 @@ function isSameChild (child, oldChild) { return oldChild.key === child.key && oldChild.tag === child.tag } +var isNotTextNode = function (c) { return c.tag || isAsyncPlaceholder(c); }; + +var isVShowDirective = function (d) { return d.name === 'show'; }; + var Transition = { name: 'transition', props: transitionProps, @@ -12201,7 +12316,7 @@ var Transition = { } // filter out text nodes (possible whitespaces) - children = children.filter(function (c) { return c.tag || isAsyncPlaceholder(c); }); + children = children.filter(isNotTextNode); /* istanbul ignore if */ if (!children.length) { return @@ -12266,7 +12381,7 @@ var Transition = { // mark v-show // so that the transition module can hand over the control to the directive - if (child.data.directives && child.data.directives.some(function (d) { return d.name === 'show'; })) { + if (child.data.directives && child.data.directives.some(isVShowDirective)) { child.data.show = true; } @@ -12304,21 +12419,10 @@ var Transition = { return rawChild } -} +}; /* */ -// Provides transition support for list items. -// supports move transitions using the FLIP technique. - -// Because the vdom's children update algorithm is "unstable" - i.e. -// it doesn't guarantee the relative positioning of removed elements, -// we force transition-group to update its children into two passes: -// in the first pass, we remove all nodes that need to be removed, -// triggering their leaving transition; in the second pass, we insert/move -// into the final desired state. This way in the second pass removed -// nodes will remain where they should be. - var props = extend({ tag: String, moveClass: String @@ -12329,6 +12433,25 @@ delete props.mode; var TransitionGroup = { props: props, + beforeMount: function beforeMount () { + var this$1 = this; + + var update = this._update; + this._update = function (vnode, hydrating) { + var restoreActiveInstance = setActiveInstance(this$1); + // force removing pass + this$1.__patch__( + this$1._vnode, + this$1.kept, + false, // hydrating + true // removeOnly (!important, avoids unnecessary moves) + ); + this$1._vnode = this$1.kept; + restoreActiveInstance(); + update.call(this$1, vnode, hydrating); + }; + }, + render: function render (h) { var tag = this.tag || this.$vnode.data.tag || 'span'; var map = Object.create(null); @@ -12372,17 +12495,6 @@ var TransitionGroup = { return h(tag, null, children) }, - beforeUpdate: function beforeUpdate () { - // force removing pass - this.__patch__( - this._vnode, - this.kept, - false, // hydrating - true // removeOnly (!important, avoids unnecessary moves) - ); - this._vnode = this.kept; - }, - updated: function updated () { var children = this.prevChildren; var moveClass = this.moveClass || ((this.name || 'v') + '-move'); @@ -12408,6 +12520,9 @@ var TransitionGroup = { addTransitionClass(el, moveClass); s.transform = s.WebkitTransform = s.transitionDuration = ''; el.addEventListener(transitionEndEvent, el._moveCb = function cb (e) { + if (e && e.target !== el) { + return + } if (!e || /transform$/.test(e.propertyName)) { el.removeEventListener(transitionEndEvent, cb); el._moveCb = null; @@ -12445,7 +12560,7 @@ var TransitionGroup = { return (this._hasMove = info.hasTransform) } } -} +}; function callPendingCbs (c) { /* istanbul ignore if */ @@ -12478,7 +12593,7 @@ function applyTranslation (c) { var platformComponents = { Transition: Transition, TransitionGroup: TransitionGroup -} +}; /* */ @@ -12539,7 +12654,7 @@ if (inBrowser) { /* */ -var defaultTagRE = /\{\{((?:.|\n)+?)\}\}/g; +var defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g; var regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g; var buildRegex = cached(function (delimiters) { @@ -12625,7 +12740,7 @@ var klass$1 = { staticKeys: ['staticClass'], transformNode: transformNode, genData: genData -} +}; /* */ @@ -12669,7 +12784,7 @@ var style$1 = { staticKeys: ['staticStyle'], transformNode: transformNode$1, genData: genData$1 -} +}; /* */ @@ -12681,7 +12796,7 @@ var he = { decoder.innerHTML = html; return decoder.textContent } -} +}; /* */ @@ -12710,13 +12825,6 @@ var isNonPhrasingTag = makeMap( * Not type-checking this file because it's mostly vendor code. */ -/*! - * HTML Parser By John Resig (ejohn.org) - * Modified by Juriy "kangax" Zaytsev - * Original code by Erik Arvidsson, Mozilla Public License - * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js - */ - // Regular Expressions for parsing tags and attributes var attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/; // could use https://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-QName @@ -12731,11 +12839,6 @@ var doctype = /^]+>/i; var comment = /^= 0; pos--) { if (stack[pos].lowerCasedTag === lowerCasedTagName) { break @@ -13018,7 +13112,7 @@ function parseHTML (html, options) { var onRE = /^@|^v-on:/; var dirRE = /^v-|^@|^:/; -var forAliasRE = /([^]*?)\s+(?:in|of)\s+([^]*)/; +var forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/; var forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/; var stripParensRE = /^\(|\)$/g; @@ -13203,7 +13297,8 @@ function parse ( processIfConditions(element, currentParent); } else if (element.slotScope) { // scoped slot currentParent.plain = false; - var name = element.slotTarget || '"default"';(currentParent.scopedSlots || (currentParent.scopedSlots = {}))[name] = element; + var name = element.slotTarget || '"default"' + ;(currentParent.scopedSlots || (currentParent.scopedSlots = {}))[name] = element; } else { currentParent.children.push(element); element.parent = currentParent; @@ -13327,8 +13422,20 @@ function processElement (element, options) { function processKey (el) { var exp = getBindingAttr(el, 'key'); if (exp) { - if ("development" !== 'production' && el.tag === 'template') { - warn$2("