From a9b6b5d7203bb1c60402d81621574a1b90d2286c Mon Sep 17 00:00:00 2001 From: Krzysztof Fudali Date: Sun, 12 Nov 2017 22:06:39 +0200 Subject: [PATCH] 1.70.145 --- CHANGELOG.md | 2 +- README-zh-CN.md | 2 +- README.md | 2 +- ...ndor.js => 585fef694780e845886d.vendor.js} | 152936 +++++++-------- ...525.app.js => 7be432e0378bd1ecb1aa.app.js} | 512 +- ...ime.js => e99382357561012f4a99.runtime.js} | 2 +- bin/pub/img/delete.svg | 3 + bin/pub/img/preset_icon.png | Bin 0 -> 237 bytes bin/pub/img/zone_icon.png | Bin 0 -> 1413 bytes bin/pub/index.html | 2 +- bin/pub/proxies.html | 6 + lib/swagger.json | 2 +- package.json | 8 +- src/pub/add_proxy.js | 91 + src/pub/app.js | 21 +- src/pub/app.less | 122 +- src/pub/intro/index.js | 2 +- 17 files changed, 76480 insertions(+), 77233 deletions(-) rename bin/pub/{3963ba67072360784ca3.vendor.js => 585fef694780e845886d.vendor.js} (96%) rename bin/pub/{fa8a905ef6f43741a525.app.js => 7be432e0378bd1ecb1aa.app.js} (93%) rename bin/pub/{86ec1a907e9b12488174.runtime.js => e99382357561012f4a99.runtime.js} (97%) create mode 100755 bin/pub/img/delete.svg create mode 100755 bin/pub/img/preset_icon.png create mode 100755 bin/pub/img/zone_icon.png create mode 100755 src/pub/add_proxy.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 3802cb7a..5fc71ba2 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ Luminati Proxy manager - Change Log -## 1.69.931 +## 1.70.145 - :bug: fixed login bug - :bug: fixed debug log info diff --git a/README-zh-CN.md b/README-zh-CN.md index 80a246cb..57904b86 100755 --- a/README-zh-CN.md +++ b/README-zh-CN.md @@ -31,7 +31,7 @@ - Node.js 6+版 ### Windows -下载 代理管理安装器. +下载 代理管理安装器. ### Linux/MacOS - 安装 Node.js 6+版 (最好用x diff --git a/README.md b/README.md index ddcb948f..b66bb843 100755 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ This tool requires a [Luminati](https://luminati.io/?cam=github-proxy) account. ## Installation ### Windows -Download the Luminati Proxy Manager installer. +Download the Luminati Proxy Manager installer. ### Linux/MacOS - Install Node.js 6 or above ([nodejs.org](https://nodejs.org/en/download/)) diff --git a/bin/pub/3963ba67072360784ca3.vendor.js b/bin/pub/585fef694780e845886d.vendor.js similarity index 96% rename from bin/pub/3963ba67072360784ca3.vendor.js rename to bin/pub/585fef694780e845886d.vendor.js index a815d0e0..11ce7e47 100755 --- a/bin/pub/3963ba67072360784ca3.vendor.js +++ b/bin/pub/585fef694780e845886d.vendor.js @@ -5,7 +5,7 @@ webpackJsonp([0],[ "use strict"; -module.exports = __webpack_require__(66); +module.exports = __webpack_require__(59); /***/ }), @@ -222,7 +222,7 @@ exports.default = function (instance, Constructor) { exports.__esModule = true; -var _typeof2 = __webpack_require__(149); +var _typeof2 = __webpack_require__(125); var _typeof3 = _interopRequireDefault(_typeof2); @@ -245,15 +245,15 @@ exports.default = function (self, call) { exports.__esModule = true; -var _setPrototypeOf = __webpack_require__(415); +var _setPrototypeOf = __webpack_require__(366); var _setPrototypeOf2 = _interopRequireDefault(_setPrototypeOf); -var _create = __webpack_require__(419); +var _create = __webpack_require__(370); var _create2 = _interopRequireDefault(_create); -var _typeof2 = __webpack_require__(149); +var _typeof2 = __webpack_require__(125); var _typeof3 = _interopRequireDefault(_typeof2); @@ -284,7 +284,7 @@ exports.default = function (subClass, superClass) { exports.__esModule = true; -var _assign = __webpack_require__(218); +var _assign = __webpack_require__(192); var _assign2 = _interopRequireDefault(_assign); @@ -406,11 +406,11 @@ if (process.env.NODE_ENV !== 'production') { // By explicitly using `prop-types` you are opting into new development behavior. // http://fb.me/prop-types-in-prod var throwOnDirectAccess = true; - module.exports = __webpack_require__(217)(isValidElement, throwOnDirectAccess); + module.exports = __webpack_require__(191)(isValidElement, throwOnDirectAccess); } else { // By explicitly using `prop-types` you are opting into new production behavior. // http://fb.me/prop-types-in-prod - module.exports = __webpack_require__(422)(); + module.exports = __webpack_require__(373)(); } /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) @@ -430,15 +430,15 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); /* harmony export (immutable) */ __webpack_exports__["splitBsPropsAndOmit"] = splitBsPropsAndOmit; /* harmony export (immutable) */ __webpack_exports__["addStyle"] = addStyle; /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_curry", function() { return _curry; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_object_entries__ = __webpack_require__(230); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_object_entries__ = __webpack_require__(204); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_object_entries___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_object_entries__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_extends__ = __webpack_require__(5); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_extends___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_extends__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_invariant__ = __webpack_require__(106); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_invariant__ = __webpack_require__(93); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_invariant___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_invariant__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_prop_types__ = __webpack_require__(8); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_prop_types__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__StyleConfig__ = __webpack_require__(23); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__StyleConfig__ = __webpack_require__(21); // TODO: The publicly exposed parts of this should be in lib/BootstrapUtils. @@ -497,8 +497,7 @@ var bsStyles = curry(function (styles, defaultStyle, Component) { var propType = __WEBPACK_IMPORTED_MODULE_3_prop_types___default.a.oneOf(existing); // expose the values on the propType function for documentation - Component.STYLES = existing; - propType._values = existing; + Component.STYLES = propType._values = existing; Component.propTypes = __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_extends___default()({}, propTypes, { bsStyle: propType @@ -644,20 +643,20 @@ var _curry = curry; // unguarded in another place, it seems safer to define global only for this module !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ - __webpack_require__(99), - __webpack_require__(22), - __webpack_require__(639), - __webpack_require__(182), - __webpack_require__(297), - __webpack_require__(298), - __webpack_require__(183), - __webpack_require__(181), - __webpack_require__(640), - __webpack_require__(184), - __webpack_require__(299), - __webpack_require__(641), - __webpack_require__(62), - __webpack_require__(300) + __webpack_require__(89), + __webpack_require__(20), + __webpack_require__(586), + __webpack_require__(162), + __webpack_require__(272), + __webpack_require__(273), + __webpack_require__(163), + __webpack_require__(161), + __webpack_require__(587), + __webpack_require__(164), + __webpack_require__(274), + __webpack_require__(588), + __webpack_require__(55), + __webpack_require__(275) ], __WEBPACK_AMD_DEFINE_RESULT__ = function( arr, document, getProto, slice, concat, push, indexOf, class2type, toString, hasOwn, fnToString, ObjectFunctionString, support, DOMEval ) { @@ -1117,7 +1116,7 @@ return jQuery; }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(25))) +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(19))) /***/ }), /* 11 */ @@ -1194,7 +1193,7 @@ module.exports = invariant; -var emptyFunction = __webpack_require__(30); +var emptyFunction = __webpack_require__(26); /** * Similar to invariant but only logs a warning if the condition is not met. @@ -1252,573 +1251,6 @@ module.exports = warning; /* 13 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; -/* WEBPACK VAR INJECTION */(function(global) { -Object.defineProperty(exports, "__esModule", { value: true }); -/** - * Random utility functions used in the UI-Router code - * - * These functions are exported, but are subject to change without notice. - * - * @preferred - * @module common - */ -/** for typedoc */ -var predicates_1 = __webpack_require__(16); -var hof_1 = __webpack_require__(17); -var coreservices_1 = __webpack_require__(27); -exports.root = (typeof self === 'object' && self.self === self && self) || - (typeof global === 'object' && global.global === global && global) || this; -var angular = exports.root.angular || {}; -exports.fromJson = angular.fromJson || JSON.parse.bind(JSON); -exports.toJson = angular.toJson || JSON.stringify.bind(JSON); -exports.forEach = angular.forEach || _forEach; -exports.extend = Object.assign || _extend; -exports.equals = angular.equals || _equals; -function identity(x) { return x; } -exports.identity = identity; -function noop() { } -exports.noop = noop; -/** - * Builds proxy functions on the `to` object which pass through to the `from` object. - * - * For each key in `fnNames`, creates a proxy function on the `to` object. - * The proxy function calls the real function on the `from` object. - * - * - * #### Example: - * This example creates an new class instance whose functions are prebound to the new'd object. - * ```js - * class Foo { - * constructor(data) { - * // Binds all functions from Foo.prototype to 'this', - * // then copies them to 'this' - * bindFunctions(Foo.prototype, this, this); - * this.data = data; - * } - * - * log() { - * console.log(this.data); - * } - * } - * - * let myFoo = new Foo([1,2,3]); - * var logit = myFoo.log; - * logit(); // logs [1, 2, 3] from the myFoo 'this' instance - * ``` - * - * #### Example: - * This example creates a bound version of a service function, and copies it to another object - * ``` - * - * var SomeService = { - * this.data = [3, 4, 5]; - * this.log = function() { - * console.log(this.data); - * } - * } - * - * // Constructor fn - * function OtherThing() { - * // Binds all functions from SomeService to SomeService, - * // then copies them to 'this' - * bindFunctions(SomeService, this, SomeService); - * } - * - * let myOtherThing = new OtherThing(); - * myOtherThing.log(); // logs [3, 4, 5] from SomeService's 'this' - * ``` - * - * @param source A function that returns the source object which contains the original functions to be bound - * @param target A function that returns the target object which will receive the bound functions - * @param bind A function that returns the object which the functions will be bound to - * @param fnNames The function names which will be bound (Defaults to all the functions found on the 'from' object) - * @param latebind If true, the binding of the function is delayed until the first time it's invoked - */ -function createProxyFunctions(source, target, bind, fnNames, latebind) { - if (latebind === void 0) { latebind = false; } - var bindFunction = function (fnName) { - return source()[fnName].bind(bind()); - }; - var makeLateRebindFn = function (fnName) { return function lateRebindFunction() { - target[fnName] = bindFunction(fnName); - return target[fnName].apply(null, arguments); - }; }; - fnNames = fnNames || Object.keys(source()); - return fnNames.reduce(function (acc, name) { - acc[name] = latebind ? makeLateRebindFn(name) : bindFunction(name); - return acc; - }, target); -} -exports.createProxyFunctions = createProxyFunctions; -/** - * prototypal inheritance helper. - * Creates a new object which has `parent` object as its prototype, and then copies the properties from `extra` onto it - */ -exports.inherit = function (parent, extra) { - return exports.extend(Object.create(parent), extra); -}; -/** Given an array, returns true if the object is found in the array, (using indexOf) */ -exports.inArray = hof_1.curry(_inArray); -function _inArray(array, obj) { - return array.indexOf(obj) !== -1; -} -exports._inArray = _inArray; -/** - * Given an array, and an item, if the item is found in the array, it removes it (in-place). - * The same array is returned - */ -exports.removeFrom = hof_1.curry(_removeFrom); -function _removeFrom(array, obj) { - var idx = array.indexOf(obj); - if (idx >= 0) - array.splice(idx, 1); - return array; -} -exports._removeFrom = _removeFrom; -/** pushes a values to an array and returns the value */ -exports.pushTo = hof_1.curry(_pushTo); -function _pushTo(arr, val) { - return (arr.push(val), val); -} -exports._pushTo = _pushTo; -/** Given an array of (deregistration) functions, calls all functions and removes each one from the source array */ -exports.deregAll = function (functions) { - return functions.slice().forEach(function (fn) { - typeof fn === 'function' && fn(); - exports.removeFrom(functions, fn); - }); -}; -/** - * Applies a set of defaults to an options object. The options object is filtered - * to only those properties of the objects in the defaultsList. - * Earlier objects in the defaultsList take precedence when applying defaults. - */ -function defaults(opts) { - var defaultsList = []; - for (var _i = 1; _i < arguments.length; _i++) { - defaultsList[_i - 1] = arguments[_i]; - } - var _defaultsList = defaultsList.concat({}).reverse(); - var defaultVals = exports.extend.apply(null, _defaultsList); - return exports.extend({}, defaultVals, pick(opts || {}, Object.keys(defaultVals))); -} -exports.defaults = defaults; -/** Reduce function that merges each element of the list into a single object, using extend */ -exports.mergeR = function (memo, item) { return exports.extend(memo, item); }; -/** - * Finds the common ancestor path between two states. - * - * @param {Object} first The first state. - * @param {Object} second The second state. - * @return {Array} Returns an array of state names in descending order, not including the root. - */ -function ancestors(first, second) { - var path = []; - for (var n in first.path) { - if (first.path[n] !== second.path[n]) - break; - path.push(first.path[n]); - } - return path; -} -exports.ancestors = ancestors; -/** - * Return a copy of the object only containing the whitelisted properties. - * - * #### Example: - * ``` - * var foo = { a: 1, b: 2, c: 3 }; - * var ab = pick(foo, ['a', 'b']); // { a: 1, b: 2 } - * ``` - * @param obj the source object - * @param propNames an Array of strings, which are the whitelisted property names - */ -function pick(obj, propNames) { - var objCopy = {}; - for (var prop_1 in obj) { - if (propNames.indexOf(prop_1) !== -1) { - objCopy[prop_1] = obj[prop_1]; - } - } - return objCopy; -} -exports.pick = pick; -/** - * Return a copy of the object omitting the blacklisted properties. - * - * @example - * ``` - * - * var foo = { a: 1, b: 2, c: 3 }; - * var ab = omit(foo, ['a', 'b']); // { c: 3 } - * ``` - * @param obj the source object - * @param propNames an Array of strings, which are the blacklisted property names - */ -function omit(obj, propNames) { - return Object.keys(obj) - .filter(hof_1.not(exports.inArray(propNames))) - .reduce(function (acc, key) { return (acc[key] = obj[key], acc); }, {}); -} -exports.omit = omit; -/** - * Maps an array, or object to a property (by name) - */ -function pluck(collection, propName) { - return map(collection, hof_1.prop(propName)); -} -exports.pluck = pluck; -/** Filters an Array or an Object's properties based on a predicate */ -function filter(collection, callback) { - var arr = predicates_1.isArray(collection), result = arr ? [] : {}; - var accept = arr ? function (x) { return result.push(x); } : function (x, key) { return result[key] = x; }; - exports.forEach(collection, function (item, i) { - if (callback(item, i)) - accept(item, i); - }); - return result; -} -exports.filter = filter; -/** Finds an object from an array, or a property of an object, that matches a predicate */ -function find(collection, callback) { - var result; - exports.forEach(collection, function (item, i) { - if (result) - return; - if (callback(item, i)) - result = item; - }); - return result; -} -exports.find = find; -/** Given an object, returns a new object, where each property is transformed by the callback function */ -exports.mapObj = map; -/** Maps an array or object properties using a callback function */ -function map(collection, callback) { - var result = predicates_1.isArray(collection) ? [] : {}; - exports.forEach(collection, function (item, i) { return result[i] = callback(item, i); }); - return result; -} -exports.map = map; -/** - * Given an object, return its enumerable property values - * - * @example - * ``` - * - * let foo = { a: 1, b: 2, c: 3 } - * let vals = values(foo); // [ 1, 2, 3 ] - * ``` - */ -exports.values = function (obj) { - return Object.keys(obj).map(function (key) { return obj[key]; }); -}; -/** - * Reduce function that returns true if all of the values are truthy. - * - * @example - * ``` - * - * let vals = [ 1, true, {}, "hello world"]; - * vals.reduce(allTrueR, true); // true - * - * vals.push(0); - * vals.reduce(allTrueR, true); // false - * ``` - */ -exports.allTrueR = function (memo, elem) { return memo && elem; }; -/** - * Reduce function that returns true if any of the values are truthy. - * - * * @example - * ``` - * - * let vals = [ 0, null, undefined ]; - * vals.reduce(anyTrueR, true); // false - * - * vals.push("hello world"); - * vals.reduce(anyTrueR, true); // true - * ``` - */ -exports.anyTrueR = function (memo, elem) { return memo || elem; }; -/** - * Reduce function which un-nests a single level of arrays - * @example - * ``` - * - * let input = [ [ "a", "b" ], [ "c", "d" ], [ [ "double", "nested" ] ] ]; - * input.reduce(unnestR, []) // [ "a", "b", "c", "d", [ "double, "nested" ] ] - * ``` - */ -exports.unnestR = function (memo, elem) { return memo.concat(elem); }; -/** - * Reduce function which recursively un-nests all arrays - * - * @example - * ``` - * - * let input = [ [ "a", "b" ], [ "c", "d" ], [ [ "double", "nested" ] ] ]; - * input.reduce(unnestR, []) // [ "a", "b", "c", "d", "double, "nested" ] - * ``` - */ -exports.flattenR = function (memo, elem) { - return predicates_1.isArray(elem) ? memo.concat(elem.reduce(exports.flattenR, [])) : pushR(memo, elem); -}; -/** - * Reduce function that pushes an object to an array, then returns the array. - * Mostly just for [[flattenR]] and [[uniqR]] - */ -function pushR(arr, obj) { - arr.push(obj); - return arr; -} -exports.pushR = pushR; -/** Reduce function that filters out duplicates */ -exports.uniqR = function (acc, token) { - return exports.inArray(acc, token) ? acc : pushR(acc, token); -}; -/** - * Return a new array with a single level of arrays unnested. - * - * @example - * ``` - * - * let input = [ [ "a", "b" ], [ "c", "d" ], [ [ "double", "nested" ] ] ]; - * unnest(input) // [ "a", "b", "c", "d", [ "double, "nested" ] ] - * ``` - */ -exports.unnest = function (arr) { return arr.reduce(exports.unnestR, []); }; -/** - * Return a completely flattened version of an array. - * - * @example - * ``` - * - * let input = [ [ "a", "b" ], [ "c", "d" ], [ [ "double", "nested" ] ] ]; - * flatten(input) // [ "a", "b", "c", "d", "double, "nested" ] - * ``` - */ -exports.flatten = function (arr) { return arr.reduce(exports.flattenR, []); }; -/** - * Given a .filter Predicate, builds a .filter Predicate which throws an error if any elements do not pass. - * @example - * ``` - * - * let isNumber = (obj) => typeof(obj) === 'number'; - * let allNumbers = [ 1, 2, 3, 4, 5 ]; - * allNumbers.filter(assertPredicate(isNumber)); //OK - * - * let oneString = [ 1, 2, 3, 4, "5" ]; - * oneString.filter(assertPredicate(isNumber, "Not all numbers")); // throws Error(""Not all numbers""); - * ``` - */ -exports.assertPredicate = assertFn; -/** - * Given a .map function, builds a .map function which throws an error if any mapped elements do not pass a truthyness test. - * @example - * ``` - * - * var data = { foo: 1, bar: 2 }; - * - * let keys = [ 'foo', 'bar' ] - * let values = keys.map(assertMap(key => data[key], "Key not found")); - * // values is [1, 2] - * - * let keys = [ 'foo', 'bar', 'baz' ] - * let values = keys.map(assertMap(key => data[key], "Key not found")); - * // throws Error("Key not found") - * ``` - */ -exports.assertMap = assertFn; -function assertFn(predicateOrMap, errMsg) { - if (errMsg === void 0) { errMsg = "assert failure"; } - return function (obj) { - var result = predicateOrMap(obj); - if (!result) { - throw new Error(predicates_1.isFunction(errMsg) ? errMsg(obj) : errMsg); - } - return result; - }; -} -exports.assertFn = assertFn; -/** - * Like _.pairs: Given an object, returns an array of key/value pairs - * - * @example - * ``` - * - * pairs({ foo: "FOO", bar: "BAR }) // [ [ "foo", "FOO" ], [ "bar": "BAR" ] ] - * ``` - */ -exports.pairs = function (obj) { - return Object.keys(obj).map(function (key) { return [key, obj[key]]; }); -}; -/** - * Given two or more parallel arrays, returns an array of tuples where - * each tuple is composed of [ a[i], b[i], ... z[i] ] - * - * @example - * ``` - * - * let foo = [ 0, 2, 4, 6 ]; - * let bar = [ 1, 3, 5, 7 ]; - * let baz = [ 10, 30, 50, 70 ]; - * arrayTuples(foo, bar); // [ [0, 1], [2, 3], [4, 5], [6, 7] ] - * arrayTuples(foo, bar, baz); // [ [0, 1, 10], [2, 3, 30], [4, 5, 50], [6, 7, 70] ] - * ``` - */ -function arrayTuples() { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - if (args.length === 0) - return []; - var maxArrayLen = args.reduce(function (min, arr) { return Math.min(arr.length, min); }, 9007199254740991); // aka 2^53 − 1 aka Number.MAX_SAFE_INTEGER - var i, result = []; - for (i = 0; i < maxArrayLen; i++) { - // This is a hot function - // Unroll when there are 1-4 arguments - switch (args.length) { - case 1: - result.push([args[0][i]]); - break; - case 2: - result.push([args[0][i], args[1][i]]); - break; - case 3: - result.push([args[0][i], args[1][i], args[2][i]]); - break; - case 4: - result.push([args[0][i], args[1][i], args[2][i], args[3][i]]); - break; - default: - result.push(args.map(function (array) { return array[i]; })); - break; - } - } - return result; -} -exports.arrayTuples = arrayTuples; -/** - * Reduce function which builds an object from an array of [key, value] pairs. - * - * Each iteration sets the key/val pair on the memo object, then returns the memo for the next iteration. - * - * Each keyValueTuple should be an array with values [ key: string, value: any ] - * - * @example - * ``` - * - * var pairs = [ ["fookey", "fooval"], ["barkey", "barval"] ] - * - * var pairsToObj = pairs.reduce((memo, pair) => applyPairs(memo, pair), {}) - * // pairsToObj == { fookey: "fooval", barkey: "barval" } - * - * // Or, more simply: - * var pairsToObj = pairs.reduce(applyPairs, {}) - * // pairsToObj == { fookey: "fooval", barkey: "barval" } - * ``` - */ -function applyPairs(memo, keyValTuple) { - var key, value; - if (predicates_1.isArray(keyValTuple)) - key = keyValTuple[0], value = keyValTuple[1]; - if (!predicates_1.isString(key)) - throw new Error("invalid parameters to applyPairs"); - memo[key] = value; - return memo; -} -exports.applyPairs = applyPairs; -/** Get the last element of an array */ -function tail(arr) { - return arr.length && arr[arr.length - 1] || undefined; -} -exports.tail = tail; -/** - * shallow copy from src to dest - */ -function copy(src, dest) { - if (dest) - Object.keys(dest).forEach(function (key) { return delete dest[key]; }); - if (!dest) - dest = {}; - return exports.extend(dest, src); -} -exports.copy = copy; -/** Naive forEach implementation works with Objects or Arrays */ -function _forEach(obj, cb, _this) { - if (predicates_1.isArray(obj)) - return obj.forEach(cb, _this); - Object.keys(obj).forEach(function (key) { return cb(obj[key], key); }); -} -function _extend(toObj) { - for (var i = 1; i < arguments.length; i++) { - var obj = arguments[i]; - if (!obj) - continue; - var keys = Object.keys(obj); - for (var j = 0; j < keys.length; j++) { - toObj[keys[j]] = obj[keys[j]]; - } - } - return toObj; -} -exports._extend = _extend; -function _equals(o1, o2) { - if (o1 === o2) - return true; - if (o1 === null || o2 === null) - return false; - if (o1 !== o1 && o2 !== o2) - return true; // NaN === NaN - var t1 = typeof o1, t2 = typeof o2; - if (t1 !== t2 || t1 !== 'object') - return false; - var tup = [o1, o2]; - if (hof_1.all(predicates_1.isArray)(tup)) - return _arraysEq(o1, o2); - if (hof_1.all(predicates_1.isDate)(tup)) - return o1.getTime() === o2.getTime(); - if (hof_1.all(predicates_1.isRegExp)(tup)) - return o1.toString() === o2.toString(); - if (hof_1.all(predicates_1.isFunction)(tup)) - return true; // meh - var predicates = [predicates_1.isFunction, predicates_1.isArray, predicates_1.isDate, predicates_1.isRegExp]; - if (predicates.map(hof_1.any).reduce(function (b, fn) { return b || !!fn(tup); }, false)) - return false; - var key, keys = {}; - for (key in o1) { - if (!_equals(o1[key], o2[key])) - return false; - keys[key] = true; - } - for (key in o2) { - if (!keys[key]) - return false; - } - return true; -} -function _arraysEq(a1, a2) { - if (a1.length !== a2.length) - return false; - return arrayTuples(a1, a2).reduce(function (b, t) { return b && _equals(t[0], t[1]); }, true); -} -// issue #2676 -exports.silenceUncaughtInPromise = function (promise) { - return promise.catch(function (e) { return 0; }) && promise; -}; -exports.silentRejection = function (error) { - return exports.silenceUncaughtInPromise(coreservices_1.services.$q.reject(error)); -}; -//# sourceMappingURL=common.js.map -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(134))) - -/***/ }), -/* 14 */ -/***/ (function(module, exports, __webpack_require__) { - "use strict"; /** * Copyright (c) 2013-present, Facebook, Inc. @@ -1858,7 +1290,7 @@ function reactProdInvariant(code) { module.exports = reactProdInvariant; /***/ }), -/* 15 */ +/* 14 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -1874,7 +1306,7 @@ var _react = __webpack_require__(0); var _react2 = _interopRequireDefault(_react); -var _createChainableTypeChecker = __webpack_require__(107); +var _createChainableTypeChecker = __webpack_require__(132); var _createChainableTypeChecker2 = _interopRequireDefault(_createChainableTypeChecker); @@ -1899,311 +1331,7 @@ exports.default = (0, _createChainableTypeChecker2.default)(elementType); module.exports = exports['default']; /***/ }), -/* 16 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -/** Predicates - * - * These predicates return true/false based on the input. - * Although these functions are exported, they are subject to change without notice. - * - * @module common_predicates - */ -/** */ -var hof_1 = __webpack_require__(17); -var stateObject_1 = __webpack_require__(197); -var toStr = Object.prototype.toString; -var tis = function (t) { return function (x) { return typeof (x) === t; }; }; -exports.isUndefined = tis('undefined'); -exports.isDefined = hof_1.not(exports.isUndefined); -exports.isNull = function (o) { return o === null; }; -exports.isNullOrUndefined = hof_1.or(exports.isNull, exports.isUndefined); -exports.isFunction = tis('function'); -exports.isNumber = tis('number'); -exports.isString = tis('string'); -exports.isObject = function (x) { return x !== null && typeof x === 'object'; }; -exports.isArray = Array.isArray; -exports.isDate = (function (x) { return toStr.call(x) === '[object Date]'; }); -exports.isRegExp = (function (x) { return toStr.call(x) === '[object RegExp]'; }); -exports.isState = stateObject_1.StateObject.isState; -/** - * Predicate which checks if a value is injectable - * - * A value is "injectable" if it is a function, or if it is an ng1 array-notation-style array - * where all the elements in the array are Strings, except the last one, which is a Function - */ -function isInjectable(val) { - if (exports.isArray(val) && val.length) { - var head = val.slice(0, -1), tail = val.slice(-1); - return !(head.filter(hof_1.not(exports.isString)).length || tail.filter(hof_1.not(exports.isFunction)).length); - } - return exports.isFunction(val); -} -exports.isInjectable = isInjectable; -/** - * Predicate which checks if a value looks like a Promise - * - * It is probably a Promise if it's an object, and it has a `then` property which is a Function - */ -exports.isPromise = hof_1.and(exports.isObject, hof_1.pipe(hof_1.prop('then'), exports.isFunction)); -//# sourceMappingURL=predicates.js.map - -/***/ }), -/* 17 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -/** - * Higher order functions - * - * These utility functions are exported, but are subject to change without notice. - * - * @module common_hof - */ /** */ -Object.defineProperty(exports, "__esModule", { value: true }); -/** - * Returns a new function for [Partial Application](https://en.wikipedia.org/wiki/Partial_application) of the original function. - * - * Given a function with N parameters, returns a new function that supports partial application. - * The new function accepts anywhere from 1 to N parameters. When that function is called with M parameters, - * where M is less than N, it returns a new function that accepts the remaining parameters. It continues to - * accept more parameters until all N parameters have been supplied. - * - * - * This contrived example uses a partially applied function as an predicate, which returns true - * if an object is found in both arrays. - * @example - * ``` - * // returns true if an object is in both of the two arrays - * function inBoth(array1, array2, object) { - * return array1.indexOf(object) !== -1 && - * array2.indexOf(object) !== 1; - * } - * let obj1, obj2, obj3, obj4, obj5, obj6, obj7 - * let foos = [obj1, obj3] - * let bars = [obj3, obj4, obj5] - * - * // A curried "copy" of inBoth - * let curriedInBoth = curry(inBoth); - * // Partially apply both the array1 and array2 - * let inFoosAndBars = curriedInBoth(foos, bars); - * - * // Supply the final argument; since all arguments are - * // supplied, the original inBoth function is then called. - * let obj1InBoth = inFoosAndBars(obj1); // false - * - * // Use the inFoosAndBars as a predicate. - * // Filter, on each iteration, supplies the final argument - * let allObjs = [ obj1, obj2, obj3, obj4, obj5, obj6, obj7 ]; - * let foundInBoth = allObjs.filter(inFoosAndBars); // [ obj3 ] - * - * ``` - * - * Stolen from: http://stackoverflow.com/questions/4394747/javascript-curry-function - * - * @param fn - * @returns {*|function(): (*|any)} - */ -function curry(fn) { - var initial_args = [].slice.apply(arguments, [1]); - var func_args_length = fn.length; - function curried(args) { - if (args.length >= func_args_length) - return fn.apply(null, args); - return function () { - return curried(args.concat([].slice.apply(arguments))); - }; - } - return curried(initial_args); -} -exports.curry = curry; -/** - * Given a varargs list of functions, returns a function that composes the argument functions, right-to-left - * given: f(x), g(x), h(x) - * let composed = compose(f,g,h) - * then, composed is: f(g(h(x))) - */ -function compose() { - var args = arguments; - var start = args.length - 1; - return function () { - var i = start, result = args[start].apply(this, arguments); - while (i--) - result = args[i].call(this, result); - return result; - }; -} -exports.compose = compose; -/** - * Given a varargs list of functions, returns a function that is composes the argument functions, left-to-right - * given: f(x), g(x), h(x) - * let piped = pipe(f,g,h); - * then, piped is: h(g(f(x))) - */ -function pipe() { - var funcs = []; - for (var _i = 0; _i < arguments.length; _i++) { - funcs[_i] = arguments[_i]; - } - return compose.apply(null, [].slice.call(arguments).reverse()); -} -exports.pipe = pipe; -/** - * Given a property name, returns a function that returns that property from an object - * let obj = { foo: 1, name: "blarg" }; - * let getName = prop("name"); - * getName(obj) === "blarg" - */ -exports.prop = function (name) { - return function (obj) { return obj && obj[name]; }; -}; -/** - * Given a property name and a value, returns a function that returns a boolean based on whether - * the passed object has a property that matches the value - * let obj = { foo: 1, name: "blarg" }; - * let getName = propEq("name", "blarg"); - * getName(obj) === true - */ -exports.propEq = curry(function (name, val, obj) { return obj && obj[name] === val; }); -/** - * Given a dotted property name, returns a function that returns a nested property from an object, or undefined - * let obj = { id: 1, nestedObj: { foo: 1, name: "blarg" }, }; - * let getName = prop("nestedObj.name"); - * getName(obj) === "blarg" - * let propNotFound = prop("this.property.doesnt.exist"); - * propNotFound(obj) === undefined - */ -exports.parse = function (name) { - return pipe.apply(null, name.split(".").map(exports.prop)); -}; -/** - * Given a function that returns a truthy or falsey value, returns a - * function that returns the opposite (falsey or truthy) value given the same inputs - */ -exports.not = function (fn) { - return function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - return !fn.apply(null, args); - }; -}; -/** - * Given two functions that return truthy or falsey values, returns a function that returns truthy - * if both functions return truthy for the given arguments - */ -function and(fn1, fn2) { - return function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - return fn1.apply(null, args) && fn2.apply(null, args); - }; -} -exports.and = and; -/** - * Given two functions that return truthy or falsey values, returns a function that returns truthy - * if at least one of the functions returns truthy for the given arguments - */ -function or(fn1, fn2) { - return function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - return fn1.apply(null, args) || fn2.apply(null, args); - }; -} -exports.or = or; -/** - * Check if all the elements of an array match a predicate function - * - * @param fn1 a predicate function `fn1` - * @returns a function which takes an array and returns true if `fn1` is true for all elements of the array - */ -exports.all = function (fn1) { - return function (arr) { return arr.reduce(function (b, x) { return b && !!fn1(x); }, true); }; -}; -exports.any = function (fn1) { - return function (arr) { return arr.reduce(function (b, x) { return b || !!fn1(x); }, false); }; -}; -/** Given a class, returns a Predicate function that returns true if the object is of that class */ -exports.is = function (ctor) { - return function (obj) { - return (obj != null && obj.constructor === ctor || obj instanceof ctor); - }; -}; -/** Given a value, returns a Predicate function that returns true if another value is === equal to the original value */ -exports.eq = function (val) { return function (other) { - return val === other; -}; }; -/** Given a value, returns a function which returns the value */ -exports.val = function (v) { return function () { return v; }; }; -function invoke(fnName, args) { - return function (obj) { - return obj[fnName].apply(obj, args); - }; -} -exports.invoke = invoke; -/** - * Sorta like Pattern Matching (a functional programming conditional construct) - * - * See http://c2.com/cgi/wiki?PatternMatching - * - * This is a conditional construct which allows a series of predicates and output functions - * to be checked and then applied. Each predicate receives the input. If the predicate - * returns truthy, then its matching output function (mapping function) is provided with - * the input and, then the result is returned. - * - * Each combination (2-tuple) of predicate + output function should be placed in an array - * of size 2: [ predicate, mapFn ] - * - * These 2-tuples should be put in an outer array. - * - * @example - * ``` - * - * // Here's a 2-tuple where the first element is the isString predicate - * // and the second element is a function that returns a description of the input - * let firstTuple = [ angular.isString, (input) => `Heres your string ${input}` ]; - * - * // Second tuple: predicate "isNumber", mapfn returns a description - * let secondTuple = [ angular.isNumber, (input) => `(${input}) That's a number!` ]; - * - * let third = [ (input) => input === null, (input) => `Oh, null...` ]; - * - * let fourth = [ (input) => input === undefined, (input) => `notdefined` ]; - * - * let descriptionOf = pattern([ firstTuple, secondTuple, third, fourth ]); - * - * console.log(descriptionOf(undefined)); // 'notdefined' - * console.log(descriptionOf(55)); // '(55) That's a number!' - * console.log(descriptionOf("foo")); // 'Here's your string foo' - * ``` - * - * @param struct A 2D array. Each element of the array should be an array, a 2-tuple, - * with a Predicate and a mapping/output function - * @returns {function(any): *} - */ -function pattern(struct) { - return function (x) { - for (var i = 0; i < struct.length; i++) { - if (struct[i][0](x)) - return struct[i][1](x); - } - }; -} -exports.pattern = pattern; -//# sourceMappingURL=hof.js.map - -/***/ }), -/* 18 */ +/* 15 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -2300,7 +1428,7 @@ module.exports = shouldUseNative() ? Object.assign : function (target, source) { /***/ }), -/* 19 */ +/* 16 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -2314,10 +1442,10 @@ module.exports = shouldUseNative() ? Object.assign : function (target, source) { -var _prodInvariant = __webpack_require__(14); +var _prodInvariant = __webpack_require__(13); -var DOMProperty = __webpack_require__(50); -var ReactDOMComponentFlags = __webpack_require__(234); +var DOMProperty = __webpack_require__(44); +var ReactDOMComponentFlags = __webpack_require__(208); var invariant = __webpack_require__(11); @@ -2499,7 +1627,7 @@ module.exports = ReactDOMComponentTree; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 20 */ +/* 17 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -2542,7 +1670,7 @@ function createChainedFunction() { /* harmony default export */ __webpack_exports__["a"] = (createChainedFunction); /***/ }), -/* 21 */ +/* 18 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -2581,7 +1709,55 @@ var ExecutionEnvironment = { module.exports = ExecutionEnvironment; /***/ }), -/* 22 */ +/* 19 */ +/***/ (function(module, exports, __webpack_require__) { + +var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ + __webpack_require__(10), + __webpack_require__(22), + __webpack_require__(70), + __webpack_require__(170), + __webpack_require__(69), + __webpack_require__(594), + __webpack_require__(285), + __webpack_require__(595), + __webpack_require__(172), + __webpack_require__(596), + __webpack_require__(600), + __webpack_require__(71), + __webpack_require__(604), + __webpack_require__(605), + __webpack_require__(110), + __webpack_require__(607), + __webpack_require__(610), + __webpack_require__(88), + __webpack_require__(611), + __webpack_require__(299), + __webpack_require__(72), + __webpack_require__(612), + __webpack_require__(613), + __webpack_require__(614), + __webpack_require__(615), + __webpack_require__(618), + __webpack_require__(173), + __webpack_require__(619), + __webpack_require__(620), + __webpack_require__(621), + __webpack_require__(622), + __webpack_require__(623), + __webpack_require__(624) +], __WEBPACK_AMD_DEFINE_RESULT__ = function( jQuery ) { + +"use strict"; + +return jQuery; + +}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), + __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }), +/* 20 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function() { @@ -2593,7 +1769,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function() { /***/ }), -/* 23 */ +/* 21 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -2636,92 +1812,17 @@ var Style = { }; /***/ }), -/* 24 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = __webpack_require__(433); - - -/***/ }), -/* 25 */ -/***/ (function(module, exports, __webpack_require__) { - -var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ - __webpack_require__(10), - __webpack_require__(26), - __webpack_require__(78), - __webpack_require__(190), - __webpack_require__(77), - __webpack_require__(647), - __webpack_require__(310), - __webpack_require__(648), - __webpack_require__(192), - __webpack_require__(649), - __webpack_require__(653), - __webpack_require__(79), - __webpack_require__(657), - __webpack_require__(658), - __webpack_require__(127), - __webpack_require__(660), - __webpack_require__(663), - __webpack_require__(98), - __webpack_require__(664), - __webpack_require__(324), - __webpack_require__(80), - __webpack_require__(665), - __webpack_require__(666), - __webpack_require__(667), - __webpack_require__(668), - __webpack_require__(671), - __webpack_require__(193), - __webpack_require__(672), - __webpack_require__(673), - __webpack_require__(674), - __webpack_require__(675), - __webpack_require__(676), - __webpack_require__(677) -], __WEBPACK_AMD_DEFINE_RESULT__ = function( jQuery ) { - -"use strict"; - -return jQuery; - -}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), - __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - - -/***/ }), -/* 26 */ +/* 22 */ /***/ (function(module, exports, __webpack_require__) { -var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(642) ], __WEBPACK_AMD_DEFINE_RESULT__ = function() { +var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(589) ], __WEBPACK_AMD_DEFINE_RESULT__ = function() { "use strict"; }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); /***/ }), -/* 27 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -exports.notImplemented = function (fnname) { return function () { - throw new Error(fnname + "(): No coreservices implementation for UI-Router is loaded."); -}; }; -var services = { - $q: undefined, - $injector: undefined, -}; -exports.services = services; -//# sourceMappingURL=coreservices.js.map - -/***/ }), -/* 28 */ +/* 23 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -2828,7 +1929,7 @@ function filter(children, func, context) { function find(children, func, context) { var index = 0; - var result = void 0; + var result = undefined; __WEBPACK_IMPORTED_MODULE_0_react___default.a.Children.forEach(children, function (child) { if (result) { @@ -2912,7 +2013,17 @@ function toArray(children) { }); /***/ }), -/* 29 */ +/* 24 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = __webpack_require__(384); + + +/***/ }), +/* 25 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -2927,9 +2038,9 @@ function toArray(children) { -var _prodInvariant = __webpack_require__(67); +var _prodInvariant = __webpack_require__(60); -var ReactCurrentOwner = __webpack_require__(37); +var ReactCurrentOwner = __webpack_require__(32); var invariant = __webpack_require__(11); var warning = __webpack_require__(12); @@ -3295,7 +2406,7 @@ module.exports = ReactComponentTreeHook; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 30 */ +/* 26 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3337,7 +2448,7 @@ emptyFunction.thatReturnsArgument = function (arg) { module.exports = emptyFunction; /***/ }), -/* 31 */ +/* 27 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3357,7 +2468,7 @@ module.exports = emptyFunction; var debugTool = null; if (process.env.NODE_ENV !== 'production') { - var ReactDebugTool = __webpack_require__(443); + var ReactDebugTool = __webpack_require__(394); debugTool = ReactDebugTool; } @@ -3365,82 +2476,14 @@ module.exports = { debugTool: debugTool }; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 32 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - - - -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -var warning = function() {}; - -if (process.env.NODE_ENV !== 'production') { - warning = function(condition, format, args) { - var len = arguments.length; - args = new Array(len > 2 ? len - 2 : 0); - for (var key = 2; key < len; key++) { - args[key - 2] = arguments[key]; - } - if (format === undefined) { - throw new Error( - '`warning(condition, format, ...args)` requires a warning ' + - 'message argument' - ); - } - - if (format.length < 10 || (/^[s\W]*$/).test(format)) { - throw new Error( - 'The warning format should be able to uniquely identify this ' + - 'warning. Please, use a more descriptive format than: ' + format - ); - } - - if (!condition) { - var argIndex = 0; - var message = 'Warning: ' + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); - if (typeof console !== 'undefined') { - console.error(message); - } - try { - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - throw new Error(message); - } catch(x) {} - } - }; -} - -module.exports = warning; - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) - -/***/ }), -/* 33 */ +/* 28 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var bind = __webpack_require__(288); -var isBuffer = __webpack_require__(615); +var bind = __webpack_require__(264); +var isBuffer = __webpack_require__(563); /*global toString:true*/ @@ -3743,16 +2786,84 @@ module.exports = { /***/ }), -/* 34 */ +/* 29 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(process) {/** + * Copyright 2014-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + + + +/** + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ + +var warning = function() {}; + +if (process.env.NODE_ENV !== 'production') { + warning = function(condition, format, args) { + var len = arguments.length; + args = new Array(len > 2 ? len - 2 : 0); + for (var key = 2; key < len; key++) { + args[key - 2] = arguments[key]; + } + if (format === undefined) { + throw new Error( + '`warning(condition, format, ...args)` requires a warning ' + + 'message argument' + ); + } + + if (format.length < 10 || (/^[s\W]*$/).test(format)) { + throw new Error( + 'The warning format should be able to uniquely identify this ' + + 'warning. Please, use a more descriptive format than: ' + format + ); + } + + if (!condition) { + var argIndex = 0; + var message = 'Warning: ' + + format.replace(/%s/g, function() { + return args[argIndex++]; + }); + if (typeof console !== 'undefined') { + console.error(message); + } + try { + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch(x) {} + } + }; +} + +module.exports = warning; + +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) + +/***/ }), +/* 30 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// Initialize a jQuery object !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(10), - __webpack_require__(22), - __webpack_require__(307), + __webpack_require__(20), + __webpack_require__(282), - __webpack_require__(308) + __webpack_require__(283) ], __WEBPACK_AMD_DEFINE_RESULT__ = function( jQuery, document, rsingleTag ) { "use strict"; @@ -3878,28 +2989,7 @@ return init; /***/ }), -/* 35 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; -} -Object.defineProperty(exports, "__esModule", { value: true }); -/** @module common */ /** for typedoc */ -__export(__webpack_require__(13)); -__export(__webpack_require__(27)); -__export(__webpack_require__(128)); -__export(__webpack_require__(17)); -__export(__webpack_require__(16)); -__export(__webpack_require__(198)); -__export(__webpack_require__(44)); -__export(__webpack_require__(54)); -//# sourceMappingURL=index.js.map - -/***/ }), -/* 36 */ +/* 31 */ /***/ (function(module, exports, __webpack_require__) { // This method of obtaining a reference to the global object needs to be @@ -3917,7 +3007,7 @@ var oldRuntime = hadRuntime && g.regeneratorRuntime; // Force reevalutation of runtime.js. g.regeneratorRuntime = undefined; -module.exports = __webpack_require__(372); +module.exports = __webpack_require__(323); if (hadRuntime) { // Restore the original runtime. @@ -3933,7 +3023,7 @@ if (hadRuntime) { /***/ }), -/* 37 */ +/* 32 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3965,152 +3055,152 @@ var ReactCurrentOwner = { module.exports = ReactCurrentOwner; /***/ }), -/* 38 */ +/* 33 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Accordion__ = __webpack_require__(387); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Accordion__ = __webpack_require__(338); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Accordion", function() { return __WEBPACK_IMPORTED_MODULE_0__Accordion__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Alert__ = __webpack_require__(425); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Alert__ = __webpack_require__(376); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Alert", function() { return __WEBPACK_IMPORTED_MODULE_1__Alert__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Badge__ = __webpack_require__(428); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Badge__ = __webpack_require__(379); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Badge", function() { return __WEBPACK_IMPORTED_MODULE_2__Badge__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Breadcrumb__ = __webpack_require__(429); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Breadcrumb__ = __webpack_require__(380); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Breadcrumb", function() { return __WEBPACK_IMPORTED_MODULE_3__Breadcrumb__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__BreadcrumbItem__ = __webpack_require__(232); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__BreadcrumbItem__ = __webpack_require__(206); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "BreadcrumbItem", function() { return __WEBPACK_IMPORTED_MODULE_4__BreadcrumbItem__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Button__ = __webpack_require__(91); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Button__ = __webpack_require__(80); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Button", function() { return __WEBPACK_IMPORTED_MODULE_5__Button__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__ButtonGroup__ = __webpack_require__(156); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__ButtonGroup__ = __webpack_require__(133); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "ButtonGroup", function() { return __WEBPACK_IMPORTED_MODULE_6__ButtonGroup__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__ButtonToolbar__ = __webpack_require__(430); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__ButtonToolbar__ = __webpack_require__(381); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "ButtonToolbar", function() { return __WEBPACK_IMPORTED_MODULE_7__ButtonToolbar__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__Carousel__ = __webpack_require__(431); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__Carousel__ = __webpack_require__(382); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Carousel", function() { return __WEBPACK_IMPORTED_MODULE_8__Carousel__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__CarouselItem__ = __webpack_require__(233); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__CarouselItem__ = __webpack_require__(207); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "CarouselItem", function() { return __WEBPACK_IMPORTED_MODULE_9__CarouselItem__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__Checkbox__ = __webpack_require__(519); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__Checkbox__ = __webpack_require__(470); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Checkbox", function() { return __WEBPACK_IMPORTED_MODULE_10__Checkbox__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__Clearfix__ = __webpack_require__(520); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__Clearfix__ = __webpack_require__(471); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Clearfix", function() { return __WEBPACK_IMPORTED_MODULE_11__Clearfix__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__CloseButton__ = __webpack_require__(155); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__CloseButton__ = __webpack_require__(131); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "CloseButton", function() { return __WEBPACK_IMPORTED_MODULE_12__CloseButton__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__ControlLabel__ = __webpack_require__(521); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__ControlLabel__ = __webpack_require__(472); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "ControlLabel", function() { return __WEBPACK_IMPORTED_MODULE_13__ControlLabel__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__Col__ = __webpack_require__(522); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__Col__ = __webpack_require__(473); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Col", function() { return __WEBPACK_IMPORTED_MODULE_14__Col__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15__Collapse__ = __webpack_require__(174); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15__Collapse__ = __webpack_require__(151); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Collapse", function() { return __WEBPACK_IMPORTED_MODULE_15__Collapse__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16__Dropdown__ = __webpack_require__(117); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16__Dropdown__ = __webpack_require__(103); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Dropdown", function() { return __WEBPACK_IMPORTED_MODULE_16__Dropdown__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_17__DropdownButton__ = __webpack_require__(542); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_17__DropdownButton__ = __webpack_require__(493); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "DropdownButton", function() { return __WEBPACK_IMPORTED_MODULE_17__DropdownButton__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_18__Fade__ = __webpack_require__(120); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_18__Fade__ = __webpack_require__(106); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Fade", function() { return __WEBPACK_IMPORTED_MODULE_18__Fade__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_19__Form__ = __webpack_require__(543); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_19__Form__ = __webpack_require__(494); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Form", function() { return __WEBPACK_IMPORTED_MODULE_19__Form__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_20__FormControl__ = __webpack_require__(544); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_20__FormControl__ = __webpack_require__(495); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "FormControl", function() { return __WEBPACK_IMPORTED_MODULE_20__FormControl__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_21__FormGroup__ = __webpack_require__(547); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_21__FormGroup__ = __webpack_require__(498); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "FormGroup", function() { return __WEBPACK_IMPORTED_MODULE_21__FormGroup__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_22__Glyphicon__ = __webpack_require__(173); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_22__Glyphicon__ = __webpack_require__(150); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Glyphicon", function() { return __WEBPACK_IMPORTED_MODULE_22__Glyphicon__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_23__Grid__ = __webpack_require__(267); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_23__Grid__ = __webpack_require__(241); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Grid", function() { return __WEBPACK_IMPORTED_MODULE_23__Grid__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_24__HelpBlock__ = __webpack_require__(548); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_24__HelpBlock__ = __webpack_require__(499); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "HelpBlock", function() { return __WEBPACK_IMPORTED_MODULE_24__HelpBlock__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_25__Image__ = __webpack_require__(549); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_25__Image__ = __webpack_require__(500); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Image", function() { return __WEBPACK_IMPORTED_MODULE_25__Image__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_26__InputGroup__ = __webpack_require__(550); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_26__InputGroup__ = __webpack_require__(501); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "InputGroup", function() { return __WEBPACK_IMPORTED_MODULE_26__InputGroup__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_27__Jumbotron__ = __webpack_require__(553); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_27__Jumbotron__ = __webpack_require__(504); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Jumbotron", function() { return __WEBPACK_IMPORTED_MODULE_27__Jumbotron__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_28__Label__ = __webpack_require__(554); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_28__Label__ = __webpack_require__(505); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Label", function() { return __WEBPACK_IMPORTED_MODULE_28__Label__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_29__ListGroup__ = __webpack_require__(555); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_29__ListGroup__ = __webpack_require__(506); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "ListGroup", function() { return __WEBPACK_IMPORTED_MODULE_29__ListGroup__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_30__ListGroupItem__ = __webpack_require__(268); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_30__ListGroupItem__ = __webpack_require__(242); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "ListGroupItem", function() { return __WEBPACK_IMPORTED_MODULE_30__ListGroupItem__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_31__Media__ = __webpack_require__(121); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_31__Media__ = __webpack_require__(154); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Media", function() { return __WEBPACK_IMPORTED_MODULE_31__Media__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_32__MenuItem__ = __webpack_require__(562); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_32__MenuItem__ = __webpack_require__(513); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "MenuItem", function() { return __WEBPACK_IMPORTED_MODULE_32__MenuItem__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_33__Modal__ = __webpack_require__(563); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_33__Modal__ = __webpack_require__(514); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Modal", function() { return __WEBPACK_IMPORTED_MODULE_33__Modal__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_34__ModalBody__ = __webpack_require__(273); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_34__ModalBody__ = __webpack_require__(249); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "ModalBody", function() { return __WEBPACK_IMPORTED_MODULE_34__ModalBody__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_35__ModalFooter__ = __webpack_require__(274); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_35__ModalFooter__ = __webpack_require__(250); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "ModalFooter", function() { return __WEBPACK_IMPORTED_MODULE_35__ModalFooter__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_36__ModalHeader__ = __webpack_require__(275); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_36__ModalHeader__ = __webpack_require__(251); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "ModalHeader", function() { return __WEBPACK_IMPORTED_MODULE_36__ModalHeader__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_37__ModalTitle__ = __webpack_require__(276); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_37__ModalTitle__ = __webpack_require__(252); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "ModalTitle", function() { return __WEBPACK_IMPORTED_MODULE_37__ModalTitle__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_38__Nav__ = __webpack_require__(277); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_38__Nav__ = __webpack_require__(253); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Nav", function() { return __WEBPACK_IMPORTED_MODULE_38__Nav__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_39__Navbar__ = __webpack_require__(579); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_39__Navbar__ = __webpack_require__(527); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Navbar", function() { return __WEBPACK_IMPORTED_MODULE_39__Navbar__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_40__NavbarBrand__ = __webpack_require__(278); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_40__NavbarBrand__ = __webpack_require__(254); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "NavbarBrand", function() { return __WEBPACK_IMPORTED_MODULE_40__NavbarBrand__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_41__NavDropdown__ = __webpack_require__(583); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_41__NavDropdown__ = __webpack_require__(531); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "NavDropdown", function() { return __WEBPACK_IMPORTED_MODULE_41__NavDropdown__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_42__NavItem__ = __webpack_require__(279); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_42__NavItem__ = __webpack_require__(255); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "NavItem", function() { return __WEBPACK_IMPORTED_MODULE_42__NavItem__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_43__Overlay__ = __webpack_require__(280); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_43__Overlay__ = __webpack_require__(256); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Overlay", function() { return __WEBPACK_IMPORTED_MODULE_43__Overlay__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_44__OverlayTrigger__ = __webpack_require__(590); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_44__OverlayTrigger__ = __webpack_require__(538); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "OverlayTrigger", function() { return __WEBPACK_IMPORTED_MODULE_44__OverlayTrigger__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_45__PageHeader__ = __webpack_require__(591); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_45__PageHeader__ = __webpack_require__(539); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "PageHeader", function() { return __WEBPACK_IMPORTED_MODULE_45__PageHeader__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_46__PageItem__ = __webpack_require__(592); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_46__PageItem__ = __webpack_require__(540); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "PageItem", function() { return __WEBPACK_IMPORTED_MODULE_46__PageItem__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_47__Pager__ = __webpack_require__(594); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_47__Pager__ = __webpack_require__(542); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Pager", function() { return __WEBPACK_IMPORTED_MODULE_47__Pager__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_48__Pagination__ = __webpack_require__(595); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_48__Pagination__ = __webpack_require__(543); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Pagination", function() { return __WEBPACK_IMPORTED_MODULE_48__Pagination__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_49__PaginationButton__ = __webpack_require__(284); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_49__PaginationButton__ = __webpack_require__(260); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "PaginationButton", function() { return __WEBPACK_IMPORTED_MODULE_49__PaginationButton__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_50__Panel__ = __webpack_require__(596); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_50__Panel__ = __webpack_require__(544); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Panel", function() { return __WEBPACK_IMPORTED_MODULE_50__Panel__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_51__PanelGroup__ = __webpack_require__(229); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_51__PanelGroup__ = __webpack_require__(203); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "PanelGroup", function() { return __WEBPACK_IMPORTED_MODULE_51__PanelGroup__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_52__Popover__ = __webpack_require__(597); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_52__Popover__ = __webpack_require__(545); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Popover", function() { return __WEBPACK_IMPORTED_MODULE_52__Popover__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_53__ProgressBar__ = __webpack_require__(598); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_53__ProgressBar__ = __webpack_require__(546); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "ProgressBar", function() { return __WEBPACK_IMPORTED_MODULE_53__ProgressBar__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_54__Radio__ = __webpack_require__(599); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_54__Radio__ = __webpack_require__(547); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Radio", function() { return __WEBPACK_IMPORTED_MODULE_54__Radio__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_55__ResponsiveEmbed__ = __webpack_require__(600); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_55__ResponsiveEmbed__ = __webpack_require__(548); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "ResponsiveEmbed", function() { return __WEBPACK_IMPORTED_MODULE_55__ResponsiveEmbed__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_56__Row__ = __webpack_require__(601); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_56__Row__ = __webpack_require__(549); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Row", function() { return __WEBPACK_IMPORTED_MODULE_56__Row__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_57__SafeAnchor__ = __webpack_require__(41); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_57__SafeAnchor__ = __webpack_require__(36); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "SafeAnchor", function() { return __WEBPACK_IMPORTED_MODULE_57__SafeAnchor__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_58__SplitButton__ = __webpack_require__(602); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_58__SplitButton__ = __webpack_require__(550); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "SplitButton", function() { return __WEBPACK_IMPORTED_MODULE_58__SplitButton__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_59__Tab__ = __webpack_require__(604); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_59__Tab__ = __webpack_require__(552); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Tab", function() { return __WEBPACK_IMPORTED_MODULE_59__Tab__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_60__TabContainer__ = __webpack_require__(177); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_60__TabContainer__ = __webpack_require__(157); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "TabContainer", function() { return __WEBPACK_IMPORTED_MODULE_60__TabContainer__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_61__TabContent__ = __webpack_require__(178); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_61__TabContent__ = __webpack_require__(158); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "TabContent", function() { return __WEBPACK_IMPORTED_MODULE_61__TabContent__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_62__Table__ = __webpack_require__(605); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_62__Table__ = __webpack_require__(553); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Table", function() { return __WEBPACK_IMPORTED_MODULE_62__Table__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_63__TabPane__ = __webpack_require__(285); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_63__TabPane__ = __webpack_require__(261); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "TabPane", function() { return __WEBPACK_IMPORTED_MODULE_63__TabPane__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_64__Tabs__ = __webpack_require__(606); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_64__Tabs__ = __webpack_require__(554); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Tabs", function() { return __WEBPACK_IMPORTED_MODULE_64__Tabs__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_65__Thumbnail__ = __webpack_require__(607); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_65__Thumbnail__ = __webpack_require__(555); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Thumbnail", function() { return __WEBPACK_IMPORTED_MODULE_65__Thumbnail__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_66__ToggleButton__ = __webpack_require__(286); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_66__ToggleButton__ = __webpack_require__(262); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "ToggleButton", function() { return __WEBPACK_IMPORTED_MODULE_66__ToggleButton__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_67__ToggleButtonGroup__ = __webpack_require__(608); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_67__ToggleButtonGroup__ = __webpack_require__(556); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "ToggleButtonGroup", function() { return __WEBPACK_IMPORTED_MODULE_67__ToggleButtonGroup__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_68__Tooltip__ = __webpack_require__(609); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_68__Tooltip__ = __webpack_require__(557); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Tooltip", function() { return __WEBPACK_IMPORTED_MODULE_68__Tooltip__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_69__Well__ = __webpack_require__(610); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_69__Well__ = __webpack_require__(558); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Well", function() { return __WEBPACK_IMPORTED_MODULE_69__Well__["a"]; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_70__utils__ = __webpack_require__(611); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_70__utils__ = __webpack_require__(559); /* harmony reexport (module object) */ __webpack_require__.d(__webpack_exports__, "utils", function() { return __WEBPACK_IMPORTED_MODULE_70__utils__; }); @@ -4256,7 +3346,7 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); /***/ }), -/* 39 */ +/* 34 */ /***/ (function(module, exports) { var core = module.exports = { version: '2.5.1' }; @@ -4264,12 +3354,12 @@ if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef /***/ }), -/* 40 */ +/* 35 */ /***/ (function(module, exports, __webpack_require__) { -var store = __webpack_require__(145)('wks'); -var uid = __webpack_require__(105); -var Symbol = __webpack_require__(49).Symbol; +var store = __webpack_require__(121)('wks'); +var uid = __webpack_require__(92); +var Symbol = __webpack_require__(43).Symbol; var USE_SYMBOL = typeof Symbol == 'function'; var $exports = module.exports = function (name) { @@ -4281,7 +3371,7 @@ $exports.store = store; /***/ }), -/* 41 */ +/* 36 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -4299,9 +3389,9 @@ $exports.store = store; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_react__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_prop_types__ = __webpack_require__(8); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_prop_types__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_prop_types_extra_lib_elementType__ = __webpack_require__(15); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_prop_types_extra_lib_elementType__ = __webpack_require__(14); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_prop_types_extra_lib_elementType___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_prop_types_extra_lib_elementType__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__utils_createChainedFunction__ = __webpack_require__(20); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__utils_createChainedFunction__ = __webpack_require__(17); @@ -4417,7 +3507,7 @@ SafeAnchor.defaultProps = defaultProps; /* harmony default export */ __webpack_exports__["a"] = (SafeAnchor); /***/ }), -/* 42 */ +/* 37 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -4431,14 +3521,14 @@ SafeAnchor.defaultProps = defaultProps; -var _prodInvariant = __webpack_require__(14), - _assign = __webpack_require__(18); +var _prodInvariant = __webpack_require__(13), + _assign = __webpack_require__(15); -var CallbackQueue = __webpack_require__(238); -var PooledClass = __webpack_require__(59); -var ReactFeatureFlags = __webpack_require__(239); -var ReactReconciler = __webpack_require__(72); -var Transaction = __webpack_require__(110); +var CallbackQueue = __webpack_require__(212); +var PooledClass = __webpack_require__(52); +var ReactFeatureFlags = __webpack_require__(213); +var ReactReconciler = __webpack_require__(65); +var Transaction = __webpack_require__(96); var invariant = __webpack_require__(11); @@ -4672,11 +3762,11 @@ module.exports = ReactUpdates; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 43 */ +/* 38 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ - __webpack_require__(311) + __webpack_require__(286) ], __WEBPACK_AMD_DEFINE_RESULT__ = function( Data ) { "use strict"; @@ -4686,171 +3776,7 @@ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_ /***/ }), -/* 44 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -/** - * Functions that manipulate strings - * - * Although these functions are exported, they are subject to change without notice. - * - * @module common_strings - */ /** */ -Object.defineProperty(exports, "__esModule", { value: true }); -var predicates_1 = __webpack_require__(16); -var rejectFactory_1 = __webpack_require__(100); -var common_1 = __webpack_require__(13); -var hof_1 = __webpack_require__(17); -var transition_1 = __webpack_require__(129); -var resolvable_1 = __webpack_require__(102); -/** - * Returns a string shortened to a maximum length - * - * If the string is already less than the `max` length, return the string. - * Else return the string, shortened to `max - 3` and append three dots ("..."). - * - * @param max the maximum length of the string to return - * @param str the input string - */ -function maxLength(max, str) { - if (str.length <= max) - return str; - return str.substr(0, max - 3) + "..."; -} -exports.maxLength = maxLength; -/** - * Returns a string, with spaces added to the end, up to a desired str length - * - * If the string is already longer than the desired length, return the string. - * Else returns the string, with extra spaces on the end, such that it reaches `length` characters. - * - * @param length the desired length of the string to return - * @param str the input string - */ -function padString(length, str) { - while (str.length < length) - str += " "; - return str; -} -exports.padString = padString; -function kebobString(camelCase) { - return camelCase - .replace(/^([A-Z])/, function ($1) { return $1.toLowerCase(); }) // replace first char - .replace(/([A-Z])/g, function ($1) { return "-" + $1.toLowerCase(); }); // replace rest -} -exports.kebobString = kebobString; -function _toJson(obj) { - return JSON.stringify(obj); -} -function _fromJson(json) { - return predicates_1.isString(json) ? JSON.parse(json) : json; -} -function promiseToString(p) { - return "Promise(" + JSON.stringify(p) + ")"; -} -function functionToString(fn) { - var fnStr = fnToString(fn); - var namedFunctionMatch = fnStr.match(/^(function [^ ]+\([^)]*\))/); - var toStr = namedFunctionMatch ? namedFunctionMatch[1] : fnStr; - var fnName = fn['name'] || ""; - if (fnName && toStr.match(/function \(/)) { - return 'function ' + fnName + toStr.substr(9); - } - return toStr; -} -exports.functionToString = functionToString; -function fnToString(fn) { - var _fn = predicates_1.isArray(fn) ? fn.slice(-1)[0] : fn; - return _fn && _fn.toString() || "undefined"; -} -exports.fnToString = fnToString; -var stringifyPatternFn = null; -var stringifyPattern = function (value) { - var isRejection = rejectFactory_1.Rejection.isRejectionPromise; - stringifyPatternFn = stringifyPatternFn || hof_1.pattern([ - [hof_1.not(predicates_1.isDefined), hof_1.val("undefined")], - [predicates_1.isNull, hof_1.val("null")], - [predicates_1.isPromise, hof_1.val("[Promise]")], - [isRejection, function (x) { return x._transitionRejection.toString(); }], - [hof_1.is(rejectFactory_1.Rejection), hof_1.invoke("toString")], - [hof_1.is(transition_1.Transition), hof_1.invoke("toString")], - [hof_1.is(resolvable_1.Resolvable), hof_1.invoke("toString")], - [predicates_1.isInjectable, functionToString], - [hof_1.val(true), common_1.identity] - ]); - return stringifyPatternFn(value); -}; -function stringify(o) { - var seen = []; - function format(val) { - if (predicates_1.isObject(val)) { - if (seen.indexOf(val) !== -1) - return '[circular ref]'; - seen.push(val); - } - return stringifyPattern(val); - } - return JSON.stringify(o, function (key, val) { return format(val); }).replace(/\\"/g, '"'); -} -exports.stringify = stringify; -/** Returns a function that splits a string on a character or substring */ -exports.beforeAfterSubstr = function (char) { return function (str) { - if (!str) - return ["", ""]; - var idx = str.indexOf(char); - if (idx === -1) - return [str, ""]; - return [str.substr(0, idx), str.substr(idx + 1)]; -}; }; -exports.hostRegex = new RegExp('^(?:[a-z]+:)?//[^/]+/'); -exports.stripFile = function (str) { return str.replace(/\/[^/]*$/, ''); }; -exports.splitHash = exports.beforeAfterSubstr("#"); -exports.splitQuery = exports.beforeAfterSubstr("?"); -exports.splitEqual = exports.beforeAfterSubstr("="); -exports.trimHashVal = function (str) { return str ? str.replace(/^#/, "") : ""; }; -/** - * Splits on a delimiter, but returns the delimiters in the array - * - * #### Example: - * ```js - * var splitOnSlashes = splitOnDelim('/'); - * splitOnSlashes("/foo"); // ["/", "foo"] - * splitOnSlashes("/foo/"); // ["/", "foo", "/"] - * ``` - */ -function splitOnDelim(delim) { - var re = new RegExp("(" + delim + ")", "g"); - return function (str) { - return str.split(re).filter(common_1.identity); - }; -} -exports.splitOnDelim = splitOnDelim; -; -/** - * Reduce fn that joins neighboring strings - * - * Given an array of strings, returns a new array - * where all neighboring strings have been joined. - * - * #### Example: - * ```js - * let arr = ["foo", "bar", 1, "baz", "", "qux" ]; - * arr.reduce(joinNeighborsR, []) // ["foobar", 1, "bazqux" ] - * ``` - */ -function joinNeighborsR(acc, x) { - if (predicates_1.isString(common_1.tail(acc)) && predicates_1.isString(x)) - return acc.slice(0, -1).concat(common_1.tail(acc) + x); - return common_1.pushR(acc, x); -} -exports.joinNeighborsR = joinNeighborsR; -; -//# sourceMappingURL=strings.js.map - -/***/ }), -/* 45 */ +/* 39 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -4864,11 +3790,11 @@ exports.joinNeighborsR = joinNeighborsR; -var _assign = __webpack_require__(18); +var _assign = __webpack_require__(15); -var PooledClass = __webpack_require__(59); +var PooledClass = __webpack_require__(52); -var emptyFunction = __webpack_require__(30); +var emptyFunction = __webpack_require__(26); var warning = __webpack_require__(12); var didWarnForAddedNewProperty = false; @@ -5125,8 +4051,8 @@ function getPooledWarningPropertyDefinition(propName, getVal) { /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 46 */, -/* 47 */ +/* 40 */, +/* 41 */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(global, module) {var __WEBPACK_AMD_DEFINE_RESULT__;/** @@ -22215,16 +21141,16 @@ function getPooledWarningPropertyDefinition(propName, getVal) { } }.call(this)); -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(134), __webpack_require__(209)(module))) +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(182), __webpack_require__(183)(module))) /***/ }), -/* 48 */ +/* 42 */ /***/ (function(module, exports, __webpack_require__) { -var global = __webpack_require__(49); -var core = __webpack_require__(39); -var ctx = __webpack_require__(139); -var hide = __webpack_require__(68); +var global = __webpack_require__(43); +var core = __webpack_require__(34); +var ctx = __webpack_require__(115); +var hide = __webpack_require__(61); var PROTOTYPE = 'prototype'; var $export = function (type, name, source) { @@ -22285,7 +21211,7 @@ module.exports = $export; /***/ }), -/* 49 */ +/* 43 */ /***/ (function(module, exports) { // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 @@ -22297,7 +21223,7 @@ if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef /***/ }), -/* 50 */ +/* 44 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -22311,7 +21237,7 @@ if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef -var _prodInvariant = __webpack_require__(14); +var _prodInvariant = __webpack_require__(13); var invariant = __webpack_require__(11); @@ -22510,7 +21436,7 @@ module.exports = DOMProperty; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 51 */ +/* 45 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -22523,7 +21449,7 @@ exports.default = !!(typeof window !== 'undefined' && window.document && window. module.exports = exports['default']; /***/ }), -/* 52 */ +/* 46 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function() { @@ -22538,7 +21464,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function() { /***/ }), -/* 53 */ +/* 47 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function() { @@ -22558,252 +21484,7 @@ return nodeName; /***/ }), -/* 54 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -/** - * # Transition tracing (debug) - * - * Enable transition tracing to print transition information to the console, - * in order to help debug your application. - * Tracing logs detailed information about each Transition to your console. - * - * To enable tracing, import the [[Trace]] singleton and enable one or more categories. - * - * ### ES6 - * ```js - * import {trace} from "ui-router-ng2"; // or "angular-ui-router" - * trace.enable(1, 5); // TRANSITION and VIEWCONFIG - * ``` - * - * ### CJS - * ```js - * let trace = require("angular-ui-router").trace; // or "ui-router-ng2" - * trace.enable("TRANSITION", "VIEWCONFIG"); - * ``` - * - * ### Globals - * ```js - * let trace = window["angular-ui-router"].trace; // or "ui-router-ng2" - * trace.enable(); // Trace everything (very verbose) - * ``` - * - * ### Angular 1: - * ```js - * app.run($trace => $trace.enable()); - * ``` - * - * @coreapi - * @module trace - */ /** for typedoc */ -var hof_1 = __webpack_require__(17); -var predicates_1 = __webpack_require__(16); -var strings_1 = __webpack_require__(44); -/** @hidden */ -function uiViewString(uiview) { - if (!uiview) - return 'ui-view (defunct)'; - var state = uiview.creationContext ? uiview.creationContext.name || '(root)' : '(none)'; - return "[ui-view#" + uiview.id + " " + uiview.$type + ":" + uiview.fqn + " (" + uiview.name + "@" + state + ")]"; -} -/** @hidden */ -var viewConfigString = function (viewConfig) { - var view = viewConfig.viewDecl; - var state = view.$context.name || '(root)'; - return "[View#" + viewConfig.$id + " from '" + state + "' state]: target ui-view: '" + view.$uiViewName + "@" + view.$uiViewContextAnchor + "'"; -}; -/** @hidden */ -function normalizedCat(input) { - return predicates_1.isNumber(input) ? Category[input] : Category[Category[input]]; -} -/** @hidden */ -var consoleLog = Function.prototype.bind.call(console.log, console); -/** @hidden */ -var consoletable = predicates_1.isFunction(console.table) ? console.table.bind(console) : consoleLog.bind(console); -/** - * Trace categories Enum - * - * Enable or disable a category using [[Trace.enable]] or [[Trace.disable]] - * - * `trace.enable(Category.TRANSITION)` - * - * These can also be provided using a matching string, or position ordinal - * - * `trace.enable("TRANSITION")` - * - * `trace.enable(1)` - */ -var Category; -(function (Category) { - Category[Category["RESOLVE"] = 0] = "RESOLVE"; - Category[Category["TRANSITION"] = 1] = "TRANSITION"; - Category[Category["HOOK"] = 2] = "HOOK"; - Category[Category["UIVIEW"] = 3] = "UIVIEW"; - Category[Category["VIEWCONFIG"] = 4] = "VIEWCONFIG"; -})(Category = exports.Category || (exports.Category = {})); -/** @hidden */ var _tid = hof_1.parse("$id"); -/** @hidden */ var _rid = hof_1.parse("router.$id"); -/** @hidden */ var transLbl = function (trans) { return "Transition #" + _tid(trans) + "-" + _rid(trans); }; -/** - * Prints UI-Router Transition trace information to the console. - */ -var Trace = /** @class */ (function () { - /** @hidden */ - function Trace() { - /** @hidden */ - this._enabled = {}; - this.approximateDigests = 0; - } - /** @hidden */ - Trace.prototype._set = function (enabled, categories) { - var _this = this; - if (!categories.length) { - categories = Object.keys(Category) - .map(function (k) { return parseInt(k, 10); }) - .filter(function (k) { return !isNaN(k); }) - .map(function (key) { return Category[key]; }); - } - categories.map(normalizedCat).forEach(function (category) { return _this._enabled[category] = enabled; }); - }; - Trace.prototype.enable = function () { - var categories = []; - for (var _i = 0; _i < arguments.length; _i++) { - categories[_i] = arguments[_i]; - } - this._set(true, categories); - }; - Trace.prototype.disable = function () { - var categories = []; - for (var _i = 0; _i < arguments.length; _i++) { - categories[_i] = arguments[_i]; - } - this._set(false, categories); - }; - /** - * Retrieves the enabled stateus of a [[Category]] - * - * ```js - * trace.enabled("VIEWCONFIG"); // true or false - * ``` - * - * @returns boolean true if the category is enabled - */ - Trace.prototype.enabled = function (category) { - return !!this._enabled[normalizedCat(category)]; - }; - /** @internalapi called by ui-router code */ - Trace.prototype.traceTransitionStart = function (trans) { - if (!this.enabled(Category.TRANSITION)) - return; - console.log(transLbl(trans) + ": Started -> " + strings_1.stringify(trans)); - }; - /** @internalapi called by ui-router code */ - Trace.prototype.traceTransitionIgnored = function (trans) { - if (!this.enabled(Category.TRANSITION)) - return; - console.log(transLbl(trans) + ": Ignored <> " + strings_1.stringify(trans)); - }; - /** @internalapi called by ui-router code */ - Trace.prototype.traceHookInvocation = function (step, trans, options) { - if (!this.enabled(Category.HOOK)) - return; - var event = hof_1.parse("traceData.hookType")(options) || "internal", context = hof_1.parse("traceData.context.state.name")(options) || hof_1.parse("traceData.context")(options) || "unknown", name = strings_1.functionToString(step.registeredHook.callback); - console.log(transLbl(trans) + ": Hook -> " + event + " context: " + context + ", " + strings_1.maxLength(200, name)); - }; - /** @internalapi called by ui-router code */ - Trace.prototype.traceHookResult = function (hookResult, trans, transitionOptions) { - if (!this.enabled(Category.HOOK)) - return; - console.log(transLbl(trans) + ": <- Hook returned: " + strings_1.maxLength(200, strings_1.stringify(hookResult))); - }; - /** @internalapi called by ui-router code */ - Trace.prototype.traceResolvePath = function (path, when, trans) { - if (!this.enabled(Category.RESOLVE)) - return; - console.log(transLbl(trans) + ": Resolving " + path + " (" + when + ")"); - }; - /** @internalapi called by ui-router code */ - Trace.prototype.traceResolvableResolved = function (resolvable, trans) { - if (!this.enabled(Category.RESOLVE)) - return; - console.log(transLbl(trans) + ": <- Resolved " + resolvable + " to: " + strings_1.maxLength(200, strings_1.stringify(resolvable.data))); - }; - /** @internalapi called by ui-router code */ - Trace.prototype.traceError = function (reason, trans) { - if (!this.enabled(Category.TRANSITION)) - return; - console.log(transLbl(trans) + ": <- Rejected " + strings_1.stringify(trans) + ", reason: " + reason); - }; - /** @internalapi called by ui-router code */ - Trace.prototype.traceSuccess = function (finalState, trans) { - if (!this.enabled(Category.TRANSITION)) - return; - console.log(transLbl(trans) + ": <- Success " + strings_1.stringify(trans) + ", final state: " + finalState.name); - }; - /** @internalapi called by ui-router code */ - Trace.prototype.traceUIViewEvent = function (event, viewData, extra) { - if (extra === void 0) { extra = ""; } - if (!this.enabled(Category.UIVIEW)) - return; - console.log("ui-view: " + strings_1.padString(30, event) + " " + uiViewString(viewData) + extra); - }; - /** @internalapi called by ui-router code */ - Trace.prototype.traceUIViewConfigUpdated = function (viewData, context) { - if (!this.enabled(Category.UIVIEW)) - return; - this.traceUIViewEvent("Updating", viewData, " with ViewConfig from context='" + context + "'"); - }; - /** @internalapi called by ui-router code */ - Trace.prototype.traceUIViewFill = function (viewData, html) { - if (!this.enabled(Category.UIVIEW)) - return; - this.traceUIViewEvent("Fill", viewData, " with: " + strings_1.maxLength(200, html)); - }; - /** @internalapi called by ui-router code */ - Trace.prototype.traceViewSync = function (pairs) { - if (!this.enabled(Category.VIEWCONFIG)) - return; - var mapping = pairs.map(function (_a) { - var uiViewData = _a[0], config = _a[1]; - var uiView = uiViewData.$type + ":" + uiViewData.fqn; - var view = config && config.viewDecl.$context.name + ": " + config.viewDecl.$name + " (" + config.viewDecl.$type + ")"; - return { 'ui-view fqn': uiView, 'state: view name': view }; - }).sort(function (a, b) { return a['ui-view fqn'].localeCompare(b['ui-view fqn']); }); - consoletable(mapping); - }; - /** @internalapi called by ui-router code */ - Trace.prototype.traceViewServiceEvent = function (event, viewConfig) { - if (!this.enabled(Category.VIEWCONFIG)) - return; - console.log("VIEWCONFIG: " + event + " " + viewConfigString(viewConfig)); - }; - /** @internalapi called by ui-router code */ - Trace.prototype.traceViewServiceUIViewEvent = function (event, viewData) { - if (!this.enabled(Category.VIEWCONFIG)) - return; - console.log("VIEWCONFIG: " + event + " " + uiViewString(viewData)); - }; - return Trace; -}()); -exports.Trace = Trace; -/** - * The [[Trace]] singleton - * - * #### Example: - * ```js - * import {trace} from "angular-ui-router"; - * trace.enable(1, 5); - * ``` - */ -var trace = new Trace(); -exports.trace = trace; -//# sourceMappingURL=trace.js.map - -/***/ }), -/* 55 */ +/* 48 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -22817,15 +21498,15 @@ exports.trace = trace; -var _assign = __webpack_require__(18); +var _assign = __webpack_require__(15); -var ReactCurrentOwner = __webpack_require__(37); +var ReactCurrentOwner = __webpack_require__(32); var warning = __webpack_require__(12); -var canDefineProperty = __webpack_require__(103); +var canDefineProperty = __webpack_require__(90); var hasOwnProperty = Object.prototype.hasOwnProperty; -var REACT_ELEMENT_TYPE = __webpack_require__(213); +var REACT_ELEMENT_TYPE = __webpack_require__(187); var RESERVED_PROPS = { key: true, @@ -23148,15 +21829,15 @@ module.exports = ReactElement; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 56 */ +/* 49 */ /***/ (function(module, exports, __webpack_require__) { -var anObject = __webpack_require__(69); -var IE8_DOM_DEFINE = __webpack_require__(219); -var toPrimitive = __webpack_require__(140); +var anObject = __webpack_require__(62); +var IE8_DOM_DEFINE = __webpack_require__(193); +var toPrimitive = __webpack_require__(116); var dP = Object.defineProperty; -exports.f = __webpack_require__(70) ? Object.defineProperty : function defineProperty(O, P, Attributes) { +exports.f = __webpack_require__(63) ? Object.defineProperty : function defineProperty(O, P, Attributes) { anObject(O); P = toPrimitive(P, true); anObject(Attributes); @@ -23170,7 +21851,7 @@ exports.f = __webpack_require__(70) ? Object.defineProperty : function definePro /***/ }), -/* 57 */ +/* 50 */ /***/ (function(module, exports) { var hasOwnProperty = {}.hasOwnProperty; @@ -23180,19 +21861,19 @@ module.exports = function (it, key) { /***/ }), -/* 58 */ +/* 51 */ /***/ (function(module, exports, __webpack_require__) { // to indexed object, toObject with fallback for non-array-like ES3 strings -var IObject = __webpack_require__(222); -var defined = __webpack_require__(142); +var IObject = __webpack_require__(196); +var defined = __webpack_require__(118); module.exports = function (it) { return IObject(defined(it)); }; /***/ }), -/* 59 */ +/* 52 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -23207,7 +21888,7 @@ module.exports = function (it) { -var _prodInvariant = __webpack_require__(14); +var _prodInvariant = __webpack_require__(13); var invariant = __webpack_require__(11); @@ -23308,9 +21989,9 @@ module.exports = PooledClass; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 60 */, -/* 61 */, -/* 62 */ +/* 53 */, +/* 54 */, +/* 55 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function() { @@ -23323,7 +22004,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function() { /***/ }), -/* 63 */ +/* 56 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ @@ -23400,7 +22081,7 @@ return access; /***/ }), -/* 64 */ +/* 57 */ /***/ (function(module, exports) { /* @@ -23482,7 +22163,7 @@ function toComment(sourceMap) { /***/ }), -/* 65 */ +/* 58 */ /***/ (function(module, exports, __webpack_require__) { /* @@ -23528,7 +22209,7 @@ var singleton = null; var singletonCounter = 0; var stylesInsertedAtTop = []; -var fixUrls = __webpack_require__(360); +var fixUrls = __webpack_require__(311); module.exports = function(list, options) { if (typeof DEBUG !== "undefined" && DEBUG) { @@ -23841,7 +22522,7 @@ function updateLink (link, options, obj) { /***/ }), -/* 66 */ +/* 59 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -23855,26 +22536,26 @@ function updateLink (link, options, obj) { -var _assign = __webpack_require__(18); +var _assign = __webpack_require__(15); -var ReactBaseClasses = __webpack_require__(211); -var ReactChildren = __webpack_require__(373); -var ReactDOMFactories = __webpack_require__(377); -var ReactElement = __webpack_require__(55); -var ReactPropTypes = __webpack_require__(381); -var ReactVersion = __webpack_require__(383); +var ReactBaseClasses = __webpack_require__(185); +var ReactChildren = __webpack_require__(324); +var ReactDOMFactories = __webpack_require__(328); +var ReactElement = __webpack_require__(48); +var ReactPropTypes = __webpack_require__(332); +var ReactVersion = __webpack_require__(334); -var createReactClass = __webpack_require__(384); -var onlyChild = __webpack_require__(386); +var createReactClass = __webpack_require__(335); +var onlyChild = __webpack_require__(337); var createElement = ReactElement.createElement; var createFactory = ReactElement.createFactory; var cloneElement = ReactElement.cloneElement; if (process.env.NODE_ENV !== 'production') { - var lowPriorityWarning = __webpack_require__(137); - var canDefineProperty = __webpack_require__(103); - var ReactElementValidator = __webpack_require__(215); + var lowPriorityWarning = __webpack_require__(113); + var canDefineProperty = __webpack_require__(90); + var ReactElementValidator = __webpack_require__(189); var didWarnPropTypesDeprecated = false; createElement = ReactElementValidator.createElement; createFactory = ReactElementValidator.createFactory; @@ -23977,7 +22658,7 @@ module.exports = React; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 67 */ +/* 60 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -24019,12 +22700,12 @@ function reactProdInvariant(code) { module.exports = reactProdInvariant; /***/ }), -/* 68 */ +/* 61 */ /***/ (function(module, exports, __webpack_require__) { -var dP = __webpack_require__(56); -var createDesc = __webpack_require__(87); -module.exports = __webpack_require__(70) ? function (object, key, value) { +var dP = __webpack_require__(49); +var createDesc = __webpack_require__(76); +module.exports = __webpack_require__(63) ? function (object, key, value) { return dP.f(object, key, createDesc(1, value)); } : function (object, key, value) { object[key] = value; @@ -24033,10 +22714,10 @@ module.exports = __webpack_require__(70) ? function (object, key, value) { /***/ }), -/* 69 */ +/* 62 */ /***/ (function(module, exports, __webpack_require__) { -var isObject = __webpack_require__(85); +var isObject = __webpack_require__(74); module.exports = function (it) { if (!isObject(it)) throw TypeError(it + ' is not an object!'); return it; @@ -24044,23 +22725,23 @@ module.exports = function (it) { /***/ }), -/* 70 */ +/* 63 */ /***/ (function(module, exports, __webpack_require__) { // Thank's IE8 for his funny defineProperty -module.exports = !__webpack_require__(86)(function () { +module.exports = !__webpack_require__(75)(function () { return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7; }); /***/ }), -/* 71 */ +/* 64 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = { "default": __webpack_require__(426), __esModule: true }; +module.exports = { "default": __webpack_require__(377), __esModule: true }; /***/ }), -/* 72 */ +/* 65 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -24074,8 +22755,8 @@ module.exports = { "default": __webpack_require__(426), __esModule: true }; -var ReactRef = __webpack_require__(441); -var ReactInstrumentation = __webpack_require__(31); +var ReactRef = __webpack_require__(392); +var ReactInstrumentation = __webpack_require__(27); var warning = __webpack_require__(12); @@ -24230,7 +22911,7 @@ module.exports = ReactReconciler; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 73 */ +/* 66 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -24244,11 +22925,11 @@ module.exports = ReactReconciler; -var DOMNamespaces = __webpack_require__(163); -var setInnerHTML = __webpack_require__(112); +var DOMNamespaces = __webpack_require__(140); +var setInnerHTML = __webpack_require__(98); -var createMicrosoftUnsafeLocalFunction = __webpack_require__(164); -var setTextContent = __webpack_require__(243); +var createMicrosoftUnsafeLocalFunction = __webpack_require__(141); +var setTextContent = __webpack_require__(217); var ELEMENT_NODE_TYPE = 1; var DOCUMENT_FRAGMENT_NODE_TYPE = 11; @@ -24351,7 +23032,7 @@ DOMLazyTree.queueText = queueText; module.exports = DOMLazyTree; /***/ }), -/* 74 */ +/* 67 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -24367,7 +23048,7 @@ function ownerDocument(node) { module.exports = exports["default"]; /***/ }), -/* 75 */ +/* 68 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -24377,7 +23058,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); -var _inDOM = __webpack_require__(51); +var _inDOM = __webpack_require__(45); var _inDOM2 = _interopRequireDefault(_inDOM); @@ -24407,38 +23088,13 @@ function fallback(context, node) { module.exports = exports['default']; /***/ }), -/* 76 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -exports.default = function (componentOrElement) { - return (0, _ownerDocument2.default)(_reactDom2.default.findDOMNode(componentOrElement)); -}; - -var _reactDom = __webpack_require__(24); - -var _reactDom2 = _interopRequireDefault(_reactDom); - -var _ownerDocument = __webpack_require__(74); - -var _ownerDocument2 = _interopRequireDefault(_ownerDocument); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -module.exports = exports['default']; - -/***/ }), -/* 77 */ +/* 69 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(10), - __webpack_require__(182), - __webpack_require__(190) + __webpack_require__(162), + __webpack_require__(170) ], __WEBPACK_AMD_DEFINE_RESULT__ = function( jQuery, slice ) { "use strict"; @@ -24830,20 +23486,20 @@ return jQuery; /***/ }), -/* 78 */ +/* 70 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(10), - __webpack_require__(183), - __webpack_require__(645), - __webpack_require__(646), - __webpack_require__(309), - __webpack_require__(53), - - __webpack_require__(34), - __webpack_require__(308), - __webpack_require__(26) + __webpack_require__(163), + __webpack_require__(592), + __webpack_require__(593), + __webpack_require__(284), + __webpack_require__(47), + + __webpack_require__(30), + __webpack_require__(283), + __webpack_require__(22) ], __WEBPACK_AMD_DEFINE_RESULT__ = function( jQuery, indexOf, dir, siblings, rneedsContext, nodeName ) { "use strict"; @@ -25028,20 +23684,20 @@ return jQuery; /***/ }), -/* 79 */ +/* 71 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(10), - __webpack_require__(22), - __webpack_require__(189), - __webpack_require__(52), - __webpack_require__(182), - __webpack_require__(43), - __webpack_require__(53), - - __webpack_require__(34), - __webpack_require__(26) + __webpack_require__(20), + __webpack_require__(169), + __webpack_require__(46), + __webpack_require__(162), + __webpack_require__(38), + __webpack_require__(47), + + __webpack_require__(30), + __webpack_require__(22) ], __WEBPACK_AMD_DEFINE_RESULT__ = function( jQuery, document, documentElement, rnothtmlwhite, slice, dataPriv, nodeName ) { "use strict"; @@ -25781,22 +24437,22 @@ return jQuery; /***/ }), -/* 80 */ +/* 72 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(10), - __webpack_require__(22), - __webpack_require__(52), - __webpack_require__(661), - __webpack_require__(322), - __webpack_require__(323), - - __webpack_require__(34), - __webpack_require__(662), - __webpack_require__(196), - __webpack_require__(77), - __webpack_require__(324) // jQuery.param + __webpack_require__(20), + __webpack_require__(46), + __webpack_require__(608), + __webpack_require__(297), + __webpack_require__(298), + + __webpack_require__(30), + __webpack_require__(609), + __webpack_require__(176), + __webpack_require__(69), + __webpack_require__(299) // jQuery.param ], __WEBPACK_AMD_DEFINE_RESULT__ = function( jQuery, document, rnothtmlwhite, location, nonce, rquery ) { "use strict"; @@ -26643,396 +25299,15 @@ return jQuery; /***/ }), -/* 81 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var TransitionHookPhase; -(function (TransitionHookPhase) { - TransitionHookPhase[TransitionHookPhase["CREATE"] = 0] = "CREATE"; - TransitionHookPhase[TransitionHookPhase["BEFORE"] = 1] = "BEFORE"; - TransitionHookPhase[TransitionHookPhase["RUN"] = 2] = "RUN"; - TransitionHookPhase[TransitionHookPhase["SUCCESS"] = 3] = "SUCCESS"; - TransitionHookPhase[TransitionHookPhase["ERROR"] = 4] = "ERROR"; -})(TransitionHookPhase = exports.TransitionHookPhase || (exports.TransitionHookPhase = {})); -var TransitionHookScope; -(function (TransitionHookScope) { - TransitionHookScope[TransitionHookScope["TRANSITION"] = 0] = "TRANSITION"; - TransitionHookScope[TransitionHookScope["STATE"] = 1] = "STATE"; -})(TransitionHookScope = exports.TransitionHookScope || (exports.TransitionHookScope = {})); -//# sourceMappingURL=interface.js.map - -/***/ }), -/* 82 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -/** - * @coreapi - * @module state - */ /** for typedoc */ -Object.defineProperty(exports, "__esModule", { value: true }); -var predicates_1 = __webpack_require__(16); -var strings_1 = __webpack_require__(44); -var common_1 = __webpack_require__(35); -/** - * Encapsulate the target (destination) state/params/options of a [[Transition]]. - * - * This class is frequently used to redirect a transition to a new destination. - * - * See: - * - * - [[HookResult]] - * - [[TransitionHookFn]] - * - [[TransitionService.onStart]] - * - * To create a `TargetState`, use [[StateService.target]]. - * - * --- - * - * This class wraps: - * - * 1) an identifier for a state - * 2) a set of parameters - * 3) and transition options - * 4) the registered state object (the [[StateDeclaration]]) - * - * Many UI-Router APIs such as [[StateService.go]] take a [[StateOrName]] argument which can - * either be a *state object* (a [[StateDeclaration]] or [[StateObject]]) or a *state name* (a string). - * The `TargetState` class normalizes those options. - * - * A `TargetState` may be valid (the state being targeted exists in the registry) - * or invalid (the state being targeted is not registered). - */ -var TargetState = /** @class */ (function () { - /** - * The TargetState constructor - * - * Note: Do not construct a `TargetState` manually. - * To create a `TargetState`, use the [[StateService.target]] factory method. - * - * @param _stateRegistry The StateRegistry to use to look up the _definition - * @param _identifier An identifier for a state. - * Either a fully-qualified state name, or the object used to define the state. - * @param _params Parameters for the target state - * @param _options Transition options. - * - * @internalapi - */ - function TargetState(_stateRegistry, _identifier, _params, _options) { - this._stateRegistry = _stateRegistry; - this._identifier = _identifier; - this._identifier = _identifier; - this._params = common_1.extend({}, _params || {}); - this._options = common_1.extend({}, _options || {}); - this._definition = _stateRegistry.matcher.find(_identifier, this._options.relative); - } - /** The name of the state this object targets */ - TargetState.prototype.name = function () { - return this._definition && this._definition.name || this._identifier; - }; - /** The identifier used when creating this TargetState */ - TargetState.prototype.identifier = function () { - return this._identifier; - }; - /** The target parameter values */ - TargetState.prototype.params = function () { - return this._params; - }; - /** The internal state object (if it was found) */ - TargetState.prototype.$state = function () { - return this._definition; - }; - /** The internal state declaration (if it was found) */ - TargetState.prototype.state = function () { - return this._definition && this._definition.self; - }; - /** The target options */ - TargetState.prototype.options = function () { - return this._options; - }; - /** True if the target state was found */ - TargetState.prototype.exists = function () { - return !!(this._definition && this._definition.self); - }; - /** True if the object is valid */ - TargetState.prototype.valid = function () { - return !this.error(); - }; - /** If the object is invalid, returns the reason why */ - TargetState.prototype.error = function () { - var base = this.options().relative; - if (!this._definition && !!base) { - var stateName = base.name ? base.name : base; - return "Could not resolve '" + this.name() + "' from state '" + stateName + "'"; - } - if (!this._definition) - return "No such state '" + this.name() + "'"; - if (!this._definition.self) - return "State '" + this.name() + "' has an invalid definition"; - }; - TargetState.prototype.toString = function () { - return "'" + this.name() + "'" + strings_1.stringify(this.params()); - }; - /** - * Returns a copy of this TargetState which targets a different state. - * The new TargetState has the same parameter values and transition options. - * - * @param state The new state that should be targeted - */ - TargetState.prototype.withState = function (state) { - return new TargetState(this._stateRegistry, state, this._params, this._options); - }; - /** - * Returns a copy of this TargetState, using the specified parameter values. - * - * @param params the new parameter values to use - * @param replace When false (default) the new parameter values will be merged with the current values. - * When true the parameter values will be used instead of the current values. - */ - TargetState.prototype.withParams = function (params, replace) { - if (replace === void 0) { replace = false; } - var newParams = replace ? params : common_1.extend({}, this._params, params); - return new TargetState(this._stateRegistry, this._identifier, newParams, this._options); - }; - /** - * Returns a copy of this TargetState, using the specified Transition Options. - * - * @param options the new options to use - * @param replace When false (default) the new options will be merged with the current options. - * When true the options will be used instead of the current options. - */ - TargetState.prototype.withOptions = function (options, replace) { - if (replace === void 0) { replace = false; } - var newOpts = replace ? options : common_1.extend({}, this._options, options); - return new TargetState(this._stateRegistry, this._identifier, this._params, newOpts); - }; - /** Returns true if the object has a state property that might be a state or state name */ - TargetState.isDef = function (obj) { - return obj && obj.state && (predicates_1.isString(obj.state) || predicates_1.isString(obj.state.name)); - }; - return TargetState; -}()); -exports.TargetState = TargetState; -//# sourceMappingURL=targetState.js.map - -/***/ }), -/* 83 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -/** - * @coreapi - * @module params - */ /** for typedoc */ -var common_1 = __webpack_require__(13); -var hof_1 = __webpack_require__(17); -var predicates_1 = __webpack_require__(16); -var coreservices_1 = __webpack_require__(27); -var paramType_1 = __webpack_require__(201); -/** @hidden */ var hasOwn = Object.prototype.hasOwnProperty; -/** @hidden */ var isShorthand = function (cfg) { - return ["value", "type", "squash", "array", "dynamic"].filter(hasOwn.bind(cfg || {})).length === 0; -}; -/** @internalapi */ -var DefType; -(function (DefType) { - DefType[DefType["PATH"] = 0] = "PATH"; - DefType[DefType["SEARCH"] = 1] = "SEARCH"; - DefType[DefType["CONFIG"] = 2] = "CONFIG"; -})(DefType = exports.DefType || (exports.DefType = {})); -/** @hidden */ -function unwrapShorthand(cfg) { - cfg = isShorthand(cfg) && { value: cfg } || cfg; - getStaticDefaultValue['__cacheable'] = true; - function getStaticDefaultValue() { - return cfg.value; - } - return common_1.extend(cfg, { - $$fn: predicates_1.isInjectable(cfg.value) ? cfg.value : getStaticDefaultValue, - }); -} -/** @hidden */ -function getType(cfg, urlType, location, id, paramTypes) { - if (cfg.type && urlType && urlType.name !== 'string') - throw new Error("Param '" + id + "' has two type configurations."); - if (cfg.type && urlType && urlType.name === 'string' && paramTypes.type(cfg.type)) - return paramTypes.type(cfg.type); - if (urlType) - return urlType; - if (!cfg.type) { - var type = location === DefType.CONFIG ? "any" : - location === DefType.PATH ? "path" : - location === DefType.SEARCH ? "query" : "string"; - return paramTypes.type(type); - } - return cfg.type instanceof paramType_1.ParamType ? cfg.type : paramTypes.type(cfg.type); -} -/** - * @internalapi - * returns false, true, or the squash value to indicate the "default parameter url squash policy". - */ -function getSquashPolicy(config, isOptional, defaultPolicy) { - var squash = config.squash; - if (!isOptional || squash === false) - return false; - if (!predicates_1.isDefined(squash) || squash == null) - return defaultPolicy; - if (squash === true || predicates_1.isString(squash)) - return squash; - throw new Error("Invalid squash policy: '" + squash + "'. Valid policies: false, true, or arbitrary string"); -} -/** @internalapi */ -function getReplace(config, arrayMode, isOptional, squash) { - var replace, configuredKeys, defaultPolicy = [ - { from: "", to: (isOptional || arrayMode ? undefined : "") }, - { from: null, to: (isOptional || arrayMode ? undefined : "") }, - ]; - replace = predicates_1.isArray(config.replace) ? config.replace : []; - if (predicates_1.isString(squash)) - replace.push({ from: squash, to: undefined }); - configuredKeys = common_1.map(replace, hof_1.prop("from")); - return common_1.filter(defaultPolicy, function (item) { return configuredKeys.indexOf(item.from) === -1; }).concat(replace); -} -/** @internalapi */ -var Param = /** @class */ (function () { - function Param(id, type, config, location, urlMatcherFactory) { - config = unwrapShorthand(config); - type = getType(config, type, location, id, urlMatcherFactory.paramTypes); - var arrayMode = getArrayMode(); - type = arrayMode ? type.$asArray(arrayMode, location === DefType.SEARCH) : type; - var isOptional = config.value !== undefined || location === DefType.SEARCH; - var dynamic = predicates_1.isDefined(config.dynamic) ? !!config.dynamic : !!type.dynamic; - var raw = predicates_1.isDefined(config.raw) ? !!config.raw : !!type.raw; - var squash = getSquashPolicy(config, isOptional, urlMatcherFactory.defaultSquashPolicy()); - var replace = getReplace(config, arrayMode, isOptional, squash); - var inherit = predicates_1.isDefined(config.inherit) ? !!config.inherit : !!type.inherit; - // array config: param name (param[]) overrides default settings. explicit config overrides param name. - function getArrayMode() { - var arrayDefaults = { array: (location === DefType.SEARCH ? "auto" : false) }; - var arrayParamNomenclature = id.match(/\[\]$/) ? { array: true } : {}; - return common_1.extend(arrayDefaults, arrayParamNomenclature, config).array; - } - common_1.extend(this, { id: id, type: type, location: location, isOptional: isOptional, dynamic: dynamic, raw: raw, squash: squash, replace: replace, inherit: inherit, array: arrayMode, config: config }); - } - Param.prototype.isDefaultValue = function (value) { - return this.isOptional && this.type.equals(this.value(), value); - }; - /** - * [Internal] Gets the decoded representation of a value if the value is defined, otherwise, returns the - * default value, which may be the result of an injectable function. - */ - Param.prototype.value = function (value) { - var _this = this; - /** - * [Internal] Get the default value of a parameter, which may be an injectable function. - */ - var getDefaultValue = function () { - if (_this._defaultValueCache) - return _this._defaultValueCache.defaultValue; - if (!coreservices_1.services.$injector) - throw new Error("Injectable functions cannot be called at configuration time"); - var defaultValue = coreservices_1.services.$injector.invoke(_this.config.$$fn); - if (defaultValue !== null && defaultValue !== undefined && !_this.type.is(defaultValue)) - throw new Error("Default value (" + defaultValue + ") for parameter '" + _this.id + "' is not an instance of ParamType (" + _this.type.name + ")"); - if (_this.config.$$fn['__cacheable']) { - _this._defaultValueCache = { defaultValue: defaultValue }; - } - return defaultValue; - }; - var replaceSpecialValues = function (val) { - for (var _i = 0, _a = _this.replace; _i < _a.length; _i++) { - var tuple = _a[_i]; - if (tuple.from === val) - return tuple.to; - } - return val; - }; - value = replaceSpecialValues(value); - return predicates_1.isUndefined(value) ? getDefaultValue() : this.type.$normalize(value); - }; - Param.prototype.isSearch = function () { - return this.location === DefType.SEARCH; - }; - Param.prototype.validates = function (value) { - // There was no parameter value, but the param is optional - if ((predicates_1.isUndefined(value) || value === null) && this.isOptional) - return true; - // The value was not of the correct ParamType, and could not be decoded to the correct ParamType - var normalized = this.type.$normalize(value); - if (!this.type.is(normalized)) - return false; - // The value was of the correct type, but when encoded, did not match the ParamType's regexp - var encoded = this.type.encode(normalized); - return !(predicates_1.isString(encoded) && !this.type.pattern.exec(encoded)); - }; - Param.prototype.toString = function () { - return "{Param:" + this.id + " " + this.type + " squash: '" + this.squash + "' optional: " + this.isOptional + "}"; - }; - Param.values = function (params, values) { - if (values === void 0) { values = {}; } - var paramValues = {}; - for (var _i = 0, params_1 = params; _i < params_1.length; _i++) { - var param = params_1[_i]; - paramValues[param.id] = param.value(values[param.id]); - } - return paramValues; - }; - /** - * Finds [[Param]] objects which have different param values - * - * Filters a list of [[Param]] objects to only those whose parameter values differ in two param value objects - * - * @param params: The list of Param objects to filter - * @param values1: The first set of parameter values - * @param values2: the second set of parameter values - * - * @returns any Param objects whose values were different between values1 and values2 - */ - Param.changed = function (params, values1, values2) { - if (values1 === void 0) { values1 = {}; } - if (values2 === void 0) { values2 = {}; } - return params.filter(function (param) { return !param.type.equals(values1[param.id], values2[param.id]); }); - }; - /** - * Checks if two param value objects are equal (for a set of [[Param]] objects) - * - * @param params The list of [[Param]] objects to check - * @param values1 The first set of param values - * @param values2 The second set of param values - * - * @returns true if the param values in values1 and values2 are equal - */ - Param.equals = function (params, values1, values2) { - if (values1 === void 0) { values1 = {}; } - if (values2 === void 0) { values2 = {}; } - return Param.changed(params, values1, values2).length === 0; - }; - /** Returns true if a the parameter values are valid, according to the Param definitions */ - Param.validates = function (params, values) { - if (values === void 0) { values = {}; } - return params.map(function (param) { return param.validates(values[param.id]); }).reduce(common_1.allTrueR, true); - }; - return Param; -}()); -exports.Param = Param; -//# sourceMappingURL=param.js.map - -/***/ }), -/* 84 */ +/* 73 */ /***/ (function(module, exports, __webpack_require__) { -__webpack_require__(368); +__webpack_require__(319); module.exports = angular; /***/ }), -/* 85 */ +/* 74 */ /***/ (function(module, exports) { module.exports = function (it) { @@ -27041,7 +25316,7 @@ module.exports = function (it) { /***/ }), -/* 86 */ +/* 75 */ /***/ (function(module, exports) { module.exports = function (exec) { @@ -27054,7 +25329,7 @@ module.exports = function (exec) { /***/ }), -/* 87 */ +/* 76 */ /***/ (function(module, exports) { module.exports = function (bitmap, value) { @@ -27068,12 +25343,12 @@ module.exports = function (bitmap, value) { /***/ }), -/* 88 */ +/* 77 */ /***/ (function(module, exports, __webpack_require__) { // 19.1.2.14 / 15.2.3.14 Object.keys(O) -var $keys = __webpack_require__(221); -var enumBugKeys = __webpack_require__(146); +var $keys = __webpack_require__(195); +var enumBugKeys = __webpack_require__(122); module.exports = Object.keys || function keys(O) { return $keys(O, enumBugKeys); @@ -27081,25 +25356,25 @@ module.exports = Object.keys || function keys(O) { /***/ }), -/* 89 */ +/* 78 */ /***/ (function(module, exports) { exports.f = {}.propertyIsEnumerable; /***/ }), -/* 90 */ +/* 79 */ /***/ (function(module, exports) { module.exports = {}; /***/ }), -/* 91 */ +/* 80 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_object_values__ = __webpack_require__(71); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_object_values__ = __webpack_require__(64); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_object_values___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_object_values__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_objectWithoutProperties__ = __webpack_require__(6); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_objectWithoutProperties___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_objectWithoutProperties__); @@ -27117,11 +25392,11 @@ module.exports = {}; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_react__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_prop_types__ = __webpack_require__(8); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_8_prop_types__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9_prop_types_extra_lib_elementType__ = __webpack_require__(15); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9_prop_types_extra_lib_elementType__ = __webpack_require__(14); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_9_prop_types_extra_lib_elementType___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_9_prop_types_extra_lib_elementType__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__utils_bootstrapUtils__ = __webpack_require__(9); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__utils_StyleConfig__ = __webpack_require__(23); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__SafeAnchor__ = __webpack_require__(41); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__utils_StyleConfig__ = __webpack_require__(21); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__SafeAnchor__ = __webpack_require__(36); @@ -27219,7 +25494,7 @@ Button.defaultProps = defaultProps; /* harmony default export */ __webpack_exports__["a"] = (Object(__WEBPACK_IMPORTED_MODULE_10__utils_bootstrapUtils__["bsClass"])('btn', Object(__WEBPACK_IMPORTED_MODULE_10__utils_bootstrapUtils__["bsSizes"])([__WEBPACK_IMPORTED_MODULE_11__utils_StyleConfig__["c" /* Size */].LARGE, __WEBPACK_IMPORTED_MODULE_11__utils_StyleConfig__["c" /* Size */].SMALL, __WEBPACK_IMPORTED_MODULE_11__utils_StyleConfig__["c" /* Size */].XSMALL], Object(__WEBPACK_IMPORTED_MODULE_10__utils_bootstrapUtils__["bsStyles"])([].concat(__WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_object_values___default()(__WEBPACK_IMPORTED_MODULE_11__utils_StyleConfig__["d" /* State */]), [__WEBPACK_IMPORTED_MODULE_11__utils_StyleConfig__["e" /* Style */].DEFAULT, __WEBPACK_IMPORTED_MODULE_11__utils_StyleConfig__["e" /* Style */].PRIMARY, __WEBPACK_IMPORTED_MODULE_11__utils_StyleConfig__["e" /* Style */].LINK]), __WEBPACK_IMPORTED_MODULE_11__utils_StyleConfig__["e" /* Style */].DEFAULT, Button)))); /***/ }), -/* 92 */ +/* 81 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -27233,11 +25508,11 @@ Button.defaultProps = defaultProps; -var EventPluginHub = __webpack_require__(93); -var EventPluginUtils = __webpack_require__(157); +var EventPluginHub = __webpack_require__(82); +var EventPluginUtils = __webpack_require__(134); -var accumulateInto = __webpack_require__(235); -var forEachAccumulated = __webpack_require__(236); +var accumulateInto = __webpack_require__(209); +var forEachAccumulated = __webpack_require__(210); var warning = __webpack_require__(12); var getListener = EventPluginHub.getListener; @@ -27357,7 +25632,7 @@ module.exports = EventPropagators; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 93 */ +/* 82 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -27371,14 +25646,14 @@ module.exports = EventPropagators; -var _prodInvariant = __webpack_require__(14); +var _prodInvariant = __webpack_require__(13); -var EventPluginRegistry = __webpack_require__(109); -var EventPluginUtils = __webpack_require__(157); -var ReactErrorUtils = __webpack_require__(158); +var EventPluginRegistry = __webpack_require__(95); +var EventPluginUtils = __webpack_require__(134); +var ReactErrorUtils = __webpack_require__(135); -var accumulateInto = __webpack_require__(235); -var forEachAccumulated = __webpack_require__(236); +var accumulateInto = __webpack_require__(209); +var forEachAccumulated = __webpack_require__(210); var invariant = __webpack_require__(11); /** @@ -27635,7 +25910,7 @@ module.exports = EventPluginHub; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 94 */ +/* 83 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -27649,9 +25924,9 @@ module.exports = EventPluginHub; -var SyntheticEvent = __webpack_require__(45); +var SyntheticEvent = __webpack_require__(39); -var getEventTarget = __webpack_require__(159); +var getEventTarget = __webpack_require__(136); /** * @interface UIEvent @@ -27697,7 +25972,7 @@ SyntheticEvent.augmentClass(SyntheticUIEvent, UIEventInterface); module.exports = SyntheticUIEvent; /***/ }), -/* 95 */ +/* 84 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -27746,7 +26021,7 @@ var ReactInstanceMap = { module.exports = ReactInstanceMap; /***/ }), -/* 96 */ +/* 85 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -27754,7 +26029,7 @@ module.exports = ReactInstanceMap; exports.__esModule = true; -var _createUncontrollable = __webpack_require__(529); +var _createUncontrollable = __webpack_require__(480); var _createUncontrollable2 = _interopRequireDefault(_createUncontrollable); @@ -27783,29 +26058,56 @@ exports.default = (0, _createUncontrollable2.default)(mixin, set); module.exports = exports['default']; /***/ }), -/* 97 */, -/* 98 */ +/* 86 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +exports.default = function (componentOrElement) { + return (0, _ownerDocument2.default)(_reactDom2.default.findDOMNode(componentOrElement)); +}; + +var _reactDom = __webpack_require__(24); + +var _reactDom2 = _interopRequireDefault(_reactDom); + +var _ownerDocument = __webpack_require__(67); + +var _ownerDocument2 = _interopRequireDefault(_ownerDocument); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +module.exports = exports['default']; + +/***/ }), +/* 87 */, +/* 88 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(10), - __webpack_require__(186), - __webpack_require__(63), - __webpack_require__(301), - __webpack_require__(22), - __webpack_require__(185), - __webpack_require__(187), - __webpack_require__(302), - __webpack_require__(303), - __webpack_require__(296), - __webpack_require__(304), - __webpack_require__(305), - __webpack_require__(306), - __webpack_require__(188), - - __webpack_require__(34), - __webpack_require__(310), - __webpack_require__(26) // contains + __webpack_require__(166), + __webpack_require__(56), + __webpack_require__(276), + __webpack_require__(20), + __webpack_require__(165), + __webpack_require__(167), + __webpack_require__(277), + __webpack_require__(278), + __webpack_require__(271), + __webpack_require__(279), + __webpack_require__(280), + __webpack_require__(281), + __webpack_require__(168), + + __webpack_require__(30), + __webpack_require__(285), + __webpack_require__(22) // contains ], __WEBPACK_AMD_DEFINE_RESULT__ = function( jQuery, pnum, access, rmargin, document, rcssNum, rnumnonpx, cssExpand, getStyles, swap, curCSS, adjustCSS, addGetHookIf, support ) { @@ -28229,7 +26531,7 @@ return jQuery; /***/ }), -/* 99 */ +/* 89 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function() { @@ -28241,473 +26543,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function() { /***/ }), -/* 100 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * @coreapi - * @module transition - */ /** for typedoc */ - -Object.defineProperty(exports, "__esModule", { value: true }); -var common_1 = __webpack_require__(13); -var strings_1 = __webpack_require__(44); -var hof_1 = __webpack_require__(17); -var RejectType; -(function (RejectType) { - RejectType[RejectType["SUPERSEDED"] = 2] = "SUPERSEDED"; - RejectType[RejectType["ABORTED"] = 3] = "ABORTED"; - RejectType[RejectType["INVALID"] = 4] = "INVALID"; - RejectType[RejectType["IGNORED"] = 5] = "IGNORED"; - RejectType[RejectType["ERROR"] = 6] = "ERROR"; -})(RejectType = exports.RejectType || (exports.RejectType = {})); -/** @hidden */ var id = 0; -var Rejection = /** @class */ (function () { - function Rejection(type, message, detail) { - this.$id = id++; - this.type = type; - this.message = message; - this.detail = detail; - } - Rejection.prototype.toString = function () { - var detailString = function (d) { - return d && d.toString !== Object.prototype.toString ? d.toString() : strings_1.stringify(d); - }; - var detail = detailString(this.detail); - var _a = this, $id = _a.$id, type = _a.type, message = _a.message; - return "Transition Rejection($id: " + $id + " type: " + type + ", message: " + message + ", detail: " + detail + ")"; - }; - Rejection.prototype.toPromise = function () { - return common_1.extend(common_1.silentRejection(this), { _transitionRejection: this }); - }; - /** Returns true if the obj is a rejected promise created from the `asPromise` factory */ - Rejection.isRejectionPromise = function (obj) { - return obj && (typeof obj.then === 'function') && hof_1.is(Rejection)(obj._transitionRejection); - }; - /** Returns a Rejection due to transition superseded */ - Rejection.superseded = function (detail, options) { - var message = "The transition has been superseded by a different transition"; - var rejection = new Rejection(RejectType.SUPERSEDED, message, detail); - if (options && options.redirected) { - rejection.redirected = true; - } - return rejection; - }; - /** Returns a Rejection due to redirected transition */ - Rejection.redirected = function (detail) { - return Rejection.superseded(detail, { redirected: true }); - }; - /** Returns a Rejection due to invalid transition */ - Rejection.invalid = function (detail) { - var message = "This transition is invalid"; - return new Rejection(RejectType.INVALID, message, detail); - }; - /** Returns a Rejection due to ignored transition */ - Rejection.ignored = function (detail) { - var message = "The transition was ignored"; - return new Rejection(RejectType.IGNORED, message, detail); - }; - /** Returns a Rejection due to aborted transition */ - Rejection.aborted = function (detail) { - var message = "The transition has been aborted"; - return new Rejection(RejectType.ABORTED, message, detail); - }; - /** Returns a Rejection due to aborted transition */ - Rejection.errored = function (detail) { - var message = "The transition errored"; - return new Rejection(RejectType.ERROR, message, detail); - }; - /** - * Returns a Rejection - * - * Normalizes a value as a Rejection. - * If the value is already a Rejection, returns it. - * Otherwise, wraps and returns the value as a Rejection (Rejection type: ERROR). - * - * @returns `detail` if it is already a `Rejection`, else returns an ERROR Rejection. - */ - Rejection.normalize = function (detail) { - return hof_1.is(Rejection)(detail) ? detail : Rejection.errored(detail); - }; - return Rejection; -}()); -exports.Rejection = Rejection; -//# sourceMappingURL=rejectFactory.js.map - -/***/ }), -/* 101 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -/** - * @coreapi - * @module transition - */ -/** for typedoc */ -var interface_1 = __webpack_require__(81); -var common_1 = __webpack_require__(13); -var strings_1 = __webpack_require__(44); -var predicates_1 = __webpack_require__(16); -var hof_1 = __webpack_require__(17); -var trace_1 = __webpack_require__(54); -var coreservices_1 = __webpack_require__(27); -var rejectFactory_1 = __webpack_require__(100); -var targetState_1 = __webpack_require__(82); -var defaultOptions = { - current: common_1.noop, - transition: null, - traceData: {}, - bind: null, -}; -/** @hidden */ -var TransitionHook = /** @class */ (function () { - function TransitionHook(transition, stateContext, registeredHook, options) { - var _this = this; - this.transition = transition; - this.stateContext = stateContext; - this.registeredHook = registeredHook; - this.options = options; - this.isSuperseded = function () { - return _this.type.hookPhase === interface_1.TransitionHookPhase.RUN && !_this.options.transition.isActive(); - }; - this.options = common_1.defaults(options, defaultOptions); - this.type = registeredHook.eventType; - } - TransitionHook.prototype.logError = function (err) { - this.transition.router.stateService.defaultErrorHandler()(err); - }; - TransitionHook.prototype.invokeHook = function () { - var _this = this; - var hook = this.registeredHook; - if (hook._deregistered) - return; - var notCurrent = this.getNotCurrentRejection(); - if (notCurrent) - return notCurrent; - var options = this.options; - trace_1.trace.traceHookInvocation(this, this.transition, options); - var invokeCallback = function () { - return hook.callback.call(options.bind, _this.transition, _this.stateContext); - }; - var normalizeErr = function (err) { - return rejectFactory_1.Rejection.normalize(err).toPromise(); - }; - var handleError = function (err) { - return hook.eventType.getErrorHandler(_this)(err); - }; - var handleResult = function (result) { - return hook.eventType.getResultHandler(_this)(result); - }; - try { - var result = invokeCallback(); - if (!this.type.synchronous && predicates_1.isPromise(result)) { - return result.catch(normalizeErr) - .then(handleResult, handleError); - } - else { - return handleResult(result); - } - } - catch (err) { - // If callback throws (synchronously) - return handleError(rejectFactory_1.Rejection.normalize(err)); - } - finally { - if (hook.invokeLimit && ++hook.invokeCount >= hook.invokeLimit) { - hook.deregister(); - } - } - }; - /** - * This method handles the return value of a Transition Hook. - * - * A hook can return false (cancel), a TargetState (redirect), - * or a promise (which may later resolve to false or a redirect) - * - * This also handles "transition superseded" -- when a new transition - * was started while the hook was still running - */ - TransitionHook.prototype.handleHookResult = function (result) { - var _this = this; - var notCurrent = this.getNotCurrentRejection(); - if (notCurrent) - return notCurrent; - // Hook returned a promise - if (predicates_1.isPromise(result)) { - // Wait for the promise, then reprocess with the resulting value - return result.then(function (val) { return _this.handleHookResult(val); }); - } - trace_1.trace.traceHookResult(result, this.transition, this.options); - // Hook returned false - if (result === false) { - // Abort this Transition - return rejectFactory_1.Rejection.aborted("Hook aborted transition").toPromise(); - } - var isTargetState = hof_1.is(targetState_1.TargetState); - // hook returned a TargetState - if (isTargetState(result)) { - // Halt the current Transition and redirect (a new Transition) to the TargetState. - return rejectFactory_1.Rejection.redirected(result).toPromise(); - } - }; - /** - * Return a Rejection promise if the transition is no longer current due - * to a stopped router (disposed), or a new transition has started and superseded this one. - */ - TransitionHook.prototype.getNotCurrentRejection = function () { - var router = this.transition.router; - // The router is stopped - if (router._disposed) { - return rejectFactory_1.Rejection.aborted("UIRouter instance #" + router.$id + " has been stopped (disposed)").toPromise(); - } - if (this.transition._aborted) { - return rejectFactory_1.Rejection.aborted().toPromise(); - } - // This transition is no longer current. - // Another transition started while this hook was still running. - if (this.isSuperseded()) { - // Abort this transition - return rejectFactory_1.Rejection.superseded(this.options.current()).toPromise(); - } - }; - TransitionHook.prototype.toString = function () { - var _a = this, options = _a.options, registeredHook = _a.registeredHook; - var event = hof_1.parse("traceData.hookType")(options) || "internal", context = hof_1.parse("traceData.context.state.name")(options) || hof_1.parse("traceData.context")(options) || "unknown", name = strings_1.fnToString(registeredHook.callback); - return event + " context: " + context + ", " + strings_1.maxLength(200, name); - }; - /** - * Chains together an array of TransitionHooks. - * - * Given a list of [[TransitionHook]] objects, chains them together. - * Each hook is invoked after the previous one completes. - * - * #### Example: - * ```js - * var hooks: TransitionHook[] = getHooks(); - * let promise: Promise = TransitionHook.chain(hooks); - * - * promise.then(handleSuccess, handleError); - * ``` - * - * @param hooks the list of hooks to chain together - * @param waitFor if provided, the chain is `.then()`'ed off this promise - * @returns a `Promise` for sequentially invoking the hooks (in order) - */ - TransitionHook.chain = function (hooks, waitFor) { - // Chain the next hook off the previous - var createHookChainR = function (prev, nextHook) { - return prev.then(function () { return nextHook.invokeHook(); }); - }; - return hooks.reduce(createHookChainR, waitFor || coreservices_1.services.$q.when()); - }; - /** - * Invokes all the provided TransitionHooks, in order. - * Each hook's return value is checked. - * If any hook returns a promise, then the rest of the hooks are chained off that promise, and the promise is returned. - * If no hook returns a promise, then all hooks are processed synchronously. - * - * @param hooks the list of TransitionHooks to invoke - * @param doneCallback a callback that is invoked after all the hooks have successfully completed - * - * @returns a promise for the async result, or the result of the callback - */ - TransitionHook.invokeHooks = function (hooks, doneCallback) { - for (var idx = 0; idx < hooks.length; idx++) { - var hookResult = hooks[idx].invokeHook(); - if (predicates_1.isPromise(hookResult)) { - var remainingHooks = hooks.slice(idx + 1); - return TransitionHook.chain(remainingHooks, hookResult) - .then(doneCallback); - } - } - return doneCallback(); - }; - /** - * Run all TransitionHooks, ignoring their return value. - */ - TransitionHook.runAllHooks = function (hooks) { - hooks.forEach(function (hook) { return hook.invokeHook(); }); - }; - /** - * These GetResultHandler(s) are used by [[invokeHook]] below - * Each HookType chooses a GetResultHandler (See: [[TransitionService._defineCoreEvents]]) - */ - TransitionHook.HANDLE_RESULT = function (hook) { return function (result) { - return hook.handleHookResult(result); - }; }; - /** - * If the result is a promise rejection, log it. - * Otherwise, ignore the result. - */ - TransitionHook.LOG_REJECTED_RESULT = function (hook) { return function (result) { - predicates_1.isPromise(result) && result.catch(function (err) { - return hook.logError(rejectFactory_1.Rejection.normalize(err)); - }); - return undefined; - }; }; - /** - * These GetErrorHandler(s) are used by [[invokeHook]] below - * Each HookType chooses a GetErrorHandler (See: [[TransitionService._defineCoreEvents]]) - */ - TransitionHook.LOG_ERROR = function (hook) { return function (error) { - return hook.logError(error); - }; }; - TransitionHook.REJECT_ERROR = function (hook) { return function (error) { - return common_1.silentRejection(error); - }; }; - TransitionHook.THROW_ERROR = function (hook) { return function (error) { - throw error; - }; }; - return TransitionHook; -}()); -exports.TransitionHook = TransitionHook; -//# sourceMappingURL=transitionHook.js.map - -/***/ }), -/* 102 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -/** - * @coreapi - * @module resolve - */ /** for typedoc */ -var common_1 = __webpack_require__(13); -var coreservices_1 = __webpack_require__(27); -var trace_1 = __webpack_require__(54); -var strings_1 = __webpack_require__(44); -var predicates_1 = __webpack_require__(16); -var common_2 = __webpack_require__(35); -// TODO: explicitly make this user configurable -exports.defaultResolvePolicy = { - when: "LAZY", - async: "WAIT" -}; -/** - * The basic building block for the resolve system. - * - * Resolvables encapsulate a state's resolve's resolveFn, the resolveFn's declared dependencies, the wrapped (.promise), - * and the unwrapped-when-complete (.data) result of the resolveFn. - * - * Resolvable.get() either retrieves the Resolvable's existing promise, or else invokes resolve() (which invokes the - * resolveFn) and returns the resulting promise. - * - * Resolvable.get() and Resolvable.resolve() both execute within a context path, which is passed as the first - * parameter to those fns. - */ -var Resolvable = /** @class */ (function () { - function Resolvable(arg1, resolveFn, deps, policy, data) { - this.resolved = false; - this.promise = undefined; - if (arg1 instanceof Resolvable) { - common_1.extend(this, arg1); - } - else if (predicates_1.isFunction(resolveFn)) { - if (common_2.isNullOrUndefined(arg1)) - throw new Error("new Resolvable(): token argument is required"); - if (!predicates_1.isFunction(resolveFn)) - throw new Error("new Resolvable(): resolveFn argument must be a function"); - this.token = arg1; - this.policy = policy; - this.resolveFn = resolveFn; - this.deps = deps || []; - this.data = data; - this.resolved = data !== undefined; - this.promise = this.resolved ? coreservices_1.services.$q.when(this.data) : undefined; - } - else if (predicates_1.isObject(arg1) && arg1.token && predicates_1.isFunction(arg1.resolveFn)) { - var literal = arg1; - return new Resolvable(literal.token, literal.resolveFn, literal.deps, literal.policy, literal.data); - } - } - Resolvable.prototype.getPolicy = function (state) { - var thisPolicy = this.policy || {}; - var statePolicy = state && state.resolvePolicy || {}; - return { - when: thisPolicy.when || statePolicy.when || exports.defaultResolvePolicy.when, - async: thisPolicy.async || statePolicy.async || exports.defaultResolvePolicy.async, - }; - }; - /** - * Asynchronously resolve this Resolvable's data - * - * Given a ResolveContext that this Resolvable is found in: - * Wait for this Resolvable's dependencies, then invoke this Resolvable's function - * and update the Resolvable's state - */ - Resolvable.prototype.resolve = function (resolveContext, trans) { - var _this = this; - var $q = coreservices_1.services.$q; - // Gets all dependencies from ResolveContext and wait for them to be resolved - var getResolvableDependencies = function () { - return $q.all(resolveContext.getDependencies(_this).map(function (resolvable) { - return resolvable.get(resolveContext, trans); - })); - }; - // Invokes the resolve function passing the resolved dependencies as arguments - var invokeResolveFn = function (resolvedDeps) { - return _this.resolveFn.apply(null, resolvedDeps); - }; - /** - * For RXWAIT policy: - * - * Given an observable returned from a resolve function: - * - enables .cache() mode (this allows multicast subscribers) - * - then calls toPromise() (this triggers subscribe() and thus fetches) - * - Waits for the promise, then return the cached observable (not the first emitted value). - */ - var waitForRx = function (observable$) { - var cached = observable$.cache(1); - return cached.take(1).toPromise().then(function () { return cached; }); - }; - // If the resolve policy is RXWAIT, wait for the observable to emit something. otherwise pass through. - var node = resolveContext.findNode(this); - var state = node && node.state; - var maybeWaitForRx = this.getPolicy(state).async === "RXWAIT" ? waitForRx : common_1.identity; - // After the final value has been resolved, update the state of the Resolvable - var applyResolvedValue = function (resolvedValue) { - _this.data = resolvedValue; - _this.resolved = true; - trace_1.trace.traceResolvableResolved(_this, trans); - return _this.data; - }; - // Sets the promise property first, then getsResolvableDependencies in the context of the promise chain. Always waits one tick. - return this.promise = $q.when() - .then(getResolvableDependencies) - .then(invokeResolveFn) - .then(maybeWaitForRx) - .then(applyResolvedValue); - }; - /** - * Gets a promise for this Resolvable's data. - * - * Fetches the data and returns a promise. - * Returns the existing promise if it has already been fetched once. - */ - Resolvable.prototype.get = function (resolveContext, trans) { - return this.promise || this.resolve(resolveContext, trans); - }; - Resolvable.prototype.toString = function () { - return "Resolvable(token: " + strings_1.stringify(this.token) + ", requires: [" + this.deps.map(strings_1.stringify) + "])"; - }; - Resolvable.prototype.clone = function () { - return new Resolvable(this); - }; - Resolvable.fromData = function (token, data) { - return new Resolvable(token, function () { return data; }, null, null, data); - }; - return Resolvable; -}()); -exports.Resolvable = Resolvable; -//# sourceMappingURL=resolvable.js.map - -/***/ }), -/* 103 */ +/* 90 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -28737,7 +26573,7 @@ module.exports = canDefineProperty; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 104 */ +/* 91 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -28761,7 +26597,7 @@ module.exports = emptyObject; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 105 */ +/* 92 */ /***/ (function(module, exports) { var id = 0; @@ -28772,7 +26608,7 @@ module.exports = function (key) { /***/ }), -/* 106 */ +/* 93 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -28831,56 +26667,7 @@ module.exports = invariant; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 107 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = createChainableTypeChecker; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -// Mostly taken from ReactPropTypes. - -function createChainableTypeChecker(validate) { - function checkType(isRequired, props, propName, componentName, location, propFullName) { - var componentNameSafe = componentName || '<>'; - var propFullNameSafe = propFullName || propName; - - if (props[propName] == null) { - if (isRequired) { - return new Error('Required ' + location + ' `' + propFullNameSafe + '` was not specified ' + ('in `' + componentNameSafe + '`.')); - } - - return null; - } - - for (var _len = arguments.length, args = Array(_len > 6 ? _len - 6 : 0), _key = 6; _key < _len; _key++) { - args[_key - 6] = arguments[_key]; - } - - return validate.apply(undefined, [props, propName, componentNameSafe, location, propFullNameSafe].concat(args)); - } - - var chainedCheckType = checkType.bind(null, false); - chainedCheckType.isRequired = checkType.bind(null, true); - - return chainedCheckType; -} -module.exports = exports['default']; - -/***/ }), -/* 108 */ +/* 94 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -28891,7 +26678,7 @@ Object.defineProperty(exports, "__esModule", { }); exports.default = all; -var _createChainableTypeChecker = __webpack_require__(107); +var _createChainableTypeChecker = __webpack_require__(132); var _createChainableTypeChecker2 = _interopRequireDefault(_createChainableTypeChecker); @@ -28928,7 +26715,7 @@ function all() { module.exports = exports['default']; /***/ }), -/* 109 */ +/* 95 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -28943,7 +26730,7 @@ module.exports = exports['default']; -var _prodInvariant = __webpack_require__(14); +var _prodInvariant = __webpack_require__(13); var invariant = __webpack_require__(11); @@ -29185,7 +26972,7 @@ module.exports = EventPluginRegistry; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 110 */ +/* 96 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -29200,7 +26987,7 @@ module.exports = EventPluginRegistry; -var _prodInvariant = __webpack_require__(14); +var _prodInvariant = __webpack_require__(13); var invariant = __webpack_require__(11); @@ -29417,7 +27204,7 @@ module.exports = TransactionImpl; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 111 */ +/* 97 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -29431,10 +27218,10 @@ module.exports = TransactionImpl; -var SyntheticUIEvent = __webpack_require__(94); -var ViewportMetrics = __webpack_require__(242); +var SyntheticUIEvent = __webpack_require__(83); +var ViewportMetrics = __webpack_require__(216); -var getEventModifierState = __webpack_require__(161); +var getEventModifierState = __webpack_require__(138); /** * @interface MouseEvent @@ -29492,7 +27279,7 @@ SyntheticUIEvent.augmentClass(SyntheticMouseEvent, MouseEventInterface); module.exports = SyntheticMouseEvent; /***/ }), -/* 112 */ +/* 98 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -29506,13 +27293,13 @@ module.exports = SyntheticMouseEvent; -var ExecutionEnvironment = __webpack_require__(21); -var DOMNamespaces = __webpack_require__(163); +var ExecutionEnvironment = __webpack_require__(18); +var DOMNamespaces = __webpack_require__(140); var WHITESPACE_TEST = /^[ \r\n\t\f]/; var NONVISIBLE_TEST = /<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/; -var createMicrosoftUnsafeLocalFunction = __webpack_require__(164); +var createMicrosoftUnsafeLocalFunction = __webpack_require__(141); // SVG temp container for IE lacking innerHTML var reusableSVGContainer; @@ -29593,7 +27380,7 @@ if (ExecutionEnvironment.canUseDOM) { module.exports = setInnerHTML; /***/ }), -/* 113 */ +/* 99 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -29718,7 +27505,7 @@ function escapeTextContentForBrowser(text) { module.exports = escapeTextContentForBrowser; /***/ }), -/* 114 */ +/* 100 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -29732,14 +27519,14 @@ module.exports = escapeTextContentForBrowser; -var _assign = __webpack_require__(18); +var _assign = __webpack_require__(15); -var EventPluginRegistry = __webpack_require__(109); -var ReactEventEmitterMixin = __webpack_require__(467); -var ViewportMetrics = __webpack_require__(242); +var EventPluginRegistry = __webpack_require__(95); +var ReactEventEmitterMixin = __webpack_require__(418); +var ViewportMetrics = __webpack_require__(216); -var getVendorPrefixedEventName = __webpack_require__(468); -var isEventSupported = __webpack_require__(160); +var getVendorPrefixedEventName = __webpack_require__(419); +var isEventSupported = __webpack_require__(137); /** * Summary of `ReactBrowserEventEmitter` event handling: @@ -30045,7 +27832,7 @@ var ReactBrowserEventEmitter = _assign({}, ReactEventEmitterMixin, { module.exports = ReactBrowserEventEmitter; /***/ }), -/* 115 */ +/* 101 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -30056,25 +27843,25 @@ Object.defineProperty(exports, "__esModule", { }); exports.default = style; -var _camelizeStyle = __webpack_require__(260); +var _camelizeStyle = __webpack_require__(234); var _camelizeStyle2 = _interopRequireDefault(_camelizeStyle); -var _hyphenateStyle = __webpack_require__(524); +var _hyphenateStyle = __webpack_require__(475); var _hyphenateStyle2 = _interopRequireDefault(_hyphenateStyle); -var _getComputedStyle2 = __webpack_require__(526); +var _getComputedStyle2 = __webpack_require__(477); var _getComputedStyle3 = _interopRequireDefault(_getComputedStyle2); -var _removeStyle = __webpack_require__(527); +var _removeStyle = __webpack_require__(478); var _removeStyle2 = _interopRequireDefault(_removeStyle); -var _properties = __webpack_require__(261); +var _properties = __webpack_require__(235); -var _isTransform = __webpack_require__(528); +var _isTransform = __webpack_require__(479); var _isTransform2 = _interopRequireDefault(_isTransform); @@ -30113,7 +27900,7 @@ function style(node, property, value) { module.exports = exports['default']; /***/ }), -/* 116 */ +/* 102 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -30123,7 +27910,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); -var _inDOM = __webpack_require__(51); +var _inDOM = __webpack_require__(45); var _inDOM2 = _interopRequireDefault(_inDOM); @@ -30150,14 +27937,14 @@ exports.default = on; module.exports = exports['default']; /***/ }), -/* 117 */ +/* 103 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_extends__ = __webpack_require__(5); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_extends___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_extends__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_objectWithoutProperties__ = __webpack_require__(6); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_objectWithoutProperties___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_objectWithoutProperties__); +/* WEBPACK VAR INJECTION */(function(process) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_objectWithoutProperties__ = __webpack_require__(6); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_objectWithoutProperties___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_objectWithoutProperties__); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_extends__ = __webpack_require__(5); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_extends___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_extends__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_babel_runtime_helpers_classCallCheck__ = __webpack_require__(2); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_babel_runtime_helpers_classCallCheck___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_babel_runtime_helpers_classCallCheck__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_babel_runtime_helpers_possibleConstructorReturn__ = __webpack_require__(3); @@ -30166,11 +27953,11 @@ module.exports = exports['default']; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_babel_runtime_helpers_inherits___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_babel_runtime_helpers_inherits__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_classnames__ = __webpack_require__(7); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_classnames___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_classnames__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_dom_helpers_activeElement__ = __webpack_require__(263); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_dom_helpers_activeElement__ = __webpack_require__(237); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_dom_helpers_activeElement___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_dom_helpers_activeElement__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_dom_helpers_query_contains__ = __webpack_require__(75); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_dom_helpers_query_contains__ = __webpack_require__(68); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_dom_helpers_query_contains___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_dom_helpers_query_contains__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_keycode__ = __webpack_require__(175); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_keycode__ = __webpack_require__(152); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_keycode___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_8_keycode__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_9_react__ = __webpack_require__(0); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_9_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_9_react__); @@ -30178,23 +27965,23 @@ module.exports = exports['default']; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_10_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_10_prop_types__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_11_react_dom__ = __webpack_require__(24); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_11_react_dom___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_11_react_dom__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12_prop_types_extra_lib_all__ = __webpack_require__(108); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12_prop_types_extra_lib_all__ = __webpack_require__(94); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_12_prop_types_extra_lib_all___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_12_prop_types_extra_lib_all__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13_prop_types_extra_lib_elementType__ = __webpack_require__(15); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13_prop_types_extra_lib_elementType__ = __webpack_require__(14); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_13_prop_types_extra_lib_elementType___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_13_prop_types_extra_lib_elementType__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14_prop_types_extra_lib_isRequiredForA11y__ = __webpack_require__(118); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14_prop_types_extra_lib_isRequiredForA11y__ = __webpack_require__(104); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_14_prop_types_extra_lib_isRequiredForA11y___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_14_prop_types_extra_lib_isRequiredForA11y__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15_uncontrollable__ = __webpack_require__(96); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15_uncontrollable__ = __webpack_require__(85); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_15_uncontrollable___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_15_uncontrollable__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16_warning__ = __webpack_require__(32); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16_warning__ = __webpack_require__(29); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_16_warning___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_16_warning__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_17__ButtonGroup__ = __webpack_require__(156); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_18__DropdownMenu__ = __webpack_require__(531); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_19__DropdownToggle__ = __webpack_require__(266); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_17__ButtonGroup__ = __webpack_require__(133); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_18__DropdownMenu__ = __webpack_require__(482); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_19__DropdownToggle__ = __webpack_require__(240); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_20__utils_bootstrapUtils__ = __webpack_require__(9); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_21__utils_createChainedFunction__ = __webpack_require__(20); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_22__utils_PropTypes__ = __webpack_require__(541); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_23__utils_ValidComponentChildren__ = __webpack_require__(28); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_21__utils_createChainedFunction__ = __webpack_require__(17); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_22__utils_PropTypes__ = __webpack_require__(492); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_23__utils_ValidComponentChildren__ = __webpack_require__(23); @@ -30355,26 +28142,6 @@ var Dropdown = function (_React$Component) { } }; - Dropdown.prototype.focus = function focus() { - var toggle = __WEBPACK_IMPORTED_MODULE_11_react_dom___default.a.findDOMNode(this.toggle); - - if (toggle && toggle.focus) { - toggle.focus(); - } - }; - - Dropdown.prototype.focusNextOnOpen = function focusNextOnOpen() { - var menu = this.menu; - - if (!menu.focusNext) { - return; - } - - if (this.lastOpenEventType === 'keydown' || this.props.role === 'menuitem') { - menu.focusNext(); - } - }; - Dropdown.prototype.handleClick = function handleClick(event) { if (this.props.disabled) { return; @@ -30383,14 +28150,6 @@ var Dropdown = function (_React$Component) { this.toggleOpen(event, { source: 'click' }); }; - Dropdown.prototype.handleClose = function handleClose(event, eventDetails) { - if (!this.props.open) { - return; - } - - this.toggleOpen(event, eventDetails); - }; - Dropdown.prototype.handleKeyDown = function handleKeyDown(event) { if (this.props.disabled) { return; @@ -30425,54 +28184,82 @@ var Dropdown = function (_React$Component) { } }; - Dropdown.prototype.renderMenu = function renderMenu(child, _ref) { - var _this2 = this; + Dropdown.prototype.handleClose = function handleClose(event, eventDetails) { + if (!this.props.open) { + return; + } - var id = _ref.id, - onSelect = _ref.onSelect, - rootCloseEvent = _ref.rootCloseEvent, - props = __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_objectWithoutProperties___default()(_ref, ['id', 'onSelect', 'rootCloseEvent']); + this.toggleOpen(event, eventDetails); + }; + + Dropdown.prototype.focusNextOnOpen = function focusNextOnOpen() { + var menu = this.menu; + + if (!menu.focusNext) { + return; + } + + if (this.lastOpenEventType === 'keydown' || this.props.role === 'menuitem') { + menu.focusNext(); + } + }; + + Dropdown.prototype.focus = function focus() { + var toggle = __WEBPACK_IMPORTED_MODULE_11_react_dom___default.a.findDOMNode(this.toggle); + + if (toggle && toggle.focus) { + toggle.focus(); + } + }; + + Dropdown.prototype.renderToggle = function renderToggle(child, props) { + var _this2 = this; var ref = function ref(c) { - _this2.menu = c; + _this2.toggle = c; }; if (typeof child.ref === 'string') { - process.env.NODE_ENV !== 'production' ? __WEBPACK_IMPORTED_MODULE_16_warning___default()(false, 'String refs are not supported on `` components. ' + 'To apply a ref to the component use the callback signature:\n\n ' + 'https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute') : void 0; + process.env.NODE_ENV !== 'production' ? __WEBPACK_IMPORTED_MODULE_16_warning___default()(false, 'String refs are not supported on `` components. ' + 'To apply a ref to the component use the callback signature:\n\n ' + 'https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute') : void 0; } else { ref = Object(__WEBPACK_IMPORTED_MODULE_21__utils_createChainedFunction__["a" /* default */])(child.ref, ref); } - return Object(__WEBPACK_IMPORTED_MODULE_9_react__["cloneElement"])(child, __WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_extends___default()({}, props, { + return Object(__WEBPACK_IMPORTED_MODULE_9_react__["cloneElement"])(child, __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_extends___default()({}, props, { ref: ref, - labelledBy: id, - bsClass: Object(__WEBPACK_IMPORTED_MODULE_20__utils_bootstrapUtils__["prefix"])(props, 'menu'), - onClose: Object(__WEBPACK_IMPORTED_MODULE_21__utils_createChainedFunction__["a" /* default */])(child.props.onClose, this.handleClose), - onSelect: Object(__WEBPACK_IMPORTED_MODULE_21__utils_createChainedFunction__["a" /* default */])(child.props.onSelect, onSelect, function (key, event) { - return _this2.handleClose(event, { source: 'select' }); - }), - rootCloseEvent: rootCloseEvent + bsClass: Object(__WEBPACK_IMPORTED_MODULE_20__utils_bootstrapUtils__["prefix"])(props, 'toggle'), + onClick: Object(__WEBPACK_IMPORTED_MODULE_21__utils_createChainedFunction__["a" /* default */])(child.props.onClick, this.handleClick), + onKeyDown: Object(__WEBPACK_IMPORTED_MODULE_21__utils_createChainedFunction__["a" /* default */])(child.props.onKeyDown, this.handleKeyDown) })); }; - Dropdown.prototype.renderToggle = function renderToggle(child, props) { + Dropdown.prototype.renderMenu = function renderMenu(child, _ref) { var _this3 = this; + var id = _ref.id, + onSelect = _ref.onSelect, + rootCloseEvent = _ref.rootCloseEvent, + props = __WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_objectWithoutProperties___default()(_ref, ['id', 'onSelect', 'rootCloseEvent']); + var ref = function ref(c) { - _this3.toggle = c; + _this3.menu = c; }; if (typeof child.ref === 'string') { - process.env.NODE_ENV !== 'production' ? __WEBPACK_IMPORTED_MODULE_16_warning___default()(false, 'String refs are not supported on `` components. ' + 'To apply a ref to the component use the callback signature:\n\n ' + 'https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute') : void 0; + process.env.NODE_ENV !== 'production' ? __WEBPACK_IMPORTED_MODULE_16_warning___default()(false, 'String refs are not supported on `` components. ' + 'To apply a ref to the component use the callback signature:\n\n ' + 'https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute') : void 0; } else { ref = Object(__WEBPACK_IMPORTED_MODULE_21__utils_createChainedFunction__["a" /* default */])(child.ref, ref); } - return Object(__WEBPACK_IMPORTED_MODULE_9_react__["cloneElement"])(child, __WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_extends___default()({}, props, { + return Object(__WEBPACK_IMPORTED_MODULE_9_react__["cloneElement"])(child, __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_extends___default()({}, props, { ref: ref, - bsClass: Object(__WEBPACK_IMPORTED_MODULE_20__utils_bootstrapUtils__["prefix"])(props, 'toggle'), - onClick: Object(__WEBPACK_IMPORTED_MODULE_21__utils_createChainedFunction__["a" /* default */])(child.props.onClick, this.handleClick), - onKeyDown: Object(__WEBPACK_IMPORTED_MODULE_21__utils_createChainedFunction__["a" /* default */])(child.props.onKeyDown, this.handleKeyDown) + labelledBy: id, + bsClass: Object(__WEBPACK_IMPORTED_MODULE_20__utils_bootstrapUtils__["prefix"])(props, 'menu'), + onClose: Object(__WEBPACK_IMPORTED_MODULE_21__utils_createChainedFunction__["a" /* default */])(child.props.onClose, this.handleClose), + onSelect: Object(__WEBPACK_IMPORTED_MODULE_21__utils_createChainedFunction__["a" /* default */])(child.props.onSelect, onSelect, function (key, event) { + return _this3.handleClose(event, { source: 'select' }); + }), + rootCloseEvent: rootCloseEvent })); }; @@ -30493,7 +28280,7 @@ var Dropdown = function (_React$Component) { className = _props.className, rootCloseEvent = _props.rootCloseEvent, children = _props.children, - props = __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_objectWithoutProperties___default()(_props, ['componentClass', 'id', 'dropup', 'disabled', 'pullRight', 'open', 'onSelect', 'role', 'bsClass', 'className', 'rootCloseEvent', 'children']); + props = __WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_objectWithoutProperties___default()(_props, ['componentClass', 'id', 'dropup', 'disabled', 'pullRight', 'open', 'onSelect', 'role', 'bsClass', 'className', 'rootCloseEvent', 'children']); delete props.onToggle; @@ -30509,7 +28296,7 @@ var Dropdown = function (_React$Component) { return __WEBPACK_IMPORTED_MODULE_9_react___default.a.createElement( Component, - __WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_extends___default()({}, props, { + __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_extends___default()({}, props, { className: __WEBPACK_IMPORTED_MODULE_5_classnames___default()(className, classes) }), __WEBPACK_IMPORTED_MODULE_23__utils_ValidComponentChildren__["a" /* default */].map(children, function (child) { @@ -30546,7 +28333,7 @@ UncontrolledDropdown.Menu = __WEBPACK_IMPORTED_MODULE_18__DropdownMenu__["a" /* /* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(1))) /***/ }), -/* 118 */ +/* 104 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -30575,12 +28362,12 @@ function isRequiredForA11y(validator) { module.exports = exports['default']; /***/ }), -/* 119 */ +/* 105 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (immutable) */ __webpack_exports__["a"] = splitComponentProps; -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_object_entries__ = __webpack_require__(230); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_object_entries__ = __webpack_require__(204); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_object_entries___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_object_entries__); function splitComponentProps(props, Component) { @@ -30604,7 +28391,7 @@ function splitComponentProps(props, Component) { } /***/ }), -/* 120 */ +/* 106 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -30622,7 +28409,7 @@ function splitComponentProps(props, Component) { /* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_react__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_prop_types__ = __webpack_require__(8); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_prop_types__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_react_overlays_lib_Transition__ = __webpack_require__(262); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_react_overlays_lib_Transition__ = __webpack_require__(236); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_react_overlays_lib_Transition___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_react_overlays_lib_Transition__); @@ -30637,7 +28424,7 @@ var propTypes = { /** * Show the component; triggers the fade in or fade out animation */ - in: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.bool, + 'in': __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.bool, /** * Wait until the first "enter" transition to mount the component (add it to the DOM) @@ -30689,7 +28476,7 @@ var propTypes = { }; var defaultProps = { - in: false, + 'in': false, timeout: 300, mountOnEnter: false, unmountOnExit: false, @@ -30722,142 +28509,7 @@ Fade.defaultProps = defaultProps; /* harmony default export */ __webpack_exports__["a"] = (Fade); /***/ }), -/* 121 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_extends__ = __webpack_require__(5); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_extends___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_extends__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_objectWithoutProperties__ = __webpack_require__(6); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_objectWithoutProperties___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_objectWithoutProperties__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_babel_runtime_helpers_classCallCheck__ = __webpack_require__(2); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_babel_runtime_helpers_classCallCheck___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_babel_runtime_helpers_classCallCheck__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_babel_runtime_helpers_possibleConstructorReturn__ = __webpack_require__(3); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_babel_runtime_helpers_possibleConstructorReturn___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_babel_runtime_helpers_possibleConstructorReturn__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_babel_runtime_helpers_inherits__ = __webpack_require__(4); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_babel_runtime_helpers_inherits___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_babel_runtime_helpers_inherits__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_classnames__ = __webpack_require__(7); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_classnames___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_classnames__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_react__ = __webpack_require__(0); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_react__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_prop_types_extra_lib_elementType__ = __webpack_require__(15); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_prop_types_extra_lib_elementType___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_prop_types_extra_lib_elementType__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__MediaBody__ = __webpack_require__(556); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__MediaHeading__ = __webpack_require__(557); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__MediaLeft__ = __webpack_require__(558); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__MediaList__ = __webpack_require__(559); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__MediaListItem__ = __webpack_require__(560); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__MediaRight__ = __webpack_require__(561); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__utils_bootstrapUtils__ = __webpack_require__(9); - - - - - - - - - - - - - - - - - -var propTypes = { - componentClass: __WEBPACK_IMPORTED_MODULE_7_prop_types_extra_lib_elementType___default.a -}; - -var defaultProps = { - componentClass: 'div' -}; - -var Media = function (_React$Component) { - __WEBPACK_IMPORTED_MODULE_4_babel_runtime_helpers_inherits___default()(Media, _React$Component); - - function Media() { - __WEBPACK_IMPORTED_MODULE_2_babel_runtime_helpers_classCallCheck___default()(this, Media); - - return __WEBPACK_IMPORTED_MODULE_3_babel_runtime_helpers_possibleConstructorReturn___default()(this, _React$Component.apply(this, arguments)); - } - - Media.prototype.render = function render() { - var _props = this.props, - Component = _props.componentClass, - className = _props.className, - props = __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_objectWithoutProperties___default()(_props, ['componentClass', 'className']); - - var _splitBsProps = Object(__WEBPACK_IMPORTED_MODULE_14__utils_bootstrapUtils__["splitBsProps"])(props), - bsProps = _splitBsProps[0], - elementProps = _splitBsProps[1]; - - var classes = Object(__WEBPACK_IMPORTED_MODULE_14__utils_bootstrapUtils__["getClassSet"])(bsProps); - - return __WEBPACK_IMPORTED_MODULE_6_react___default.a.createElement(Component, __WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_extends___default()({}, elementProps, { - className: __WEBPACK_IMPORTED_MODULE_5_classnames___default()(className, classes) - })); - }; - - return Media; -}(__WEBPACK_IMPORTED_MODULE_6_react___default.a.Component); - -Media.propTypes = propTypes; -Media.defaultProps = defaultProps; - -Media.Heading = __WEBPACK_IMPORTED_MODULE_9__MediaHeading__["a" /* default */]; -Media.Body = __WEBPACK_IMPORTED_MODULE_8__MediaBody__["a" /* default */]; -Media.Left = __WEBPACK_IMPORTED_MODULE_10__MediaLeft__["a" /* default */]; -Media.Right = __WEBPACK_IMPORTED_MODULE_13__MediaRight__["a" /* default */]; -Media.List = __WEBPACK_IMPORTED_MODULE_11__MediaList__["a" /* default */]; -Media.ListItem = __WEBPACK_IMPORTED_MODULE_12__MediaListItem__["a" /* default */]; - -/* harmony default export */ __webpack_exports__["a"] = (Object(__WEBPACK_IMPORTED_MODULE_14__utils_bootstrapUtils__["bsClass"])('media', Media)); - -/***/ }), -/* 122 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - -var _react = __webpack_require__(0); - -var _react2 = _interopRequireDefault(_react); - -var _createChainableTypeChecker = __webpack_require__(107); - -var _createChainableTypeChecker2 = _interopRequireDefault(_createChainableTypeChecker); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function validate(props, propName, componentName, location, propFullName) { - var propValue = props[propName]; - var propType = typeof propValue === 'undefined' ? 'undefined' : _typeof(propValue); - - if (_react2.default.isValidElement(propValue)) { - return new Error('Invalid ' + location + ' `' + propFullName + '` of type ReactElement ' + ('supplied to `' + componentName + '`, expected a ReactComponent or a ') + 'DOMElement. You can usually obtain a ReactComponent or DOMElement ' + 'from a ReactElement by attaching a ref to it.'); - } - - if ((propType !== 'object' || typeof propValue.render !== 'function') && propValue.nodeType !== 1) { - return new Error('Invalid ' + location + ' `' + propFullName + '` of value `' + propValue + '` ' + ('supplied to `' + componentName + '`, expected a ReactComponent or a ') + 'DOMElement.'); - } - - return null; -} - -exports.default = (0, _createChainableTypeChecker2.default)(validate); -module.exports = exports['default']; - -/***/ }), -/* 123 */ +/* 107 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -30873,57 +28525,35 @@ function getWindow(node) { module.exports = exports["default"]; /***/ }), -/* 124 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -exports.default = getContainer; - -var _reactDom = __webpack_require__(24); - -var _reactDom2 = _interopRequireDefault(_reactDom); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function getContainer(container, defaultContainer) { - container = typeof container === 'function' ? container() : container; - return _reactDom2.default.findDOMNode(container) || defaultContainer; -} -module.exports = exports['default']; - -/***/ }), -/* 125 */, -/* 126 */, -/* 127 */ +/* 108 */, +/* 109 */, +/* 110 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(10), - __webpack_require__(297), - __webpack_require__(298), - __webpack_require__(63), - __webpack_require__(314), - __webpack_require__(315), - __webpack_require__(316), - __webpack_require__(317), - __webpack_require__(318), - __webpack_require__(319), - __webpack_require__(320), - __webpack_require__(651), - - __webpack_require__(43), - __webpack_require__(312), - __webpack_require__(191), - __webpack_require__(300), - __webpack_require__(53), - - __webpack_require__(34), - __webpack_require__(78), - __webpack_require__(26), - __webpack_require__(79) + __webpack_require__(272), + __webpack_require__(273), + __webpack_require__(56), + __webpack_require__(289), + __webpack_require__(290), + __webpack_require__(291), + __webpack_require__(292), + __webpack_require__(293), + __webpack_require__(294), + __webpack_require__(295), + __webpack_require__(598), + + __webpack_require__(38), + __webpack_require__(287), + __webpack_require__(171), + __webpack_require__(275), + __webpack_require__(47), + + __webpack_require__(30), + __webpack_require__(70), + __webpack_require__(22), + __webpack_require__(71) ], __WEBPACK_AMD_DEFINE_RESULT__ = function( jQuery, concat, push, access, rcheckableType, rtagName, rscriptType, wrapMap, getAll, setGlobalEval, buildFragment, support, @@ -31392,1961 +29022,249 @@ return jQuery; /***/ }), -/* 128 */ +/* 111 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +/* WEBPACK VAR INJECTION */(function(module) {//! moment.js +//! version : 2.18.1 +//! authors : Tim Wood, Iskren Chernev, Moment.js contributors +//! license : MIT +//! momentjs.com -Object.defineProperty(exports, "__esModule", { value: true }); -/** - * @coreapi - * @module core - */ -/** - * Matches state names using glob-like pattern strings. - * - * Globs can be used in specific APIs including: - * - * - [[StateService.is]] - * - [[StateService.includes]] - * - The first argument to Hook Registration functions like [[TransitionService.onStart]] - * - [[HookMatchCriteria]] and [[HookMatchCriterion]] - * - * A `Glob` string is a pattern which matches state names. - * Nested state names are split into segments (separated by a dot) when processing. - * The state named `foo.bar.baz` is split into three segments ['foo', 'bar', 'baz'] - * - * Globs work according to the following rules: - * - * ### Exact match: - * - * The glob `'A.B'` matches the state named exactly `'A.B'`. - * - * | Glob |Matches states named|Does not match state named| - * |:------------|:--------------------|:---------------------| - * | `'A'` | `'A'` | `'B'` , `'A.C'` | - * | `'A.B'` | `'A.B'` | `'A'` , `'A.B.C'` | - * | `'foo'` | `'foo'` | `'FOO'` , `'foo.bar'`| - * - * ### Single star (`*`) - * - * A single star (`*`) is a wildcard that matches exactly one segment. - * - * | Glob |Matches states named |Does not match state named | - * |:------------|:---------------------|:--------------------------| - * | `'*'` | `'A'` , `'Z'` | `'A.B'` , `'Z.Y.X'` | - * | `'A.*'` | `'A.B'` , `'A.C'` | `'A'` , `'A.B.C'` | - * | `'A.*.*'` | `'A.B.C'` , `'A.X.Y'`| `'A'`, `'A.B'` , `'Z.Y.X'`| - * - * ### Double star (`**`) - * - * A double star (`'**'`) is a wildcard that matches *zero or more segments* - * - * | Glob |Matches states named |Does not match state named | - * |:------------|:----------------------------------------------|:----------------------------------| - * | `'**'` | `'A'` , `'A.B'`, `'Z.Y.X'` | (matches all states) | - * | `'A.**'` | `'A'` , `'A.B'` , `'A.C.X'` | `'Z.Y.X'` | - * | `'**.X'` | `'X'` , `'A.X'` , `'Z.Y.X'` | `'A'` , `'A.login.Z'` | - * | `'A.**.X'` | `'A.X'` , `'A.B.X'` , `'A.B.C.X'` | `'A'` , `'A.B.C'` | - * - */ -var Glob = /** @class */ (function () { - function Glob(text) { - this.text = text; - this.glob = text.split('.'); - var regexpString = this.text.split('.') - .map(function (seg) { - if (seg === '**') - return '(?:|(?:\\.[^.]*)*)'; - if (seg === '*') - return '\\.[^.]*'; - return '\\.' + seg; - }).join(''); - this.regexp = new RegExp("^" + regexpString + "$"); +;(function (global, factory) { + true ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + global.moment = factory() +}(this, (function () { 'use strict'; + +var hookCallback; + +function hooks () { + return hookCallback.apply(null, arguments); +} + +// This is done to register the method called with moment() +// without creating circular dependencies. +function setHookCallback (callback) { + hookCallback = callback; +} + +function isArray(input) { + return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]'; +} + +function isObject(input) { + // IE8 will treat undefined and null as object if it wasn't for + // input != null + return input != null && Object.prototype.toString.call(input) === '[object Object]'; +} + +function isObjectEmpty(obj) { + var k; + for (k in obj) { + // even if its not own property I'd still call it non-empty + return false; } - Glob.prototype.matches = function (name) { - return this.regexp.test('.' + name); - }; - /** Returns true if the string has glob-like characters in it */ - Glob.is = function (text) { - return !!/[!,*]+/.exec(text); - }; - /** Returns a glob from the string, or null if the string isn't Glob-like */ - Glob.fromString = function (text) { - return Glob.is(text) ? new Glob(text) : null; - }; - return Glob; -}()); -exports.Glob = Glob; -//# sourceMappingURL=glob.js.map + return true; +} -/***/ }), -/* 129 */ -/***/ (function(module, exports, __webpack_require__) { +function isUndefined(input) { + return input === void 0; +} -"use strict"; +function isNumber(input) { + return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]'; +} -Object.defineProperty(exports, "__esModule", { value: true }); -/** - * @coreapi - * @module transition - */ -/** for typedoc */ -var trace_1 = __webpack_require__(54); -var coreservices_1 = __webpack_require__(27); -var strings_1 = __webpack_require__(44); -var common_1 = __webpack_require__(13); -var predicates_1 = __webpack_require__(16); -var hof_1 = __webpack_require__(17); -var interface_1 = __webpack_require__(81); // has or is using -var transitionHook_1 = __webpack_require__(101); -var hookRegistry_1 = __webpack_require__(199); -var hookBuilder_1 = __webpack_require__(333); -var pathFactory_1 = __webpack_require__(130); -var param_1 = __webpack_require__(83); -var resolvable_1 = __webpack_require__(102); -var resolveContext_1 = __webpack_require__(131); -/** @hidden */ -var stateSelf = hof_1.prop("self"); -/** - * Represents a transition between two states. - * - * When navigating to a state, we are transitioning **from** the current state **to** the new state. - * - * This object contains all contextual information about the to/from states, parameters, resolves. - * It has information about all states being entered and exited as a result of the transition. - */ -var Transition = /** @class */ (function () { - /** - * Creates a new Transition object. - * - * If the target state is not valid, an error is thrown. - * - * @internalapi - * - * @param fromPath The path of [[PathNode]]s from which the transition is leaving. The last node in the `fromPath` - * encapsulates the "from state". - * @param targetState The target state and parameters being transitioned to (also, the transition options) - * @param router The [[UIRouter]] instance - */ - function Transition(fromPath, targetState, router) { - var _this = this; - /** @hidden */ - this._deferred = coreservices_1.services.$q.defer(); - /** - * This promise is resolved or rejected based on the outcome of the Transition. - * - * When the transition is successful, the promise is resolved - * When the transition is unsuccessful, the promise is rejected with the [[Rejection]] or javascript error - */ - this.promise = this._deferred.promise; - /** @hidden Holds the hook registration functions such as those passed to Transition.onStart() */ - this._registeredHooks = {}; - /** @hidden */ - this._hookBuilder = new hookBuilder_1.HookBuilder(this); - /** Checks if this transition is currently active/running. */ - this.isActive = function () { - return _this.router.globals.transition === _this; - }; - this.router = router; - this._targetState = targetState; - if (!targetState.valid()) { - throw new Error(targetState.error()); - } - // current() is assumed to come from targetState.options, but provide a naive implementation otherwise. - this._options = common_1.extend({ current: hof_1.val(this) }, targetState.options()); - this.$id = router.transitionService._transitionCount++; - var toPath = pathFactory_1.PathUtils.buildToPath(fromPath, targetState); - this._treeChanges = pathFactory_1.PathUtils.treeChanges(fromPath, toPath, this._options.reloadState); - this.createTransitionHookRegFns(); - var onCreateHooks = this._hookBuilder.buildHooksForPhase(interface_1.TransitionHookPhase.CREATE); - transitionHook_1.TransitionHook.invokeHooks(onCreateHooks, function () { return null; }); - this.applyViewConfigs(router); +function isDate(input) { + return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]'; +} + +function map(arr, fn) { + var res = [], i; + for (i = 0; i < arr.length; ++i) { + res.push(fn(arr[i], i)); } - /** @hidden */ - Transition.prototype.onBefore = function (criteria, callback, options) { return; }; - /** @inheritdoc */ - Transition.prototype.onStart = function (criteria, callback, options) { return; }; - /** @inheritdoc */ - Transition.prototype.onExit = function (criteria, callback, options) { return; }; - /** @inheritdoc */ - Transition.prototype.onRetain = function (criteria, callback, options) { return; }; - /** @inheritdoc */ - Transition.prototype.onEnter = function (criteria, callback, options) { return; }; - /** @inheritdoc */ - Transition.prototype.onFinish = function (criteria, callback, options) { return; }; - /** @inheritdoc */ - Transition.prototype.onSuccess = function (criteria, callback, options) { return; }; - /** @inheritdoc */ - Transition.prototype.onError = function (criteria, callback, options) { return; }; - /** @hidden - * Creates the transition-level hook registration functions - * (which can then be used to register hooks) - */ - Transition.prototype.createTransitionHookRegFns = function () { - var _this = this; - this.router.transitionService._pluginapi._getEvents() - .filter(function (type) { return type.hookPhase !== interface_1.TransitionHookPhase.CREATE; }) - .forEach(function (type) { return hookRegistry_1.makeEvent(_this, _this.router.transitionService, type); }); - }; - /** @internalapi */ - Transition.prototype.getHooks = function (hookName) { - return this._registeredHooks[hookName]; - }; - Transition.prototype.applyViewConfigs = function (router) { - var enteringStates = this._treeChanges.entering.map(function (node) { return node.state; }); - pathFactory_1.PathUtils.applyViewConfigs(router.transitionService.$view, this._treeChanges.to, enteringStates); - }; - /** - * @internalapi - * - * @returns the internal from [State] object - */ - Transition.prototype.$from = function () { - return common_1.tail(this._treeChanges.from).state; - }; - /** - * @internalapi - * - * @returns the internal to [State] object - */ - Transition.prototype.$to = function () { - return common_1.tail(this._treeChanges.to).state; - }; - /** - * Returns the "from state" - * - * Returns the state that the transition is coming *from*. - * - * @returns The state declaration object for the Transition's ("from state"). - */ - Transition.prototype.from = function () { - return this.$from().self; - }; - /** - * Returns the "to state" - * - * Returns the state that the transition is going *to*. - * - * @returns The state declaration object for the Transition's target state ("to state"). - */ - Transition.prototype.to = function () { - return this.$to().self; - }; - /** - * Gets the Target State - * - * A transition's [[TargetState]] encapsulates the [[to]] state, the [[params]], and the [[options]] as a single object. - * - * @returns the [[TargetState]] of this Transition - */ - Transition.prototype.targetState = function () { - return this._targetState; - }; - /** - * Determines whether two transitions are equivalent. - * @deprecated - */ - Transition.prototype.is = function (compare) { - if (compare instanceof Transition) { - // TODO: Also compare parameters - return this.is({ to: compare.$to().name, from: compare.$from().name }); - } - return !((compare.to && !hookRegistry_1.matchState(this.$to(), compare.to)) || - (compare.from && !hookRegistry_1.matchState(this.$from(), compare.from))); - }; - Transition.prototype.params = function (pathname) { - if (pathname === void 0) { pathname = "to"; } - return Object.freeze(this._treeChanges[pathname].map(hof_1.prop("paramValues")).reduce(common_1.mergeR, {})); - }; - /** - * Creates a [[UIInjector]] Dependency Injector - * - * Returns a Dependency Injector for the Transition's target state (to state). - * The injector provides resolve values which the target state has access to. - * - * The `UIInjector` can also provide values from the native root/global injector (ng1/ng2). - * - * #### Example: - * ```js - * .onEnter({ entering: 'myState' }, trans => { - * var myResolveValue = trans.injector().get('myResolve'); - * // Inject a global service from the global/native injector (if it exists) - * var MyService = trans.injector().get('MyService'); - * }) - * ``` - * - * In some cases (such as `onBefore`), you may need access to some resolve data but it has not yet been fetched. - * You can use [[UIInjector.getAsync]] to get a promise for the data. - * #### Example: - * ```js - * .onBefore({}, trans => { - * return trans.injector().getAsync('myResolve').then(myResolveValue => - * return myResolveValue !== 'ABORT'; - * }); - * }); - * ``` - * - * If a `state` is provided, the injector that is returned will be limited to resolve values that the provided state has access to. - * This can be useful if both a parent state `foo` and a child state `foo.bar` have both defined a resolve such as `data`. - * #### Example: - * ```js - * .onEnter({ to: 'foo.bar' }, trans => { - * // returns result of `foo` state's `data` resolve - * // even though `foo.bar` also has a `data` resolve - * var fooData = trans.injector('foo').get('data'); - * }); - * ``` - * - * If you need resolve data from the exiting states, pass `'from'` as `pathName`. - * The resolve data from the `from` path will be returned. - * #### Example: - * ```js - * .onExit({ exiting: 'foo.bar' }, trans => { - * // Gets the resolve value of `data` from the exiting state. - * var fooData = trans.injector(null, 'foo.bar').get('data'); - * }); - * ``` - * - * - * @param state Limits the resolves provided to only the resolves the provided state has access to. - * @param pathName Default: `'to'`: Chooses the path for which to create the injector. Use this to access resolves for `exiting` states. - * - * @returns a [[UIInjector]] - */ - Transition.prototype.injector = function (state, pathName) { - if (pathName === void 0) { pathName = "to"; } - var path = this._treeChanges[pathName]; - if (state) - path = pathFactory_1.PathUtils.subPath(path, function (node) { return node.state === state || node.state.name === state; }); - return new resolveContext_1.ResolveContext(path).injector(); - }; - /** - * Gets all available resolve tokens (keys) - * - * This method can be used in conjunction with [[injector]] to inspect the resolve values - * available to the Transition. - * - * This returns all the tokens defined on [[StateDeclaration.resolve]] blocks, for the states - * in the Transition's [[TreeChanges.to]] path. - * - * #### Example: - * This example logs all resolve values - * ```js - * let tokens = trans.getResolveTokens(); - * tokens.forEach(token => console.log(token + " = " + trans.injector().get(token))); - * ``` - * - * #### Example: - * This example creates promises for each resolve value. - * This triggers fetches of resolves (if any have not yet been fetched). - * When all promises have all settled, it logs the resolve values. - * ```js - * let tokens = trans.getResolveTokens(); - * let promise = tokens.map(token => trans.injector().getAsync(token)); - * Promise.all(promises).then(values => console.log("Resolved values: " + values)); - * ``` - * - * Note: Angular 1 users whould use `$q.all()` - * - * @param pathname resolve context's path name (e.g., `to` or `from`) - * - * @returns an array of resolve tokens (keys) - */ - Transition.prototype.getResolveTokens = function (pathname) { - if (pathname === void 0) { pathname = "to"; } - return new resolveContext_1.ResolveContext(this._treeChanges[pathname]).getTokens(); - }; - /** - * Dynamically adds a new [[Resolvable]] (i.e., [[StateDeclaration.resolve]]) to this transition. - * - * #### Example: - * ```js - * transitionService.onBefore({}, transition => { - * transition.addResolvable({ - * token: 'myResolve', - * deps: ['MyService'], - * resolveFn: myService => myService.getData() - * }); - * }); - * ``` - * - * @param resolvable a [[ResolvableLiteral]] object (or a [[Resolvable]]) - * @param state the state in the "to path" which should receive the new resolve (otherwise, the root state) - */ - Transition.prototype.addResolvable = function (resolvable, state) { - if (state === void 0) { state = ""; } - resolvable = hof_1.is(resolvable_1.Resolvable)(resolvable) ? resolvable : new resolvable_1.Resolvable(resolvable); - var stateName = (typeof state === "string") ? state : state.name; - var topath = this._treeChanges.to; - var targetNode = common_1.find(topath, function (node) { return node.state.name === stateName; }); - var resolveContext = new resolveContext_1.ResolveContext(topath); - resolveContext.addResolvables([resolvable], targetNode.state); - }; - /** - * Gets the transition from which this transition was redirected. - * - * If the current transition is a redirect, this method returns the transition that was redirected. - * - * #### Example: - * ```js - * let transitionA = $state.go('A').transition - * transitionA.onStart({}, () => $state.target('B')); - * $transitions.onSuccess({ to: 'B' }, (trans) => { - * trans.to().name === 'B'; // true - * trans.redirectedFrom() === transitionA; // true - * }); - * ``` - * - * @returns The previous Transition, or null if this Transition is not the result of a redirection - */ - Transition.prototype.redirectedFrom = function () { - return this._options.redirectedFrom || null; - }; - /** - * Gets the original transition in a redirect chain - * - * A transition might belong to a long chain of multiple redirects. - * This method walks the [[redirectedFrom]] chain back to the original (first) transition in the chain. - * - * #### Example: - * ```js - * // states - * registry.register({ name: 'A', redirectTo: 'B' }); - * registry.register({ name: 'B', redirectTo: 'C' }); - * registry.register({ name: 'C', redirectTo: 'D' }); - * registry.register({ name: 'D' }); - * - * let transitionA = $state.go('A').transition - * - * $transitions.onSuccess({ to: 'D' }, (trans) => { - * trans.to().name === 'D'; // true - * trans.redirectedFrom().to().name === 'C'; // true - * trans.originalTransition() === transitionA; // true - * trans.originalTransition().to().name === 'A'; // true - * }); - * ``` - * - * @returns The original Transition that started a redirect chain - */ - Transition.prototype.originalTransition = function () { - var rf = this.redirectedFrom(); - return (rf && rf.originalTransition()) || this; - }; - /** - * Get the transition options - * - * @returns the options for this Transition. - */ - Transition.prototype.options = function () { - return this._options; - }; - /** - * Gets the states being entered. - * - * @returns an array of states that will be entered during this transition. - */ - Transition.prototype.entering = function () { - return common_1.map(this._treeChanges.entering, hof_1.prop('state')).map(stateSelf); - }; - /** - * Gets the states being exited. - * - * @returns an array of states that will be exited during this transition. - */ - Transition.prototype.exiting = function () { - return common_1.map(this._treeChanges.exiting, hof_1.prop('state')).map(stateSelf).reverse(); - }; - /** - * Gets the states being retained. - * - * @returns an array of states that are already entered from a previous Transition, that will not be - * exited during this Transition - */ - Transition.prototype.retained = function () { - return common_1.map(this._treeChanges.retained, hof_1.prop('state')).map(stateSelf); - }; - /** - * Get the [[ViewConfig]]s associated with this Transition - * - * Each state can define one or more views (template/controller), which are encapsulated as `ViewConfig` objects. - * This method fetches the `ViewConfigs` for a given path in the Transition (e.g., "to" or "entering"). - * - * @param pathname the name of the path to fetch views for: - * (`'to'`, `'from'`, `'entering'`, `'exiting'`, `'retained'`) - * @param state If provided, only returns the `ViewConfig`s for a single state in the path - * - * @returns a list of ViewConfig objects for the given path. - */ - Transition.prototype.views = function (pathname, state) { - if (pathname === void 0) { pathname = "entering"; } - var path = this._treeChanges[pathname]; - path = !state ? path : path.filter(hof_1.propEq('state', state)); - return path.map(hof_1.prop("views")).filter(common_1.identity).reduce(common_1.unnestR, []); - }; - Transition.prototype.treeChanges = function (pathname) { - return pathname ? this._treeChanges[pathname] : this._treeChanges; - }; - /** - * Creates a new transition that is a redirection of the current one. - * - * This transition can be returned from a [[TransitionService]] hook to - * redirect a transition to a new state and/or set of parameters. - * - * @internalapi - * - * @returns Returns a new [[Transition]] instance. - */ - Transition.prototype.redirect = function (targetState) { - var redirects = 1, trans = this; - while ((trans = trans.redirectedFrom()) != null) { - if (++redirects > 20) - throw new Error("Too many consecutive Transition redirects (20+)"); - } - var redirectOpts = { redirectedFrom: this, source: "redirect" }; - // If the original transition was caused by URL sync, then use { location: 'replace' } - // on the new transition (unless the target state explicitly specifies location: false). - // This causes the original url to be replaced with the url for the redirect target - // so the original url disappears from the browser history. - if (this.options().source === 'url' && targetState.options().location !== false) { - redirectOpts.location = 'replace'; - } - var newOptions = common_1.extend({}, this.options(), targetState.options(), redirectOpts); - targetState = targetState.withOptions(newOptions, true); - var newTransition = this.router.transitionService.create(this._treeChanges.from, targetState); - var originalEnteringNodes = this._treeChanges.entering; - var redirectEnteringNodes = newTransition._treeChanges.entering; - // --- Re-use resolve data from original transition --- - // When redirecting from a parent state to a child state where the parent parameter values haven't changed - // (because of the redirect), the resolves fetched by the original transition are still valid in the - // redirected transition. - // - // This allows you to define a redirect on a parent state which depends on an async resolve value. - // You can wait for the resolve, then redirect to a child state based on the result. - // The redirected transition does not have to re-fetch the resolve. - // --------------------------------------------------------- - var nodeIsReloading = function (reloadState) { return function (node) { - return reloadState && node.state.includes[reloadState.name]; - }; }; - // Find any "entering" nodes in the redirect path that match the original path and aren't being reloaded - var matchingEnteringNodes = pathFactory_1.PathUtils.matching(redirectEnteringNodes, originalEnteringNodes, pathFactory_1.PathUtils.nonDynamicParams) - .filter(hof_1.not(nodeIsReloading(targetState.options().reloadState))); - // Use the existing (possibly pre-resolved) resolvables for the matching entering nodes. - matchingEnteringNodes.forEach(function (node, idx) { - node.resolvables = originalEnteringNodes[idx].resolvables; - }); - return newTransition; - }; - /** @hidden If a transition doesn't exit/enter any states, returns any [[Param]] whose value changed */ - Transition.prototype._changedParams = function () { - var tc = this._treeChanges; - /** Return undefined if it's not a "dynamic" transition, for the following reasons */ - // If user explicitly wants a reload - if (this._options.reload) - return undefined; - // If any states are exiting or entering - if (tc.exiting.length || tc.entering.length) - return undefined; - // If to/from path lengths differ - if (tc.to.length !== tc.from.length) - return undefined; - // If the to/from paths are different - var pathsDiffer = common_1.arrayTuples(tc.to, tc.from) - .map(function (tuple) { return tuple[0].state !== tuple[1].state; }) - .reduce(common_1.anyTrueR, false); - if (pathsDiffer) - return undefined; - // Find any parameter values that differ - var nodeSchemas = tc.to.map(function (node) { return node.paramSchema; }); - var _a = [tc.to, tc.from].map(function (path) { return path.map(function (x) { return x.paramValues; }); }), toValues = _a[0], fromValues = _a[1]; - var tuples = common_1.arrayTuples(nodeSchemas, toValues, fromValues); - return tuples.map(function (_a) { - var schema = _a[0], toVals = _a[1], fromVals = _a[2]; - return param_1.Param.changed(schema, toVals, fromVals); - }).reduce(common_1.unnestR, []); - }; - /** - * Returns true if the transition is dynamic. - * - * A transition is dynamic if no states are entered nor exited, but at least one dynamic parameter has changed. - * - * @returns true if the Transition is dynamic - */ - Transition.prototype.dynamic = function () { - var changes = this._changedParams(); - return !changes ? false : changes.map(function (x) { return x.dynamic; }).reduce(common_1.anyTrueR, false); - }; - /** - * Returns true if the transition is ignored. - * - * A transition is ignored if no states are entered nor exited, and no parameter values have changed. - * - * @returns true if the Transition is ignored. - */ - Transition.prototype.ignored = function () { - return !!this._ignoredReason(); - }; - /** @hidden */ - Transition.prototype._ignoredReason = function () { - var pending = this.router.globals.transition; - var reloadState = this._options.reloadState; - var same = function (pathA, pathB) { - if (pathA.length !== pathB.length) - return false; - var matching = pathFactory_1.PathUtils.matching(pathA, pathB); - return pathA.length === matching.filter(function (node) { return !reloadState || !node.state.includes[reloadState.name]; }).length; - }; - var newTC = this.treeChanges(); - var pendTC = pending && pending.treeChanges(); - if (pendTC && same(pendTC.to, newTC.to) && same(pendTC.exiting, newTC.exiting)) - return "SameAsPending"; - if (newTC.exiting.length === 0 && newTC.entering.length === 0 && same(newTC.from, newTC.to)) - return "SameAsCurrent"; - }; - /** - * Runs the transition - * - * This method is generally called from the [[StateService.transitionTo]] - * - * @internalapi - * - * @returns a promise for a successful transition. - */ - Transition.prototype.run = function () { - var _this = this; - var runAllHooks = transitionHook_1.TransitionHook.runAllHooks; - // Gets transition hooks array for the given phase - var getHooksFor = function (phase) { - return _this._hookBuilder.buildHooksForPhase(phase); - }; - // When the chain is complete, then resolve or reject the deferred - var transitionSuccess = function () { - trace_1.trace.traceSuccess(_this.$to(), _this); - _this.success = true; - _this._deferred.resolve(_this.to()); - runAllHooks(getHooksFor(interface_1.TransitionHookPhase.SUCCESS)); - }; - var transitionError = function (reason) { - trace_1.trace.traceError(reason, _this); - _this.success = false; - _this._deferred.reject(reason); - _this._error = reason; - runAllHooks(getHooksFor(interface_1.TransitionHookPhase.ERROR)); - }; - var runTransition = function () { - // Wait to build the RUN hook chain until the BEFORE hooks are done - // This allows a BEFORE hook to dynamically add additional RUN hooks via the Transition object. - var allRunHooks = getHooksFor(interface_1.TransitionHookPhase.RUN); - var done = function () { return coreservices_1.services.$q.when(undefined); }; - return transitionHook_1.TransitionHook.invokeHooks(allRunHooks, done); - }; - var startTransition = function () { - var globals = _this.router.globals; - globals.lastStartedTransitionId = _this.$id; - globals.transition = _this; - globals.transitionHistory.enqueue(_this); - trace_1.trace.traceTransitionStart(_this); - return coreservices_1.services.$q.when(undefined); - }; - var allBeforeHooks = getHooksFor(interface_1.TransitionHookPhase.BEFORE); - transitionHook_1.TransitionHook.invokeHooks(allBeforeHooks, startTransition) - .then(runTransition) - .then(transitionSuccess, transitionError); - return this.promise; - }; - /** - * Checks if the Transition is valid - * - * @returns true if the Transition is valid - */ - Transition.prototype.valid = function () { - return !this.error() || this.success !== undefined; - }; - /** - * Aborts this transition - * - * Imperative API to abort a Transition. - * This only applies to Transitions that are not yet complete. - */ - Transition.prototype.abort = function () { - // Do not set flag if the transition is already complete - if (predicates_1.isUndefined(this.success)) { - this._aborted = true; - } - }; - /** - * The Transition error reason. - * - * If the transition is invalid (and could not be run), returns the reason the transition is invalid. - * If the transition was valid and ran, but was not successful, returns the reason the transition failed. - * - * @returns an error message explaining why the transition is invalid, or the reason the transition failed. - */ - Transition.prototype.error = function () { - var state = this.$to(); - if (state.self.abstract) - return "Cannot transition to abstract state '" + state.name + "'"; - var paramDefs = state.parameters(), values = this.params(); - var invalidParams = paramDefs.filter(function (param) { return !param.validates(values[param.id]); }); - if (invalidParams.length) { - return "Param values not valid for state '" + state.name + "'. Invalid params: [ " + invalidParams.map(function (param) { return param.id; }).join(', ') + " ]"; - } - if (this.success === false) - return this._error; - }; - /** - * A string representation of the Transition - * - * @returns A string representation of the Transition - */ - Transition.prototype.toString = function () { - var fromStateOrName = this.from(); - var toStateOrName = this.to(); - var avoidEmptyHash = function (params) { - return (params["#"] !== null && params["#"] !== undefined) ? params : common_1.omit(params, ["#"]); - }; - // (X) means the to state is invalid. - var id = this.$id, from = predicates_1.isObject(fromStateOrName) ? fromStateOrName.name : fromStateOrName, fromParams = strings_1.stringify(avoidEmptyHash(this._treeChanges.from.map(hof_1.prop('paramValues')).reduce(common_1.mergeR, {}))), toValid = this.valid() ? "" : "(X) ", to = predicates_1.isObject(toStateOrName) ? toStateOrName.name : toStateOrName, toParams = strings_1.stringify(avoidEmptyHash(this.params())); - return "Transition#" + id + "( '" + from + "'" + fromParams + " -> " + toValid + "'" + to + "'" + toParams + " )"; - }; - /** @hidden */ - Transition.diToken = Transition; - return Transition; -}()); -exports.Transition = Transition; -//# sourceMappingURL=transition.js.map + return res; +} -/***/ }), -/* 130 */ -/***/ (function(module, exports, __webpack_require__) { +function hasOwnProp(a, b) { + return Object.prototype.hasOwnProperty.call(a, b); +} -"use strict"; +function extend(a, b) { + for (var i in b) { + if (hasOwnProp(b, i)) { + a[i] = b[i]; + } + } -/** @module path */ /** for typedoc */ -Object.defineProperty(exports, "__esModule", { value: true }); -var common_1 = __webpack_require__(13); -var hof_1 = __webpack_require__(17); -var targetState_1 = __webpack_require__(82); -var pathNode_1 = __webpack_require__(200); -/** - * This class contains functions which convert TargetStates, Nodes and paths from one type to another. - */ -var PathUtils = /** @class */ (function () { - function PathUtils() { + if (hasOwnProp(b, 'toString')) { + a.toString = b.toString; } - /** Given a PathNode[], create an TargetState */ - PathUtils.makeTargetState = function (registry, path) { - var state = common_1.tail(path).state; - return new targetState_1.TargetState(registry, state, path.map(hof_1.prop("paramValues")).reduce(common_1.mergeR, {}), {}); - }; - PathUtils.buildPath = function (targetState) { - var toParams = targetState.params(); - return targetState.$state().path.map(function (state) { return new pathNode_1.PathNode(state).applyRawParams(toParams); }); + + if (hasOwnProp(b, 'valueOf')) { + a.valueOf = b.valueOf; + } + + return a; +} + +function createUTC (input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, true).utc(); +} + +function defaultParsingFlags() { + // We need to deep clone this object. + return { + empty : false, + unusedTokens : [], + unusedInput : [], + overflow : -2, + charsLeftOver : 0, + nullInput : false, + invalidMonth : null, + invalidFormat : false, + userInvalidated : false, + iso : false, + parsedDateParts : [], + meridiem : null, + rfc2822 : false, + weekdayMismatch : false }; - /** Given a fromPath: PathNode[] and a TargetState, builds a toPath: PathNode[] */ - PathUtils.buildToPath = function (fromPath, targetState) { - var toPath = PathUtils.buildPath(targetState); - if (targetState.options().inherit) { - return PathUtils.inheritParams(fromPath, toPath, Object.keys(targetState.params())); +} + +function getParsingFlags(m) { + if (m._pf == null) { + m._pf = defaultParsingFlags(); + } + return m._pf; +} + +var some; +if (Array.prototype.some) { + some = Array.prototype.some; +} else { + some = function (fun) { + var t = Object(this); + var len = t.length >>> 0; + + for (var i = 0; i < len; i++) { + if (i in t && fun.call(this, t[i], i, t)) { + return true; + } } - return toPath; + + return false; }; - /** - * Creates ViewConfig objects and adds to nodes. - * - * On each [[PathNode]], creates ViewConfig objects from the views: property of the node's state - */ - PathUtils.applyViewConfigs = function ($view, path, states) { - // Only apply the viewConfigs to the nodes for the given states - path.filter(function (node) { return common_1.inArray(states, node.state); }).forEach(function (node) { - var viewDecls = common_1.values(node.state.views || {}); - var subPath = PathUtils.subPath(path, function (n) { return n === node; }); - var viewConfigs = viewDecls.map(function (view) { return $view.createViewConfig(subPath, view); }); - node.views = viewConfigs.reduce(common_1.unnestR, []); +} + +var some$1 = some; + +function isValid(m) { + if (m._isValid == null) { + var flags = getParsingFlags(m); + var parsedParts = some$1.call(flags.parsedDateParts, function (i) { + return i != null; }); - }; - /** - * Given a fromPath and a toPath, returns a new to path which inherits parameters from the fromPath - * - * For a parameter in a node to be inherited from the from path: - * - The toPath's node must have a matching node in the fromPath (by state). - * - The parameter name must not be found in the toKeys parameter array. - * - * Note: the keys provided in toKeys are intended to be those param keys explicitly specified by some - * caller, for instance, $state.transitionTo(..., toParams). If a key was found in toParams, - * it is not inherited from the fromPath. - */ - PathUtils.inheritParams = function (fromPath, toPath, toKeys) { - if (toKeys === void 0) { toKeys = []; } - function nodeParamVals(path, state) { - var node = common_1.find(path, hof_1.propEq('state', state)); - return common_1.extend({}, node && node.paramValues); + var isNowValid = !isNaN(m._d.getTime()) && + flags.overflow < 0 && + !flags.empty && + !flags.invalidMonth && + !flags.invalidWeekday && + !flags.nullInput && + !flags.invalidFormat && + !flags.userInvalidated && + (!flags.meridiem || (flags.meridiem && parsedParts)); + + if (m._strict) { + isNowValid = isNowValid && + flags.charsLeftOver === 0 && + flags.unusedTokens.length === 0 && + flags.bigHour === undefined; } - var noInherit = fromPath.map(function (node) { return node.paramSchema; }) - .reduce(common_1.unnestR, []) - .filter(function (param) { return !param.inherit; }) - .map(hof_1.prop('id')); - /** - * Given an [[PathNode]] "toNode", return a new [[PathNode]] with param values inherited from the - * matching node in fromPath. Only inherit keys that aren't found in "toKeys" from the node in "fromPath"" - */ - function makeInheritedParamsNode(toNode) { - // All param values for the node (may include default key/vals, when key was not found in toParams) - var toParamVals = common_1.extend({}, toNode && toNode.paramValues); - // limited to only those keys found in toParams - var incomingParamVals = common_1.pick(toParamVals, toKeys); - toParamVals = common_1.omit(toParamVals, toKeys); - var fromParamVals = common_1.omit(nodeParamVals(fromPath, toNode.state) || {}, noInherit); - // extend toParamVals with any fromParamVals, then override any of those those with incomingParamVals - var ownParamVals = common_1.extend(toParamVals, fromParamVals, incomingParamVals); - return new pathNode_1.PathNode(toNode.state).applyRawParams(ownParamVals); + + if (Object.isFrozen == null || !Object.isFrozen(m)) { + m._isValid = isNowValid; } - // The param keys specified by the incoming toParams - return toPath.map(makeInheritedParamsNode); - }; - /** - * Computes the tree changes (entering, exiting) between a fromPath and toPath. - */ - PathUtils.treeChanges = function (fromPath, toPath, reloadState) { - var keep = 0, max = Math.min(fromPath.length, toPath.length); - var nodesMatch = function (node1, node2) { - return node1.equals(node2, PathUtils.nonDynamicParams); - }; - while (keep < max && fromPath[keep].state !== reloadState && nodesMatch(fromPath[keep], toPath[keep])) { - keep++; + else { + return isNowValid; } - /** Given a retained node, return a new node which uses the to node's param values */ - function applyToParams(retainedNode, idx) { - var cloned = pathNode_1.PathNode.clone(retainedNode); - cloned.paramValues = toPath[idx].paramValues; - return cloned; + } + return m._isValid; +} + +function createInvalid (flags) { + var m = createUTC(NaN); + if (flags != null) { + extend(getParsingFlags(m), flags); + } + else { + getParsingFlags(m).userInvalidated = true; + } + + return m; +} + +// Plugins that add properties should also add the key here (null value), +// so we can properly clone ourselves. +var momentProperties = hooks.momentProperties = []; + +function copyConfig(to, from) { + var i, prop, val; + + if (!isUndefined(from._isAMomentObject)) { + to._isAMomentObject = from._isAMomentObject; + } + if (!isUndefined(from._i)) { + to._i = from._i; + } + if (!isUndefined(from._f)) { + to._f = from._f; + } + if (!isUndefined(from._l)) { + to._l = from._l; + } + if (!isUndefined(from._strict)) { + to._strict = from._strict; + } + if (!isUndefined(from._tzm)) { + to._tzm = from._tzm; + } + if (!isUndefined(from._isUTC)) { + to._isUTC = from._isUTC; + } + if (!isUndefined(from._offset)) { + to._offset = from._offset; + } + if (!isUndefined(from._pf)) { + to._pf = getParsingFlags(from); + } + if (!isUndefined(from._locale)) { + to._locale = from._locale; + } + + if (momentProperties.length > 0) { + for (i = 0; i < momentProperties.length; i++) { + prop = momentProperties[i]; + val = from[prop]; + if (!isUndefined(val)) { + to[prop] = val; + } } - var from, retained, exiting, entering, to; - from = fromPath; - retained = from.slice(0, keep); - exiting = from.slice(keep); - // Create a new retained path (with shallow copies of nodes) which have the params of the toPath mapped - var retainedWithToParams = retained.map(applyToParams); - entering = toPath.slice(keep); - to = (retainedWithToParams).concat(entering); - return { from: from, to: to, retained: retained, exiting: exiting, entering: entering }; - }; - /** - * Returns a new path which is: the subpath of the first path which matches the second path. - * - * The new path starts from root and contains any nodes that match the nodes in the second path. - * It stops before the first non-matching node. - * - * Nodes are compared using their state property and their parameter values. - * If a `paramsFn` is provided, only the [[Param]] returned by the function will be considered when comparing nodes. - * - * @param pathA the first path - * @param pathB the second path - * @param paramsFn a function which returns the parameters to consider when comparing - * - * @returns an array of PathNodes from the first path which match the nodes in the second path - */ - PathUtils.matching = function (pathA, pathB, paramsFn) { - var done = false; - var tuples = common_1.arrayTuples(pathA, pathB); - return tuples.reduce(function (matching, _a) { - var nodeA = _a[0], nodeB = _a[1]; - done = done || !nodeA.equals(nodeB, paramsFn); - return done ? matching : matching.concat(nodeA); - }, []); - }; - /** - * Returns true if two paths are identical. - * - * @param pathA - * @param pathB - * @param paramsFn a function which returns the parameters to consider when comparing - * @returns true if the the states and parameter values for both paths are identical - */ - PathUtils.equals = function (pathA, pathB, paramsFn) { - return pathA.length === pathB.length && - PathUtils.matching(pathA, pathB, paramsFn).length === pathA.length; - }; - /** - * Return a subpath of a path, which stops at the first matching node - * - * Given an array of nodes, returns a subset of the array starting from the first node, - * stopping when the first node matches the predicate. - * - * @param path a path of [[PathNode]]s - * @param predicate a [[Predicate]] fn that matches [[PathNode]]s - * @returns a subpath up to the matching node, or undefined if no match is found - */ - PathUtils.subPath = function (path, predicate) { - var node = common_1.find(path, predicate); - var elementIdx = path.indexOf(node); - return elementIdx === -1 ? undefined : path.slice(0, elementIdx + 1); - }; - PathUtils.nonDynamicParams = function (node) { - return node.state.parameters({ inherit: false }) - .filter(function (param) { return !param.dynamic; }); - }; - /** Gets the raw parameter values from a path */ - PathUtils.paramValues = function (path) { - return path.reduce(function (acc, node) { return common_1.extend(acc, node.paramValues); }, {}); - }; - return PathUtils; -}()); -exports.PathUtils = PathUtils; -//# sourceMappingURL=pathFactory.js.map + } -/***/ }), -/* 131 */ -/***/ (function(module, exports, __webpack_require__) { + return to; +} -"use strict"; +var updateInProgress = false; -Object.defineProperty(exports, "__esModule", { value: true }); -/** @module resolve */ -/** for typedoc */ -var common_1 = __webpack_require__(13); -var hof_1 = __webpack_require__(17); -var trace_1 = __webpack_require__(54); -var coreservices_1 = __webpack_require__(27); -var interface_1 = __webpack_require__(334); -var resolvable_1 = __webpack_require__(102); -var pathFactory_1 = __webpack_require__(130); -var strings_1 = __webpack_require__(44); -var common_2 = __webpack_require__(35); -var whens = interface_1.resolvePolicies.when; -var ALL_WHENS = [whens.EAGER, whens.LAZY]; -var EAGER_WHENS = [whens.EAGER]; -exports.NATIVE_INJECTOR_TOKEN = "Native Injector"; -/** - * Encapsulates Dependency Injection for a path of nodes - * - * UI-Router states are organized as a tree. - * A nested state has a path of ancestors to the root of the tree. - * When a state is being activated, each element in the path is wrapped as a [[PathNode]]. - * A `PathNode` is a stateful object that holds things like parameters and resolvables for the state being activated. - * - * The ResolveContext closes over the [[PathNode]]s, and provides DI for the last node in the path. - */ -var ResolveContext = /** @class */ (function () { - function ResolveContext(_path) { - this._path = _path; - } - /** Gets all the tokens found in the resolve context, de-duplicated */ - ResolveContext.prototype.getTokens = function () { - return this._path.reduce(function (acc, node) { return acc.concat(node.resolvables.map(function (r) { return r.token; })); }, []).reduce(common_1.uniqR, []); - }; - /** - * Gets the Resolvable that matches the token - * - * Gets the last Resolvable that matches the token in this context, or undefined. - * Throws an error if it doesn't exist in the ResolveContext - */ - ResolveContext.prototype.getResolvable = function (token) { - var matching = this._path.map(function (node) { return node.resolvables; }) - .reduce(common_1.unnestR, []) - .filter(function (r) { return r.token === token; }); - return common_1.tail(matching); - }; - /** Returns the [[ResolvePolicy]] for the given [[Resolvable]] */ - ResolveContext.prototype.getPolicy = function (resolvable) { - var node = this.findNode(resolvable); - return resolvable.getPolicy(node.state); - }; - /** - * Returns a ResolveContext that includes a portion of this one - * - * Given a state, this method creates a new ResolveContext from this one. - * The new context starts at the first node (root) and stops at the node for the `state` parameter. - * - * #### Why - * - * When a transition is created, the nodes in the "To Path" are injected from a ResolveContext. - * A ResolveContext closes over a path of [[PathNode]]s and processes the resolvables. - * The "To State" can inject values from its own resolvables, as well as those from all its ancestor state's (node's). - * This method is used to create a narrower context when injecting ancestor nodes. - * - * @example - * `let ABCD = new ResolveContext([A, B, C, D]);` - * - * Given a path `[A, B, C, D]`, where `A`, `B`, `C` and `D` are nodes for states `a`, `b`, `c`, `d`: - * When injecting `D`, `D` should have access to all resolvables from `A`, `B`, `C`, `D`. - * However, `B` should only be able to access resolvables from `A`, `B`. - * - * When resolving for the `B` node, first take the full "To Path" Context `[A,B,C,D]` and limit to the subpath `[A,B]`. - * `let AB = ABCD.subcontext(a)` - */ - ResolveContext.prototype.subContext = function (state) { - return new ResolveContext(pathFactory_1.PathUtils.subPath(this._path, function (node) { return node.state === state; })); - }; - /** - * Adds Resolvables to the node that matches the state - * - * This adds a [[Resolvable]] (generally one created on the fly; not declared on a [[StateDeclaration.resolve]] block). - * The resolvable is added to the node matching the `state` parameter. - * - * These new resolvables are not automatically fetched. - * The calling code should either fetch them, fetch something that depends on them, - * or rely on [[resolvePath]] being called when some state is being entered. - * - * Note: each resolvable's [[ResolvePolicy]] is merged with the state's policy, and the global default. - * - * @param newResolvables the new Resolvables - * @param state Used to find the node to put the resolvable on - */ - ResolveContext.prototype.addResolvables = function (newResolvables, state) { - var node = common_1.find(this._path, hof_1.propEq('state', state)); - var keys = newResolvables.map(function (r) { return r.token; }); - node.resolvables = node.resolvables.filter(function (r) { return keys.indexOf(r.token) === -1; }).concat(newResolvables); - }; - /** - * Returns a promise for an array of resolved path Element promises - * - * @param when - * @param trans - * @returns {Promise|any} - */ - ResolveContext.prototype.resolvePath = function (when, trans) { - var _this = this; - if (when === void 0) { when = "LAZY"; } - // This option determines which 'when' policy Resolvables we are about to fetch. - var whenOption = common_1.inArray(ALL_WHENS, when) ? when : "LAZY"; - // If the caller specified EAGER, only the EAGER Resolvables are fetched. - // if the caller specified LAZY, both EAGER and LAZY Resolvables are fetched.` - var matchedWhens = whenOption === interface_1.resolvePolicies.when.EAGER ? EAGER_WHENS : ALL_WHENS; - // get the subpath to the state argument, if provided - trace_1.trace.traceResolvePath(this._path, when, trans); - var matchesPolicy = function (acceptedVals, whenOrAsync) { - return function (resolvable) { - return common_1.inArray(acceptedVals, _this.getPolicy(resolvable)[whenOrAsync]); - }; - }; - // Trigger all the (matching) Resolvables in the path - // Reduce all the "WAIT" Resolvables into an array - var promises = this._path.reduce(function (acc, node) { - var nodeResolvables = node.resolvables.filter(matchesPolicy(matchedWhens, 'when')); - var nowait = nodeResolvables.filter(matchesPolicy(['NOWAIT'], 'async')); - var wait = nodeResolvables.filter(hof_1.not(matchesPolicy(['NOWAIT'], 'async'))); - // For the matching Resolvables, start their async fetch process. - var subContext = _this.subContext(node.state); - var getResult = function (r) { return r.get(subContext, trans) - .then(function (value) { return ({ token: r.token, value: value }); }); }; - nowait.forEach(getResult); - return acc.concat(wait.map(getResult)); - }, []); - // Wait for all the "WAIT" resolvables - return coreservices_1.services.$q.all(promises); - }; - ResolveContext.prototype.injector = function () { - return this._injector || (this._injector = new UIInjectorImpl(this)); - }; - ResolveContext.prototype.findNode = function (resolvable) { - return common_1.find(this._path, function (node) { return common_1.inArray(node.resolvables, resolvable); }); - }; - /** - * Gets the async dependencies of a Resolvable - * - * Given a Resolvable, returns its dependencies as a Resolvable[] - */ - ResolveContext.prototype.getDependencies = function (resolvable) { - var _this = this; - var node = this.findNode(resolvable); - // Find which other resolvables are "visible" to the `resolvable` argument - // subpath stopping at resolvable's node, or the whole path (if the resolvable isn't in the path) - var subPath = pathFactory_1.PathUtils.subPath(this._path, function (x) { return x === node; }) || this._path; - var availableResolvables = subPath - .reduce(function (acc, _node) { return acc.concat(_node.resolvables); }, []) //all of subpath's resolvables - .filter(function (res) { return res !== resolvable; }); // filter out the `resolvable` argument - var getDependency = function (token) { - var matching = availableResolvables.filter(function (r) { return r.token === token; }); - if (matching.length) - return common_1.tail(matching); - var fromInjector = _this.injector().getNative(token); - if (common_2.isUndefined(fromInjector)) { - throw new Error("Could not find Dependency Injection token: " + strings_1.stringify(token)); - } - return new resolvable_1.Resolvable(token, function () { return fromInjector; }, [], fromInjector); - }; - return resolvable.deps.map(getDependency); - }; - return ResolveContext; -}()); -exports.ResolveContext = ResolveContext; -var UIInjectorImpl = /** @class */ (function () { - function UIInjectorImpl(context) { - this.context = context; - this.native = this.get(exports.NATIVE_INJECTOR_TOKEN) || coreservices_1.services.$injector; - } - UIInjectorImpl.prototype.get = function (token) { - var resolvable = this.context.getResolvable(token); - if (resolvable) { - if (this.context.getPolicy(resolvable).async === 'NOWAIT') { - return resolvable.get(this.context); - } - if (!resolvable.resolved) { - throw new Error("Resolvable async .get() not complete:" + strings_1.stringify(resolvable.token)); - } - return resolvable.data; - } - return this.getNative(token); - }; - UIInjectorImpl.prototype.getAsync = function (token) { - var resolvable = this.context.getResolvable(token); - if (resolvable) - return resolvable.get(this.context); - return coreservices_1.services.$q.when(this.native.get(token)); - }; - UIInjectorImpl.prototype.getNative = function (token) { - return this.native && this.native.get(token); - }; - return UIInjectorImpl; -}()); -//# sourceMappingURL=resolveContext.js.map - -/***/ }), -/* 132 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -/** - * @coreapi - * @module url - */ -/** for typedoc */ -var common_1 = __webpack_require__(13); -var hof_1 = __webpack_require__(17); -var predicates_1 = __webpack_require__(16); -var param_1 = __webpack_require__(83); -var strings_1 = __webpack_require__(44); -/** @hidden */ -function quoteRegExp(string, param) { - var surroundPattern = ['', ''], result = string.replace(/[\\\[\]\^$*+?.()|{}]/g, "\\$&"); - if (!param) - return result; - switch (param.squash) { - case false: - surroundPattern = ['(', ')' + (param.isOptional ? '?' : '')]; - break; - case true: - result = result.replace(/\/$/, ''); - surroundPattern = ['(?:\/(', ')|\/)?']; - break; - default: - surroundPattern = ["(" + param.squash + "|", ')?']; - break; - } - return result + surroundPattern[0] + param.type.pattern.source + surroundPattern[1]; -} -/** @hidden */ -var memoizeTo = function (obj, prop, fn) { - return obj[prop] = obj[prop] || fn(); -}; -/** @hidden */ -var splitOnSlash = strings_1.splitOnDelim('/'); -/** - * Matches URLs against patterns. - * - * Matches URLs against patterns and extracts named parameters from the path or the search - * part of the URL. - * - * A URL pattern consists of a path pattern, optionally followed by '?' and a list of search (query) - * parameters. Multiple search parameter names are separated by '&'. Search parameters - * do not influence whether or not a URL is matched, but their values are passed through into - * the matched parameters returned by [[UrlMatcher.exec]]. - * - * - *Path parameters* are defined using curly brace placeholders (`/somepath/{param}`) - * or colon placeholders (`/somePath/:param`). - * - * - *A parameter RegExp* may be defined for a param after a colon - * (`/somePath/{param:[a-zA-Z0-9]+}`) in a curly brace placeholder. - * The regexp must match for the url to be matched. - * Should the regexp itself contain curly braces, they must be in matched pairs or escaped with a backslash. - * - * Note: a RegExp parameter will encode its value using either [[ParamTypes.path]] or [[ParamTypes.query]]. - * - * - *Custom parameter types* may also be specified after a colon (`/somePath/{param:int}`) in curly brace parameters. - * See [[UrlMatcherFactory.type]] for more information. - * - * - *Catch-all parameters* are defined using an asterisk placeholder (`/somepath/*catchallparam`). - * A catch-all * parameter value will contain the remainder of the URL. - * - * --- - * - * Parameter names may contain only word characters (latin letters, digits, and underscore) and - * must be unique within the pattern (across both path and search parameters). - * A path parameter matches any number of characters other than '/'. For catch-all - * placeholders the path parameter matches any number of characters. - * - * Examples: - * - * * `'/hello/'` - Matches only if the path is exactly '/hello/'. There is no special treatment for - * trailing slashes, and patterns have to match the entire path, not just a prefix. - * * `'/user/:id'` - Matches '/user/bob' or '/user/1234!!!' or even '/user/' but not '/user' or - * '/user/bob/details'. The second path segment will be captured as the parameter 'id'. - * * `'/user/{id}'` - Same as the previous example, but using curly brace syntax. - * * `'/user/{id:[^/]*}'` - Same as the previous example. - * * `'/user/{id:[0-9a-fA-F]{1,8}}'` - Similar to the previous example, but only matches if the id - * parameter consists of 1 to 8 hex digits. - * * `'/files/{path:.*}'` - Matches any URL starting with '/files/' and captures the rest of the - * path into the parameter 'path'. - * * `'/files/*path'` - ditto. - * * `'/calendar/{start:date}'` - Matches "/calendar/2014-11-12" (because the pattern defined - * in the built-in `date` ParamType matches `2014-11-12`) and provides a Date object in $stateParams.start - * - */ -var UrlMatcher = /** @class */ (function () { - /** - * @param pattern The pattern to compile into a matcher. - * @param paramTypes The [[ParamTypes]] registry - * @param config A configuration object - * - `caseInsensitive` - `true` if URL matching should be case insensitive, otherwise `false`, the default value (for backward compatibility) is `false`. - * - `strict` - `false` if matching against a URL with a trailing slash should be treated as equivalent to a URL without a trailing slash, the default value is `true`. - */ - function UrlMatcher(pattern, paramTypes, paramFactory, config) { - var _this = this; - this.config = config; - /** @hidden */ - this._cache = { path: [this] }; - /** @hidden */ - this._children = []; - /** @hidden */ - this._params = []; - /** @hidden */ - this._segments = []; - /** @hidden */ - this._compiled = []; - this.pattern = pattern; - this.config = common_1.defaults(this.config, { - params: {}, - strict: true, - caseInsensitive: false, - paramMap: common_1.identity - }); - // Find all placeholders and create a compiled pattern, using either classic or curly syntax: - // '*' name - // ':' name - // '{' name '}' - // '{' name ':' regexp '}' - // The regular expression is somewhat complicated due to the need to allow curly braces - // inside the regular expression. The placeholder regexp breaks down as follows: - // ([:*])([\w\[\]]+) - classic placeholder ($1 / $2) (search version has - for snake-case) - // \{([\w\[\]]+)(?:\:\s*( ... ))?\} - curly brace placeholder ($3) with optional regexp/type ... ($4) (search version has - for snake-case - // (?: ... | ... | ... )+ - the regexp consists of any number of atoms, an atom being either - // [^{}\\]+ - anything other than curly braces or backslash - // \\. - a backslash escape - // \{(?:[^{}\\]+|\\.)*\} - a matched set of curly braces containing other atoms - var placeholder = /([:*])([\w\[\]]+)|\{([\w\[\]]+)(?:\:\s*((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g, searchPlaceholder = /([:]?)([\w\[\].-]+)|\{([\w\[\].-]+)(?:\:\s*((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g, last = 0, m, patterns = []; - var checkParamErrors = function (id) { - if (!UrlMatcher.nameValidator.test(id)) - throw new Error("Invalid parameter name '" + id + "' in pattern '" + pattern + "'"); - if (common_1.find(_this._params, hof_1.propEq('id', id))) - throw new Error("Duplicate parameter name '" + id + "' in pattern '" + pattern + "'"); - }; - // Split into static segments separated by path parameter placeholders. - // The number of segments is always 1 more than the number of parameters. - var matchDetails = function (m, isSearch) { - // IE[78] returns '' for unmatched groups instead of null - var id = m[2] || m[3]; - var regexp = isSearch ? m[4] : m[4] || (m[1] === '*' ? '[\\s\\S]*' : null); - var makeRegexpType = function (regexp) { return common_1.inherit(paramTypes.type(isSearch ? "query" : "path"), { - pattern: new RegExp(regexp, _this.config.caseInsensitive ? 'i' : undefined) - }); }; - return { - id: id, - regexp: regexp, - cfg: _this.config.params[id], - segment: pattern.substring(last, m.index), - type: !regexp ? null : paramTypes.type(regexp) || makeRegexpType(regexp) - }; - }; - var p, segment; - while ((m = placeholder.exec(pattern))) { - p = matchDetails(m, false); - if (p.segment.indexOf('?') >= 0) - break; // we're into the search part - checkParamErrors(p.id); - this._params.push(paramFactory.fromPath(p.id, p.type, this.config.paramMap(p.cfg, false))); - this._segments.push(p.segment); - patterns.push([p.segment, common_1.tail(this._params)]); - last = placeholder.lastIndex; - } - segment = pattern.substring(last); - // Find any search parameter names and remove them from the last segment - var i = segment.indexOf('?'); - if (i >= 0) { - var search = segment.substring(i); - segment = segment.substring(0, i); - if (search.length > 0) { - last = 0; - while ((m = searchPlaceholder.exec(search))) { - p = matchDetails(m, true); - checkParamErrors(p.id); - this._params.push(paramFactory.fromSearch(p.id, p.type, this.config.paramMap(p.cfg, true))); - last = placeholder.lastIndex; - // check if ?& - } - } - } - this._segments.push(segment); - this._compiled = patterns.map(function (pattern) { return quoteRegExp.apply(null, pattern); }).concat(quoteRegExp(segment)); - } - /** - * Creates a new concatenated UrlMatcher - * - * Builds a new UrlMatcher by appending another UrlMatcher to this one. - * - * @param url A `UrlMatcher` instance to append as a child of the current `UrlMatcher`. - */ - UrlMatcher.prototype.append = function (url) { - this._children.push(url); - url._cache = { - path: this._cache.path.concat(url), - parent: this, - pattern: null, - }; - return url; - }; - /** @hidden */ - UrlMatcher.prototype.isRoot = function () { - return this._cache.path[0] === this; - }; - /** Returns the input pattern string */ - UrlMatcher.prototype.toString = function () { - return this.pattern; - }; - /** - * Tests the specified url/path against this matcher. - * - * Tests if the given url matches this matcher's pattern, and returns an object containing the captured - * parameter values. Returns null if the path does not match. - * - * The returned object contains the values - * of any search parameters that are mentioned in the pattern, but their value may be null if - * they are not present in `search`. This means that search parameters are always treated - * as optional. - * - * #### Example: - * ```js - * new UrlMatcher('/user/{id}?q&r').exec('/user/bob', { - * x: '1', q: 'hello' - * }); - * // returns { id: 'bob', q: 'hello', r: null } - * ``` - * - * @param path The URL path to match, e.g. `$location.path()`. - * @param search URL search parameters, e.g. `$location.search()`. - * @param hash URL hash e.g. `$location.hash()`. - * @param options - * - * @returns The captured parameter values. - */ - UrlMatcher.prototype.exec = function (path, search, hash, options) { - var _this = this; - if (search === void 0) { search = {}; } - if (options === void 0) { options = {}; } - var match = memoizeTo(this._cache, 'pattern', function () { - return new RegExp([ - '^', - common_1.unnest(_this._cache.path.map(hof_1.prop('_compiled'))).join(''), - _this.config.strict === false ? '\/?' : '', - '$' - ].join(''), _this.config.caseInsensitive ? 'i' : undefined); - }).exec(path); - if (!match) - return null; - //options = defaults(options, { isolate: false }); - var allParams = this.parameters(), pathParams = allParams.filter(function (param) { return !param.isSearch(); }), searchParams = allParams.filter(function (param) { return param.isSearch(); }), nPathSegments = this._cache.path.map(function (urlm) { return urlm._segments.length - 1; }).reduce(function (a, x) { return a + x; }), values = {}; - if (nPathSegments !== match.length - 1) - throw new Error("Unbalanced capture group in route '" + this.pattern + "'"); - function decodePathArray(string) { - var reverseString = function (str) { return str.split("").reverse().join(""); }; - var unquoteDashes = function (str) { return str.replace(/\\-/g, "-"); }; - var split = reverseString(string).split(/-(?!\\)/); - var allReversed = common_1.map(split, reverseString); - return common_1.map(allReversed, unquoteDashes).reverse(); - } - for (var i = 0; i < nPathSegments; i++) { - var param = pathParams[i]; - var value = match[i + 1]; - // if the param value matches a pre-replace pair, replace the value before decoding. - for (var j = 0; j < param.replace.length; j++) { - if (param.replace[j].from === value) - value = param.replace[j].to; - } - if (value && param.array === true) - value = decodePathArray(value); - if (predicates_1.isDefined(value)) - value = param.type.decode(value); - values[param.id] = param.value(value); - } - searchParams.forEach(function (param) { - var value = search[param.id]; - for (var j = 0; j < param.replace.length; j++) { - if (param.replace[j].from === value) - value = param.replace[j].to; - } - if (predicates_1.isDefined(value)) - value = param.type.decode(value); - values[param.id] = param.value(value); - }); - if (hash) - values["#"] = hash; - return values; - }; - /** - * @hidden - * Returns all the [[Param]] objects of all path and search parameters of this pattern in order of appearance. - * - * @returns {Array.} An array of [[Param]] objects. Must be treated as read-only. If the - * pattern has no parameters, an empty array is returned. - */ - UrlMatcher.prototype.parameters = function (opts) { - if (opts === void 0) { opts = {}; } - if (opts.inherit === false) - return this._params; - return common_1.unnest(this._cache.path.map(function (matcher) { return matcher._params; })); - }; - /** - * @hidden - * Returns a single parameter from this UrlMatcher by id - * - * @param id - * @param opts - * @returns {T|Param|any|boolean|UrlMatcher|null} - */ - UrlMatcher.prototype.parameter = function (id, opts) { - var _this = this; - if (opts === void 0) { opts = {}; } - var findParam = function () { - for (var _i = 0, _a = _this._params; _i < _a.length; _i++) { - var param = _a[_i]; - if (param.id === id) - return param; - } - }; - var parent = this._cache.parent; - return findParam() || (opts.inherit !== false && parent && parent.parameter(id, opts)) || null; - }; - /** - * Validates the input parameter values against this UrlMatcher - * - * Checks an object hash of parameters to validate their correctness according to the parameter - * types of this `UrlMatcher`. - * - * @param params The object hash of parameters to validate. - * @returns Returns `true` if `params` validates, otherwise `false`. - */ - UrlMatcher.prototype.validates = function (params) { - var validParamVal = function (param, val) { - return !param || param.validates(val); - }; - params = params || {}; - // I'm not sure why this checks only the param keys passed in, and not all the params known to the matcher - var paramSchema = this.parameters().filter(function (paramDef) { return params.hasOwnProperty(paramDef.id); }); - return paramSchema.map(function (paramDef) { return validParamVal(paramDef, params[paramDef.id]); }).reduce(common_1.allTrueR, true); - }; - /** - * Given a set of parameter values, creates a URL from this UrlMatcher. - * - * Creates a URL that matches this pattern by substituting the specified values - * for the path and search parameters. - * - * #### Example: - * ```js - * new UrlMatcher('/user/{id}?q').format({ id:'bob', q:'yes' }); - * // returns '/user/bob?q=yes' - * ``` - * - * @param values the values to substitute for the parameters in this pattern. - * @returns the formatted URL (path and optionally search part). - */ - UrlMatcher.prototype.format = function (values) { - if (values === void 0) { values = {}; } - // Build the full path of UrlMatchers (including all parent UrlMatchers) - var urlMatchers = this._cache.path; - // Extract all the static segments and Params (processed as ParamDetails) - // into an ordered array - var pathSegmentsAndParams = urlMatchers.map(UrlMatcher.pathSegmentsAndParams) - .reduce(common_1.unnestR, []) - .map(function (x) { return predicates_1.isString(x) ? x : getDetails(x); }); - // Extract the query params into a separate array - var queryParams = urlMatchers.map(UrlMatcher.queryParams) - .reduce(common_1.unnestR, []) - .map(getDetails); - var isInvalid = function (param) { return param.isValid === false; }; - if (pathSegmentsAndParams.concat(queryParams).filter(isInvalid).length) { - return null; - } - /** - * Given a Param, applies the parameter value, then returns detailed information about it - */ - function getDetails(param) { - // Normalize to typed value - var value = param.value(values[param.id]); - var isValid = param.validates(value); - var isDefaultValue = param.isDefaultValue(value); - // Check if we're in squash mode for the parameter - var squash = isDefaultValue ? param.squash : false; - // Allow the Parameter's Type to encode the value - var encoded = param.type.encode(value); - return { param: param, value: value, isValid: isValid, isDefaultValue: isDefaultValue, squash: squash, encoded: encoded }; - } - // Build up the path-portion from the list of static segments and parameters - var pathString = pathSegmentsAndParams.reduce(function (acc, x) { - // The element is a static segment (a raw string); just append it - if (predicates_1.isString(x)) - return acc + x; - // Otherwise, it's a ParamDetails. - var squash = x.squash, encoded = x.encoded, param = x.param; - // If squash is === true, try to remove a slash from the path - if (squash === true) - return (acc.match(/\/$/)) ? acc.slice(0, -1) : acc; - // If squash is a string, use the string for the param value - if (predicates_1.isString(squash)) - return acc + squash; - if (squash !== false) - return acc; // ? - if (encoded == null) - return acc; - // If this parameter value is an array, encode the value using encodeDashes - if (predicates_1.isArray(encoded)) - return acc + common_1.map(encoded, UrlMatcher.encodeDashes).join("-"); - // If the parameter type is "raw", then do not encodeURIComponent - if (param.raw) - return acc + encoded; - // Encode the value - return acc + encodeURIComponent(encoded); - }, ""); - // Build the query string by applying parameter values (array or regular) - // then mapping to key=value, then flattening and joining using "&" - var queryString = queryParams.map(function (paramDetails) { - var param = paramDetails.param, squash = paramDetails.squash, encoded = paramDetails.encoded, isDefaultValue = paramDetails.isDefaultValue; - if (encoded == null || (isDefaultValue && squash !== false)) - return; - if (!predicates_1.isArray(encoded)) - encoded = [encoded]; - if (encoded.length === 0) - return; - if (!param.raw) - encoded = common_1.map(encoded, encodeURIComponent); - return encoded.map(function (val) { return param.id + "=" + val; }); - }).filter(common_1.identity).reduce(common_1.unnestR, []).join("&"); - // Concat the pathstring with the queryString (if exists) and the hashString (if exists) - return pathString + (queryString ? "?" + queryString : "") + (values["#"] ? "#" + values["#"] : ""); - }; - /** @hidden */ - UrlMatcher.encodeDashes = function (str) { - return encodeURIComponent(str).replace(/-/g, function (c) { return "%5C%" + c.charCodeAt(0).toString(16).toUpperCase(); }); - }; - /** @hidden Given a matcher, return an array with the matcher's path segments and path params, in order */ - UrlMatcher.pathSegmentsAndParams = function (matcher) { - var staticSegments = matcher._segments; - var pathParams = matcher._params.filter(function (p) { return p.location === param_1.DefType.PATH; }); - return common_1.arrayTuples(staticSegments, pathParams.concat(undefined)) - .reduce(common_1.unnestR, []) - .filter(function (x) { return x !== "" && predicates_1.isDefined(x); }); - }; - /** @hidden Given a matcher, return an array with the matcher's query params */ - UrlMatcher.queryParams = function (matcher) { - return matcher._params.filter(function (p) { return p.location === param_1.DefType.SEARCH; }); - }; - /** - * Compare two UrlMatchers - * - * This comparison function converts a UrlMatcher into static and dynamic path segments. - * Each static path segment is a static string between a path separator (slash character). - * Each dynamic segment is a path parameter. - * - * The comparison function sorts static segments before dynamic ones. - */ - UrlMatcher.compare = function (a, b) { - /** - * Turn a UrlMatcher and all its parent matchers into an array - * of slash literals '/', string literals, and Param objects - * - * This example matcher matches strings like "/foo/:param/tail": - * var matcher = $umf.compile("/foo").append($umf.compile("/:param")).append($umf.compile("/")).append($umf.compile("tail")); - * var result = segments(matcher); // [ '/', 'foo', '/', Param, '/', 'tail' ] - * - * Caches the result as `matcher._cache.segments` - */ - var segments = function (matcher) { - return matcher._cache.segments = matcher._cache.segments || - matcher._cache.path.map(UrlMatcher.pathSegmentsAndParams) - .reduce(common_1.unnestR, []) - .reduce(strings_1.joinNeighborsR, []) - .map(function (x) { return predicates_1.isString(x) ? splitOnSlash(x) : x; }) - .reduce(common_1.unnestR, []); - }; - /** - * Gets the sort weight for each segment of a UrlMatcher - * - * Caches the result as `matcher._cache.weights` - */ - var weights = function (matcher) { - return matcher._cache.weights = matcher._cache.weights || - segments(matcher).map(function (segment) { - // Sort slashes first, then static strings, the Params - if (segment === '/') - return 1; - if (predicates_1.isString(segment)) - return 2; - if (segment instanceof param_1.Param) - return 3; - }); - }; - /** - * Pads shorter array in-place (mutates) - */ - var padArrays = function (l, r, padVal) { - var len = Math.max(l.length, r.length); - while (l.length < len) - l.push(padVal); - while (r.length < len) - r.push(padVal); - }; - var weightsA = weights(a), weightsB = weights(b); - padArrays(weightsA, weightsB, 0); - var cmp, i, pairs = common_1.arrayTuples(weightsA, weightsB); - for (i = 0; i < pairs.length; i++) { - cmp = pairs[i][0] - pairs[i][1]; - if (cmp !== 0) - return cmp; - } - return 0; - }; - /** @hidden */ - UrlMatcher.nameValidator = /^\w+([-.]+\w+)*(?:\[\])?$/; - return UrlMatcher; -}()); -exports.UrlMatcher = UrlMatcher; -//# sourceMappingURL=urlMatcher.js.map - -/***/ }), -/* 133 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -/** - * @internalapi - * @module vanilla - */ /** */ -Object.defineProperty(exports, "__esModule", { value: true }); -var common_1 = __webpack_require__(35); -var utils_1 = __webpack_require__(203); -/** A base `LocationServices` */ -var BaseLocationServices = /** @class */ (function () { - function BaseLocationServices(router, fireAfterUpdate) { - var _this = this; - this.fireAfterUpdate = fireAfterUpdate; - this._listener = function (evt) { return _this._listeners.forEach(function (cb) { return cb(evt); }); }; - this._listeners = []; - this.hash = function () { return utils_1.parseUrl(_this._get()).hash; }; - this.path = function () { return utils_1.parseUrl(_this._get()).path; }; - this.search = function () { return utils_1.getParams(utils_1.parseUrl(_this._get()).search); }; - this._location = common_1.root.location; - this._history = common_1.root.history; - } - BaseLocationServices.prototype.url = function (url, replace) { - if (replace === void 0) { replace = true; } - if (common_1.isDefined(url) && url !== this._get()) { - this._set(null, null, url, replace); - if (this.fireAfterUpdate) { - this._listeners.forEach(function (cb) { return cb({ url: url }); }); - } - } - return utils_1.buildUrl(this); - }; - BaseLocationServices.prototype.onChange = function (cb) { - var _this = this; - this._listeners.push(cb); - return function () { return common_1.removeFrom(_this._listeners, cb); }; - }; - BaseLocationServices.prototype.dispose = function (router) { - common_1.deregAll(this._listeners); - }; - return BaseLocationServices; -}()); -exports.BaseLocationServices = BaseLocationServices; -//# sourceMappingURL=baseLocationService.js.map - -/***/ }), -/* 134 */ -/***/ (function(module, exports) { - -var g; - -// This works in non-strict mode -g = (function() { - return this; -})(); - -try { - // This works if eval is allowed (see CSP) - g = g || Function("return this")() || (1,eval)("this"); -} catch(e) { - // This works if the window reference is available - if(typeof window === "object") - g = window; -} - -// g can still be undefined, but nothing to do about it... -// We return undefined, instead of nothing here, so it's -// easier to handle this case. if(!global) { ...} - -module.exports = g; - - -/***/ }), -/* 135 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(module) {var require;//! moment.js -//! version : 2.19.1 -//! authors : Tim Wood, Iskren Chernev, Moment.js contributors -//! license : MIT -//! momentjs.com - -;(function (global, factory) { - true ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - global.moment = factory() -}(this, (function () { 'use strict'; - -var hookCallback; - -function hooks () { - return hookCallback.apply(null, arguments); -} - -// This is done to register the method called with moment() -// without creating circular dependencies. -function setHookCallback (callback) { - hookCallback = callback; -} - -function isArray(input) { - return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]'; -} - -function isObject(input) { - // IE8 will treat undefined and null as object if it wasn't for - // input != null - return input != null && Object.prototype.toString.call(input) === '[object Object]'; -} - -function isObjectEmpty(obj) { - if (Object.getOwnPropertyNames) { - return (Object.getOwnPropertyNames(obj).length === 0); - } else { - var k; - for (k in obj) { - if (obj.hasOwnProperty(k)) { - return false; - } - } - return true; - } -} - -function isUndefined(input) { - return input === void 0; -} - -function isNumber(input) { - return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]'; -} - -function isDate(input) { - return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]'; -} - -function map(arr, fn) { - var res = [], i; - for (i = 0; i < arr.length; ++i) { - res.push(fn(arr[i], i)); - } - return res; -} - -function hasOwnProp(a, b) { - return Object.prototype.hasOwnProperty.call(a, b); -} - -function extend(a, b) { - for (var i in b) { - if (hasOwnProp(b, i)) { - a[i] = b[i]; - } - } - - if (hasOwnProp(b, 'toString')) { - a.toString = b.toString; - } - - if (hasOwnProp(b, 'valueOf')) { - a.valueOf = b.valueOf; - } - - return a; -} - -function createUTC (input, format, locale, strict) { - return createLocalOrUTC(input, format, locale, strict, true).utc(); -} - -function defaultParsingFlags() { - // We need to deep clone this object. - return { - empty : false, - unusedTokens : [], - unusedInput : [], - overflow : -2, - charsLeftOver : 0, - nullInput : false, - invalidMonth : null, - invalidFormat : false, - userInvalidated : false, - iso : false, - parsedDateParts : [], - meridiem : null, - rfc2822 : false, - weekdayMismatch : false - }; -} - -function getParsingFlags(m) { - if (m._pf == null) { - m._pf = defaultParsingFlags(); - } - return m._pf; -} - -var some; -if (Array.prototype.some) { - some = Array.prototype.some; -} else { - some = function (fun) { - var t = Object(this); - var len = t.length >>> 0; - - for (var i = 0; i < len; i++) { - if (i in t && fun.call(this, t[i], i, t)) { - return true; - } - } - - return false; - }; -} - -function isValid(m) { - if (m._isValid == null) { - var flags = getParsingFlags(m); - var parsedParts = some.call(flags.parsedDateParts, function (i) { - return i != null; - }); - var isNowValid = !isNaN(m._d.getTime()) && - flags.overflow < 0 && - !flags.empty && - !flags.invalidMonth && - !flags.invalidWeekday && - !flags.weekdayMismatch && - !flags.nullInput && - !flags.invalidFormat && - !flags.userInvalidated && - (!flags.meridiem || (flags.meridiem && parsedParts)); - - if (m._strict) { - isNowValid = isNowValid && - flags.charsLeftOver === 0 && - flags.unusedTokens.length === 0 && - flags.bigHour === undefined; - } - - if (Object.isFrozen == null || !Object.isFrozen(m)) { - m._isValid = isNowValid; - } - else { - return isNowValid; - } - } - return m._isValid; -} - -function createInvalid (flags) { - var m = createUTC(NaN); - if (flags != null) { - extend(getParsingFlags(m), flags); - } - else { - getParsingFlags(m).userInvalidated = true; - } - - return m; -} - -// Plugins that add properties should also add the key here (null value), -// so we can properly clone ourselves. -var momentProperties = hooks.momentProperties = []; - -function copyConfig(to, from) { - var i, prop, val; - - if (!isUndefined(from._isAMomentObject)) { - to._isAMomentObject = from._isAMomentObject; - } - if (!isUndefined(from._i)) { - to._i = from._i; - } - if (!isUndefined(from._f)) { - to._f = from._f; - } - if (!isUndefined(from._l)) { - to._l = from._l; - } - if (!isUndefined(from._strict)) { - to._strict = from._strict; - } - if (!isUndefined(from._tzm)) { - to._tzm = from._tzm; - } - if (!isUndefined(from._isUTC)) { - to._isUTC = from._isUTC; - } - if (!isUndefined(from._offset)) { - to._offset = from._offset; - } - if (!isUndefined(from._pf)) { - to._pf = getParsingFlags(from); - } - if (!isUndefined(from._locale)) { - to._locale = from._locale; - } - - if (momentProperties.length > 0) { - for (i = 0; i < momentProperties.length; i++) { - prop = momentProperties[i]; - val = from[prop]; - if (!isUndefined(val)) { - to[prop] = val; - } - } - } - - return to; -} - -var updateInProgress = false; - -// Moment prototype object -function Moment(config) { - copyConfig(this, config); - this._d = new Date(config._d != null ? config._d.getTime() : NaN); - if (!this.isValid()) { - this._d = new Date(NaN); +// Moment prototype object +function Moment(config) { + copyConfig(this, config); + this._d = new Date(config._d != null ? config._d.getTime() : NaN); + if (!this.isValid()) { + this._d = new Date(NaN); } // Prevent infinite loop in case updateOffset creates new moment // objects. @@ -33519,6 +29437,8 @@ if (Object.keys) { }; } +var keys$1 = keys; + var defaultCalendar = { sameDay : '[Today at] LT', nextDay : '[Tomorrow at] LT', @@ -33644,6 +29564,56 @@ function getPrioritizedUnits(unitsObj) { return units; } +function makeGetSet (unit, keepTime) { + return function (value) { + if (value != null) { + set$1(this, unit, value); + hooks.updateOffset(this, keepTime); + return this; + } else { + return get(this, unit); + } + }; +} + +function get (mom, unit) { + return mom.isValid() ? + mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; +} + +function set$1 (mom, unit, value) { + if (mom.isValid()) { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); + } +} + +// MOMENTS + +function stringGet (units) { + units = normalizeUnits(units); + if (isFunction(this[units])) { + return this[units](); + } + return this; +} + + +function stringSet (units, value) { + if (typeof units === 'object') { + units = normalizeObjectUnits(units); + var prioritized = getPrioritizedUnits(units); + for (var i = 0; i < prioritized.length; i++) { + this[prioritized[i].unit](units[prioritized[i].unit]); + } + } else { + units = normalizeUnits(units); + if (isFunction(this[units])) { + return this[units](value); + } + } + return this; +} + function zeroFill(number, targetLength, forceSign) { var absNumber = '' + Math.abs(number), zerosToFill = targetLength - absNumber.length, @@ -33834,215 +29804,87 @@ var MILLISECOND = 6; var WEEK = 7; var WEEKDAY = 8; +var indexOf; + +if (Array.prototype.indexOf) { + indexOf = Array.prototype.indexOf; +} else { + indexOf = function (o) { + // I know + var i; + for (i = 0; i < this.length; ++i) { + if (this[i] === o) { + return i; + } + } + return -1; + }; +} + +var indexOf$1 = indexOf; + +function daysInMonth(year, month) { + return new Date(Date.UTC(year, month + 1, 0)).getUTCDate(); +} + // FORMATTING -addFormatToken('Y', 0, 0, function () { - var y = this.year(); - return y <= 9999 ? '' + y : '+' + y; +addFormatToken('M', ['MM', 2], 'Mo', function () { + return this.month() + 1; }); -addFormatToken(0, ['YY', 2], 0, function () { - return this.year() % 100; +addFormatToken('MMM', 0, 0, function (format) { + return this.localeData().monthsShort(this, format); }); -addFormatToken(0, ['YYYY', 4], 0, 'year'); -addFormatToken(0, ['YYYYY', 5], 0, 'year'); -addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); +addFormatToken('MMMM', 0, 0, function (format) { + return this.localeData().months(this, format); +}); // ALIASES -addUnitAlias('year', 'y'); +addUnitAlias('month', 'M'); -// PRIORITIES +// PRIORITY -addUnitPriority('year', 1); +addUnitPriority('month', 8); // PARSING -addRegexToken('Y', matchSigned); -addRegexToken('YY', match1to2, match2); -addRegexToken('YYYY', match1to4, match4); -addRegexToken('YYYYY', match1to6, match6); -addRegexToken('YYYYYY', match1to6, match6); - -addParseToken(['YYYYY', 'YYYYYY'], YEAR); -addParseToken('YYYY', function (input, array) { - array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); +addRegexToken('M', match1to2); +addRegexToken('MM', match1to2, match2); +addRegexToken('MMM', function (isStrict, locale) { + return locale.monthsShortRegex(isStrict); }); -addParseToken('YY', function (input, array) { - array[YEAR] = hooks.parseTwoDigitYear(input); +addRegexToken('MMMM', function (isStrict, locale) { + return locale.monthsRegex(isStrict); }); -addParseToken('Y', function (input, array) { - array[YEAR] = parseInt(input, 10); + +addParseToken(['M', 'MM'], function (input, array) { + array[MONTH] = toInt(input) - 1; }); -// HELPERS +addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { + var month = config._locale.monthsParse(input, token, config._strict); + // if we didn't find a month name, mark the date as invalid. + if (month != null) { + array[MONTH] = month; + } else { + getParsingFlags(config).invalidMonth = input; + } +}); -function daysInYear(year) { - return isLeapYear(year) ? 366 : 365; -} - -function isLeapYear(year) { - return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; -} - -// HOOKS - -hooks.parseTwoDigitYear = function (input) { - return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); -}; - -// MOMENTS - -var getSetYear = makeGetSet('FullYear', true); - -function getIsLeapYear () { - return isLeapYear(this.year()); -} - -function makeGetSet (unit, keepTime) { - return function (value) { - if (value != null) { - set$1(this, unit, value); - hooks.updateOffset(this, keepTime); - return this; - } else { - return get(this, unit); - } - }; -} - -function get (mom, unit) { - return mom.isValid() ? - mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; -} - -function set$1 (mom, unit, value) { - if (mom.isValid() && !isNaN(value)) { - if (unit === 'FullYear' && isLeapYear(mom.year())) { - mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month())); - } - else { - mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); - } - } -} - -// MOMENTS - -function stringGet (units) { - units = normalizeUnits(units); - if (isFunction(this[units])) { - return this[units](); - } - return this; -} - - -function stringSet (units, value) { - if (typeof units === 'object') { - units = normalizeObjectUnits(units); - var prioritized = getPrioritizedUnits(units); - for (var i = 0; i < prioritized.length; i++) { - this[prioritized[i].unit](units[prioritized[i].unit]); - } - } else { - units = normalizeUnits(units); - if (isFunction(this[units])) { - return this[units](value); - } - } - return this; -} - -function mod(n, x) { - return ((n % x) + x) % x; -} - -var indexOf; - -if (Array.prototype.indexOf) { - indexOf = Array.prototype.indexOf; -} else { - indexOf = function (o) { - // I know - var i; - for (i = 0; i < this.length; ++i) { - if (this[i] === o) { - return i; - } - } - return -1; - }; -} - -function daysInMonth(year, month) { - if (isNaN(year) || isNaN(month)) { - return NaN; - } - var modMonth = mod(month, 12); - year += (month - modMonth) / 12; - return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2); -} - -// FORMATTING - -addFormatToken('M', ['MM', 2], 'Mo', function () { - return this.month() + 1; -}); - -addFormatToken('MMM', 0, 0, function (format) { - return this.localeData().monthsShort(this, format); -}); - -addFormatToken('MMMM', 0, 0, function (format) { - return this.localeData().months(this, format); -}); - -// ALIASES - -addUnitAlias('month', 'M'); - -// PRIORITY - -addUnitPriority('month', 8); - -// PARSING - -addRegexToken('M', match1to2); -addRegexToken('MM', match1to2, match2); -addRegexToken('MMM', function (isStrict, locale) { - return locale.monthsShortRegex(isStrict); -}); -addRegexToken('MMMM', function (isStrict, locale) { - return locale.monthsRegex(isStrict); -}); - -addParseToken(['M', 'MM'], function (input, array) { - array[MONTH] = toInt(input) - 1; -}); - -addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { - var month = config._locale.monthsParse(input, token, config._strict); - // if we didn't find a month name, mark the date as invalid. - if (month != null) { - array[MONTH] = month; - } else { - getParsingFlags(config).invalidMonth = input; - } -}); - -// LOCALES - -var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/; -var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); -function localeMonths (m, format) { - if (!m) { - return isArray(this._months) ? this._months : - this._months['standalone']; - } - return isArray(this._months) ? this._months[m.month()] : - this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()]; +// LOCALES + +var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/; +var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); +function localeMonths (m, format) { + if (!m) { + return isArray(this._months) ? this._months : + this._months['standalone']; + } + return isArray(this._months) ? this._months[m.month()] : + this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()]; } var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); @@ -34071,26 +29913,26 @@ function handleStrictParse(monthName, format, strict) { if (strict) { if (format === 'MMM') { - ii = indexOf.call(this._shortMonthsParse, llc); + ii = indexOf$1.call(this._shortMonthsParse, llc); return ii !== -1 ? ii : null; } else { - ii = indexOf.call(this._longMonthsParse, llc); + ii = indexOf$1.call(this._longMonthsParse, llc); return ii !== -1 ? ii : null; } } else { if (format === 'MMM') { - ii = indexOf.call(this._shortMonthsParse, llc); + ii = indexOf$1.call(this._shortMonthsParse, llc); if (ii !== -1) { return ii; } - ii = indexOf.call(this._longMonthsParse, llc); + ii = indexOf$1.call(this._longMonthsParse, llc); return ii !== -1 ? ii : null; } else { - ii = indexOf.call(this._longMonthsParse, llc); + ii = indexOf$1.call(this._longMonthsParse, llc); if (ii !== -1) { return ii; } - ii = indexOf.call(this._shortMonthsParse, llc); + ii = indexOf$1.call(this._shortMonthsParse, llc); return ii !== -1 ? ii : null; } } @@ -34249,6 +30091,72 @@ function computeMonthsParse () { this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); } +// FORMATTING + +addFormatToken('Y', 0, 0, function () { + var y = this.year(); + return y <= 9999 ? '' + y : '+' + y; +}); + +addFormatToken(0, ['YY', 2], 0, function () { + return this.year() % 100; +}); + +addFormatToken(0, ['YYYY', 4], 0, 'year'); +addFormatToken(0, ['YYYYY', 5], 0, 'year'); +addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); + +// ALIASES + +addUnitAlias('year', 'y'); + +// PRIORITIES + +addUnitPriority('year', 1); + +// PARSING + +addRegexToken('Y', matchSigned); +addRegexToken('YY', match1to2, match2); +addRegexToken('YYYY', match1to4, match4); +addRegexToken('YYYYY', match1to6, match6); +addRegexToken('YYYYYY', match1to6, match6); + +addParseToken(['YYYYY', 'YYYYYY'], YEAR); +addParseToken('YYYY', function (input, array) { + array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); +}); +addParseToken('YY', function (input, array) { + array[YEAR] = hooks.parseTwoDigitYear(input); +}); +addParseToken('Y', function (input, array) { + array[YEAR] = parseInt(input, 10); +}); + +// HELPERS + +function daysInYear(year) { + return isLeapYear(year) ? 366 : 365; +} + +function isLeapYear(year) { + return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; +} + +// HOOKS + +hooks.parseTwoDigitYear = function (input) { + return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); +}; + +// MOMENTS + +var getSetYear = makeGetSet('FullYear', true); + +function getIsLeapYear () { + return isLeapYear(this.year()); +} + function createDate (y, m, d, h, M, s, ms) { // can't just apply() to create a date: // https://stackoverflow.com/q/181348 @@ -34516,48 +30424,48 @@ function handleStrictParse$1(weekdayName, format, strict) { if (strict) { if (format === 'dddd') { - ii = indexOf.call(this._weekdaysParse, llc); + ii = indexOf$1.call(this._weekdaysParse, llc); return ii !== -1 ? ii : null; } else if (format === 'ddd') { - ii = indexOf.call(this._shortWeekdaysParse, llc); + ii = indexOf$1.call(this._shortWeekdaysParse, llc); return ii !== -1 ? ii : null; } else { - ii = indexOf.call(this._minWeekdaysParse, llc); + ii = indexOf$1.call(this._minWeekdaysParse, llc); return ii !== -1 ? ii : null; } } else { if (format === 'dddd') { - ii = indexOf.call(this._weekdaysParse, llc); + ii = indexOf$1.call(this._weekdaysParse, llc); if (ii !== -1) { return ii; } - ii = indexOf.call(this._shortWeekdaysParse, llc); + ii = indexOf$1.call(this._shortWeekdaysParse, llc); if (ii !== -1) { return ii; } - ii = indexOf.call(this._minWeekdaysParse, llc); + ii = indexOf$1.call(this._minWeekdaysParse, llc); return ii !== -1 ? ii : null; } else if (format === 'ddd') { - ii = indexOf.call(this._shortWeekdaysParse, llc); + ii = indexOf$1.call(this._shortWeekdaysParse, llc); if (ii !== -1) { return ii; } - ii = indexOf.call(this._weekdaysParse, llc); + ii = indexOf$1.call(this._weekdaysParse, llc); if (ii !== -1) { return ii; } - ii = indexOf.call(this._minWeekdaysParse, llc); + ii = indexOf$1.call(this._minWeekdaysParse, llc); return ii !== -1 ? ii : null; } else { - ii = indexOf.call(this._minWeekdaysParse, llc); + ii = indexOf$1.call(this._minWeekdaysParse, llc); if (ii !== -1) { return ii; } - ii = indexOf.call(this._weekdaysParse, llc); + ii = indexOf$1.call(this._weekdaysParse, llc); if (ii !== -1) { return ii; } - ii = indexOf.call(this._shortWeekdaysParse, llc); + ii = indexOf$1.call(this._shortWeekdaysParse, llc); return ii !== -1 ? ii : null; } } @@ -34946,10 +30854,11 @@ function loadLocale(name) { module && module.exports) { try { oldLocale = globalLocale._abbr; - var aliasedRequire = require; !(function webpackMissingModule() { var e = new Error("Cannot find module \"./locale\""); e.code = 'MODULE_NOT_FOUND'; throw e; }()); + // because defineLocale currently also sets the global locale, we + // want to undo that for lazy loaded locales getSetGlobalLocale(oldLocale); - } catch (e) {} + } catch (e) { } } return locales[name]; } @@ -35075,7 +30984,7 @@ function getLocale (key) { } function listLocales() { - return keys(locales); + return keys$1(locales); } function checkOverflow (m) { @@ -35108,154 +31017,6 @@ function checkOverflow (m) { return m; } -// Pick the first defined of two or three arguments. -function defaults(a, b, c) { - if (a != null) { - return a; - } - if (b != null) { - return b; - } - return c; -} - -function currentDateArray(config) { - // hooks is actually the exported moment object - var nowValue = new Date(hooks.now()); - if (config._useUTC) { - return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; - } - return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; -} - -// convert an array to a date. -// the array should mirror the parameters below -// note: all values past the year are optional and will default to the lowest possible value. -// [year, month, day , hour, minute, second, millisecond] -function configFromArray (config) { - var i, date, input = [], currentDate, yearToUse; - - if (config._d) { - return; - } - - currentDate = currentDateArray(config); - - //compute day of the year from weeks and weekdays - if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { - dayOfYearFromWeekInfo(config); - } - - //if the day of the year is set, figure out what it is - if (config._dayOfYear != null) { - yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); - - if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) { - getParsingFlags(config)._overflowDayOfYear = true; - } - - date = createUTCDate(yearToUse, 0, config._dayOfYear); - config._a[MONTH] = date.getUTCMonth(); - config._a[DATE] = date.getUTCDate(); - } - - // Default to current date. - // * if no year, month, day of month are given, default to today - // * if day of month is given, default month and year - // * if month is given, default only year - // * if year is given, don't default anything - for (i = 0; i < 3 && config._a[i] == null; ++i) { - config._a[i] = input[i] = currentDate[i]; - } - - // Zero out whatever was not defaulted, including time - for (; i < 7; i++) { - config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; - } - - // Check for 24:00:00.000 - if (config._a[HOUR] === 24 && - config._a[MINUTE] === 0 && - config._a[SECOND] === 0 && - config._a[MILLISECOND] === 0) { - config._nextDay = true; - config._a[HOUR] = 0; - } - - config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); - // Apply timezone offset from input. The actual utcOffset can be changed - // with parseZone. - if (config._tzm != null) { - config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); - } - - if (config._nextDay) { - config._a[HOUR] = 24; - } - - // check for mismatching day of week - if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== config._d.getDay()) { - getParsingFlags(config).weekdayMismatch = true; - } -} - -function dayOfYearFromWeekInfo(config) { - var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; - - w = config._w; - if (w.GG != null || w.W != null || w.E != null) { - dow = 1; - doy = 4; - - // TODO: We need to take the current isoWeekYear, but that depends on - // how we interpret now (local, utc, fixed offset). So create - // a now version of current config (take local/utc/offset flags, and - // create now). - weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year); - week = defaults(w.W, 1); - weekday = defaults(w.E, 1); - if (weekday < 1 || weekday > 7) { - weekdayOverflow = true; - } - } else { - dow = config._locale._week.dow; - doy = config._locale._week.doy; - - var curWeek = weekOfYear(createLocal(), dow, doy); - - weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); - - // Default to current week. - week = defaults(w.w, curWeek.week); - - if (w.d != null) { - // weekday -- low day numbers are considered next week - weekday = w.d; - if (weekday < 0 || weekday > 6) { - weekdayOverflow = true; - } - } else if (w.e != null) { - // local weekday -- counting starts from begining of week - weekday = w.e + dow; - if (w.e < 0 || w.e > 6) { - weekdayOverflow = true; - } - } else { - // default to begining of week - weekday = dow; - } - } - if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { - getParsingFlags(config)._overflowWeeks = true; - } else if (weekdayOverflow != null) { - getParsingFlags(config)._overflowWeekday = true; - } else { - temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); - config._a[YEAR] = temp.year; - config._dayOfYear = temp.dayOfYear; - } -} - // iso 8601 regex // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; @@ -35347,94 +31108,70 @@ function configFromISO(config) { } // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 -var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/; - -function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { - var result = [ - untruncateYear(yearStr), - defaultLocaleMonthsShort.indexOf(monthStr), - parseInt(dayStr, 10), - parseInt(hourStr, 10), - parseInt(minuteStr, 10) - ]; - - if (secondStr) { - result.push(parseInt(secondStr, 10)); - } - - return result; -} - -function untruncateYear(yearStr) { - var year = parseInt(yearStr, 10); - if (year <= 49) { - return 2000 + year; - } else if (year <= 999) { - return 1900 + year; - } - return year; -} - -function preprocessRFC2822(s) { - // Remove comments and folding whitespace and replace multiple-spaces with a single space - return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').trim(); -} - -function checkWeekday(weekdayStr, parsedInput, config) { - if (weekdayStr) { - // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check. - var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), - weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay(); - if (weekdayProvided !== weekdayActual) { - getParsingFlags(config).weekdayMismatch = true; - config._isValid = false; - return false; - } - } - return true; -} - -var obsOffsets = { - UT: 0, - GMT: 0, - EDT: -4 * 60, - EST: -5 * 60, - CDT: -5 * 60, - CST: -6 * 60, - MDT: -6 * 60, - MST: -7 * 60, - PDT: -7 * 60, - PST: -8 * 60 -}; - -function calculateOffset(obsOffset, militaryOffset, numOffset) { - if (obsOffset) { - return obsOffsets[obsOffset]; - } else if (militaryOffset) { - // the only allowed military tz is Z - return 0; - } else { - var hm = parseInt(numOffset, 10); - var m = hm % 100, h = (hm - m) / 100; - return h * 60 + m; - } -} +var basicRfcRegex = /^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d?\d\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(?:\d\d)?\d\d\s)(\d\d:\d\d)(\:\d\d)?(\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\d{4}))$/; // date and time from ref 2822 format function configFromRFC2822(config) { - var match = rfc2822.exec(preprocessRFC2822(config._i)); + var string, match, dayFormat, + dateFormat, timeFormat, tzFormat; + var timezones = { + ' GMT': ' +0000', + ' EDT': ' -0400', + ' EST': ' -0500', + ' CDT': ' -0500', + ' CST': ' -0600', + ' MDT': ' -0600', + ' MST': ' -0700', + ' PDT': ' -0700', + ' PST': ' -0800' + }; + var military = 'YXWVUTSRQPONZABCDEFGHIKLM'; + var timezone, timezoneIndex; + + string = config._i + .replace(/\([^\)]*\)|[\n\t]/g, ' ') // Remove comments and folding whitespace + .replace(/(\s\s+)/g, ' ') // Replace multiple-spaces with a single space + .replace(/^\s|\s$/g, ''); // Remove leading and trailing spaces + match = basicRfcRegex.exec(string); + if (match) { - var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]); - if (!checkWeekday(match[1], parsedArray, config)) { - return; - } + dayFormat = match[1] ? 'ddd' + ((match[1].length === 5) ? ', ' : ' ') : ''; + dateFormat = 'D MMM ' + ((match[2].length > 10) ? 'YYYY ' : 'YY '); + timeFormat = 'HH:mm' + (match[4] ? ':ss' : ''); - config._a = parsedArray; - config._tzm = calculateOffset(match[8], match[9], match[10]); + // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check. + if (match[1]) { // day of week given + var momentDate = new Date(match[2]); + var momentDay = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][momentDate.getDay()]; - config._d = createUTCDate.apply(null, config._a); - config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + if (match[1].substr(0,3) !== momentDay) { + getParsingFlags(config).weekdayMismatch = true; + config._isValid = false; + return; + } + } + switch (match[5].length) { + case 2: // military + if (timezoneIndex === 0) { + timezone = ' +0000'; + } else { + timezoneIndex = military.indexOf(match[5][1].toUpperCase()) - 12; + timezone = ((timezoneIndex < 0) ? ' -' : ' +') + + (('' + timezoneIndex).replace(/^-?/, '0')).match(/..$/)[0] + '00'; + } + break; + case 4: // Zone + timezone = timezones[match[5]]; + break; + default: // UT or +/-9999 + timezone = timezones[' GMT']; + } + match[5] = timezone; + config._i = match.splice(1).join(''); + tzFormat = ' ZZ'; + config._f = dayFormat + dateFormat + timeFormat + tzFormat; + configFromStringAndFormat(config); getParsingFlags(config).rfc2822 = true; } else { config._isValid = false; @@ -35478,6 +31215,149 @@ hooks.createFromInputFallback = deprecate( } ); +// Pick the first defined of two or three arguments. +function defaults(a, b, c) { + if (a != null) { + return a; + } + if (b != null) { + return b; + } + return c; +} + +function currentDateArray(config) { + // hooks is actually the exported moment object + var nowValue = new Date(hooks.now()); + if (config._useUTC) { + return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; + } + return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; +} + +// convert an array to a date. +// the array should mirror the parameters below +// note: all values past the year are optional and will default to the lowest possible value. +// [year, month, day , hour, minute, second, millisecond] +function configFromArray (config) { + var i, date, input = [], currentDate, yearToUse; + + if (config._d) { + return; + } + + currentDate = currentDateArray(config); + + //compute day of the year from weeks and weekdays + if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { + dayOfYearFromWeekInfo(config); + } + + //if the day of the year is set, figure out what it is + if (config._dayOfYear != null) { + yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); + + if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) { + getParsingFlags(config)._overflowDayOfYear = true; + } + + date = createUTCDate(yearToUse, 0, config._dayOfYear); + config._a[MONTH] = date.getUTCMonth(); + config._a[DATE] = date.getUTCDate(); + } + + // Default to current date. + // * if no year, month, day of month are given, default to today + // * if day of month is given, default month and year + // * if month is given, default only year + // * if year is given, don't default anything + for (i = 0; i < 3 && config._a[i] == null; ++i) { + config._a[i] = input[i] = currentDate[i]; + } + + // Zero out whatever was not defaulted, including time + for (; i < 7; i++) { + config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; + } + + // Check for 24:00:00.000 + if (config._a[HOUR] === 24 && + config._a[MINUTE] === 0 && + config._a[SECOND] === 0 && + config._a[MILLISECOND] === 0) { + config._nextDay = true; + config._a[HOUR] = 0; + } + + config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); + // Apply timezone offset from input. The actual utcOffset can be changed + // with parseZone. + if (config._tzm != null) { + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + } + + if (config._nextDay) { + config._a[HOUR] = 24; + } +} + +function dayOfYearFromWeekInfo(config) { + var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; + + w = config._w; + if (w.GG != null || w.W != null || w.E != null) { + dow = 1; + doy = 4; + + // TODO: We need to take the current isoWeekYear, but that depends on + // how we interpret now (local, utc, fixed offset). So create + // a now version of current config (take local/utc/offset flags, and + // create now). + weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year); + week = defaults(w.W, 1); + weekday = defaults(w.E, 1); + if (weekday < 1 || weekday > 7) { + weekdayOverflow = true; + } + } else { + dow = config._locale._week.dow; + doy = config._locale._week.doy; + + var curWeek = weekOfYear(createLocal(), dow, doy); + + weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); + + // Default to current week. + week = defaults(w.w, curWeek.week); + + if (w.d != null) { + // weekday -- low day numbers are considered next week + weekday = w.d; + if (weekday < 0 || weekday > 6) { + weekdayOverflow = true; + } + } else if (w.e != null) { + // local weekday -- counting starts from begining of week + weekday = w.e + dow; + if (w.e < 0 || w.e > 6) { + weekdayOverflow = true; + } + } else { + // default to begining of week + weekday = dow; + } + } + if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { + getParsingFlags(config)._overflowWeeks = true; + } else if (weekdayOverflow != null) { + getParsingFlags(config)._overflowWeekday = true; + } else { + temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); + config._a[YEAR] = temp.year; + config._dayOfYear = temp.dayOfYear; + } +} + // constant that refers to the ISO standard hooks.ISO_8601 = function () {}; @@ -35802,7 +31682,7 @@ var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'se function isDurationValid(m) { for (var key in m) { - if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) { + if (!(ordering.indexOf(key) !== -1 && (m[key] == null || !isNaN(m[key])))) { return false; } } @@ -35853,7 +31733,7 @@ function Duration (duration) { // day when working around DST, we need to store them separately this._days = +days + weeks * 7; - // It is impossible to translate months into days without knowing + // It is impossible translate months into days without knowing // which months you are are talking about, so we have to store // it separately. this._months = +months + @@ -36100,12 +31980,12 @@ function isUtc () { } // ASP.NET json date format regex -var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; +var aspNetRegex = /^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere // and further modified to allow for strings containing both week and day -var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; +var isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/; function createDuration (input, key) { var duration = input, @@ -36139,7 +32019,7 @@ function createDuration (input, key) { ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match }; } else if (!!(match = isoRegex.exec(input))) { - sign = (match[1] === '-') ? -1 : (match[1] === '+') ? 1 : 1; + sign = (match[1] === '-') ? -1 : 1; duration = { y : parseIso(match[2], sign), M : parseIso(match[3], sign), @@ -36242,14 +32122,14 @@ function addSubtract (mom, duration, isAdding, updateOffset) { updateOffset = updateOffset == null ? true : updateOffset; - if (months) { - setMonth(mom, get(mom, 'Month') + months * isAdding); + if (milliseconds) { + mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); } if (days) { set$1(mom, 'Date', get(mom, 'Date') + days * isAdding); } - if (milliseconds) { - mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); + if (months) { + setMonth(mom, get(mom, 'Month') + months * isAdding); } if (updateOffset) { hooks.updateOffset(mom, days || months); @@ -36359,18 +32239,22 @@ function diff (input, units, asFloat) { units = normalizeUnits(units); - switch (units) { - case 'year': output = monthDiff(this, that) / 12; break; - case 'month': output = monthDiff(this, that); break; - case 'quarter': output = monthDiff(this, that) / 3; break; - case 'second': output = (this - that) / 1e3; break; // 1000 - case 'minute': output = (this - that) / 6e4; break; // 1000 * 60 - case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60 - case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst - case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst - default: output = this - that; + if (units === 'year' || units === 'month' || units === 'quarter') { + output = monthDiff(this, that); + if (units === 'quarter') { + output = output / 3; + } else if (units === 'year') { + output = output / 12; + } + } else { + delta = this - that; + output = units === 'second' ? delta / 1e3 : // 1000 + units === 'minute' ? delta / 6e4 : // 1000 * 60 + units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60 + units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst + units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst + delta; } - return asFloat ? output : absFloor(output); } @@ -37348,10 +33232,6 @@ var asWeeks = makeAs('w'); var asMonths = makeAs('M'); var asYears = makeAs('y'); -function clone$1 () { - return createDuration(this); -} - function get$2 (units) { units = normalizeUnits(units); return this.isValid() ? this[units + 's']() : NaN; @@ -37461,10 +33341,6 @@ function humanize (withSuffix) { var abs$1 = Math.abs; -function sign(x) { - return ((x > 0) - (x < 0)) || +x; -} - function toISOString$1() { // for ISO strings we do not use the normal bubbling rules: // * milliseconds bubble up until they become hours @@ -37499,7 +33375,7 @@ function toISOString$1() { var D = days; var h = hours; var m = minutes; - var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; + var s = seconds; var total = this.asSeconds(); if (!total) { @@ -37508,19 +33384,15 @@ function toISOString$1() { return 'P0D'; } - var totalSign = total < 0 ? '-' : ''; - var ymSign = sign(this._months) !== sign(total) ? '-' : ''; - var daysSign = sign(this._days) !== sign(total) ? '-' : ''; - var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; - - return totalSign + 'P' + - (Y ? ymSign + Y + 'Y' : '') + - (M ? ymSign + M + 'M' : '') + - (D ? daysSign + D + 'D' : '') + + return (total < 0 ? '-' : '') + + 'P' + + (Y ? Y + 'Y' : '') + + (M ? M + 'M' : '') + + (D ? D + 'D' : '') + ((h || m || s) ? 'T' : '') + - (h ? hmsSign + h + 'H' : '') + - (m ? hmsSign + m + 'M' : '') + - (s ? hmsSign + s + 'S' : ''); + (h ? h + 'H' : '') + + (m ? m + 'M' : '') + + (s ? s + 'S' : ''); } var proto$2 = Duration.prototype; @@ -37540,7 +33412,6 @@ proto$2.asMonths = asMonths; proto$2.asYears = asYears; proto$2.valueOf = valueOf$1; proto$2._bubble = bubble; -proto$2.clone = clone$1; proto$2.get = get$2; proto$2.milliseconds = milliseconds; proto$2.seconds = seconds; @@ -37582,7 +33453,7 @@ addParseToken('x', function (input, array, config) { // Side effect imports -hooks.version = '2.19.1'; +hooks.version = '2.18.1'; setHookCallback(createLocal); @@ -37609,7 +33480,7 @@ hooks.updateLocale = updateLocale; hooks.locales = listLocales; hooks.weekdaysShort = listWeekdaysShort; hooks.normalizeUnits = normalizeUnits; -hooks.relativeTimeRounding = getSetRelativeTimeRounding; +hooks.relativeTimeRounding = getSetRelativeTimeRounding; hooks.relativeTimeThreshold = getSetRelativeTimeThreshold; hooks.calendarFormat = getCalendarFormat; hooks.prototype = proto; @@ -37618,10 +33489,10 @@ return hooks; }))); -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(209)(module))) +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(183)(module))) /***/ }), -/* 136 */ +/* 112 */ /***/ (function(module, exports, __webpack_require__) { // CodeMirror, copyright (c) by Marijn Haverbeke and others @@ -37905,18 +33776,13 @@ function skipExtendingChars(str, pos, dir) { } // Returns the value from the range [`from`; `to`] that satisfies -// `pred` and is closest to `from`. Assumes that at least `to` -// satisfies `pred`. Supports `from` being greater than `to`. +// `pred` and is closest to `from`. Assumes that at least `to` satisfies `pred`. function findFirst(pred, from, to) { - // At any point we are certain `to` satisfies `pred`, don't know - // whether `from` does. - var dir = from > to ? -1 : 1; for (;;) { - if (from == to) { return from } - var midF = (from + to) / 2, mid = dir < 0 ? Math.ceil(midF) : Math.floor(midF); - if (mid == from) { return pred(mid) ? from : to } + if (Math.abs(from - to) <= 1) { return pred(from) ? from : to } + var mid = Math.floor((from + to) / 2); if (pred(mid)) { to = mid; } - else { from = mid + dir; } + else { from = mid; } } } @@ -38528,12 +34394,12 @@ function findMaxLine(cm) { // BIDI HELPERS function iterateBidiSections(order, from, to, f) { - if (!order) { return f(from, to, "ltr", 0) } + if (!order) { return f(from, to, "ltr") } var found = false; for (var i = 0; i < order.length; ++i) { var part = order[i]; if (part.from < to && part.to > from || from == to && part.to == from) { - f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr", i); + f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr"); found = true; } } @@ -38714,15 +34580,13 @@ var bidiOrdering = (function() { if (pos < i$7) { order.splice(at, 0, new BidiSpan(1, pos, i$7)); } } } - if (direction == "ltr") { - if (order[0].level == 1 && (m = str.match(/^\s+/))) { - order[0].from = m[0].length; - order.unshift(new BidiSpan(0, 0, m[0].length)); - } - if (lst(order).level == 1 && (m = str.match(/\s+$/))) { - lst(order).to -= m[0].length; - order.push(new BidiSpan(0, len - m[0].length, len)); - } + if (order[0].level == 1 && (m = str.match(/^\s+/))) { + order[0].from = m[0].length; + order.unshift(new BidiSpan(0, 0, m[0].length)); + } + if (lst(order).level == 1 && (m = str.match(/\s+$/))) { + lst(order).to -= m[0].length; + order.push(new BidiSpan(0, len - m[0].length, len)); } return direction == "rtl" ? order.reverse() : order @@ -38738,6 +34602,112 @@ function getOrder(line, direction) { return order } +function moveCharLogically(line, ch, dir) { + var target = skipExtendingChars(line.text, ch + dir, dir); + return target < 0 || target > line.text.length ? null : target +} + +function moveLogically(line, start, dir) { + var ch = moveCharLogically(line, start.ch, dir); + return ch == null ? null : new Pos(start.line, ch, dir < 0 ? "after" : "before") +} + +function endOfLine(visually, cm, lineObj, lineNo, dir) { + if (visually) { + var order = getOrder(lineObj, cm.doc.direction); + if (order) { + var part = dir < 0 ? lst(order) : order[0]; + var moveInStorageOrder = (dir < 0) == (part.level == 1); + var sticky = moveInStorageOrder ? "after" : "before"; + var ch; + // With a wrapped rtl chunk (possibly spanning multiple bidi parts), + // it could be that the last bidi part is not on the last visual line, + // since visual lines contain content order-consecutive chunks. + // Thus, in rtl, we are looking for the first (content-order) character + // in the rtl chunk that is on the last line (that is, the same line + // as the last (content-order) character). + if (part.level > 0) { + var prep = prepareMeasureForLine(cm, lineObj); + ch = dir < 0 ? lineObj.text.length - 1 : 0; + var targetTop = measureCharPrepared(cm, prep, ch).top; + ch = findFirst(function (ch) { return measureCharPrepared(cm, prep, ch).top == targetTop; }, (dir < 0) == (part.level == 1) ? part.from : part.to - 1, ch); + if (sticky == "before") { ch = moveCharLogically(lineObj, ch, 1); } + } else { ch = dir < 0 ? part.to : part.from; } + return new Pos(lineNo, ch, sticky) + } + } + return new Pos(lineNo, dir < 0 ? lineObj.text.length : 0, dir < 0 ? "before" : "after") +} + +function moveVisually(cm, line, start, dir) { + var bidi = getOrder(line, cm.doc.direction); + if (!bidi) { return moveLogically(line, start, dir) } + if (start.ch >= line.text.length) { + start.ch = line.text.length; + start.sticky = "before"; + } else if (start.ch <= 0) { + start.ch = 0; + start.sticky = "after"; + } + var partPos = getBidiPartAt(bidi, start.ch, start.sticky), part = bidi[partPos]; + if (cm.doc.direction == "ltr" && part.level % 2 == 0 && (dir > 0 ? part.to > start.ch : part.from < start.ch)) { + // Case 1: We move within an ltr part in an ltr editor. Even with wrapped lines, + // nothing interesting happens. + return moveLogically(line, start, dir) + } + + var mv = function (pos, dir) { return moveCharLogically(line, pos instanceof Pos ? pos.ch : pos, dir); }; + var prep; + var getWrappedLineExtent = function (ch) { + if (!cm.options.lineWrapping) { return {begin: 0, end: line.text.length} } + prep = prep || prepareMeasureForLine(cm, line); + return wrappedLineExtentChar(cm, line, prep, ch) + }; + var wrappedLineExtent = getWrappedLineExtent(start.sticky == "before" ? mv(start, -1) : start.ch); + + if (cm.doc.direction == "rtl" || part.level == 1) { + var moveInStorageOrder = (part.level == 1) == (dir < 0); + var ch = mv(start, moveInStorageOrder ? 1 : -1); + if (ch != null && (!moveInStorageOrder ? ch >= part.from && ch >= wrappedLineExtent.begin : ch <= part.to && ch <= wrappedLineExtent.end)) { + // Case 2: We move within an rtl part or in an rtl editor on the same visual line + var sticky = moveInStorageOrder ? "before" : "after"; + return new Pos(start.line, ch, sticky) + } + } + + // Case 3: Could not move within this bidi part in this visual line, so leave + // the current bidi part + + var searchInVisualLine = function (partPos, dir, wrappedLineExtent) { + var getRes = function (ch, moveInStorageOrder) { return moveInStorageOrder + ? new Pos(start.line, mv(ch, 1), "before") + : new Pos(start.line, ch, "after"); }; + + for (; partPos >= 0 && partPos < bidi.length; partPos += dir) { + var part = bidi[partPos]; + var moveInStorageOrder = (dir > 0) == (part.level != 1); + var ch = moveInStorageOrder ? wrappedLineExtent.begin : mv(wrappedLineExtent.end, -1); + if (part.from <= ch && ch < part.to) { return getRes(ch, moveInStorageOrder) } + ch = moveInStorageOrder ? part.from : mv(part.to, -1); + if (wrappedLineExtent.begin <= ch && ch < wrappedLineExtent.end) { return getRes(ch, moveInStorageOrder) } + } + }; + + // Case 3a: Look for other bidi parts on the same visual line + var res = searchInVisualLine(partPos + dir, dir, wrappedLineExtent); + if (res) { return res } + + // Case 3b: Look for other bidi parts on the next visual line + var nextCh = dir > 0 ? wrappedLineExtent.end : mv(wrappedLineExtent.begin, -1); + if (nextCh != null && !(dir > 0 && nextCh == line.text.length)) { + res = searchInVisualLine(dir > 0 ? 0 : bidi.length - 1, dir, getWrappedLineExtent(nextCh)); + if (res) { return res } + } + + // Case 4: Nowhere to move + return null +} + // EVENT HANDLING // Lightweight event framework. on/off also work on DOM nodes, @@ -39099,10 +35069,6 @@ StringStream.prototype.lookAhead = function (n) { var oracle = this.lineOracle; return oracle && oracle.lookAhead(n) }; -StringStream.prototype.baseToken = function () { - var oracle = this.lineOracle; - return oracle && oracle.baseToken(this.pos) -}; var SavedContext = function(state, lookAhead) { this.state = state; @@ -39114,8 +35080,6 @@ var Context = function(doc, state, line, lookAhead) { this.doc = doc; this.line = line; this.maxLookAhead = lookAhead || 0; - this.baseTokens = null; - this.baseTokenPos = 1; }; Context.prototype.lookAhead = function (n) { @@ -39124,17 +35088,6 @@ Context.prototype.lookAhead = function (n) { return line }; -Context.prototype.baseToken = function (n) { - var this$1 = this; - - if (!this.baseTokens) { return null } - while (this.baseTokens[this.baseTokenPos] <= n) - { this$1.baseTokenPos += 2; } - var type = this.baseTokens[this.baseTokenPos + 1]; - return {type: type && type.replace(/( |^)overlay .*/, ""), - size: this.baseTokens[this.baseTokenPos] - n} -}; - Context.prototype.nextLine = function () { this.line++; if (this.maxLookAhead > 0) { this.maxLookAhead--; } @@ -39168,7 +35121,6 @@ function highlightLine(cm, line, context, forceToEnd) { // Run overlays, adjust style array. var loop = function ( o ) { - context.baseTokens = st; var overlay = cm.state.overlays[o], i = 1, at = 0; context.state = true; runMode(cm, line.text, overlay.mode, context, function (end, style) { @@ -39192,12 +35144,10 @@ function highlightLine(cm, line, context, forceToEnd) { } } }, lineClasses); - context.state = state; - context.baseTokens = null; - context.baseTokenPos = 1; }; for (var o = 0; o < cm.state.overlays.length; ++o) loop( o ); + context.state = state; return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null} } @@ -40268,22 +36218,15 @@ function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop } -function widgetTopHeight(lineObj) { - var height = 0; - if (lineObj.widgets) { for (var i = 0; i < lineObj.widgets.length; ++i) { if (lineObj.widgets[i].above) - { height += widgetHeight(lineObj.widgets[i]); } } } - return height -} - // Converts a {top, bottom, left, right} box from line-local // coordinates into another coordinate system. Context may be one of // "line", "div" (display.lineDiv), "local"./null (editor), "window", // or "page". function intoCoordSystem(cm, lineObj, rect, context, includeWidgets) { - if (!includeWidgets) { - var height = widgetTopHeight(lineObj); - rect.top += height; rect.bottom += height; - } + if (!includeWidgets && lineObj.widgets) { for (var i = 0; i < lineObj.widgets.length; ++i) { if (lineObj.widgets[i].above) { + var size = widgetHeight(lineObj.widgets[i]); + rect.top += size; rect.bottom += size; + } } } if (context == "line") { return rect } if (!context) { context = "local"; } var yOff = heightAtLine(lineObj); @@ -40358,7 +36301,7 @@ function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) { if (!order) { return get(sticky == "before" ? ch - 1 : ch, sticky == "before") } function getBidi(ch, partPos, invert) { - var part = order[partPos], right = part.level == 1; + var part = order[partPos], right = (part.level % 2) != 0; return get(invert ? ch - 1 : ch, right != invert) } var partPos = getBidiPartAt(order, ch, sticky); @@ -40416,147 +36359,77 @@ function coordsChar(cm, x, y) { } function wrappedLineExtent(cm, lineObj, preparedMeasure, y) { - y -= widgetTopHeight(lineObj); + var measure = function (ch) { return intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, ch), "line"); }; var end = lineObj.text.length; - var begin = findFirst(function (ch) { return measureCharPrepared(cm, preparedMeasure, ch - 1).bottom <= y; }, end, 0); - end = findFirst(function (ch) { return measureCharPrepared(cm, preparedMeasure, ch).top > y; }, begin, end); + var begin = findFirst(function (ch) { return measure(ch - 1).bottom <= y; }, end, 0); + end = findFirst(function (ch) { return measure(ch).top > y; }, begin, end); return {begin: begin, end: end} } function wrappedLineExtentChar(cm, lineObj, preparedMeasure, target) { - if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj); } var targetTop = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, target), "line").top; return wrappedLineExtent(cm, lineObj, preparedMeasure, targetTop) } -// Returns true if the given side of a box is after the given -// coordinates, in top-to-bottom, left-to-right order. -function boxIsAfter(box, x, y, left) { - return box.bottom <= y ? false : box.top > y ? true : (left ? box.left : box.right) > x -} - function coordsCharInner(cm, lineObj, lineNo$$1, x, y) { - // Move y into line-local coordinate space y -= heightAtLine(lineObj); + var begin = 0, end = lineObj.text.length; var preparedMeasure = prepareMeasureForLine(cm, lineObj); - // When directly calling `measureCharPrepared`, we have to adjust - // for the widgets at this line. - var widgetHeight$$1 = widgetTopHeight(lineObj); - var begin = 0, end = lineObj.text.length, ltr = true; - + var pos; var order = getOrder(lineObj, cm.doc.direction); - // If the line isn't plain left-to-right text, first figure out - // which bidi section the coordinates fall into. if (order) { - var part = (cm.options.lineWrapping ? coordsBidiPartWrapped : coordsBidiPart) - (cm, lineObj, lineNo$$1, preparedMeasure, order, x, y); - ltr = part.level != 1; - // The awkward -1 offsets are needed because findFirst (called - // on these below) will treat its first bound as inclusive, - // second as exclusive, but we want to actually address the - // characters in the part's range - begin = ltr ? part.from : part.to - 1; - end = ltr ? part.to : part.from - 1; - } - - // A binary search to find the first character whose bounding box - // starts after the coordinates. If we run across any whose box wrap - // the coordinates, store that. - var chAround = null, boxAround = null; - var ch = findFirst(function (ch) { - var box = measureCharPrepared(cm, preparedMeasure, ch); - box.top += widgetHeight$$1; box.bottom += widgetHeight$$1; - if (!boxIsAfter(box, x, y, false)) { return false } - if (box.top <= y && box.left <= x) { - chAround = ch; - boxAround = box; + if (cm.options.lineWrapping) { + var assign; + ((assign = wrappedLineExtent(cm, lineObj, preparedMeasure, y), begin = assign.begin, end = assign.end, assign)); + } + pos = new Pos(lineNo$$1, Math.floor(begin + (end - begin) / 2)); + var beginLeft = cursorCoords(cm, pos, "line", lineObj, preparedMeasure).left; + var dir = beginLeft < x ? 1 : -1; + var prevDiff, diff = beginLeft - x, prevPos; + var steps = Math.ceil((end - begin) / 4); + outer: do { + prevDiff = diff; + prevPos = pos; + var i = 0; + for (; i < steps; ++i) { + var prevPos$1 = pos; + pos = moveVisually(cm, lineObj, pos, dir); + if (pos == null || pos.ch < begin || end <= (pos.sticky == "before" ? pos.ch - 1 : pos.ch)) { + pos = prevPos$1; + break outer + } + } + diff = cursorCoords(cm, pos, "line", lineObj, preparedMeasure).left - x; + if (steps > 1) { + var diff_change_per_step = Math.abs(diff - prevDiff) / steps; + steps = Math.min(steps, Math.ceil(Math.abs(diff) / diff_change_per_step)); + dir = diff < 0 ? 1 : -1; + } + } while (diff != 0 && (steps > 1 || ((dir < 0) != (diff < 0) && (Math.abs(diff) <= Math.abs(prevDiff))))) + if (Math.abs(diff) > Math.abs(prevDiff)) { + if ((diff < 0) == (prevDiff < 0)) { throw new Error("Broke out of infinite loop in coordsCharInner") } + pos = prevPos; } - return true - }, begin, end); - - var baseX, sticky, outside = false; - // If a box around the coordinates was found, use that - if (boxAround) { - // Distinguish coordinates nearer to the left or right side of the box - var atLeft = x - boxAround.left < boxAround.right - x, atStart = atLeft == ltr; - ch = chAround + (atStart ? 0 : 1); - sticky = atStart ? "after" : "before"; - baseX = atLeft ? boxAround.left : boxAround.right; } else { - // (Adjust for extended bound, if necessary.) - if (!ltr && (ch == end || ch == begin)) { ch++; } - // To determine which side to associate with, get the box to the - // left of the character and compare it's vertical position to the - // coordinates - sticky = ch == 0 ? "after" : ch == lineObj.text.length ? "before" : - (measureCharPrepared(cm, preparedMeasure, ch - (ltr ? 1 : 0)).bottom + widgetHeight$$1 <= y) == ltr ? - "after" : "before"; - // Now get accurate coordinates for this place, in order to get a - // base X position - var coords = cursorCoords(cm, Pos(lineNo$$1, ch, sticky), "line", lineObj, preparedMeasure); - baseX = coords.left; - outside = y < coords.top || y >= coords.bottom; - } - - ch = skipExtendingChars(lineObj.text, ch, 1); - return PosWithInfo(lineNo$$1, ch, sticky, outside, x - baseX) -} - -function coordsBidiPart(cm, lineObj, lineNo$$1, preparedMeasure, order, x, y) { - // Bidi parts are sorted left-to-right, and in a non-line-wrapping - // situation, we can take this ordering to correspond to the visual - // ordering. This finds the first part whose end is after the given - // coordinates. - var index = findFirst(function (i) { - var part = order[i], ltr = part.level != 1; - return boxIsAfter(cursorCoords(cm, Pos(lineNo$$1, ltr ? part.to : part.from, ltr ? "before" : "after"), - "line", lineObj, preparedMeasure), x, y, true) - }, 0, order.length - 1); - var part = order[index]; - // If this isn't the first part, the part's start is also after - // the coordinates, and the coordinates aren't on the same line as - // that start, move one part back. - if (index > 0) { - var ltr = part.level != 1; - var start = cursorCoords(cm, Pos(lineNo$$1, ltr ? part.from : part.to, ltr ? "after" : "before"), - "line", lineObj, preparedMeasure); - if (boxIsAfter(start, x, y, true) && start.top > y) - { part = order[index - 1]; } - } - return part -} - -function coordsBidiPartWrapped(cm, lineObj, _lineNo, preparedMeasure, order, x, y) { - // In a wrapped line, rtl text on wrapping boundaries can do things - // that don't correspond to the ordering in our `order` array at - // all, so a binary search doesn't work, and we want to return a - // part that only spans one line so that the binary search in - // coordsCharInner is safe. As such, we first find the extent of the - // wrapped line, and then do a flat search in which we discard any - // spans that aren't on the line. - var ref = wrappedLineExtent(cm, lineObj, preparedMeasure, y); - var begin = ref.begin; - var end = ref.end; - if (/\s/.test(lineObj.text.charAt(end - 1))) { end--; } - var part = null, closestDist = null; - for (var i = 0; i < order.length; i++) { - var p = order[i]; - if (p.from >= end || p.to <= begin) { continue } - var ltr = p.level != 1; - var endX = measureCharPrepared(cm, preparedMeasure, ltr ? Math.min(end, p.to) - 1 : Math.max(begin, p.from)).right; - // Weigh against spans ending before this, so that they are only - // picked if nothing ends after - var dist = endX < x ? x - endX + 1e9 : endX - x; - if (!part || closestDist > dist) { - part = p; - closestDist = dist; - } - } - if (!part) { part = order[order.length - 1]; } - // Clip the part to the wrapped line. - if (part.from < begin) { part = {from: begin, to: part.to, level: part.level}; } - if (part.to > end) { part = {from: part.from, to: end, level: part.level}; } - return part + var ch = findFirst(function (ch) { + var box = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, ch), "line"); + if (box.top > y) { + // For the cursor stickiness + end = Math.min(ch, end); + return true + } + else if (box.bottom <= y) { return false } + else if (box.left > x) { return true } + else if (box.right < x) { return false } + else { return (x - box.left < box.right - x) } + }, begin, end); + ch = skipExtendingChars(lineObj.text, ch, 1); + pos = new Pos(lineNo$$1, ch, ch == end ? "before" : "after"); + } + var coords = cursorCoords(cm, pos, "line", lineObj, preparedMeasure); + if (y < coords.top || coords.bottom < y) { pos.outside = true; } + pos.xRel = x < coords.left ? -1 : (x > coords.right ? 1 : 0); + return pos } var measureText; @@ -40682,14 +36555,12 @@ function updateSelection(cm) { } function prepareSelection(cm, primary) { - if ( primary === void 0 ) primary = true; - var doc = cm.doc, result = {}; var curFragment = result.cursors = document.createDocumentFragment(); var selFragment = result.selection = document.createDocumentFragment(); for (var i = 0; i < doc.sel.ranges.length; i++) { - if (!primary && i == doc.sel.primIndex) { continue } + if (primary === false && i == doc.sel.primIndex) { continue } var range$$1 = doc.sel.ranges[i]; if (range$$1.from().line >= cm.display.viewTo || range$$1.to().line < cm.display.viewFrom) { continue } var collapsed = range$$1.empty(); @@ -40720,15 +36591,12 @@ function drawSelectionCursor(cm, head, output) { } } -function cmpCoords(a, b) { return a.top - b.top || a.left - b.left } - // Draws the given range as a highlighted selection function drawSelectionRange(cm, range$$1, output) { var display = cm.display, doc = cm.doc; var fragment = document.createDocumentFragment(); var padding = paddingH(cm.display), leftSide = padding.left; var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right; - var docLTR = doc.direction == "ltr"; function add(left, top, width, bottom) { if (top < 0) { top = 0; } @@ -40745,49 +36613,30 @@ function drawSelectionRange(cm, range$$1, output) { return charCoords(cm, Pos(line, ch), "div", lineObj, bias) } - function wrapX(pos, dir, side) { - var extent = wrappedLineExtentChar(cm, lineObj, null, pos); - var prop = (dir == "ltr") == (side == "after") ? "left" : "right"; - var ch = side == "after" ? extent.begin : extent.end - (/\s/.test(lineObj.text.charAt(extent.end - 1)) ? 2 : 1); - return coords(ch, prop)[prop] - } - - var order = getOrder(lineObj, doc.direction); - iterateBidiSections(order, fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir, i) { - var ltr = dir == "ltr"; - var fromPos = coords(from, ltr ? "left" : "right"); - var toPos = coords(to - 1, ltr ? "right" : "left"); - - var openStart = fromArg == null && from == 0, openEnd = toArg == null && to == lineLen; - var first = i == 0, last = !order || i == order.length - 1; - if (toPos.top - fromPos.top <= 3) { // Single line - var openLeft = (docLTR ? openStart : openEnd) && first; - var openRight = (docLTR ? openEnd : openStart) && last; - var left = openLeft ? leftSide : (ltr ? fromPos : toPos).left; - var right = openRight ? rightSide : (ltr ? toPos : fromPos).right; - add(left, fromPos.top, right - left, fromPos.bottom); - } else { // Multiple lines - var topLeft, topRight, botLeft, botRight; - if (ltr) { - topLeft = docLTR && openStart && first ? leftSide : fromPos.left; - topRight = docLTR ? rightSide : wrapX(from, dir, "before"); - botLeft = docLTR ? leftSide : wrapX(to, dir, "after"); - botRight = docLTR && openEnd && last ? rightSide : toPos.right; - } else { - topLeft = !docLTR ? leftSide : wrapX(from, dir, "before"); - topRight = !docLTR && openStart && first ? rightSide : fromPos.right; - botLeft = !docLTR && openEnd && last ? leftSide : toPos.left; - botRight = !docLTR ? rightSide : wrapX(to, dir, "after"); - } - add(topLeft, fromPos.top, topRight - topLeft, fromPos.bottom); - if (fromPos.bottom < toPos.top) { add(leftSide, fromPos.bottom, null, toPos.top); } - add(botLeft, toPos.top, botRight - botLeft, toPos.bottom); - } - - if (!start || cmpCoords(fromPos, start) < 0) { start = fromPos; } - if (cmpCoords(toPos, start) < 0) { start = toPos; } - if (!end || cmpCoords(fromPos, end) < 0) { end = fromPos; } - if (cmpCoords(toPos, end) < 0) { end = toPos; } + iterateBidiSections(getOrder(lineObj, doc.direction), fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir) { + var leftPos = coords(from, "left"), rightPos, left, right; + if (from == to) { + rightPos = leftPos; + left = right = leftPos.left; + } else { + rightPos = coords(to - 1, "right"); + if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; } + left = leftPos.left; + right = rightPos.right; + } + if (fromArg == null && from == 0) { left = leftSide; } + if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part + add(left, leftPos.top, null, leftPos.bottom); + left = leftSide; + if (leftPos.bottom < rightPos.top) { add(left, leftPos.bottom, null, rightPos.top); } + } + if (toArg == null && to == lineLen) { right = rightSide; } + if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left) + { start = leftPos; } + if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right) + { end = rightPos; } + if (left < leftSide + 1) { left = leftSide; } + add(left, rightPos.top, right - left, rightPos.bottom); }); return {start: start, end: end} } @@ -41417,7 +37266,7 @@ function endOperation_R2(op) { } if (op.updatedDisplay || op.selectionChanged) - { op.preparedSelection = display.input.prepareSelection(); } + { op.preparedSelection = display.input.prepareSelection(op.focus); } } function endOperation_W2(op) { @@ -41430,7 +37279,7 @@ function endOperation_W2(op) { cm.display.maxLineChanged = false; } - var takeFocus = op.focus && op.focus == activeElt(); + var takeFocus = op.focus && op.focus == activeElt() && (!document.hasFocus || document.hasFocus()); if (op.preparedSelection) { cm.display.input.showSelection(op.preparedSelection, takeFocus); } if (op.updatedDisplay || op.startHeight != cm.doc.height) @@ -43030,8 +38879,7 @@ function makeChangeSingleDocInEditor(cm, change, spans) { function replaceRange(doc, code, from, to, origin) { if (!to) { to = from; } - if (cmp(to, from) < 0) { var assign; - (assign = [to, from], from = assign[0], to = assign[1], assign); } + if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; } if (typeof code == "string") { code = doc.splitLines(code); } makeChange(doc, {from: from, to: to, text: code, origin: origin}); } @@ -44392,112 +40240,6 @@ function deleteNearSelection(cm, compute) { }); } -function moveCharLogically(line, ch, dir) { - var target = skipExtendingChars(line.text, ch + dir, dir); - return target < 0 || target > line.text.length ? null : target -} - -function moveLogically(line, start, dir) { - var ch = moveCharLogically(line, start.ch, dir); - return ch == null ? null : new Pos(start.line, ch, dir < 0 ? "after" : "before") -} - -function endOfLine(visually, cm, lineObj, lineNo, dir) { - if (visually) { - var order = getOrder(lineObj, cm.doc.direction); - if (order) { - var part = dir < 0 ? lst(order) : order[0]; - var moveInStorageOrder = (dir < 0) == (part.level == 1); - var sticky = moveInStorageOrder ? "after" : "before"; - var ch; - // With a wrapped rtl chunk (possibly spanning multiple bidi parts), - // it could be that the last bidi part is not on the last visual line, - // since visual lines contain content order-consecutive chunks. - // Thus, in rtl, we are looking for the first (content-order) character - // in the rtl chunk that is on the last line (that is, the same line - // as the last (content-order) character). - if (part.level > 0 || cm.doc.direction == "rtl") { - var prep = prepareMeasureForLine(cm, lineObj); - ch = dir < 0 ? lineObj.text.length - 1 : 0; - var targetTop = measureCharPrepared(cm, prep, ch).top; - ch = findFirst(function (ch) { return measureCharPrepared(cm, prep, ch).top == targetTop; }, (dir < 0) == (part.level == 1) ? part.from : part.to - 1, ch); - if (sticky == "before") { ch = moveCharLogically(lineObj, ch, 1); } - } else { ch = dir < 0 ? part.to : part.from; } - return new Pos(lineNo, ch, sticky) - } - } - return new Pos(lineNo, dir < 0 ? lineObj.text.length : 0, dir < 0 ? "before" : "after") -} - -function moveVisually(cm, line, start, dir) { - var bidi = getOrder(line, cm.doc.direction); - if (!bidi) { return moveLogically(line, start, dir) } - if (start.ch >= line.text.length) { - start.ch = line.text.length; - start.sticky = "before"; - } else if (start.ch <= 0) { - start.ch = 0; - start.sticky = "after"; - } - var partPos = getBidiPartAt(bidi, start.ch, start.sticky), part = bidi[partPos]; - if (cm.doc.direction == "ltr" && part.level % 2 == 0 && (dir > 0 ? part.to > start.ch : part.from < start.ch)) { - // Case 1: We move within an ltr part in an ltr editor. Even with wrapped lines, - // nothing interesting happens. - return moveLogically(line, start, dir) - } - - var mv = function (pos, dir) { return moveCharLogically(line, pos instanceof Pos ? pos.ch : pos, dir); }; - var prep; - var getWrappedLineExtent = function (ch) { - if (!cm.options.lineWrapping) { return {begin: 0, end: line.text.length} } - prep = prep || prepareMeasureForLine(cm, line); - return wrappedLineExtentChar(cm, line, prep, ch) - }; - var wrappedLineExtent = getWrappedLineExtent(start.sticky == "before" ? mv(start, -1) : start.ch); - - if (cm.doc.direction == "rtl" || part.level == 1) { - var moveInStorageOrder = (part.level == 1) == (dir < 0); - var ch = mv(start, moveInStorageOrder ? 1 : -1); - if (ch != null && (!moveInStorageOrder ? ch >= part.from && ch >= wrappedLineExtent.begin : ch <= part.to && ch <= wrappedLineExtent.end)) { - // Case 2: We move within an rtl part or in an rtl editor on the same visual line - var sticky = moveInStorageOrder ? "before" : "after"; - return new Pos(start.line, ch, sticky) - } - } - - // Case 3: Could not move within this bidi part in this visual line, so leave - // the current bidi part - - var searchInVisualLine = function (partPos, dir, wrappedLineExtent) { - var getRes = function (ch, moveInStorageOrder) { return moveInStorageOrder - ? new Pos(start.line, mv(ch, 1), "before") - : new Pos(start.line, ch, "after"); }; - - for (; partPos >= 0 && partPos < bidi.length; partPos += dir) { - var part = bidi[partPos]; - var moveInStorageOrder = (dir > 0) == (part.level != 1); - var ch = moveInStorageOrder ? wrappedLineExtent.begin : mv(wrappedLineExtent.end, -1); - if (part.from <= ch && ch < part.to) { return getRes(ch, moveInStorageOrder) } - ch = moveInStorageOrder ? part.from : mv(part.to, -1); - if (wrappedLineExtent.begin <= ch && ch < wrappedLineExtent.end) { return getRes(ch, moveInStorageOrder) } - } - }; - - // Case 3a: Look for other bidi parts on the same visual line - var res = searchInVisualLine(partPos + dir, dir, wrappedLineExtent); - if (res) { return res } - - // Case 3b: Look for other bidi parts on the next visual line - var nextCh = dir > 0 ? wrappedLineExtent.end : mv(wrappedLineExtent.begin, -1); - if (nextCh != null && !(dir > 0 && nextCh == line.text.length)) { - res = searchInVisualLine(dir > 0 ? 0 : bidi.length - 1, dir, getWrappedLineExtent(nextCh)); - if (res) { return res } - } - - // Case 4: Nowhere to move - return null -} - // Commands are parameter-less actions that can be performed on an // editor, mostly used for keybindings. var commands = { @@ -45059,7 +40801,7 @@ function leftButtonSelect(cm, event, start, behavior) { anchor = maxPos(oldRange.to(), range$$1.head); } var ranges$1 = startSel.ranges.slice(0); - ranges$1[ourIndex] = bidiSimplify(cm, new Range(clipPos(doc, anchor), head)); + ranges$1[ourIndex] = new Range(clipPos(doc, anchor), head); setSelection(doc, normalizeSelection(ranges$1, ourIndex), sel_mouse); } } @@ -45111,52 +40853,13 @@ function leftButtonSelect(cm, event, start, behavior) { on(document, "mouseup", up); } -// Used when mouse-selecting to adjust the anchor to the proper side -// of a bidi jump depending on the visual position of the head. -function bidiSimplify(cm, range$$1) { - var anchor = range$$1.anchor; - var head = range$$1.head; - var anchorLine = getLine(cm.doc, anchor.line); - if (cmp(anchor, head) == 0 && anchor.sticky == head.sticky) { return range$$1 } - var order = getOrder(anchorLine); - if (!order) { return range$$1 } - var index = getBidiPartAt(order, anchor.ch, anchor.sticky), part = order[index]; - if (part.from != anchor.ch && part.to != anchor.ch) { return range$$1 } - var boundary = index + ((part.from == anchor.ch) == (part.level != 1) ? 0 : 1); - if (boundary == 0 || boundary == order.length) { return range$$1 } - - // Compute the relative visual position of the head compared to the - // anchor (<0 is to the left, >0 to the right) - var leftSide; - if (head.line != anchor.line) { - leftSide = (head.line - anchor.line) * (cm.doc.direction == "ltr" ? 1 : -1) > 0; - } else { - var headIndex = getBidiPartAt(order, head.ch, head.sticky); - var dir = headIndex - index || (head.ch - anchor.ch) * (part.level == 1 ? -1 : 1); - if (headIndex == boundary - 1 || headIndex == boundary) - { leftSide = dir < 0; } - else - { leftSide = dir > 0; } - } - - var usePart = order[boundary + (leftSide ? -1 : 0)]; - var from = leftSide == (usePart.level == 1); - var ch = from ? usePart.from : usePart.to, sticky = from ? "after" : "before"; - return anchor.ch == ch && anchor.sticky == sticky ? range$$1 : new Range(new Pos(anchor.line, ch, sticky), head) -} - // Determines whether an event happened in the gutter, and fires the // handlers for the corresponding event. function gutterEvent(cm, e, type, prevent) { var mX, mY; - if (e.touches) { - mX = e.touches[0].clientX; - mY = e.touches[0].clientY; - } else { - try { mX = e.clientX; mY = e.clientY; } - catch(e) { return false } - } + try { mX = e.clientX; mY = e.clientY; } + catch(e) { return false } if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) { return false } if (prevent) { e_preventDefault(e); } @@ -45494,7 +41197,7 @@ function registerEventHandlers(cm) { return dx * dx + dy * dy > 20 * 20 } on(d.scroller, "touchstart", function (e) { - if (!signalDOMEvent(cm, e) && !isMouseLikeTouchEvent(e) && !clickInGutter(cm, e)) { + if (!signalDOMEvent(cm, e) && !isMouseLikeTouchEvent(e)) { d.input.ensurePolled(); clearTimeout(touchFinished); var now = +new Date; @@ -47278,7 +42981,7 @@ CodeMirror$1.fromTextArea = fromTextArea; addLegacyProps(CodeMirror$1); -CodeMirror$1.version = "5.31.0"; +CodeMirror$1.version = "5.29.0"; return CodeMirror$1; @@ -47286,7 +42989,7 @@ return CodeMirror$1; /***/ }), -/* 137 */ +/* 113 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -47355,7 +43058,7 @@ module.exports = lowPriorityWarning; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 138 */ +/* 114 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -47374,11 +43077,11 @@ module.exports = ReactPropTypesSecret; /***/ }), -/* 139 */ +/* 115 */ /***/ (function(module, exports, __webpack_require__) { // optional / simple context binding -var aFunction = __webpack_require__(390); +var aFunction = __webpack_require__(341); module.exports = function (fn, that, length) { aFunction(fn); if (that === undefined) return fn; @@ -47400,11 +43103,11 @@ module.exports = function (fn, that, length) { /***/ }), -/* 140 */ +/* 116 */ /***/ (function(module, exports, __webpack_require__) { // 7.1.1 ToPrimitive(input [, PreferredType]) -var isObject = __webpack_require__(85); +var isObject = __webpack_require__(74); // instead of the ES6 spec version, we didn't implement @@toPrimitive case // and the second argument - flag - preferred type is a string module.exports = function (it, S) { @@ -47418,7 +43121,7 @@ module.exports = function (it, S) { /***/ }), -/* 141 */ +/* 117 */ /***/ (function(module, exports) { var toString = {}.toString; @@ -47429,7 +43132,7 @@ module.exports = function (it) { /***/ }), -/* 142 */ +/* 118 */ /***/ (function(module, exports) { // 7.2.1 RequireObjectCoercible(argument) @@ -47440,7 +43143,7 @@ module.exports = function (it) { /***/ }), -/* 143 */ +/* 119 */ /***/ (function(module, exports) { // 7.1.4 ToInteger @@ -47452,21 +43155,21 @@ module.exports = function (it) { /***/ }), -/* 144 */ +/* 120 */ /***/ (function(module, exports, __webpack_require__) { -var shared = __webpack_require__(145)('keys'); -var uid = __webpack_require__(105); +var shared = __webpack_require__(121)('keys'); +var uid = __webpack_require__(92); module.exports = function (key) { return shared[key] || (shared[key] = uid(key)); }; /***/ }), -/* 145 */ +/* 121 */ /***/ (function(module, exports, __webpack_require__) { -var global = __webpack_require__(49); +var global = __webpack_require__(43); var SHARED = '__core-js_shared__'; var store = global[SHARED] || (global[SHARED] = {}); module.exports = function (key) { @@ -47475,7 +43178,7 @@ module.exports = function (key) { /***/ }), -/* 146 */ +/* 122 */ /***/ (function(module, exports) { // IE 8- don't enum bug keys @@ -47485,25 +43188,25 @@ module.exports = ( /***/ }), -/* 147 */ +/* 123 */ /***/ (function(module, exports) { exports.f = Object.getOwnPropertySymbols; /***/ }), -/* 148 */ +/* 124 */ /***/ (function(module, exports, __webpack_require__) { // 7.1.13 ToObject(argument) -var defined = __webpack_require__(142); +var defined = __webpack_require__(118); module.exports = function (it) { return Object(defined(it)); }; /***/ }), -/* 149 */ +/* 125 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -47511,11 +43214,11 @@ module.exports = function (it) { exports.__esModule = true; -var _iterator = __webpack_require__(394); +var _iterator = __webpack_require__(345); var _iterator2 = _interopRequireDefault(_iterator); -var _symbol = __webpack_require__(405); +var _symbol = __webpack_require__(356); var _symbol2 = _interopRequireDefault(_symbol); @@ -47530,34 +43233,34 @@ exports.default = typeof _symbol2.default === "function" && _typeof(_iterator2.d }; /***/ }), -/* 150 */ +/* 126 */ /***/ (function(module, exports) { module.exports = true; /***/ }), -/* 151 */ +/* 127 */ /***/ (function(module, exports, __webpack_require__) { // 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties]) -var anObject = __webpack_require__(69); -var dPs = __webpack_require__(398); -var enumBugKeys = __webpack_require__(146); -var IE_PROTO = __webpack_require__(144)('IE_PROTO'); +var anObject = __webpack_require__(62); +var dPs = __webpack_require__(349); +var enumBugKeys = __webpack_require__(122); +var IE_PROTO = __webpack_require__(120)('IE_PROTO'); var Empty = function () { /* empty */ }; var PROTOTYPE = 'prototype'; // Create object with fake `null` prototype: use iframe Object with cleared prototype var createDict = function () { // Thrash, waste and sodomy: IE GC bug - var iframe = __webpack_require__(220)('iframe'); + var iframe = __webpack_require__(194)('iframe'); var i = enumBugKeys.length; var lt = '<'; var gt = '>'; var iframeDocument; iframe.style.display = 'none'; - __webpack_require__(399).appendChild(iframe); + __webpack_require__(350).appendChild(iframe); iframe.src = 'javascript:'; // eslint-disable-line no-script-url // createDict = iframe.contentWindow.Object; // html.removeChild(iframe); @@ -47584,12 +43287,12 @@ module.exports = Object.create || function create(O, Properties) { /***/ }), -/* 152 */ +/* 128 */ /***/ (function(module, exports, __webpack_require__) { -var def = __webpack_require__(56).f; -var has = __webpack_require__(57); -var TAG = __webpack_require__(40)('toStringTag'); +var def = __webpack_require__(49).f; +var has = __webpack_require__(50); +var TAG = __webpack_require__(35)('toStringTag'); module.exports = function (it, tag, stat) { if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag }); @@ -47597,21 +43300,21 @@ module.exports = function (it, tag, stat) { /***/ }), -/* 153 */ +/* 129 */ /***/ (function(module, exports, __webpack_require__) { -exports.f = __webpack_require__(40); +exports.f = __webpack_require__(35); /***/ }), -/* 154 */ +/* 130 */ /***/ (function(module, exports, __webpack_require__) { -var global = __webpack_require__(49); -var core = __webpack_require__(39); -var LIBRARY = __webpack_require__(150); -var wksExt = __webpack_require__(153); -var defineProperty = __webpack_require__(56).f; +var global = __webpack_require__(43); +var core = __webpack_require__(34); +var LIBRARY = __webpack_require__(126); +var wksExt = __webpack_require__(129); +var defineProperty = __webpack_require__(49).f; module.exports = function (name) { var $Symbol = core.Symbol || (core.Symbol = LIBRARY ? {} : global.Symbol || {}); if (name.charAt(0) != '_' && !(name in $Symbol)) defineProperty($Symbol, name, { value: wksExt.f(name) }); @@ -47619,7 +43322,7 @@ module.exports = function (name) { /***/ }), -/* 155 */ +/* 131 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -47691,7 +43394,56 @@ CloseButton.defaultProps = defaultProps; /* harmony default export */ __webpack_exports__["a"] = (CloseButton); /***/ }), -/* 156 */ +/* 132 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = createChainableTypeChecker; +/** + * Copyright 2013-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +// Mostly taken from ReactPropTypes. + +function createChainableTypeChecker(validate) { + function checkType(isRequired, props, propName, componentName, location, propFullName) { + var componentNameSafe = componentName || '<>'; + var propFullNameSafe = propFullName || propName; + + if (props[propName] == null) { + if (isRequired) { + return new Error('Required ' + location + ' `' + propFullNameSafe + '` was not specified ' + ('in `' + componentNameSafe + '`.')); + } + + return null; + } + + for (var _len = arguments.length, args = Array(_len > 6 ? _len - 6 : 0), _key = 6; _key < _len; _key++) { + args[_key - 6] = arguments[_key]; + } + + return validate.apply(undefined, [props, propName, componentNameSafe, location, propFullNameSafe].concat(args)); + } + + var chainedCheckType = checkType.bind(null, false); + chainedCheckType.isRequired = checkType.bind(null, true); + + return chainedCheckType; +} +module.exports = exports['default']; + +/***/ }), +/* 133 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -47711,9 +43463,9 @@ CloseButton.defaultProps = defaultProps; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_react__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_prop_types__ = __webpack_require__(8); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_prop_types__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_prop_types_extra_lib_all__ = __webpack_require__(108); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_prop_types_extra_lib_all__ = __webpack_require__(94); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_prop_types_extra_lib_all___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_8_prop_types_extra_lib_all__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__Button__ = __webpack_require__(91); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__Button__ = __webpack_require__(80); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__utils_bootstrapUtils__ = __webpack_require__(9); @@ -47788,7 +43540,7 @@ ButtonGroup.defaultProps = defaultProps; /* harmony default export */ __webpack_exports__["a"] = (Object(__WEBPACK_IMPORTED_MODULE_10__utils_bootstrapUtils__["bsClass"])('btn-group', ButtonGroup)); /***/ }), -/* 157 */ +/* 134 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -47802,9 +43554,9 @@ ButtonGroup.defaultProps = defaultProps; -var _prodInvariant = __webpack_require__(14); +var _prodInvariant = __webpack_require__(13); -var ReactErrorUtils = __webpack_require__(158); +var ReactErrorUtils = __webpack_require__(135); var invariant = __webpack_require__(11); var warning = __webpack_require__(12); @@ -48018,7 +43770,7 @@ module.exports = EventPluginUtils; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 158 */ +/* 135 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48100,7 +43852,7 @@ module.exports = ReactErrorUtils; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 159 */ +/* 136 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48138,7 +43890,7 @@ function getEventTarget(nativeEvent) { module.exports = getEventTarget; /***/ }), -/* 160 */ +/* 137 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48152,7 +43904,7 @@ module.exports = getEventTarget; -var ExecutionEnvironment = __webpack_require__(21); +var ExecutionEnvironment = __webpack_require__(18); var useHasFeature; if (ExecutionEnvironment.canUseDOM) { @@ -48201,7 +43953,7 @@ function isEventSupported(eventNameSuffix, capture) { module.exports = isEventSupported; /***/ }), -/* 161 */ +/* 138 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48247,7 +43999,7 @@ function getEventModifierState(nativeEvent) { module.exports = getEventModifierState; /***/ }), -/* 162 */ +/* 139 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48261,14 +44013,14 @@ module.exports = getEventModifierState; -var DOMLazyTree = __webpack_require__(73); -var Danger = __webpack_require__(452); -var ReactDOMComponentTree = __webpack_require__(19); -var ReactInstrumentation = __webpack_require__(31); +var DOMLazyTree = __webpack_require__(66); +var Danger = __webpack_require__(403); +var ReactDOMComponentTree = __webpack_require__(16); +var ReactInstrumentation = __webpack_require__(27); -var createMicrosoftUnsafeLocalFunction = __webpack_require__(164); -var setInnerHTML = __webpack_require__(112); -var setTextContent = __webpack_require__(243); +var createMicrosoftUnsafeLocalFunction = __webpack_require__(141); +var setInnerHTML = __webpack_require__(98); +var setTextContent = __webpack_require__(217); function getNodeAfter(parentNode, node) { // Special case for text components, which return [open, close] comments @@ -48477,7 +44229,7 @@ module.exports = DOMChildrenOperations; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 163 */ +/* 140 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48500,7 +44252,7 @@ var DOMNamespaces = { module.exports = DOMNamespaces; /***/ }), -/* 164 */ +/* 141 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48535,7 +44287,7 @@ var createMicrosoftUnsafeLocalFunction = function (func) { module.exports = createMicrosoftUnsafeLocalFunction; /***/ }), -/* 165 */ +/* 142 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48549,12 +44301,12 @@ module.exports = createMicrosoftUnsafeLocalFunction; -var _prodInvariant = __webpack_require__(14); +var _prodInvariant = __webpack_require__(13); -var ReactPropTypesSecret = __webpack_require__(247); -var propTypesFactory = __webpack_require__(216); +var ReactPropTypesSecret = __webpack_require__(221); +var propTypesFactory = __webpack_require__(190); -var React = __webpack_require__(66); +var React = __webpack_require__(59); var PropTypes = propTypesFactory(React.isValidElement); var invariant = __webpack_require__(11); @@ -48677,7 +44429,7 @@ module.exports = LinkedValueUtils; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 166 */ +/* 143 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48692,7 +44444,7 @@ module.exports = LinkedValueUtils; -var _prodInvariant = __webpack_require__(14); +var _prodInvariant = __webpack_require__(13); var invariant = __webpack_require__(11); @@ -48725,7 +44477,7 @@ module.exports = ReactComponentEnvironment; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 167 */ +/* 144 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48796,7 +44548,7 @@ function shallowEqual(objA, objB) { module.exports = shallowEqual; /***/ }), -/* 168 */ +/* 145 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48841,7 +44593,7 @@ function shouldUpdateReactComponent(prevElement, nextElement) { module.exports = shouldUpdateReactComponent; /***/ }), -/* 169 */ +/* 146 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48903,7 +44655,7 @@ var KeyEscapeUtils = { module.exports = KeyEscapeUtils; /***/ }), -/* 170 */ +/* 147 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48917,12 +44669,12 @@ module.exports = KeyEscapeUtils; -var _prodInvariant = __webpack_require__(14); +var _prodInvariant = __webpack_require__(13); -var ReactCurrentOwner = __webpack_require__(37); -var ReactInstanceMap = __webpack_require__(95); -var ReactInstrumentation = __webpack_require__(31); -var ReactUpdates = __webpack_require__(42); +var ReactCurrentOwner = __webpack_require__(32); +var ReactInstanceMap = __webpack_require__(84); +var ReactInstrumentation = __webpack_require__(27); +var ReactUpdates = __webpack_require__(37); var invariant = __webpack_require__(11); var warning = __webpack_require__(12); @@ -49141,7 +44893,7 @@ module.exports = ReactUpdateQueue; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 171 */ +/* 148 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -49155,9 +44907,9 @@ module.exports = ReactUpdateQueue; -var _assign = __webpack_require__(18); +var _assign = __webpack_require__(15); -var emptyFunction = __webpack_require__(30); +var emptyFunction = __webpack_require__(26); var warning = __webpack_require__(12); var validateDOMNesting = emptyFunction; @@ -49516,7 +45268,7 @@ module.exports = validateDOMNesting; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 172 */ +/* 149 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -49569,7 +45321,7 @@ function getEventCharCode(nativeEvent) { module.exports = getEventCharCode; /***/ }), -/* 173 */ +/* 150 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -49644,7 +45396,7 @@ Glyphicon.propTypes = propTypes; /* harmony default export */ __webpack_exports__["a"] = (Object(__WEBPACK_IMPORTED_MODULE_8__utils_bootstrapUtils__["bsClass"])('glyphicon', Glyphicon)); /***/ }), -/* 174 */ +/* 151 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -49660,16 +45412,16 @@ Glyphicon.propTypes = propTypes; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_babel_runtime_helpers_inherits___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_babel_runtime_helpers_inherits__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_classnames__ = __webpack_require__(7); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_classnames___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_classnames__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_dom_helpers_style__ = __webpack_require__(115); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_dom_helpers_style__ = __webpack_require__(101); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_dom_helpers_style___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_dom_helpers_style__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_react__ = __webpack_require__(0); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_react__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_prop_types__ = __webpack_require__(8); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_8_prop_types__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9_react_overlays_lib_Transition__ = __webpack_require__(262); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9_react_overlays_lib_Transition__ = __webpack_require__(236); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_9_react_overlays_lib_Transition___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_9_react_overlays_lib_Transition__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__utils_capitalize__ = __webpack_require__(259); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__utils_createChainedFunction__ = __webpack_require__(20); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__utils_capitalize__ = __webpack_require__(233); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__utils_createChainedFunction__ = __webpack_require__(17); @@ -49706,7 +45458,7 @@ var propTypes = { /** * Show the component; triggers the expand or collapse animation */ - in: __WEBPACK_IMPORTED_MODULE_8_prop_types___default.a.bool, + 'in': __WEBPACK_IMPORTED_MODULE_8_prop_types___default.a.bool, /** * Wait until the first "enter" transition to mount the component (add it to the DOM) @@ -49781,7 +45533,7 @@ var propTypes = { }; var defaultProps = { - in: false, + 'in': false, timeout: 300, mountOnEnter: false, unmountOnExit: false, @@ -49807,17 +45559,6 @@ var Collapse = function (_React$Component) { return _this; } - Collapse.prototype._dimension = function _dimension() { - return typeof this.props.dimension === 'function' ? this.props.dimension() : this.props.dimension; - }; - - // for testing - - - Collapse.prototype._getScrollDimensionValue = function _getScrollDimensionValue(elem, dimension) { - return elem['scroll' + Object(__WEBPACK_IMPORTED_MODULE_10__utils_capitalize__["a" /* default */])(dimension)] + 'px'; - }; - /* -- Expanding -- */ @@ -49826,14 +45567,14 @@ var Collapse = function (_React$Component) { elem.style[dimension] = '0'; }; - Collapse.prototype.handleEntered = function handleEntered(elem) { + Collapse.prototype.handleEntering = function handleEntering(elem) { var dimension = this._dimension(); - elem.style[dimension] = null; + elem.style[dimension] = this._getScrollDimensionValue(elem, dimension); }; - Collapse.prototype.handleEntering = function handleEntering(elem) { + Collapse.prototype.handleEntered = function handleEntered(elem) { var dimension = this._dimension(); - elem.style[dimension] = this._getScrollDimensionValue(elem, dimension); + elem.style[dimension] = null; }; /* -- Collapsing -- */ @@ -49850,6 +45591,17 @@ var Collapse = function (_React$Component) { elem.style[dimension] = '0'; }; + Collapse.prototype._dimension = function _dimension() { + return typeof this.props.dimension === 'function' ? this.props.dimension() : this.props.dimension; + }; + + // for testing + + + Collapse.prototype._getScrollDimensionValue = function _getScrollDimensionValue(elem, dimension) { + return elem['scroll' + Object(__WEBPACK_IMPORTED_MODULE_10__utils_capitalize__["a" /* default */])(dimension)] + 'px'; + }; + Collapse.prototype.render = function render() { var _props = this.props, onEnter = _props.onEnter, @@ -49874,7 +45626,7 @@ var Collapse = function (_React$Component) { }; return __WEBPACK_IMPORTED_MODULE_7_react___default.a.createElement(__WEBPACK_IMPORTED_MODULE_9_react_overlays_lib_Transition___default.a, __WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_extends___default()({}, props, { - 'aria-expanded': props.role ? props.in : null, + 'aria-expanded': props.role ? props['in'] : null, className: __WEBPACK_IMPORTED_MODULE_5_classnames___default()(className, classes), exitedClassName: 'collapse', exitingClassName: 'collapsing', @@ -49897,7 +45649,7 @@ Collapse.defaultProps = defaultProps; /* harmony default export */ __webpack_exports__["a"] = (Collapse); /***/ }), -/* 175 */ +/* 152 */ /***/ (function(module, exports) { // Source: http://jsfiddle.net/vWx8V/ @@ -50049,7 +45801,7 @@ for (var alias in aliases) { /***/ }), -/* 176 */ +/* 153 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -50059,7 +45811,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); -var _inDOM = __webpack_require__(51); +var _inDOM = __webpack_require__(45); var _inDOM2 = _interopRequireDefault(_inDOM); @@ -50080,7 +45832,163 @@ exports.default = off; module.exports = exports['default']; /***/ }), -/* 177 */ +/* 154 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_extends__ = __webpack_require__(5); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_extends___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_extends__); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_objectWithoutProperties__ = __webpack_require__(6); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_objectWithoutProperties___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_objectWithoutProperties__); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_babel_runtime_helpers_classCallCheck__ = __webpack_require__(2); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_babel_runtime_helpers_classCallCheck___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_babel_runtime_helpers_classCallCheck__); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_babel_runtime_helpers_possibleConstructorReturn__ = __webpack_require__(3); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_babel_runtime_helpers_possibleConstructorReturn___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_babel_runtime_helpers_possibleConstructorReturn__); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_babel_runtime_helpers_inherits__ = __webpack_require__(4); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_babel_runtime_helpers_inherits___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_babel_runtime_helpers_inherits__); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_classnames__ = __webpack_require__(7); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_classnames___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_classnames__); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_react__ = __webpack_require__(0); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_react__); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_prop_types_extra_lib_elementType__ = __webpack_require__(14); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_prop_types_extra_lib_elementType___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_prop_types_extra_lib_elementType__); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__MediaBody__ = __webpack_require__(507); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__MediaHeading__ = __webpack_require__(508); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__MediaLeft__ = __webpack_require__(509); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__MediaList__ = __webpack_require__(510); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__MediaListItem__ = __webpack_require__(511); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__MediaRight__ = __webpack_require__(512); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__utils_bootstrapUtils__ = __webpack_require__(9); + + + + + + + + + + + + + + + + + +var propTypes = { + componentClass: __WEBPACK_IMPORTED_MODULE_7_prop_types_extra_lib_elementType___default.a +}; + +var defaultProps = { + componentClass: 'div' +}; + +var Media = function (_React$Component) { + __WEBPACK_IMPORTED_MODULE_4_babel_runtime_helpers_inherits___default()(Media, _React$Component); + + function Media() { + __WEBPACK_IMPORTED_MODULE_2_babel_runtime_helpers_classCallCheck___default()(this, Media); + + return __WEBPACK_IMPORTED_MODULE_3_babel_runtime_helpers_possibleConstructorReturn___default()(this, _React$Component.apply(this, arguments)); + } + + Media.prototype.render = function render() { + var _props = this.props, + Component = _props.componentClass, + className = _props.className, + props = __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_objectWithoutProperties___default()(_props, ['componentClass', 'className']); + + var _splitBsProps = Object(__WEBPACK_IMPORTED_MODULE_14__utils_bootstrapUtils__["splitBsProps"])(props), + bsProps = _splitBsProps[0], + elementProps = _splitBsProps[1]; + + var classes = Object(__WEBPACK_IMPORTED_MODULE_14__utils_bootstrapUtils__["getClassSet"])(bsProps); + + return __WEBPACK_IMPORTED_MODULE_6_react___default.a.createElement(Component, __WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_extends___default()({}, elementProps, { + className: __WEBPACK_IMPORTED_MODULE_5_classnames___default()(className, classes) + })); + }; + + return Media; +}(__WEBPACK_IMPORTED_MODULE_6_react___default.a.Component); + +Media.propTypes = propTypes; +Media.defaultProps = defaultProps; + +Media.Heading = __WEBPACK_IMPORTED_MODULE_9__MediaHeading__["a" /* default */]; +Media.Body = __WEBPACK_IMPORTED_MODULE_8__MediaBody__["a" /* default */]; +Media.Left = __WEBPACK_IMPORTED_MODULE_10__MediaLeft__["a" /* default */]; +Media.Right = __WEBPACK_IMPORTED_MODULE_13__MediaRight__["a" /* default */]; +Media.List = __WEBPACK_IMPORTED_MODULE_11__MediaList__["a" /* default */]; +Media.ListItem = __WEBPACK_IMPORTED_MODULE_12__MediaListItem__["a" /* default */]; + +/* harmony default export */ __webpack_exports__["a"] = (Object(__WEBPACK_IMPORTED_MODULE_14__utils_bootstrapUtils__["bsClass"])('media', Media)); + +/***/ }), +/* 155 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.__esModule = true; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _createChainableTypeChecker = __webpack_require__(244); + +var _createChainableTypeChecker2 = _interopRequireDefault(_createChainableTypeChecker); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + var propType = typeof propValue === 'undefined' ? 'undefined' : _typeof(propValue); + + if (_react2.default.isValidElement(propValue)) { + return new Error('Invalid ' + location + ' `' + propFullName + '` of type ReactElement ' + ('supplied to `' + componentName + '`, expected a ReactComponent or a ') + 'DOMElement. You can usually obtain a ReactComponent or DOMElement ' + 'from a ReactElement by attaching a ref to it.'); + } + + if ((propType !== 'object' || typeof propValue.render !== 'function') && propValue.nodeType !== 1) { + return new Error('Invalid ' + location + ' `' + propFullName + '` of value `' + propValue + '` ' + ('supplied to `' + componentName + '`, expected a ReactComponent or a ') + 'DOMElement.'); + } + + return null; +} + +exports.default = (0, _createChainableTypeChecker2.default)(validate); + +/***/ }), +/* 156 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = getContainer; + +var _reactDom = __webpack_require__(24); + +var _reactDom2 = _interopRequireDefault(_reactDom); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function getContainer(container, defaultContainer) { + container = typeof container === 'function' ? container() : container; + return _reactDom2.default.findDOMNode(container) || defaultContainer; +} +module.exports = exports['default']; + +/***/ }), +/* 157 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -50096,7 +46004,7 @@ module.exports = exports['default']; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_react__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_prop_types__ = __webpack_require__(8); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_prop_types__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_uncontrollable__ = __webpack_require__(96); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_uncontrollable__ = __webpack_require__(85); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_uncontrollable___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_uncontrollable__); @@ -50228,7 +46136,7 @@ TabContainer.childContextTypes = childContextTypes; /* harmony default export */ __webpack_exports__["a"] = (__WEBPACK_IMPORTED_MODULE_6_uncontrollable___default()(TabContainer, { activeKey: 'onSelect' })); /***/ }), -/* 178 */ +/* 158 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -50248,7 +46156,7 @@ TabContainer.childContextTypes = childContextTypes; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_react__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_prop_types__ = __webpack_require__(8); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_prop_types__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_prop_types_extra_lib_elementType__ = __webpack_require__(15); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_prop_types_extra_lib_elementType__ = __webpack_require__(14); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_prop_types_extra_lib_elementType___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_8_prop_types_extra_lib_elementType__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__utils_bootstrapUtils__ = __webpack_require__(9); @@ -50369,11 +46277,6 @@ var TabContent = function (_React$Component) { this.isUnmounted = true; }; - TabContent.prototype.getContainerActiveKey = function getContainerActiveKey() { - var tabContainer = this.context.$bs_tabContainer; - return tabContainer && tabContainer.activeKey; - }; - TabContent.prototype.handlePaneEnter = function handlePaneEnter(child, childKey) { if (!this.props.animation) { return false; @@ -50412,6 +46315,11 @@ var TabContent = function (_React$Component) { }); }; + TabContent.prototype.getContainerActiveKey = function getContainerActiveKey() { + var tabContainer = this.context.$bs_tabContainer; + return tabContainer && tabContainer.activeKey; + }; + TabContent.prototype.render = function render() { var _props2 = this.props, Component = _props2.componentClass, @@ -50438,20 +46346,20 @@ TabContent.childContextTypes = childContextTypes; /* harmony default export */ __webpack_exports__["a"] = (Object(__WEBPACK_IMPORTED_MODULE_9__utils_bootstrapUtils__["bsClass"])('tab', TabContent)); /***/ }), -/* 179 */ +/* 159 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = __webpack_require__(614); +module.exports = __webpack_require__(562); /***/ }), -/* 180 */ +/* 160 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(process) { -var utils = __webpack_require__(33); -var normalizeHeaderName = __webpack_require__(617); +var utils = __webpack_require__(28); +var normalizeHeaderName = __webpack_require__(565); var DEFAULT_CONTENT_TYPE = { 'Content-Type': 'application/x-www-form-urlencoded' @@ -50467,10 +46375,10 @@ function getDefaultAdapter() { var adapter; if (typeof XMLHttpRequest !== 'undefined') { // For browsers use XHR adapter - adapter = __webpack_require__(289); + adapter = __webpack_require__(265); } else if (typeof process !== 'undefined') { // For node use HTTP adapter - adapter = __webpack_require__(289); + adapter = __webpack_require__(265); } return adapter; } @@ -50544,7 +46452,7 @@ module.exports = defaults; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) /***/ }), -/* 181 */ +/* 161 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function() { @@ -50557,11 +46465,11 @@ var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function() { /***/ }), -/* 182 */ +/* 162 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ - __webpack_require__(99) + __webpack_require__(89) ], __WEBPACK_AMD_DEFINE_RESULT__ = function( arr ) { "use strict"; @@ -50571,11 +46479,11 @@ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_ /***/ }), -/* 183 */ +/* 163 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ - __webpack_require__(99) + __webpack_require__(89) ], __WEBPACK_AMD_DEFINE_RESULT__ = function( arr ) { "use strict"; @@ -50585,11 +46493,11 @@ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_ /***/ }), -/* 184 */ +/* 164 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ - __webpack_require__(181) + __webpack_require__(161) ], __WEBPACK_AMD_DEFINE_RESULT__ = function( class2type ) { "use strict"; @@ -50599,11 +46507,11 @@ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_ /***/ }), -/* 185 */ +/* 165 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ - __webpack_require__(186) + __webpack_require__(166) ], __WEBPACK_AMD_DEFINE_RESULT__ = function( pnum ) { "use strict"; @@ -50615,7 +46523,7 @@ return new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); /***/ }), -/* 186 */ +/* 166 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function() { @@ -50627,11 +46535,11 @@ var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function() { /***/ }), -/* 187 */ +/* 167 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ - __webpack_require__(186) + __webpack_require__(166) ], __WEBPACK_AMD_DEFINE_RESULT__ = function( pnum ) { "use strict"; @@ -50641,14 +46549,14 @@ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_ /***/ }), -/* 188 */ +/* 168 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(10), - __webpack_require__(22), - __webpack_require__(189), - __webpack_require__(62) + __webpack_require__(20), + __webpack_require__(169), + __webpack_require__(55) ], __WEBPACK_AMD_DEFINE_RESULT__ = function( jQuery, document, documentElement, support ) { "use strict"; @@ -50737,11 +46645,11 @@ return support; /***/ }), -/* 189 */ +/* 169 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ - __webpack_require__(22) + __webpack_require__(20) ], __WEBPACK_AMD_DEFINE_RESULT__ = function( document ) { "use strict"; @@ -50751,12 +46659,12 @@ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_ /***/ }), -/* 190 */ +/* 170 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(10), - __webpack_require__(52) + __webpack_require__(46) ], __WEBPACK_AMD_DEFINE_RESULT__ = function( jQuery, rnothtmlwhite ) { "use strict"; @@ -50992,7 +46900,7 @@ return jQuery; /***/ }), -/* 191 */ +/* 171 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function() { @@ -51018,14 +46926,14 @@ return function( owner ) { /***/ }), -/* 192 */ +/* 172 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(10), - __webpack_require__(43), - __webpack_require__(77), - __webpack_require__(190) + __webpack_require__(38), + __webpack_require__(69), + __webpack_require__(170) ], __WEBPACK_AMD_DEFINE_RESULT__ = function( jQuery, dataPriv ) { "use strict"; @@ -51170,28 +47078,28 @@ return jQuery; /***/ }), -/* 193 */ +/* 173 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(10), - __webpack_require__(22), - __webpack_require__(185), - __webpack_require__(52), - __webpack_require__(302), - __webpack_require__(313), - __webpack_require__(296), - __webpack_require__(305), - __webpack_require__(43), - __webpack_require__(650), - - __webpack_require__(34), - __webpack_require__(192), - __webpack_require__(77), - __webpack_require__(78), - __webpack_require__(127), - __webpack_require__(98), - __webpack_require__(652) + __webpack_require__(20), + __webpack_require__(165), + __webpack_require__(46), + __webpack_require__(277), + __webpack_require__(288), + __webpack_require__(271), + __webpack_require__(280), + __webpack_require__(38), + __webpack_require__(597), + + __webpack_require__(30), + __webpack_require__(172), + __webpack_require__(69), + __webpack_require__(70), + __webpack_require__(110), + __webpack_require__(88), + __webpack_require__(599) ], __WEBPACK_AMD_DEFINE_RESULT__ = function( jQuery, document, rcssNum, rnothtmlwhite, cssExpand, isHiddenWithinTree, swap, adjustCSS, dataPriv, showHide ) { @@ -51876,12 +47784,12 @@ return jQuery; /***/ }), -/* 194 */ +/* 174 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ - __webpack_require__(22), - __webpack_require__(62) + __webpack_require__(20), + __webpack_require__(55) ], __WEBPACK_AMD_DEFINE_RESULT__ = function( document, support ) { "use strict"; @@ -51916,11 +47824,11 @@ return support; /***/ }), -/* 195 */ +/* 175 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ - __webpack_require__(52) + __webpack_require__(46) ], __WEBPACK_AMD_DEFINE_RESULT__ = function( rnothtmlwhite ) { "use strict"; @@ -51937,17 +47845,17 @@ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_ /***/ }), -/* 196 */ +/* 176 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(10), - __webpack_require__(22), - __webpack_require__(43), - __webpack_require__(191), - __webpack_require__(184), + __webpack_require__(20), + __webpack_require__(38), + __webpack_require__(171), + __webpack_require__(164), - __webpack_require__(79) + __webpack_require__(71) ], __WEBPACK_AMD_DEFINE_RESULT__ = function( jQuery, document, dataPriv, acceptData, hasOwn ) { "use strict"; @@ -52129,889 +48037,13 @@ return jQuery; /***/ }), -/* 197 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var common_1 = __webpack_require__(13); -var hof_1 = __webpack_require__(17); -var glob_1 = __webpack_require__(128); -var predicates_1 = __webpack_require__(16); -/** - * Internal representation of a UI-Router state. - * - * Instances of this class are created when a [[StateDeclaration]] is registered with the [[StateRegistry]]. - * - * A registered [[StateDeclaration]] is augmented with a getter ([[StateDeclaration.$$state]]) which returns the corresponding [[StateObject]] object. - * - * This class prototypally inherits from the corresponding [[StateDeclaration]]. - * Each of its own properties (i.e., `hasOwnProperty`) are built using builders from the [[StateBuilder]]. - */ -var StateObject = /** @class */ (function () { - /** @deprecated use State.create() */ - function StateObject(config) { - return StateObject.create(config || {}); - } - /** - * Create a state object to put the private/internal implementation details onto. - * The object's prototype chain looks like: - * (Internal State Object) -> (Copy of State.prototype) -> (State Declaration object) -> (State Declaration's prototype...) - * - * @param stateDecl the user-supplied State Declaration - * @returns {StateObject} an internal State object - */ - StateObject.create = function (stateDecl) { - stateDecl = StateObject.isStateClass(stateDecl) ? new stateDecl() : stateDecl; - var state = common_1.inherit(common_1.inherit(stateDecl, StateObject.prototype)); - stateDecl.$$state = function () { return state; }; - state.self = stateDecl; - state.__stateObjectCache = { - nameGlob: glob_1.Glob.fromString(state.name) // might return null - }; - return state; - }; - /** - * Returns true if the provided parameter is the same state. - * - * Compares the identity of the state against the passed value, which is either an object - * reference to the actual `State` instance, the original definition object passed to - * `$stateProvider.state()`, or the fully-qualified name. - * - * @param ref Can be one of (a) a `State` instance, (b) an object that was passed - * into `$stateProvider.state()`, (c) the fully-qualified name of a state as a string. - * @returns Returns `true` if `ref` matches the current `State` instance. - */ - StateObject.prototype.is = function (ref) { - return this === ref || this.self === ref || this.fqn() === ref; - }; - /** - * @deprecated this does not properly handle dot notation - * @returns Returns a dot-separated name of the state. - */ - StateObject.prototype.fqn = function () { - if (!this.parent || !(this.parent instanceof this.constructor)) - return this.name; - var name = this.parent.fqn(); - return name ? name + "." + this.name : this.name; - }; - /** - * Returns the root node of this state's tree. - * - * @returns The root of this state's tree. - */ - StateObject.prototype.root = function () { - return this.parent && this.parent.root() || this; - }; - /** - * Gets the state's `Param` objects - * - * Gets the list of [[Param]] objects owned by the state. - * If `opts.inherit` is true, it also includes the ancestor states' [[Param]] objects. - * If `opts.matchingKeys` exists, returns only `Param`s whose `id` is a key on the `matchingKeys` object - * - * @param opts options - */ - StateObject.prototype.parameters = function (opts) { - opts = common_1.defaults(opts, { inherit: true, matchingKeys: null }); - var inherited = opts.inherit && this.parent && this.parent.parameters() || []; - return inherited.concat(common_1.values(this.params)) - .filter(function (param) { return !opts.matchingKeys || opts.matchingKeys.hasOwnProperty(param.id); }); - }; - /** - * Returns a single [[Param]] that is owned by the state - * - * If `opts.inherit` is true, it also searches the ancestor states` [[Param]]s. - * @param id the name of the [[Param]] to return - * @param opts options - */ - StateObject.prototype.parameter = function (id, opts) { - if (opts === void 0) { opts = {}; } - return (this.url && this.url.parameter(id, opts) || - common_1.find(common_1.values(this.params), hof_1.propEq('id', id)) || - opts.inherit && this.parent && this.parent.parameter(id)); - }; - StateObject.prototype.toString = function () { - return this.fqn(); - }; - /** Predicate which returns true if the object is an class with @State() decorator */ - StateObject.isStateClass = function (stateDecl) { - return predicates_1.isFunction(stateDecl) && stateDecl['__uiRouterState'] === true; - }; - /** Predicate which returns true if the object is an internal [[StateObject]] object */ - StateObject.isState = function (obj) { - return predicates_1.isObject(obj['__stateObjectCache']); - }; - return StateObject; -}()); -exports.StateObject = StateObject; -//# sourceMappingURL=stateObject.js.map - -/***/ }), -/* 198 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -/** - * @module common - */ /** for typedoc */ -Object.defineProperty(exports, "__esModule", { value: true }); -var Queue = /** @class */ (function () { - function Queue(_items, _limit) { - if (_items === void 0) { _items = []; } - if (_limit === void 0) { _limit = null; } - this._items = _items; - this._limit = _limit; - } - Queue.prototype.enqueue = function (item) { - var items = this._items; - items.push(item); - if (this._limit && items.length > this._limit) - items.shift(); - return item; - }; - Queue.prototype.dequeue = function () { - if (this.size()) - return this._items.splice(0, 1)[0]; - }; - Queue.prototype.clear = function () { - var current = this._items; - this._items = []; - return current; - }; - Queue.prototype.size = function () { - return this._items.length; - }; - Queue.prototype.remove = function (item) { - var idx = this._items.indexOf(item); - return idx > -1 && this._items.splice(idx, 1)[0]; - }; - Queue.prototype.peekTail = function () { - return this._items[this._items.length - 1]; - }; - Queue.prototype.peekHead = function () { - if (this.size()) - return this._items[0]; - }; - return Queue; -}()); -exports.Queue = Queue; -//# sourceMappingURL=queue.js.map - -/***/ }), -/* 199 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -/** - * @coreapi - * @module transition - */ /** for typedoc */ -var common_1 = __webpack_require__(13); -var predicates_1 = __webpack_require__(16); -var interface_1 = __webpack_require__(81); // has or is using -var glob_1 = __webpack_require__(128); -/** - * Determines if the given state matches the matchCriteria - * - * @hidden - * - * @param state a State Object to test against - * @param criterion - * - If a string, matchState uses the string as a glob-matcher against the state name - * - If an array (of strings), matchState uses each string in the array as a glob-matchers against the state name - * and returns a positive match if any of the globs match. - * - If a function, matchState calls the function with the state and returns true if the function's result is truthy. - * @returns {boolean} - */ -function matchState(state, criterion) { - var toMatch = predicates_1.isString(criterion) ? [criterion] : criterion; - function matchGlobs(_state) { - var globStrings = toMatch; - for (var i = 0; i < globStrings.length; i++) { - var glob = new glob_1.Glob(globStrings[i]); - if ((glob && glob.matches(_state.name)) || (!glob && globStrings[i] === _state.name)) { - return true; - } - } - return false; - } - var matchFn = (predicates_1.isFunction(toMatch) ? toMatch : matchGlobs); - return !!matchFn(state); -} -exports.matchState = matchState; -/** - * @internalapi - * The registration data for a registered transition hook - */ -var RegisteredHook = /** @class */ (function () { - function RegisteredHook(tranSvc, eventType, callback, matchCriteria, removeHookFromRegistry, options) { - if (options === void 0) { options = {}; } - this.tranSvc = tranSvc; - this.eventType = eventType; - this.callback = callback; - this.matchCriteria = matchCriteria; - this.removeHookFromRegistry = removeHookFromRegistry; - this.invokeCount = 0; - this._deregistered = false; - this.priority = options.priority || 0; - this.bind = options.bind || null; - this.invokeLimit = options.invokeLimit; - } - /** - * Gets the matching [[PathNode]]s - * - * Given an array of [[PathNode]]s, and a [[HookMatchCriterion]], returns an array containing - * the [[PathNode]]s that the criteria matches, or `null` if there were no matching nodes. - * - * Returning `null` is significant to distinguish between the default - * "match-all criterion value" of `true` compared to a `() => true` function, - * when the nodes is an empty array. - * - * This is useful to allow a transition match criteria of `entering: true` - * to still match a transition, even when `entering === []`. Contrast that - * with `entering: (state) => true` which only matches when a state is actually - * being entered. - */ - RegisteredHook.prototype._matchingNodes = function (nodes, criterion) { - if (criterion === true) - return nodes; - var matching = nodes.filter(function (node) { return matchState(node.state, criterion); }); - return matching.length ? matching : null; - }; - /** - * Gets the default match criteria (all `true`) - * - * Returns an object which has all the criteria match paths as keys and `true` as values, i.e.: - * - * ```js - * { - * to: true, - * from: true, - * entering: true, - * exiting: true, - * retained: true, - * } - */ - RegisteredHook.prototype._getDefaultMatchCriteria = function () { - return common_1.map(this.tranSvc._pluginapi._getPathTypes(), function () { return true; }); - }; - /** - * Gets matching nodes as [[IMatchingNodes]] - * - * Create a IMatchingNodes object from the TransitionHookTypes that is roughly equivalent to: - * - * ```js - * let matches: IMatchingNodes = { - * to: _matchingNodes([tail(treeChanges.to)], mc.to), - * from: _matchingNodes([tail(treeChanges.from)], mc.from), - * exiting: _matchingNodes(treeChanges.exiting, mc.exiting), - * retained: _matchingNodes(treeChanges.retained, mc.retained), - * entering: _matchingNodes(treeChanges.entering, mc.entering), - * }; - * ``` - */ - RegisteredHook.prototype._getMatchingNodes = function (treeChanges) { - var _this = this; - var criteria = common_1.extend(this._getDefaultMatchCriteria(), this.matchCriteria); - var paths = common_1.values(this.tranSvc._pluginapi._getPathTypes()); - return paths.reduce(function (mn, pathtype) { - // STATE scope criteria matches against every node in the path. - // TRANSITION scope criteria matches against only the last node in the path - var isStateHook = pathtype.scope === interface_1.TransitionHookScope.STATE; - var path = treeChanges[pathtype.name] || []; - var nodes = isStateHook ? path : [common_1.tail(path)]; - mn[pathtype.name] = _this._matchingNodes(nodes, criteria[pathtype.name]); - return mn; - }, {}); - }; - /** - * Determines if this hook's [[matchCriteria]] match the given [[TreeChanges]] - * - * @returns an IMatchingNodes object, or null. If an IMatchingNodes object is returned, its values - * are the matching [[PathNode]]s for each [[HookMatchCriterion]] (to, from, exiting, retained, entering) - */ - RegisteredHook.prototype.matches = function (treeChanges) { - var matches = this._getMatchingNodes(treeChanges); - // Check if all the criteria matched the TreeChanges object - var allMatched = common_1.values(matches).every(common_1.identity); - return allMatched ? matches : null; - }; - RegisteredHook.prototype.deregister = function () { - this.removeHookFromRegistry(this); - this._deregistered = true; - }; - return RegisteredHook; -}()); -exports.RegisteredHook = RegisteredHook; -/** @hidden Return a registration function of the requested type. */ -function makeEvent(registry, transitionService, eventType) { - // Create the object which holds the registered transition hooks. - var _registeredHooks = registry._registeredHooks = (registry._registeredHooks || {}); - var hooks = _registeredHooks[eventType.name] = []; - var removeHookFn = common_1.removeFrom(hooks); - // Create hook registration function on the IHookRegistry for the event - registry[eventType.name] = hookRegistrationFn; - function hookRegistrationFn(matchObject, callback, options) { - if (options === void 0) { options = {}; } - var registeredHook = new RegisteredHook(transitionService, eventType, callback, matchObject, removeHookFn, options); - hooks.push(registeredHook); - return registeredHook.deregister.bind(registeredHook); - } - return hookRegistrationFn; -} -exports.makeEvent = makeEvent; -//# sourceMappingURL=hookRegistry.js.map - -/***/ }), -/* 200 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -/** @module path */ /** for typedoc */ -var common_1 = __webpack_require__(13); -var hof_1 = __webpack_require__(17); -var param_1 = __webpack_require__(83); -/** - * @internalapi - * - * A node in a [[TreeChanges]] path - * - * For a [[TreeChanges]] path, this class holds the stateful information for a single node in the path. - * Each PathNode corresponds to a state being entered, exited, or retained. - * The stateful information includes parameter values and resolve data. - */ -var PathNode = /** @class */ (function () { - function PathNode(stateOrNode) { - if (stateOrNode instanceof PathNode) { - var node = stateOrNode; - this.state = node.state; - this.paramSchema = node.paramSchema.slice(); - this.paramValues = common_1.extend({}, node.paramValues); - this.resolvables = node.resolvables.slice(); - this.views = node.views && node.views.slice(); - } - else { - var state = stateOrNode; - this.state = state; - this.paramSchema = state.parameters({ inherit: false }); - this.paramValues = {}; - this.resolvables = state.resolvables.map(function (res) { return res.clone(); }); - } - } - /** Sets [[paramValues]] for the node, from the values of an object hash */ - PathNode.prototype.applyRawParams = function (params) { - var getParamVal = function (paramDef) { return [paramDef.id, paramDef.value(params[paramDef.id])]; }; - this.paramValues = this.paramSchema.reduce(function (memo, pDef) { return common_1.applyPairs(memo, getParamVal(pDef)); }, {}); - return this; - }; - /** Gets a specific [[Param]] metadata that belongs to the node */ - PathNode.prototype.parameter = function (name) { - return common_1.find(this.paramSchema, hof_1.propEq("id", name)); - }; - /** - * @returns true if the state and parameter values for another PathNode are - * equal to the state and param values for this PathNode - */ - PathNode.prototype.equals = function (node, paramsFn) { - var diff = this.diff(node, paramsFn); - return diff && diff.length === 0; - }; - /** - * Finds Params with different parameter values on another PathNode. - * - * Given another node (of the same state), finds the parameter values which differ. - * Returns the [[Param]] (schema objects) whose parameter values differ. - * - * Given another node for a different state, returns `false` - * - * @param node The node to compare to - * @param paramsFn A function that returns which parameters should be compared. - * @returns The [[Param]]s which differ, or null if the two nodes are for different states - */ - PathNode.prototype.diff = function (node, paramsFn) { - if (this.state !== node.state) - return false; - var params = paramsFn ? paramsFn(this) : this.paramSchema; - return param_1.Param.changed(params, this.paramValues, node.paramValues); - }; - /** Returns a clone of the PathNode */ - PathNode.clone = function (node) { - return new PathNode(node); - }; - return PathNode; -}()); -exports.PathNode = PathNode; -//# sourceMappingURL=pathNode.js.map - -/***/ }), -/* 201 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -/** - * @coreapi - * @module params - */ -/** */ -var common_1 = __webpack_require__(13); -var predicates_1 = __webpack_require__(16); -/** - * An internal class which implements [[ParamTypeDefinition]]. - * - * A [[ParamTypeDefinition]] is a plain javascript object used to register custom parameter types. - * When a param type definition is registered, an instance of this class is created internally. - * - * This class has naive implementations for all the [[ParamTypeDefinition]] methods. - * - * Used by [[UrlMatcher]] when matching or formatting URLs, or comparing and validating parameter values. - * - * #### Example: - * ```js - * var paramTypeDef = { - * decode: function(val) { return parseInt(val, 10); }, - * encode: function(val) { return val && val.toString(); }, - * equals: function(a, b) { return this.is(a) && a === b; }, - * is: function(val) { return angular.isNumber(val) && isFinite(val) && val % 1 === 0; }, - * pattern: /\d+/ - * } - * - * var paramType = new ParamType(paramTypeDef); - * ``` - * @internalapi - */ -var ParamType = /** @class */ (function () { - /** - * @param def A configuration object which contains the custom type definition. The object's - * properties will override the default methods and/or pattern in `ParamType`'s public interface. - * @returns a new ParamType object - */ - function ParamType(def) { - /** @inheritdoc */ - this.pattern = /.*/; - /** @inheritdoc */ - this.inherit = true; - common_1.extend(this, def); - } - // consider these four methods to be "abstract methods" that should be overridden - /** @inheritdoc */ - ParamType.prototype.is = function (val, key) { return true; }; - /** @inheritdoc */ - ParamType.prototype.encode = function (val, key) { return val; }; - /** @inheritdoc */ - ParamType.prototype.decode = function (val, key) { return val; }; - /** @inheritdoc */ - ParamType.prototype.equals = function (a, b) { return a == b; }; - ParamType.prototype.$subPattern = function () { - var sub = this.pattern.toString(); - return sub.substr(1, sub.length - 2); - }; - ParamType.prototype.toString = function () { - return "{ParamType:" + this.name + "}"; - }; - /** Given an encoded string, or a decoded object, returns a decoded object */ - ParamType.prototype.$normalize = function (val) { - return this.is(val) ? val : this.decode(val); - }; - /** - * Wraps an existing custom ParamType as an array of ParamType, depending on 'mode'. - * e.g.: - * - urlmatcher pattern "/path?{queryParam[]:int}" - * - url: "/path?queryParam=1&queryParam=2 - * - $stateParams.queryParam will be [1, 2] - * if `mode` is "auto", then - * - url: "/path?queryParam=1 will create $stateParams.queryParam: 1 - * - url: "/path?queryParam=1&queryParam=2 will create $stateParams.queryParam: [1, 2] - */ - ParamType.prototype.$asArray = function (mode, isSearch) { - if (!mode) - return this; - if (mode === "auto" && !isSearch) - throw new Error("'auto' array mode is for query parameters only"); - return new ArrayType(this, mode); - }; - return ParamType; -}()); -exports.ParamType = ParamType; -/** - * Wraps up a `ParamType` object to handle array values. - * @internalapi - */ -function ArrayType(type, mode) { - var _this = this; - // Wrap non-array value as array - function arrayWrap(val) { - return predicates_1.isArray(val) ? val : (predicates_1.isDefined(val) ? [val] : []); - } - // Unwrap array value for "auto" mode. Return undefined for empty array. - function arrayUnwrap(val) { - switch (val.length) { - case 0: return undefined; - case 1: return mode === "auto" ? val[0] : val; - default: return val; - } - } - // Wraps type (.is/.encode/.decode) functions to operate on each value of an array - function arrayHandler(callback, allTruthyMode) { - return function handleArray(val) { - if (predicates_1.isArray(val) && val.length === 0) - return val; - var arr = arrayWrap(val); - var result = common_1.map(arr, callback); - return (allTruthyMode === true) ? common_1.filter(result, function (x) { return !x; }).length === 0 : arrayUnwrap(result); - }; - } - // Wraps type (.equals) functions to operate on each value of an array - function arrayEqualsHandler(callback) { - return function handleArray(val1, val2) { - var left = arrayWrap(val1), right = arrayWrap(val2); - if (left.length !== right.length) - return false; - for (var i = 0; i < left.length; i++) { - if (!callback(left[i], right[i])) - return false; - } - return true; - }; - } - ['encode', 'decode', 'equals', '$normalize'].forEach(function (name) { - var paramTypeFn = type[name].bind(type); - var wrapperFn = name === 'equals' ? arrayEqualsHandler : arrayHandler; - _this[name] = wrapperFn(paramTypeFn); - }); - common_1.extend(this, { - dynamic: type.dynamic, - name: type.name, - pattern: type.pattern, - inherit: type.inherit, - is: arrayHandler(type.is.bind(type), true), - $arrayMode: mode - }); -} -//# sourceMappingURL=paramType.js.map - -/***/ }), -/* 202 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -/** - * @coreapi - * @module transition - */ -/** for typedoc */ -var interface_1 = __webpack_require__(81); -var transition_1 = __webpack_require__(129); -var hookRegistry_1 = __webpack_require__(199); -var coreResolvables_1 = __webpack_require__(700); -var redirectTo_1 = __webpack_require__(701); -var onEnterExitRetain_1 = __webpack_require__(702); -var resolve_1 = __webpack_require__(703); -var views_1 = __webpack_require__(704); -var updateGlobals_1 = __webpack_require__(705); -var url_1 = __webpack_require__(706); -var lazyLoad_1 = __webpack_require__(349); -var transitionEventType_1 = __webpack_require__(350); -var transitionHook_1 = __webpack_require__(101); -var predicates_1 = __webpack_require__(16); -var common_1 = __webpack_require__(13); -var hof_1 = __webpack_require__(17); -var ignoredTransition_1 = __webpack_require__(707); -var invalidTransition_1 = __webpack_require__(708); -/** - * The default [[Transition]] options. - * - * Include this object when applying custom defaults: - * let reloadOpts = { reload: true, notify: true } - * let options = defaults(theirOpts, customDefaults, defaultOptions); - */ -exports.defaultTransOpts = { - location: true, - relative: null, - inherit: false, - notify: true, - reload: false, - custom: {}, - current: function () { return null; }, - source: "unknown" -}; -/** - * This class provides services related to Transitions. - * - * - Most importantly, it allows global Transition Hooks to be registered. - * - It allows the default transition error handler to be set. - * - It also has a factory function for creating new [[Transition]] objects, (used internally by the [[StateService]]). - * - * At bootstrap, [[UIRouter]] creates a single instance (singleton) of this class. - */ -var TransitionService = /** @class */ (function () { - /** @hidden */ - function TransitionService(_router) { - /** @hidden */ - this._transitionCount = 0; - /** @hidden The transition hook types, such as `onEnter`, `onStart`, etc */ - this._eventTypes = []; - /** @hidden The registered transition hooks */ - this._registeredHooks = {}; - /** @hidden The paths on a criteria object */ - this._criteriaPaths = {}; - this._router = _router; - this.$view = _router.viewService; - this._deregisterHookFns = {}; - this._pluginapi = common_1.createProxyFunctions(hof_1.val(this), {}, hof_1.val(this), [ - '_definePathType', - '_defineEvent', - '_getPathTypes', - '_getEvents', - 'getHooks', - ]); - this._defineCorePaths(); - this._defineCoreEvents(); - this._registerCoreTransitionHooks(); - } - /** - * Registers a [[TransitionHookFn]], called *while a transition is being constructed*. - * - * Registers a transition lifecycle hook, which is invoked during transition construction. - * - * This low level hook should only be used by plugins. - * This can be a useful time for plugins to add resolves or mutate the transition as needed. - * The Sticky States plugin uses this hook to modify the treechanges. - * - * ### Lifecycle - * - * `onCreate` hooks are invoked *while a transition is being constructed*. - * - * ### Return value - * - * The hook's return value is ignored - * - * @internalapi - * @param criteria defines which Transitions the Hook should be invoked for. - * @param callback the hook function which will be invoked. - * @param options the registration options - * @returns a function which deregisters the hook. - */ - TransitionService.prototype.onCreate = function (criteria, callback, options) { return; }; - /** @inheritdoc */ - TransitionService.prototype.onBefore = function (criteria, callback, options) { return; }; - /** @inheritdoc */ - TransitionService.prototype.onStart = function (criteria, callback, options) { return; }; - /** @inheritdoc */ - TransitionService.prototype.onExit = function (criteria, callback, options) { return; }; - /** @inheritdoc */ - TransitionService.prototype.onRetain = function (criteria, callback, options) { return; }; - /** @inheritdoc */ - TransitionService.prototype.onEnter = function (criteria, callback, options) { return; }; - /** @inheritdoc */ - TransitionService.prototype.onFinish = function (criteria, callback, options) { return; }; - /** @inheritdoc */ - TransitionService.prototype.onSuccess = function (criteria, callback, options) { return; }; - /** @inheritdoc */ - TransitionService.prototype.onError = function (criteria, callback, options) { return; }; - /** - * dispose - * @internalapi - */ - TransitionService.prototype.dispose = function (router) { - common_1.values(this._registeredHooks).forEach(function (hooksArray) { return hooksArray.forEach(function (hook) { - hook._deregistered = true; - common_1.removeFrom(hooksArray, hook); - }); }); - }; - /** - * Creates a new [[Transition]] object - * - * This is a factory function for creating new Transition objects. - * It is used internally by the [[StateService]] and should generally not be called by application code. - * - * @param fromPath the path to the current state (the from state) - * @param targetState the target state (destination) - * @returns a Transition - */ - TransitionService.prototype.create = function (fromPath, targetState) { - return new transition_1.Transition(fromPath, targetState, this._router); - }; - /** @hidden */ - TransitionService.prototype._defineCoreEvents = function () { - var Phase = interface_1.TransitionHookPhase; - var TH = transitionHook_1.TransitionHook; - var paths = this._criteriaPaths; - var NORMAL_SORT = false, REVERSE_SORT = true; - var ASYNCHRONOUS = false, SYNCHRONOUS = true; - this._defineEvent("onCreate", Phase.CREATE, 0, paths.to, NORMAL_SORT, TH.LOG_REJECTED_RESULT, TH.THROW_ERROR, SYNCHRONOUS); - this._defineEvent("onBefore", Phase.BEFORE, 0, paths.to); - this._defineEvent("onStart", Phase.RUN, 0, paths.to); - this._defineEvent("onExit", Phase.RUN, 100, paths.exiting, REVERSE_SORT); - this._defineEvent("onRetain", Phase.RUN, 200, paths.retained); - this._defineEvent("onEnter", Phase.RUN, 300, paths.entering); - this._defineEvent("onFinish", Phase.RUN, 400, paths.to); - this._defineEvent("onSuccess", Phase.SUCCESS, 0, paths.to, NORMAL_SORT, TH.LOG_REJECTED_RESULT, TH.LOG_ERROR, SYNCHRONOUS); - this._defineEvent("onError", Phase.ERROR, 0, paths.to, NORMAL_SORT, TH.LOG_REJECTED_RESULT, TH.LOG_ERROR, SYNCHRONOUS); - }; - /** @hidden */ - TransitionService.prototype._defineCorePaths = function () { - var STATE = interface_1.TransitionHookScope.STATE, TRANSITION = interface_1.TransitionHookScope.TRANSITION; - this._definePathType("to", TRANSITION); - this._definePathType("from", TRANSITION); - this._definePathType("exiting", STATE); - this._definePathType("retained", STATE); - this._definePathType("entering", STATE); - }; - /** @hidden */ - TransitionService.prototype._defineEvent = function (name, hookPhase, hookOrder, criteriaMatchPath, reverseSort, getResultHandler, getErrorHandler, synchronous) { - if (reverseSort === void 0) { reverseSort = false; } - if (getResultHandler === void 0) { getResultHandler = transitionHook_1.TransitionHook.HANDLE_RESULT; } - if (getErrorHandler === void 0) { getErrorHandler = transitionHook_1.TransitionHook.REJECT_ERROR; } - if (synchronous === void 0) { synchronous = false; } - var eventType = new transitionEventType_1.TransitionEventType(name, hookPhase, hookOrder, criteriaMatchPath, reverseSort, getResultHandler, getErrorHandler, synchronous); - this._eventTypes.push(eventType); - hookRegistry_1.makeEvent(this, this, eventType); - }; - ; - /** @hidden */ - TransitionService.prototype._getEvents = function (phase) { - var transitionHookTypes = predicates_1.isDefined(phase) ? - this._eventTypes.filter(function (type) { return type.hookPhase === phase; }) : - this._eventTypes.slice(); - return transitionHookTypes.sort(function (l, r) { - var cmpByPhase = l.hookPhase - r.hookPhase; - return cmpByPhase === 0 ? l.hookOrder - r.hookOrder : cmpByPhase; - }); - }; - /** - * Adds a Path to be used as a criterion against a TreeChanges path - * - * For example: the `exiting` path in [[HookMatchCriteria]] is a STATE scoped path. - * It was defined by calling `defineTreeChangesCriterion('exiting', TransitionHookScope.STATE)` - * Each state in the exiting path is checked against the criteria and returned as part of the match. - * - * Another example: the `to` path in [[HookMatchCriteria]] is a TRANSITION scoped path. - * It was defined by calling `defineTreeChangesCriterion('to', TransitionHookScope.TRANSITION)` - * Only the tail of the `to` path is checked against the criteria and returned as part of the match. - * - * @hidden - */ - TransitionService.prototype._definePathType = function (name, hookScope) { - this._criteriaPaths[name] = { name: name, scope: hookScope }; - }; - /** * @hidden */ - TransitionService.prototype._getPathTypes = function () { - return this._criteriaPaths; - }; - /** @hidden */ - TransitionService.prototype.getHooks = function (hookName) { - return this._registeredHooks[hookName]; - }; - /** @hidden */ - TransitionService.prototype._registerCoreTransitionHooks = function () { - var fns = this._deregisterHookFns; - fns.addCoreResolves = coreResolvables_1.registerAddCoreResolvables(this); - fns.ignored = ignoredTransition_1.registerIgnoredTransitionHook(this); - fns.invalid = invalidTransition_1.registerInvalidTransitionHook(this); - // Wire up redirectTo hook - fns.redirectTo = redirectTo_1.registerRedirectToHook(this); - // Wire up onExit/Retain/Enter state hooks - fns.onExit = onEnterExitRetain_1.registerOnExitHook(this); - fns.onRetain = onEnterExitRetain_1.registerOnRetainHook(this); - fns.onEnter = onEnterExitRetain_1.registerOnEnterHook(this); - // Wire up Resolve hooks - fns.eagerResolve = resolve_1.registerEagerResolvePath(this); - fns.lazyResolve = resolve_1.registerLazyResolveState(this); - // Wire up the View management hooks - fns.loadViews = views_1.registerLoadEnteringViews(this); - fns.activateViews = views_1.registerActivateViews(this); - // Updates global state after a transition - fns.updateGlobals = updateGlobals_1.registerUpdateGlobalState(this); - // After globals.current is updated at priority: 10000 - fns.updateUrl = url_1.registerUpdateUrl(this); - // Lazy load state trees - fns.lazyLoad = lazyLoad_1.registerLazyLoadHook(this); - }; - return TransitionService; -}()); -exports.TransitionService = TransitionService; -//# sourceMappingURL=transitionService.js.map - -/***/ }), -/* 203 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -/** - * @internalapi - * @module vanilla - */ -/** */ -var common_1 = __webpack_require__(35); -exports.keyValsToObjectR = function (accum, _a) { - var key = _a[0], val = _a[1]; - if (!accum.hasOwnProperty(key)) { - accum[key] = val; - } - else if (common_1.isArray(accum[key])) { - accum[key].push(val); - } - else { - accum[key] = [accum[key], val]; - } - return accum; -}; -exports.getParams = function (queryString) { - return queryString.split("&").filter(common_1.identity).map(common_1.splitEqual).reduce(exports.keyValsToObjectR, {}); -}; -function parseUrl(url) { - var orEmptyString = function (x) { return x || ""; }; - var _a = common_1.splitHash(url).map(orEmptyString), beforehash = _a[0], hash = _a[1]; - var _b = common_1.splitQuery(beforehash).map(orEmptyString), path = _b[0], search = _b[1]; - return { path: path, search: search, hash: hash, url: url }; -} -exports.parseUrl = parseUrl; -exports.buildUrl = function (loc) { - var path = loc.path(); - var searchObject = loc.search(); - var hash = loc.hash(); - var search = Object.keys(searchObject).map(function (key) { - var param = searchObject[key]; - var vals = common_1.isArray(param) ? param : [param]; - return vals.map(function (val) { return key + "=" + val; }); - }).reduce(common_1.unnestR, []).join("&"); - return path + (search ? "?" + search : "") + (hash ? "#" + hash : ""); -}; -function locationPluginFactory(name, isHtml5, serviceClass, configurationClass) { - return function (router) { - var service = router.locationService = new serviceClass(router); - var configuration = router.locationConfig = new configurationClass(router, isHtml5); - function dispose(router) { - router.dispose(service); - router.dispose(configuration); - } - return { name: name, service: service, configuration: configuration, dispose: dispose }; - }; -} -exports.locationPluginFactory = locationPluginFactory; -//# sourceMappingURL=utils.js.map - -/***/ }), -/* 204 */ +/* 177 */ /***/ (function(module, exports, __webpack_require__) { // style-loader: Adds some css to the DOM by adding a +
+ userType: + Required!
+ userType = {{userType}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+
+ + + it('should initialize to model', function() { + var userType = element(by.binding('userType')); + var valid = element(by.binding('myForm.input.$valid')); -function $SceDelegateProvider() { - this.SCE_CONTEXTS = SCE_CONTEXTS; + expect(userType.getText()).toContain('guest'); + expect(valid.getText()).toContain('true'); + }); - // Resource URLs can also be trusted by policy. - var resourceUrlWhitelist = ['self'], - resourceUrlBlacklist = []; + it('should be invalid if empty', function() { + var userType = element(by.binding('userType')); + var valid = element(by.binding('myForm.input.$valid')); + var userInput = element(by.model('userType')); - /** - * @ngdoc method - * @name $sceDelegateProvider#resourceUrlWhitelist - * @kind function - * - * @param {Array=} whitelist When provided, replaces the resourceUrlWhitelist with the value - * provided. This must be an array or null. A snapshot of this array is used so further - * changes to the array are ignored. - * Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items - * allowed in this array. - * - * @return {Array} The currently set whitelist array. - * - * @description - * Sets/Gets the whitelist of trusted resource URLs. - * - * The **default value** when no whitelist has been explicitly set is `['self']` allowing only - * same origin resource requests. - * - *
- * **Note:** the default whitelist of 'self' is not recommended if your app shares its origin - * with other apps! It is a good idea to limit it to only your application's directory. - *
- */ - this.resourceUrlWhitelist = function(value) { - if (arguments.length) { - resourceUrlWhitelist = adjustMatchers(value); - } - return resourceUrlWhitelist; - }; + userInput.clear(); + userInput.sendKeys(''); - /** - * @ngdoc method - * @name $sceDelegateProvider#resourceUrlBlacklist - * @kind function - * - * @param {Array=} blacklist When provided, replaces the resourceUrlBlacklist with the value - * provided. This must be an array or null. A snapshot of this array is used so further - * changes to the array are ignored.

- * Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items - * allowed in this array.

- * The typical usage for the blacklist is to **block - * [open redirects](http://cwe.mitre.org/data/definitions/601.html)** served by your domain as - * these would otherwise be trusted but actually return content from the redirected domain. - *

- * Finally, **the blacklist overrides the whitelist** and has the final say. - * - * @return {Array} The currently set blacklist array. - * - * @description - * Sets/Gets the blacklist of trusted resource URLs. - * - * The **default value** when no whitelist has been explicitly set is the empty array (i.e. there - * is no blacklist.) - */ + expect(userType.getText()).toEqual('userType ='); + expect(valid.getText()).toContain('false'); + }); + + + * + * @param {string=} name Name of the form. If specified, the form controller will be published into + * related scope, under this name. + */ +var formDirectiveFactory = function(isNgForm) { + return ['$timeout', '$parse', function($timeout, $parse) { + var formDirective = { + name: 'form', + restrict: isNgForm ? 'EAC' : 'E', + require: ['form', '^^?form'], //first is the form's own ctrl, second is an optional parent form + controller: FormController, + compile: function ngFormCompile(formElement, attr) { + // Setup initial state of the control + formElement.addClass(PRISTINE_CLASS).addClass(VALID_CLASS); - this.resourceUrlBlacklist = function(value) { - if (arguments.length) { - resourceUrlBlacklist = adjustMatchers(value); - } - return resourceUrlBlacklist; - }; + var nameAttr = attr.name ? 'name' : (isNgForm && attr.ngForm ? 'ngForm' : false); - this.$get = ['$injector', function($injector) { + return { + pre: function ngFormPreLink(scope, formElement, attr, ctrls) { + var controller = ctrls[0]; - var htmlSanitizer = function htmlSanitizer(html) { - throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.'); - }; + // if `action` attr is not present on the form, prevent the default action (submission) + if (!('action' in attr)) { + // we can't use jq events because if a form is destroyed during submission the default + // action is not prevented. see #1238 + // + // IE 9 is not affected because it doesn't fire a submit event and try to do a full + // page reload if the form was destroyed by submission of the form via a click handler + // on a button in the form. Looks like an IE9 specific bug. + var handleFormSubmission = function(event) { + scope.$apply(function() { + controller.$commitViewValue(); + controller.$setSubmitted(); + }); - if ($injector.has('$sanitize')) { - htmlSanitizer = $injector.get('$sanitize'); - } + event.preventDefault(); + }; + formElement[0].addEventListener('submit', handleFormSubmission); - function matchUrl(matcher, parsedUrl) { - if (matcher === 'self') { - return urlIsSameOrigin(parsedUrl); - } else { - // definitely a regex. See adjustMatchers() - return !!matcher.exec(parsedUrl.href); - } - } + // unregister the preventDefault listener so that we don't not leak memory but in a + // way that will achieve the prevention of the default action. + formElement.on('$destroy', function() { + $timeout(function() { + formElement[0].removeEventListener('submit', handleFormSubmission); + }, 0, false); + }); + } - function isResourceUrlAllowedByPolicy(url) { - var parsedUrl = urlResolve(url.toString()); - var i, n, allowed = false; - // Ensure that at least one item from the whitelist allows this url. - for (i = 0, n = resourceUrlWhitelist.length; i < n; i++) { - if (matchUrl(resourceUrlWhitelist[i], parsedUrl)) { - allowed = true; - break; - } - } - if (allowed) { - // Ensure that no item from the blacklist blocked this url. - for (i = 0, n = resourceUrlBlacklist.length; i < n; i++) { - if (matchUrl(resourceUrlBlacklist[i], parsedUrl)) { - allowed = false; - break; + var parentFormCtrl = ctrls[1] || controller.$$parentForm; + parentFormCtrl.$addControl(controller); + + var setter = nameAttr ? getSetter(controller.$name) : noop; + + if (nameAttr) { + setter(scope, controller); + attr.$observe(nameAttr, function(newValue) { + if (controller.$name === newValue) return; + setter(scope, undefined); + controller.$$parentForm.$$renameControl(controller, newValue); + setter = getSetter(controller.$name); + setter(scope, controller); + }); + } + formElement.on('$destroy', function() { + controller.$$parentForm.$removeControl(controller); + setter(scope, undefined); + extend(controller, nullFormCtrl); //stop propagating child destruction handlers upwards + }); } - } + }; } - return allowed; + }; + + return formDirective; + + function getSetter(expression) { + if (expression === '') { + //create an assignable expression, so forms with an empty name can be renamed later + return $parse('this[""]').assign; + } + return $parse(expression).assign || noop; } + }]; +}; - function generateHolderType(Base) { - var holderType = function TrustedValueHolderType(trustedValue) { - this.$$unwrapTrustedValue = function() { - return trustedValue; - }; - }; - if (Base) { - holderType.prototype = new Base(); +var formDirective = formDirectiveFactory(); +var ngFormDirective = formDirectiveFactory(true); + + + +// helper methods +function setupValidity(instance) { + instance.$$classCache = {}; + instance.$$classCache[INVALID_CLASS] = !(instance.$$classCache[VALID_CLASS] = instance.$$element.hasClass(VALID_CLASS)); +} +function addSetValidityMethod(context) { + var clazz = context.clazz, + set = context.set, + unset = context.unset; + + clazz.prototype.$setValidity = function(validationErrorKey, state, controller) { + if (isUndefined(state)) { + createAndSet(this, '$pending', validationErrorKey, controller); + } else { + unsetAndCleanup(this, '$pending', validationErrorKey, controller); + } + if (!isBoolean(state)) { + unset(this.$error, validationErrorKey, controller); + unset(this.$$success, validationErrorKey, controller); + } else { + if (state) { + unset(this.$error, validationErrorKey, controller); + set(this.$$success, validationErrorKey, controller); + } else { + set(this.$error, validationErrorKey, controller); + unset(this.$$success, validationErrorKey, controller); } - holderType.prototype.valueOf = function sceValueOf() { - return this.$$unwrapTrustedValue(); - }; - holderType.prototype.toString = function sceToString() { - return this.$$unwrapTrustedValue().toString(); - }; - return holderType; + } + if (this.$pending) { + cachedToggleClass(this, PENDING_CLASS, true); + this.$valid = this.$invalid = undefined; + toggleValidationCss(this, '', null); + } else { + cachedToggleClass(this, PENDING_CLASS, false); + this.$valid = isObjectEmpty(this.$error); + this.$invalid = !this.$valid; + toggleValidationCss(this, '', this.$valid); } - var trustedValueHolderBase = generateHolderType(), - byType = {}; + // re-read the state as the set/unset methods could have + // combined state in this.$error[validationError] (used for forms), + // where setting/unsetting only increments/decrements the value, + // and does not replace it. + var combinedState; + if (this.$pending && this.$pending[validationErrorKey]) { + combinedState = undefined; + } else if (this.$error[validationErrorKey]) { + combinedState = false; + } else if (this.$$success[validationErrorKey]) { + combinedState = true; + } else { + combinedState = null; + } - byType[SCE_CONTEXTS.HTML] = generateHolderType(trustedValueHolderBase); - byType[SCE_CONTEXTS.CSS] = generateHolderType(trustedValueHolderBase); - byType[SCE_CONTEXTS.URL] = generateHolderType(trustedValueHolderBase); - byType[SCE_CONTEXTS.JS] = generateHolderType(trustedValueHolderBase); - byType[SCE_CONTEXTS.RESOURCE_URL] = generateHolderType(byType[SCE_CONTEXTS.URL]); + toggleValidationCss(this, validationErrorKey, combinedState); + this.$$parentForm.$setValidity(validationErrorKey, combinedState, this); + }; - /** - * @ngdoc method - * @name $sceDelegate#trustAs - * - * @description - * Returns a trusted representation of the parameter for the specified context. This trusted - * object will later on be used as-is, without any security check, by bindings or directives - * that require this security context. - * For instance, marking a string as trusted for the `$sce.HTML` context will entirely bypass - * the potential `$sanitize` call in corresponding `$sce.HTML` bindings or directives, such as - * `ng-bind-html`. Note that in most cases you won't need to call this function: if you have the - * sanitizer loaded, passing the value itself will render all the HTML that does not pose a - * security risk. - * - * See {@link ng.$sceDelegate#getTrusted getTrusted} for the function that will consume those - * trusted values, and {@link ng.$sce $sce} for general documentation about strict contextual - * escaping. - * - * @param {string} type The context in which this value is safe for use, e.g. `$sce.URL`, - * `$sce.RESOURCE_URL`, `$sce.HTML`, `$sce.JS` or `$sce.CSS`. - * - * @param {*} value The value that should be considered trusted. - * @return {*} A trusted representation of value, that can be used in the given context. - */ - function trustAs(type, trustedValue) { - var Constructor = (byType.hasOwnProperty(type) ? byType[type] : null); - if (!Constructor) { - throw $sceMinErr('icontext', - 'Attempted to trust a value in invalid context. Context: {0}; Value: {1}', - type, trustedValue); - } - if (trustedValue === null || isUndefined(trustedValue) || trustedValue === '') { - return trustedValue; - } - // All the current contexts in SCE_CONTEXTS happen to be strings. In order to avoid trusting - // mutable objects, we ensure here that the value passed in is actually a string. - if (typeof trustedValue !== 'string') { - throw $sceMinErr('itype', - 'Attempted to trust a non-string value in a content requiring a string: Context: {0}', - type); - } - return new Constructor(trustedValue); + function createAndSet(ctrl, name, value, controller) { + if (!ctrl[name]) { + ctrl[name] = {}; } + set(ctrl[name], value, controller); + } - /** - * @ngdoc method - * @name $sceDelegate#valueOf - * - * @description - * If the passed parameter had been returned by a prior call to {@link ng.$sceDelegate#trustAs - * `$sceDelegate.trustAs`}, returns the value that had been passed to {@link - * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}. - * - * If the passed parameter is not a value that had been returned by {@link - * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}, it must be returned as-is. - * - * @param {*} value The result of a prior {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`} - * call or anything else. - * @return {*} The `value` that was originally provided to {@link ng.$sceDelegate#trustAs - * `$sceDelegate.trustAs`} if `value` is the result of such a call. Otherwise, returns - * `value` unchanged. - */ - function valueOf(maybeTrusted) { - if (maybeTrusted instanceof trustedValueHolderBase) { - return maybeTrusted.$$unwrapTrustedValue(); - } else { - return maybeTrusted; - } + function unsetAndCleanup(ctrl, name, value, controller) { + if (ctrl[name]) { + unset(ctrl[name], value, controller); + } + if (isObjectEmpty(ctrl[name])) { + ctrl[name] = undefined; } + } - /** - * @ngdoc method - * @name $sceDelegate#getTrusted - * - * @description - * Takes any input, and either returns a value that's safe to use in the specified context, or - * throws an exception. - * - * In practice, there are several cases. When given a string, this function runs checks - * and sanitization to make it safe without prior assumptions. When given the result of a {@link - * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`} call, it returns the originally supplied - * value if that value's context is valid for this call's context. Finally, this function can - * also throw when there is no way to turn `maybeTrusted` in a safe value (e.g., no sanitization - * is available or possible.) - * - * @param {string} type The context in which this value is to be used (such as `$sce.HTML`). - * @param {*} maybeTrusted The result of a prior {@link ng.$sceDelegate#trustAs - * `$sceDelegate.trustAs`} call, or anything else (which will not be considered trusted.) - * @return {*} A version of the value that's safe to use in the given context, or throws an - * exception if this is impossible. - */ - function getTrusted(type, maybeTrusted) { - if (maybeTrusted === null || isUndefined(maybeTrusted) || maybeTrusted === '') { - return maybeTrusted; - } - var constructor = (byType.hasOwnProperty(type) ? byType[type] : null); - // If maybeTrusted is a trusted class instance or subclass instance, then unwrap and return - // as-is. - if (constructor && maybeTrusted instanceof constructor) { - return maybeTrusted.$$unwrapTrustedValue(); - } - // Otherwise, if we get here, then we may either make it safe, or throw an exception. This - // depends on the context: some are sanitizatible (HTML), some use whitelists (RESOURCE_URL), - // some are impossible to do (JS). This step isn't implemented for CSS and URL, as AngularJS - // has no corresponding sinks. - if (type === SCE_CONTEXTS.RESOURCE_URL) { - // RESOURCE_URL uses a whitelist. - if (isResourceUrlAllowedByPolicy(maybeTrusted)) { - return maybeTrusted; - } else { - throw $sceMinErr('insecurl', - 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: {0}', - maybeTrusted.toString()); - } - } else if (type === SCE_CONTEXTS.HTML) { - // htmlSanitizer throws its own error when no sanitizer is available. - return htmlSanitizer(maybeTrusted); - } - // Default error when the $sce service has no way to make the input safe. - throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.'); + function cachedToggleClass(ctrl, className, switchValue) { + if (switchValue && !ctrl.$$classCache[className]) { + ctrl.$$animate.addClass(ctrl.$$element, className); + ctrl.$$classCache[className] = true; + } else if (!switchValue && ctrl.$$classCache[className]) { + ctrl.$$animate.removeClass(ctrl.$$element, className); + ctrl.$$classCache[className] = false; } + } - return { trustAs: trustAs, - getTrusted: getTrusted, - valueOf: valueOf }; - }]; + function toggleValidationCss(ctrl, validationErrorKey, isValid) { + validationErrorKey = validationErrorKey ? '-' + snake_case(validationErrorKey, '-') : ''; + + cachedToggleClass(ctrl, VALID_CLASS + validationErrorKey, isValid === true); + cachedToggleClass(ctrl, INVALID_CLASS + validationErrorKey, isValid === false); + } } +function isObjectEmpty(obj) { + if (obj) { + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + return false; + } + } + } + return true; +} -/** - * @ngdoc provider - * @name $sceProvider - * @this - * - * @description - * - * The $sceProvider provider allows developers to configure the {@link ng.$sce $sce} service. - * - enable/disable Strict Contextual Escaping (SCE) in a module - * - override the default implementation with a custom delegate - * - * Read more about {@link ng.$sce Strict Contextual Escaping (SCE)}. - */ +/* global + VALID_CLASS: false, + INVALID_CLASS: false, + PRISTINE_CLASS: false, + DIRTY_CLASS: false, + ngModelMinErr: false +*/ -/** - * @ngdoc service - * @name $sce - * @kind function - * - * @description - * - * `$sce` is a service that provides Strict Contextual Escaping services to AngularJS. - * - * # Strict Contextual Escaping - * - * Strict Contextual Escaping (SCE) is a mode in which AngularJS constrains bindings to only render - * trusted values. Its goal is to assist in writing code in a way that (a) is secure by default, and - * (b) makes auditing for security vulnerabilities such as XSS, clickjacking, etc. a lot easier. - * - * ## Overview - * - * To systematically block XSS security bugs, AngularJS treats all values as untrusted by default in - * HTML or sensitive URL bindings. When binding untrusted values, AngularJS will automatically - * run security checks on them (sanitizations, whitelists, depending on context), or throw when it - * cannot guarantee the security of the result. That behavior depends strongly on contexts: HTML - * can be sanitized, but template URLs cannot, for instance. - * - * To illustrate this, consider the `ng-bind-html` directive. It renders its value directly as HTML: - * we call that the *context*. When given an untrusted input, AngularJS will attempt to sanitize it - * before rendering if a sanitizer is available, and throw otherwise. To bypass sanitization and - * render the input as-is, you will need to mark it as trusted for that context before attempting - * to bind it. - * - * As of version 1.2, AngularJS ships with SCE enabled by default. - * - * ## In practice - * - * Here's an example of a binding in a privileged context: - * - * ``` - * - *

- * ``` - * - * Notice that `ng-bind-html` is bound to `userHtml` controlled by the user. With SCE - * disabled, this application allows the user to render arbitrary HTML into the DIV, which would - * be an XSS security bug. In a more realistic example, one may be rendering user comments, blog - * articles, etc. via bindings. (HTML is just one example of a context where rendering user - * controlled input creates security vulnerabilities.) - * - * For the case of HTML, you might use a library, either on the client side, or on the server side, - * to sanitize unsafe HTML before binding to the value and rendering it in the document. - * - * How would you ensure that every place that used these types of bindings was bound to a value that - * was sanitized by your library (or returned as safe for rendering by your server?) How can you - * ensure that you didn't accidentally delete the line that sanitized the value, or renamed some - * properties/fields and forgot to update the binding to the sanitized value? - * - * To be secure by default, AngularJS makes sure bindings go through that sanitization, or - * any similar validation process, unless there's a good reason to trust the given value in this - * context. That trust is formalized with a function call. This means that as a developer, you - * can assume all untrusted bindings are safe. Then, to audit your code for binding security issues, - * you just need to ensure the values you mark as trusted indeed are safe - because they were - * received from your server, sanitized by your library, etc. You can organize your codebase to - * help with this - perhaps allowing only the files in a specific directory to do this. - * Ensuring that the internal API exposed by that code doesn't markup arbitrary values as safe then - * becomes a more manageable task. - * - * In the case of AngularJS' SCE service, one uses {@link ng.$sce#trustAs $sce.trustAs} - * (and shorthand methods such as {@link ng.$sce#trustAsHtml $sce.trustAsHtml}, etc.) to - * build the trusted versions of your values. - * - * ## How does it work? - * - * In privileged contexts, directives and code will bind to the result of {@link ng.$sce#getTrusted - * $sce.getTrusted(context, value)} rather than to the value directly. Think of this function as - * a way to enforce the required security context in your data sink. Directives use {@link - * ng.$sce#parseAs $sce.parseAs} rather than `$parse` to watch attribute bindings, which performs - * the {@link ng.$sce#getTrusted $sce.getTrusted} behind the scenes on non-constant literals. Also, - * when binding without directives, AngularJS will understand the context of your bindings - * automatically. - * - * As an example, {@link ng.directive:ngBindHtml ngBindHtml} uses {@link - * ng.$sce#parseAsHtml $sce.parseAsHtml(binding expression)}. Here's the actual code (slightly - * simplified): - * - * ``` - * var ngBindHtmlDirective = ['$sce', function($sce) { - * return function(scope, element, attr) { - * scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function(value) { - * element.html(value || ''); - * }); - * }; - * }]; - * ``` - * - * ## Impact on loading templates - * - * This applies both to the {@link ng.directive:ngInclude `ng-include`} directive as well as - * `templateUrl`'s specified by {@link guide/directive directives}. - * - * By default, Angular only loads templates from the same domain and protocol as the application - * document. This is done by calling {@link ng.$sce#getTrustedResourceUrl - * $sce.getTrustedResourceUrl} on the template URL. To load templates from other domains and/or - * protocols, you may either {@link ng.$sceDelegateProvider#resourceUrlWhitelist whitelist - * them} or {@link ng.$sce#trustAsResourceUrl wrap it} into a trusted value. - * - * *Please note*: - * The browser's - * [Same Origin Policy](https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest) - * and [Cross-Origin Resource Sharing (CORS)](http://www.w3.org/TR/cors/) - * policy apply in addition to this and may further restrict whether the template is successfully - * loaded. This means that without the right CORS policy, loading templates from a different domain - * won't work on all browsers. Also, loading templates from `file://` URL does not work on some - * browsers. - * - * ## This feels like too much overhead - * - * It's important to remember that SCE only applies to interpolation expressions. - * - * If your expressions are constant literals, they're automatically trusted and you don't need to - * call `$sce.trustAs` on them (e.g. - * `
`) just works. The `$sceDelegate` will - * also use the `$sanitize` service if it is available when binding untrusted values to - * `$sce.HTML` context. AngularJS provides an implementation in `angular-sanitize.js`, and if you - * wish to use it, you will also need to depend on the {@link ngSanitize `ngSanitize`} module in - * your application. - * - * The included {@link ng.$sceDelegate $sceDelegate} comes with sane defaults to allow you to load - * templates in `ng-include` from your application's domain without having to even know about SCE. - * It blocks loading templates from other domains or loading templates over http from an https - * served document. You can change these by setting your own custom {@link - * ng.$sceDelegateProvider#resourceUrlWhitelist whitelists} and {@link - * ng.$sceDelegateProvider#resourceUrlBlacklist blacklists} for matching such URLs. - * - * This significantly reduces the overhead. It is far easier to pay the small overhead and have an - * application that's secure and can be audited to verify that with much more ease than bolting - * security onto an application later. - * - * - * ## What trusted context types are supported? - * - * | Context | Notes | - * |---------------------|----------------| - * | `$sce.HTML` | For HTML that's safe to source into the application. The {@link ng.directive:ngBindHtml ngBindHtml} directive uses this context for bindings. If an unsafe value is encountered, and the {@link ngSanitize.$sanitize $sanitize} service is available (implemented by the {@link ngSanitize ngSanitize} module) this will sanitize the value instead of throwing an error. | - * | `$sce.CSS` | For CSS that's safe to source into the application. Currently, no bindings require this context. Feel free to use it in your own directives. | - * | `$sce.URL` | For URLs that are safe to follow as links. Currently unused (`
Note that `$sce.RESOURCE_URL` makes a stronger statement about the URL than `$sce.URL` does (it's not just the URL that matters, but also what is at the end of it), and therefore contexts requiring values trusted for `$sce.RESOURCE_URL` can be used anywhere that values trusted for `$sce.URL` are required. | - * | `$sce.JS` | For JavaScript that is safe to execute in your application's context. Currently, no bindings require this context. Feel free to use it in your own directives. | - * - * - * Be aware that `a[href]` and `img[src]` automatically sanitize their URLs and do not pass them - * through {@link ng.$sce#getTrusted $sce.getTrusted}. There's no CSS-, URL-, or JS-context bindings - * in AngularJS currently, so their corresponding `$sce.trustAs` functions aren't useful yet. This - * might evolve. - * - * ## Format of items in {@link ng.$sceDelegateProvider#resourceUrlWhitelist resourceUrlWhitelist}/{@link ng.$sceDelegateProvider#resourceUrlBlacklist Blacklist}
- * - * Each element in these arrays must be one of the following: - * - * - **'self'** - * - The special **string**, `'self'`, can be used to match against all URLs of the **same - * domain** as the application document using the **same protocol**. - * - **String** (except the special value `'self'`) - * - The string is matched against the full *normalized / absolute URL* of the resource - * being tested (substring matches are not good enough.) - * - There are exactly **two wildcard sequences** - `*` and `**`. All other characters - * match themselves. - * - `*`: matches zero or more occurrences of any character other than one of the following 6 - * characters: '`:`', '`/`', '`.`', '`?`', '`&`' and '`;`'. It's a useful wildcard for use - * in a whitelist. - * - `**`: matches zero or more occurrences of *any* character. As such, it's not - * appropriate for use in a scheme, domain, etc. as it would match too much. (e.g. - * http://**.example.com/ would match http://evil.com/?ignore=.example.com/ and that might - * not have been the intention.) Its usage at the very end of the path is ok. (e.g. - * http://foo.example.com/templates/**). - * - **RegExp** (*see caveat below*) - * - *Caveat*: While regular expressions are powerful and offer great flexibility, their syntax - * (and all the inevitable escaping) makes them *harder to maintain*. It's easy to - * accidentally introduce a bug when one updates a complex expression (imho, all regexes should - * have good test coverage). For instance, the use of `.` in the regex is correct only in a - * small number of cases. A `.` character in the regex used when matching the scheme or a - * subdomain could be matched against a `:` or literal `.` that was likely not intended. It - * is highly recommended to use the string patterns and only fall back to regular expressions - * as a last resort. - * - The regular expression must be an instance of RegExp (i.e. not a string.) It is - * matched against the **entire** *normalized / absolute URL* of the resource being tested - * (even when the RegExp did not have the `^` and `$` codes.) In addition, any flags - * present on the RegExp (such as multiline, global, ignoreCase) are ignored. - * - If you are generating your JavaScript from some other templating engine (not - * recommended, e.g. in issue [#4006](https://github.com/angular/angular.js/issues/4006)), - * remember to escape your regular expression (and be aware that you might need more than - * one level of escaping depending on your templating engine and the way you interpolated - * the value.) Do make use of your platform's escaping mechanism as it might be good - * enough before coding your own. E.g. Ruby has - * [Regexp.escape(str)](http://www.ruby-doc.org/core-2.0.0/Regexp.html#method-c-escape) - * and Python has [re.escape](http://docs.python.org/library/re.html#re.escape). - * Javascript lacks a similar built in function for escaping. Take a look at Google - * Closure library's [goog.string.regExpEscape(s)]( - * http://docs.closure-library.googlecode.com/git/closure_goog_string_string.js.source.html#line962). - * - * Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} for an example. - * - * ## Show me an example using SCE. - * - * - * - *
- *

- * User comments
- * By default, HTML that isn't explicitly trusted (e.g. Alice's comment) is sanitized when - * $sanitize is available. If $sanitize isn't available, this results in an error instead of an - * exploit. - *
- *
- * {{userComment.name}}: - * - *
- *
- *
- *
- *
- * - * - * angular.module('mySceApp', ['ngSanitize']) - * .controller('AppController', ['$http', '$templateCache', '$sce', - * function AppController($http, $templateCache, $sce) { - * var self = this; - * $http.get('test_data.json', {cache: $templateCache}).then(function(response) { - * self.userComments = response.data; - * }); - * self.explicitlyTrustedHtml = $sce.trustAsHtml( - * 'Hover over this text.'); - * }]); - * - * - * - * [ - * { "name": "Alice", - * "htmlComment": - * "Is anyone reading this?" - * }, - * { "name": "Bob", - * "htmlComment": "Yes! Am I the only other one?" - * } - * ] - * - * - * - * describe('SCE doc demo', function() { - * it('should sanitize untrusted values', function() { - * expect(element.all(by.css('.htmlComment')).first().getAttribute('innerHTML')) - * .toBe('Is anyone reading this?'); - * }); - * - * it('should NOT sanitize explicitly trusted values', function() { - * expect(element(by.id('explicitlyTrustedHtml')).getAttribute('innerHTML')).toBe( - * 'Hover over this text.'); - * }); - * }); - * - *
- * - * - * - * ## Can I disable SCE completely? - * - * Yes, you can. However, this is strongly discouraged. SCE gives you a lot of security benefits - * for little coding overhead. It will be much harder to take an SCE disabled application and - * either secure it on your own or enable SCE at a later stage. It might make sense to disable SCE - * for cases where you have a lot of existing code that was written before SCE was introduced and - * you're migrating them a module at a time. Also do note that this is an app-wide setting, so if - * you are writing a library, you will cause security bugs applications using it. - * - * That said, here's how you can completely disable SCE: - * - * ``` - * angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) { - * // Completely disable SCE. For demonstration purposes only! - * // Do not use in new projects or libraries. - * $sceProvider.enabled(false); - * }); - * ``` - * - */ +// Regex code was initially obtained from SO prior to modification: https://stackoverflow.com/questions/3143070/javascript-regex-iso-datetime#answer-3143231 +var ISO_DATE_REGEXP = /^\d{4,}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+(?:[+-][0-2]\d:[0-5]\d|Z)$/; +// See valid URLs in RFC3987 (http://tools.ietf.org/html/rfc3987) +// Note: We are being more lenient, because browsers are too. +// 1. Scheme +// 2. Slashes +// 3. Username +// 4. Password +// 5. Hostname +// 6. Port +// 7. Path +// 8. Query +// 9. Fragment +// 1111111111111111 222 333333 44444 55555555555555555555555 666 77777777 8888888 999 +var URL_REGEXP = /^[a-z][a-z\d.+-]*:\/*(?:[^:@]+(?::[^@]+)?@)?(?:[^\s:/?#]+|\[[a-f\d:]+])(?::\d+)?(?:\/[^?#]*)?(?:\?[^#]*)?(?:#.*)?$/i; +// eslint-disable-next-line max-len +var EMAIL_REGEXP = /^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/; +var NUMBER_REGEXP = /^\s*(-|\+)?(\d+|(\d*(\.\d*)))([eE][+-]?\d+)?\s*$/; +var DATE_REGEXP = /^(\d{4,})-(\d{2})-(\d{2})$/; +var DATETIMELOCAL_REGEXP = /^(\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/; +var WEEK_REGEXP = /^(\d{4,})-W(\d\d)$/; +var MONTH_REGEXP = /^(\d{4,})-(\d\d)$/; +var TIME_REGEXP = /^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/; -function $SceProvider() { - var enabled = true; +var PARTIAL_VALIDATION_EVENTS = 'keydown wheel mousedown'; +var PARTIAL_VALIDATION_TYPES = createMap(); +forEach('date,datetime-local,month,time,week'.split(','), function(type) { + PARTIAL_VALIDATION_TYPES[type] = true; +}); + +var inputType = { /** - * @ngdoc method - * @name $sceProvider#enabled - * @kind function - * - * @param {boolean=} value If provided, then enables/disables SCE application-wide. - * @return {boolean} True if SCE is enabled, false otherwise. + * @ngdoc input + * @name input[text] * * @description - * Enables/disables SCE and returns the current value. - */ - this.enabled = function(value) { - if (arguments.length) { - enabled = !!value; - } - return enabled; - }; - - - /* Design notes on the default implementation for SCE. - * - * The API contract for the SCE delegate - * ------------------------------------- - * The SCE delegate object must provide the following 3 methods: - * - * - trustAs(contextEnum, value) - * This method is used to tell the SCE service that the provided value is OK to use in the - * contexts specified by contextEnum. It must return an object that will be accepted by - * getTrusted() for a compatible contextEnum and return this value. - * - * - valueOf(value) - * For values that were not produced by trustAs(), return them as is. For values that were - * produced by trustAs(), return the corresponding input value to trustAs. Basically, if - * trustAs is wrapping the given values into some type, this operation unwraps it when given - * such a value. - * - * - getTrusted(contextEnum, value) - * This function should return the a value that is safe to use in the context specified by - * contextEnum or throw and exception otherwise. - * - * NOTE: This contract deliberately does NOT state that values returned by trustAs() must be - * opaque or wrapped in some holder object. That happens to be an implementation detail. For - * instance, an implementation could maintain a registry of all trusted objects by context. In - * such a case, trustAs() would return the same object that was passed in. getTrusted() would - * return the same object passed in if it was found in the registry under a compatible context or - * throw an exception otherwise. An implementation might only wrap values some of the time based - * on some criteria. getTrusted() might return a value and not throw an exception for special - * constants or objects even if not wrapped. All such implementations fulfill this contract. - * - * - * A note on the inheritance model for SCE contexts - * ------------------------------------------------ - * I've used inheritance and made RESOURCE_URL wrapped types a subtype of URL wrapped types. This - * is purely an implementation details. + * Standard HTML text input with angular data binding, inherited by most of the `input` elements. * - * The contract is simply this: * - * getTrusted($sce.RESOURCE_URL, value) succeeding implies that getTrusted($sce.URL, value) - * will also succeed. + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} required Adds `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. Setting the attribute to a negative or non-numeric value, allows view values of + * any length. + * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string + * that contains the regular expression body that will be converted to a regular expression + * as in the ngPattern directive. + * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue} + * does not match a RegExp found by evaluating the Angular expression given in the attribute value. + * If the expression evaluates to a RegExp object, then this is used directly. + * If the expression evaluates to a string, then it will be converted to a RegExp + * after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to + * `new RegExp('^abc$')`.
+ * **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to + * start at the index of the last search's match, thus not taking the whole input value into + * account. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input. + * This parameter is ignored for input[type=password] controls, which will never trim the + * input. * - * Inheritance happens to capture this in a natural way. In some future, we may not use - * inheritance anymore. That is OK because no code outside of sce.js and sceSpecs.js would need to - * be aware of this detail. - */ - - this.$get = ['$parse', '$sceDelegate', function( - $parse, $sceDelegate) { - // Support: IE 9-11 only - // Prereq: Ensure that we're not running in IE<11 quirks mode. In that mode, IE < 11 allow - // the "expression(javascript expression)" syntax which is insecure. - if (enabled && msie < 8) { - throw $sceMinErr('iequirks', - 'Strict Contextual Escaping does not support Internet Explorer version < 11 in quirks ' + - 'mode. You can fix this by adding the text to the top of your HTML ' + - 'document. See http://docs.angularjs.org/api/ng.$sce for more information.'); - } - - var sce = shallowCopy(SCE_CONTEXTS); - - /** - * @ngdoc method - * @name $sce#isEnabled - * @kind function - * - * @return {Boolean} True if SCE is enabled, false otherwise. If you want to set the value, you - * have to do it at module config time on {@link ng.$sceProvider $sceProvider}. - * - * @description - * Returns a boolean indicating if SCE is enabled. - */ - sce.isEnabled = function() { - return enabled; - }; - sce.trustAs = $sceDelegate.trustAs; - sce.getTrusted = $sceDelegate.getTrusted; - sce.valueOf = $sceDelegate.valueOf; - - if (!enabled) { - sce.trustAs = sce.getTrusted = function(type, value) { return value; }; - sce.valueOf = identity; - } - - /** - * @ngdoc method - * @name $sce#parseAs - * - * @description - * Converts Angular {@link guide/expression expression} into a function. This is like {@link - * ng.$parse $parse} and is identical when the expression is a literal constant. Otherwise, it - * wraps the expression in a call to {@link ng.$sce#getTrusted $sce.getTrusted(*type*, - * *result*)} - * - * @param {string} type The SCE context in which this result will be used. - * @param {string} expression String expression to compile. - * @return {function(context, locals)} A function which represents the compiled expression: - * - * * `context` – `{object}` – an object against which any expressions embedded in the - * strings are evaluated against (typically a scope object). - * * `locals` – `{object=}` – local variables context object, useful for overriding values - * in `context`. - */ - sce.parseAs = function sceParseAs(type, expr) { - var parsed = $parse(expr); - if (parsed.literal && parsed.constant) { - return parsed; - } else { - return $parse(expr, function(value) { - return sce.getTrusted(type, value); - }); - } - }; + * @example + + + +
+ +
+ + Required! + + Single word only! +
+ text = {{example.text}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+
+
+ + var text = element(by.binding('example.text')); + var valid = element(by.binding('myForm.input.$valid')); + var input = element(by.model('example.text')); - /** - * @ngdoc method - * @name $sce#trustAs - * - * @description - * Delegates to {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}. As such, returns a - * wrapped object that represents your value, and the trust you have in its safety for the given - * context. AngularJS can then use that value as-is in bindings of the specified secure context. - * This is used in bindings for `ng-bind-html`, `ng-include`, and most `src` attribute - * interpolations. See {@link ng.$sce $sce} for strict contextual escaping. - * - * @param {string} type The context in which this value is safe for use, e.g. `$sce.URL`, - * `$sce.RESOURCE_URL`, `$sce.HTML`, `$sce.JS` or `$sce.CSS`. - * - * @param {*} value The value that that should be considered trusted. - * @return {*} A wrapped version of value that can be used as a trusted variant of your `value` - * in the context you specified. - */ + it('should initialize to model', function() { + expect(text.getText()).toContain('guest'); + expect(valid.getText()).toContain('true'); + }); - /** - * @ngdoc method - * @name $sce#trustAsHtml - * - * @description - * Shorthand method. `$sce.trustAsHtml(value)` → - * {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.HTML, value)`} - * - * @param {*} value The value to mark as trusted for `$sce.HTML` context. - * @return {*} A wrapped version of value that can be used as a trusted variant of your `value` - * in `$sce.HTML` context (like `ng-bind-html`). - */ + it('should be invalid if empty', function() { + input.clear(); + input.sendKeys(''); - /** - * @ngdoc method - * @name $sce#trustAsCss - * - * @description - * Shorthand method. `$sce.trustAsCss(value)` → - * {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.CSS, value)`} - * - * @param {*} value The value to mark as trusted for `$sce.CSS` context. - * @return {*} A wrapped version of value that can be used as a trusted variant - * of your `value` in `$sce.CSS` context. This context is currently unused, so there are - * almost no reasons to use this function so far. - */ + expect(text.getText()).toEqual('text ='); + expect(valid.getText()).toContain('false'); + }); - /** - * @ngdoc method - * @name $sce#trustAsUrl - * - * @description - * Shorthand method. `$sce.trustAsUrl(value)` → - * {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.URL, value)`} - * - * @param {*} value The value to mark as trusted for `$sce.URL` context. - * @return {*} A wrapped version of value that can be used as a trusted variant of your `value` - * in `$sce.URL` context. That context is currently unused, so there are almost no reasons - * to use this function so far. - */ + it('should be invalid if multi word', function() { + input.clear(); + input.sendKeys('hello world'); - /** - * @ngdoc method - * @name $sce#trustAsResourceUrl - * - * @description - * Shorthand method. `$sce.trustAsResourceUrl(value)` → - * {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.RESOURCE_URL, value)`} - * - * @param {*} value The value to mark as trusted for `$sce.RESOURCE_URL` context. - * @return {*} A wrapped version of value that can be used as a trusted variant of your `value` - * in `$sce.RESOURCE_URL` context (template URLs in `ng-include`, most `src` attribute - * bindings, ...) - */ + expect(valid.getText()).toContain('false'); + }); + +
+ */ + 'text': textInputType, /** - * @ngdoc method - * @name $sce#trustAsJs + * @ngdoc input + * @name input[date] * * @description - * Shorthand method. `$sce.trustAsJs(value)` → - * {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.JS, value)`} - * - * @param {*} value The value to mark as trusted for `$sce.JS` context. - * @return {*} A wrapped version of value that can be used as a trusted variant of your `value` - * in `$sce.JS` context. That context is currently unused, so there are almost no reasons to - * use this function so far. - */ - - /** - * @ngdoc method - * @name $sce#getTrusted + * Input with date validation and transformation. In browsers that do not yet support + * the HTML5 date input, a text element will be used. In that case, text must be entered in a valid ISO-8601 + * date format (yyyy-MM-dd), for example: `2009-01-06`. Since many + * modern browsers do not yet support this input type, it is important to provide cues to users on the + * expected input format via a placeholder or label. * - * @description - * Delegates to {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted`}. As such, - * takes any input, and either returns a value that's safe to use in the specified context, - * or throws an exception. This function is aware of trusted values created by the `trustAs` - * function and its shorthands, and when contexts are appropriate, returns the unwrapped value - * as-is. Finally, this function can also throw when there is no way to turn `maybeTrusted` in a - * safe value (e.g., no sanitization is available or possible.) + * The model must always be a Date object, otherwise Angular will throw an error. + * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string. * - * @param {string} type The context in which this value is to be used. - * @param {*} maybeTrusted The result of a prior {@link ng.$sce#trustAs - * `$sce.trustAs`} call, or anything else (which will not be considered trusted.) - * @return {*} A version of the value that's safe to use in the given context, or throws an - * exception if this is impossible. - */ - - /** - * @ngdoc method - * @name $sce#getTrustedHtml + * The timezone to be used to read/write the `Date` instance in the model can be defined using + * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser. * - * @description - * Shorthand method. `$sce.getTrustedHtml(value)` → - * {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.HTML, value)`} + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. This must be a + * valid ISO date string (yyyy-MM-dd). You can also use interpolation inside this attribute + * (e.g. `min="{{minDate | date:'yyyy-MM-dd'}}"`). Note that `min` will also add native HTML5 + * constraint validation. + * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. This must be + * a valid ISO date string (yyyy-MM-dd). You can also use interpolation inside this attribute + * (e.g. `max="{{maxDate | date:'yyyy-MM-dd'}}"`). Note that `max` will also add native HTML5 + * constraint validation. + * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO date string + * the `ngMin` expression evaluates to. Note that it does not set the `min` attribute. + * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO date string + * the `ngMax` expression evaluates to. Note that it does not set the `max` attribute. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. * - * @param {*} value The value to pass to `$sce.getTrusted`. - * @return {*} The return value of `$sce.getTrusted($sce.HTML, value)` - */ + * @example + + + +
+ + +
+ + Required! + + Not a valid date! +
+ value = {{example.value | date: "yyyy-MM-dd"}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+
+
+ + var value = element(by.binding('example.value | date: "yyyy-MM-dd"')); + var valid = element(by.binding('myForm.input.$valid')); - /** - * @ngdoc method - * @name $sce#getTrustedCss - * - * @description - * Shorthand method. `$sce.getTrustedCss(value)` → - * {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.CSS, value)`} - * - * @param {*} value The value to pass to `$sce.getTrusted`. - * @return {*} The return value of `$sce.getTrusted($sce.CSS, value)` - */ + // currently protractor/webdriver does not support + // sending keys to all known HTML5 input controls + // for various browsers (see https://github.com/angular/protractor/issues/562). + function setInput(val) { + // set the value of the element and force validation. + var scr = "var ipt = document.getElementById('exampleInput'); " + + "ipt.value = '" + val + "';" + + "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });"; + browser.executeScript(scr); + } - /** - * @ngdoc method - * @name $sce#getTrustedUrl - * - * @description - * Shorthand method. `$sce.getTrustedUrl(value)` → - * {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.URL, value)`} - * - * @param {*} value The value to pass to `$sce.getTrusted`. - * @return {*} The return value of `$sce.getTrusted($sce.URL, value)` - */ + it('should initialize to model', function() { + expect(value.getText()).toContain('2013-10-22'); + expect(valid.getText()).toContain('myForm.input.$valid = true'); + }); - /** - * @ngdoc method - * @name $sce#getTrustedResourceUrl - * - * @description - * Shorthand method. `$sce.getTrustedResourceUrl(value)` → - * {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.RESOURCE_URL, value)`} - * - * @param {*} value The value to pass to `$sceDelegate.getTrusted`. - * @return {*} The return value of `$sce.getTrusted($sce.RESOURCE_URL, value)` - */ + it('should be invalid if empty', function() { + setInput(''); + expect(value.getText()).toEqual('value ='); + expect(valid.getText()).toContain('myForm.input.$valid = false'); + }); - /** - * @ngdoc method - * @name $sce#getTrustedJs - * - * @description - * Shorthand method. `$sce.getTrustedJs(value)` → - * {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.JS, value)`} - * - * @param {*} value The value to pass to `$sce.getTrusted`. - * @return {*} The return value of `$sce.getTrusted($sce.JS, value)` + it('should be invalid if over max', function() { + setInput('2015-01-01'); + expect(value.getText()).toContain(''); + expect(valid.getText()).toContain('myForm.input.$valid = false'); + }); + +
*/ + 'date': createDateInputType('date', DATE_REGEXP, + createDateParser(DATE_REGEXP, ['yyyy', 'MM', 'dd']), + 'yyyy-MM-dd'), - /** - * @ngdoc method - * @name $sce#parseAsHtml - * - * @description - * Shorthand method. `$sce.parseAsHtml(expression string)` → - * {@link ng.$sce#parseAs `$sce.parseAs($sce.HTML, value)`} - * - * @param {string} expression String expression to compile. - * @return {function(context, locals)} A function which represents the compiled expression: - * - * * `context` – `{object}` – an object against which any expressions embedded in the - * strings are evaluated against (typically a scope object). - * * `locals` – `{object=}` – local variables context object, useful for overriding values - * in `context`. - */ + /** + * @ngdoc input + * @name input[datetime-local] + * + * @description + * Input with datetime validation and transformation. In browsers that do not yet support + * the HTML5 date input, a text element will be used. In that case, the text must be entered in a valid ISO-8601 + * local datetime format (yyyy-MM-ddTHH:mm:ss), for example: `2010-12-28T14:57:00`. + * + * The model must always be a Date object, otherwise Angular will throw an error. + * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string. + * + * The timezone to be used to read/write the `Date` instance in the model can be defined using + * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. + * This must be a valid ISO datetime format (yyyy-MM-ddTHH:mm:ss). You can also use interpolation + * inside this attribute (e.g. `min="{{minDatetimeLocal | date:'yyyy-MM-ddTHH:mm:ss'}}"`). + * Note that `min` will also add native HTML5 constraint validation. + * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. + * This must be a valid ISO datetime format (yyyy-MM-ddTHH:mm:ss). You can also use interpolation + * inside this attribute (e.g. `max="{{maxDatetimeLocal | date:'yyyy-MM-ddTHH:mm:ss'}}"`). + * Note that `max` will also add native HTML5 constraint validation. + * @param {(date|string)=} ngMin Sets the `min` validation error key to the Date / ISO datetime string + * the `ngMin` expression evaluates to. Note that it does not set the `min` attribute. + * @param {(date|string)=} ngMax Sets the `max` validation error key to the Date / ISO datetime string + * the `ngMax` expression evaluates to. Note that it does not set the `max` attribute. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+ + +
+ + Required! + + Not a valid date! +
+ value = {{example.value | date: "yyyy-MM-ddTHH:mm:ss"}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+
+
+ + var value = element(by.binding('example.value | date: "yyyy-MM-ddTHH:mm:ss"')); + var valid = element(by.binding('myForm.input.$valid')); - /** - * @ngdoc method - * @name $sce#parseAsCss - * - * @description - * Shorthand method. `$sce.parseAsCss(value)` → - * {@link ng.$sce#parseAs `$sce.parseAs($sce.CSS, value)`} - * - * @param {string} expression String expression to compile. - * @return {function(context, locals)} A function which represents the compiled expression: - * - * * `context` – `{object}` – an object against which any expressions embedded in the - * strings are evaluated against (typically a scope object). - * * `locals` – `{object=}` – local variables context object, useful for overriding values - * in `context`. - */ + // currently protractor/webdriver does not support + // sending keys to all known HTML5 input controls + // for various browsers (https://github.com/angular/protractor/issues/562). + function setInput(val) { + // set the value of the element and force validation. + var scr = "var ipt = document.getElementById('exampleInput'); " + + "ipt.value = '" + val + "';" + + "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });"; + browser.executeScript(scr); + } - /** - * @ngdoc method - * @name $sce#parseAsUrl - * - * @description - * Shorthand method. `$sce.parseAsUrl(value)` → - * {@link ng.$sce#parseAs `$sce.parseAs($sce.URL, value)`} - * - * @param {string} expression String expression to compile. - * @return {function(context, locals)} A function which represents the compiled expression: - * - * * `context` – `{object}` – an object against which any expressions embedded in the - * strings are evaluated against (typically a scope object). - * * `locals` – `{object=}` – local variables context object, useful for overriding values - * in `context`. - */ + it('should initialize to model', function() { + expect(value.getText()).toContain('2010-12-28T14:57:00'); + expect(valid.getText()).toContain('myForm.input.$valid = true'); + }); - /** - * @ngdoc method - * @name $sce#parseAsResourceUrl - * - * @description - * Shorthand method. `$sce.parseAsResourceUrl(value)` → - * {@link ng.$sce#parseAs `$sce.parseAs($sce.RESOURCE_URL, value)`} - * - * @param {string} expression String expression to compile. - * @return {function(context, locals)} A function which represents the compiled expression: - * - * * `context` – `{object}` – an object against which any expressions embedded in the - * strings are evaluated against (typically a scope object). - * * `locals` – `{object=}` – local variables context object, useful for overriding values - * in `context`. - */ + it('should be invalid if empty', function() { + setInput(''); + expect(value.getText()).toEqual('value ='); + expect(valid.getText()).toContain('myForm.input.$valid = false'); + }); - /** - * @ngdoc method - * @name $sce#parseAsJs - * - * @description - * Shorthand method. `$sce.parseAsJs(value)` → - * {@link ng.$sce#parseAs `$sce.parseAs($sce.JS, value)`} - * - * @param {string} expression String expression to compile. - * @return {function(context, locals)} A function which represents the compiled expression: - * - * * `context` – `{object}` – an object against which any expressions embedded in the - * strings are evaluated against (typically a scope object). - * * `locals` – `{object=}` – local variables context object, useful for overriding values - * in `context`. - */ + it('should be invalid if over max', function() { + setInput('2015-01-01T23:59:00'); + expect(value.getText()).toContain(''); + expect(valid.getText()).toContain('myForm.input.$valid = false'); + }); + +
+ */ + 'datetime-local': createDateInputType('datetimelocal', DATETIMELOCAL_REGEXP, + createDateParser(DATETIMELOCAL_REGEXP, ['yyyy', 'MM', 'dd', 'HH', 'mm', 'ss', 'sss']), + 'yyyy-MM-ddTHH:mm:ss.sss'), - // Shorthand delegations. - var parse = sce.parseAs, - getTrusted = sce.getTrusted, - trustAs = sce.trustAs; + /** + * @ngdoc input + * @name input[time] + * + * @description + * Input with time validation and transformation. In browsers that do not yet support + * the HTML5 time input, a text element will be used. In that case, the text must be entered in a valid ISO-8601 + * local time format (HH:mm:ss), for example: `14:57:00`. Model must be a Date object. This binding will always output a + * Date object to the model of January 1, 1970, or local date `new Date(1970, 0, 1, HH, mm, ss)`. + * + * The model must always be a Date object, otherwise Angular will throw an error. + * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string. + * + * The timezone to be used to read/write the `Date` instance in the model can be defined using + * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. + * This must be a valid ISO time format (HH:mm:ss). You can also use interpolation inside this + * attribute (e.g. `min="{{minTime | date:'HH:mm:ss'}}"`). Note that `min` will also add + * native HTML5 constraint validation. + * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. + * This must be a valid ISO time format (HH:mm:ss). You can also use interpolation inside this + * attribute (e.g. `max="{{maxTime | date:'HH:mm:ss'}}"`). Note that `max` will also add + * native HTML5 constraint validation. + * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO time string the + * `ngMin` expression evaluates to. Note that it does not set the `min` attribute. + * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO time string the + * `ngMax` expression evaluates to. Note that it does not set the `max` attribute. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+ + +
+ + Required! + + Not a valid date! +
+ value = {{example.value | date: "HH:mm:ss"}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+
+
+ + var value = element(by.binding('example.value | date: "HH:mm:ss"')); + var valid = element(by.binding('myForm.input.$valid')); - forEach(SCE_CONTEXTS, function(enumValue, name) { - var lName = lowercase(name); - sce[snakeToCamel('parse_as_' + lName)] = function(expr) { - return parse(enumValue, expr); - }; - sce[snakeToCamel('get_trusted_' + lName)] = function(value) { - return getTrusted(enumValue, value); - }; - sce[snakeToCamel('trust_as_' + lName)] = function(value) { - return trustAs(enumValue, value); - }; - }); + // currently protractor/webdriver does not support + // sending keys to all known HTML5 input controls + // for various browsers (https://github.com/angular/protractor/issues/562). + function setInput(val) { + // set the value of the element and force validation. + var scr = "var ipt = document.getElementById('exampleInput'); " + + "ipt.value = '" + val + "';" + + "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });"; + browser.executeScript(scr); + } - return sce; - }]; -} + it('should initialize to model', function() { + expect(value.getText()).toContain('14:57:00'); + expect(valid.getText()).toContain('myForm.input.$valid = true'); + }); -/* exported $SnifferProvider */ + it('should be invalid if empty', function() { + setInput(''); + expect(value.getText()).toEqual('value ='); + expect(valid.getText()).toContain('myForm.input.$valid = false'); + }); -/** - * !!! This is an undocumented "private" service !!! - * - * @name $sniffer - * @requires $window - * @requires $document - * @this - * - * @property {boolean} history Does the browser support html5 history api ? - * @property {boolean} transitions Does the browser support CSS transition events ? - * @property {boolean} animations Does the browser support CSS animation events ? - * - * @description - * This is very simple implementation of testing browser's features. - */ -function $SnifferProvider() { - this.$get = ['$window', '$document', function($window, $document) { - var eventSupport = {}, - // Chrome Packaged Apps are not allowed to access `history.pushState`. - // If not sandboxed, they can be detected by the presence of `chrome.app.runtime` - // (see https://developer.chrome.com/apps/api_index). If sandboxed, they can be detected by - // the presence of an extension runtime ID and the absence of other Chrome runtime APIs - // (see https://developer.chrome.com/apps/manifest/sandbox). - // (NW.js apps have access to Chrome APIs, but do support `history`.) - isNw = $window.nw && $window.nw.process, - isChromePackagedApp = - !isNw && - $window.chrome && - ($window.chrome.app && $window.chrome.app.runtime || - !$window.chrome.app && $window.chrome.runtime && $window.chrome.runtime.id), - hasHistoryPushState = !isChromePackagedApp && $window.history && $window.history.pushState, - android = - toInt((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]), - boxee = /Boxee/i.test(($window.navigator || {}).userAgent), - document = $document[0] || {}, - bodyStyle = document.body && document.body.style, - transitions = false, - animations = false; + it('should be invalid if over max', function() { + setInput('23:59:00'); + expect(value.getText()).toContain(''); + expect(valid.getText()).toContain('myForm.input.$valid = false'); + }); + +
+ */ + 'time': createDateInputType('time', TIME_REGEXP, + createDateParser(TIME_REGEXP, ['HH', 'mm', 'ss', 'sss']), + 'HH:mm:ss.sss'), - if (bodyStyle) { - // Support: Android <5, Blackberry Browser 10, default Chrome in Android 4.4.x - // Mentioned browsers need a -webkit- prefix for transitions & animations. - transitions = !!('transition' in bodyStyle || 'webkitTransition' in bodyStyle); - animations = !!('animation' in bodyStyle || 'webkitAnimation' in bodyStyle); - } + /** + * @ngdoc input + * @name input[week] + * + * @description + * Input with week-of-the-year validation and transformation to Date. In browsers that do not yet support + * the HTML5 week input, a text element will be used. In that case, the text must be entered in a valid ISO-8601 + * week format (yyyy-W##), for example: `2013-W02`. + * + * The model must always be a Date object, otherwise Angular will throw an error. + * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string. + * + * The timezone to be used to read/write the `Date` instance in the model can be defined using + * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. + * This must be a valid ISO week format (yyyy-W##). You can also use interpolation inside this + * attribute (e.g. `min="{{minWeek | date:'yyyy-Www'}}"`). Note that `min` will also add + * native HTML5 constraint validation. + * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. + * This must be a valid ISO week format (yyyy-W##). You can also use interpolation inside this + * attribute (e.g. `max="{{maxWeek | date:'yyyy-Www'}}"`). Note that `max` will also add + * native HTML5 constraint validation. + * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO week string + * the `ngMin` expression evaluates to. Note that it does not set the `min` attribute. + * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO week string + * the `ngMax` expression evaluates to. Note that it does not set the `max` attribute. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+ +
+ + Required! + + Not a valid date! +
+ value = {{example.value | date: "yyyy-Www"}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+
+
+ + var value = element(by.binding('example.value | date: "yyyy-Www"')); + var valid = element(by.binding('myForm.input.$valid')); + // currently protractor/webdriver does not support + // sending keys to all known HTML5 input controls + // for various browsers (https://github.com/angular/protractor/issues/562). + function setInput(val) { + // set the value of the element and force validation. + var scr = "var ipt = document.getElementById('exampleInput'); " + + "ipt.value = '" + val + "';" + + "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });"; + browser.executeScript(scr); + } - return { - // Android has history.pushState, but it does not update location correctly - // so let's not use the history API at all. - // http://code.google.com/p/android/issues/detail?id=17471 - // https://github.com/angular/angular.js/issues/904 + it('should initialize to model', function() { + expect(value.getText()).toContain('2013-W01'); + expect(valid.getText()).toContain('myForm.input.$valid = true'); + }); - // older webkit browser (533.9) on Boxee box has exactly the same problem as Android has - // so let's not use the history API also - // We are purposefully using `!(android < 4)` to cover the case when `android` is undefined - history: !!(hasHistoryPushState && !(android < 4) && !boxee), - hasEvent: function(event) { - // Support: IE 9-11 only - // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have - // it. In particular the event is not fired when backspace or delete key are pressed or - // when cut operation is performed. - // IE10+ implements 'input' event but it erroneously fires under various situations, - // e.g. when placeholder changes, or a form is focused. - if (event === 'input' && msie) return false; + it('should be invalid if empty', function() { + setInput(''); + expect(value.getText()).toEqual('value ='); + expect(valid.getText()).toContain('myForm.input.$valid = false'); + }); - if (isUndefined(eventSupport[event])) { - var divElm = document.createElement('div'); - eventSupport[event] = 'on' + event in divElm; - } + it('should be invalid if over max', function() { + setInput('2015-W01'); + expect(value.getText()).toContain(''); + expect(valid.getText()).toContain('myForm.input.$valid = false'); + }); + +
+ */ + 'week': createDateInputType('week', WEEK_REGEXP, weekParser, 'yyyy-Www'), - return eventSupport[event]; - }, - csp: csp(), - transitions: transitions, - animations: animations, - android: android - }; - }]; -} + /** + * @ngdoc input + * @name input[month] + * + * @description + * Input with month validation and transformation. In browsers that do not yet support + * the HTML5 month input, a text element will be used. In that case, the text must be entered in a valid ISO-8601 + * month format (yyyy-MM), for example: `2009-01`. + * + * The model must always be a Date object, otherwise Angular will throw an error. + * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string. + * If the model is not set to the first of the month, the next view to model update will set it + * to the first of the month. + * + * The timezone to be used to read/write the `Date` instance in the model can be defined using + * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. + * This must be a valid ISO month format (yyyy-MM). You can also use interpolation inside this + * attribute (e.g. `min="{{minMonth | date:'yyyy-MM'}}"`). Note that `min` will also add + * native HTML5 constraint validation. + * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. + * This must be a valid ISO month format (yyyy-MM). You can also use interpolation inside this + * attribute (e.g. `max="{{maxMonth | date:'yyyy-MM'}}"`). Note that `max` will also add + * native HTML5 constraint validation. + * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO week string + * the `ngMin` expression evaluates to. Note that it does not set the `min` attribute. + * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO week string + * the `ngMax` expression evaluates to. Note that it does not set the `max` attribute. -var $templateRequestMinErr = minErr('$compile'); + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+ + +
+ + Required! + + Not a valid month! +
+ value = {{example.value | date: "yyyy-MM"}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+
+
+ + var value = element(by.binding('example.value | date: "yyyy-MM"')); + var valid = element(by.binding('myForm.input.$valid')); -/** - * @ngdoc provider - * @name $templateRequestProvider - * @this - * - * @description - * Used to configure the options passed to the {@link $http} service when making a template request. - * - * For example, it can be used for specifying the "Accept" header that is sent to the server, when - * requesting a template. - */ -function $TemplateRequestProvider() { + // currently protractor/webdriver does not support + // sending keys to all known HTML5 input controls + // for various browsers (https://github.com/angular/protractor/issues/562). + function setInput(val) { + // set the value of the element and force validation. + var scr = "var ipt = document.getElementById('exampleInput'); " + + "ipt.value = '" + val + "';" + + "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });"; + browser.executeScript(scr); + } - var httpOptions; + it('should initialize to model', function() { + expect(value.getText()).toContain('2013-10'); + expect(valid.getText()).toContain('myForm.input.$valid = true'); + }); + + it('should be invalid if empty', function() { + setInput(''); + expect(value.getText()).toEqual('value ='); + expect(valid.getText()).toContain('myForm.input.$valid = false'); + }); + + it('should be invalid if over max', function() { + setInput('2015-01'); + expect(value.getText()).toContain(''); + expect(valid.getText()).toContain('myForm.input.$valid = false'); + }); + +
+ */ + 'month': createDateInputType('month', MONTH_REGEXP, + createDateParser(MONTH_REGEXP, ['yyyy', 'MM']), + 'yyyy-MM'), /** - * @ngdoc method - * @name $templateRequestProvider#httpOptions + * @ngdoc input + * @name input[number] + * * @description - * The options to be passed to the {@link $http} service when making the request. - * You can use this to override options such as the "Accept" header for template requests. + * Text input with number validation and transformation. Sets the `number` validation + * error if not a valid number. * - * The {@link $templateRequest} will set the `cache` and the `transformResponse` properties of the - * options if not overridden here. + *
+ * The model must always be of type `number` otherwise Angular will throw an error. + * Be aware that a string containing a number is not enough. See the {@link ngModel:numfmt} + * error docs for more information and an example of how to convert your model if necessary. + *
* - * @param {string=} value new value for the {@link $http} options. - * @returns {string|self} Returns the {@link $http} options when used as getter and self if used as setter. + * ## Issues with HTML5 constraint validation + * + * In browsers that follow the + * [HTML5 specification](https://html.spec.whatwg.org/multipage/forms.html#number-state-%28type=number%29), + * `input[number]` does not work as expected with {@link ngModelOptions `ngModelOptions.allowInvalid`}. + * If a non-number is entered in the input, the browser will report the value as an empty string, + * which means the view / model values in `ngModel` and subsequently the scope value + * will also be an empty string. + * + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. + * Can be interpolated. + * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. + * Can be interpolated. + * @param {string=} ngMin Like `min`, sets the `min` validation error key if the value entered is less than `ngMin`, + * but does not trigger HTML5 native validation. Takes an expression. + * @param {string=} ngMax Like `max`, sets the `max` validation error key if the value entered is greater than `ngMax`, + * but does not trigger HTML5 native validation. Takes an expression. + * @param {string=} step Sets the `step` validation error key if the value entered does not fit the `step` constraint. + * Can be interpolated. + * @param {string=} ngStep Like `step`, sets the `step` validation error key if the value entered does not fit the `ngStep` constraint, + * but does not trigger HTML5 native validation. Takes an expression. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. Setting the attribute to a negative or non-numeric value, allows view values of + * any length. + * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string + * that contains the regular expression body that will be converted to a regular expression + * as in the ngPattern directive. + * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue} + * does not match a RegExp found by evaluating the Angular expression given in the attribute value. + * If the expression evaluates to a RegExp object, then this is used directly. + * If the expression evaluates to a string, then it will be converted to a RegExp + * after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to + * `new RegExp('^abc$')`.
+ * **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to + * start at the index of the last search's match, thus not taking the whole input value into + * account. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+ +
+ + Required! + + Not valid number! +
+ value = {{example.value}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+
+
+ + var value = element(by.binding('example.value')); + var valid = element(by.binding('myForm.input.$valid')); + var input = element(by.model('example.value')); + + it('should initialize to model', function() { + expect(value.getText()).toContain('12'); + expect(valid.getText()).toContain('true'); + }); + + it('should be invalid if empty', function() { + input.clear(); + input.sendKeys(''); + expect(value.getText()).toEqual('value ='); + expect(valid.getText()).toContain('false'); + }); + + it('should be invalid if over max', function() { + input.clear(); + input.sendKeys('123'); + expect(value.getText()).toEqual('value ='); + expect(valid.getText()).toContain('false'); + }); + +
*/ - this.httpOptions = function(val) { - if (val) { - httpOptions = val; - return this; - } - return httpOptions; - }; + 'number': numberInputType, + /** - * @ngdoc service - * @name $templateRequest + * @ngdoc input + * @name input[url] * * @description - * The `$templateRequest` service runs security checks then downloads the provided template using - * `$http` and, upon success, stores the contents inside of `$templateCache`. If the HTTP request - * fails or the response data of the HTTP request is empty, a `$compile` error will be thrown (the - * exception can be thwarted by setting the 2nd parameter of the function to true). Note that the - * contents of `$templateCache` are trusted, so the call to `$sce.getTrustedUrl(tpl)` is omitted - * when `tpl` is of type string and `$templateCache` has the matching entry. - * - * If you want to pass custom options to the `$http` service, such as setting the Accept header you - * can configure this via {@link $templateRequestProvider#httpOptions}. + * Text input with URL validation. Sets the `url` validation error key if the content is not a + * valid URL. * - * @param {string|TrustedResourceUrl} tpl The HTTP request template URL - * @param {boolean=} ignoreRequestError Whether or not to ignore the exception when the request fails or the template is empty + *
+ * **Note:** `input[url]` uses a regex to validate urls that is derived from the regex + * used in Chromium. If you need stricter validation, you can use `ng-pattern` or modify + * the built-in validators (see the {@link guide/forms Forms guide}) + *
* - * @return {Promise} a promise for the HTTP response data of the given URL. + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. Setting the attribute to a negative or non-numeric value, allows view values of + * any length. + * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string + * that contains the regular expression body that will be converted to a regular expression + * as in the ngPattern directive. + * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue} + * does not match a RegExp found by evaluating the Angular expression given in the attribute value. + * If the expression evaluates to a RegExp object, then this is used directly. + * If the expression evaluates to a string, then it will be converted to a RegExp + * after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to + * `new RegExp('^abc$')`.
+ * **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to + * start at the index of the last search's match, thus not taking the whole input value into + * account. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. * - * @property {number} totalPendingRequests total amount of pending template requests being downloaded. - */ - this.$get = ['$exceptionHandler', '$templateCache', '$http', '$q', '$sce', - function($exceptionHandler, $templateCache, $http, $q, $sce) { - - function handleRequestFn(tpl, ignoreRequestError) { - handleRequestFn.totalPendingRequests++; + * @example + + + +
+
+ + var text = element(by.binding('url.text')); + var valid = element(by.binding('myForm.input.$valid')); + var input = element(by.model('url.text')); - // We consider the template cache holds only trusted templates, so - // there's no need to go through whitelisting again for keys that already - // are included in there. This also makes Angular accept any script - // directive, no matter its name. However, we still need to unwrap trusted - // types. - if (!isString(tpl) || isUndefined($templateCache.get(tpl))) { - tpl = $sce.getTrustedResourceUrl(tpl); - } + it('should initialize to model', function() { + expect(text.getText()).toContain('http://google.com'); + expect(valid.getText()).toContain('true'); + }); - var transformResponse = $http.defaults && $http.defaults.transformResponse; + it('should be invalid if empty', function() { + input.clear(); + input.sendKeys(''); - if (isArray(transformResponse)) { - transformResponse = transformResponse.filter(function(transformer) { - return transformer !== defaultHttpResponseTransform; + expect(text.getText()).toEqual('text ='); + expect(valid.getText()).toContain('false'); }); - } else if (transformResponse === defaultHttpResponseTransform) { - transformResponse = null; - } - - return $http.get(tpl, extend({ - cache: $templateCache, - transformResponse: transformResponse - }, httpOptions)) - .finally(function() { - handleRequestFn.totalPendingRequests--; - }) - .then(function(response) { - $templateCache.put(tpl, response.data); - return response.data; - }, handleError); - function handleError(resp) { - if (!ignoreRequestError) { - resp = $templateRequestMinErr('tpload', - 'Failed to load template: {0} (HTTP status: {1} {2})', - tpl, resp.status, resp.statusText); + it('should be invalid if not url', function() { + input.clear(); + input.sendKeys('box'); - $exceptionHandler(resp); - } + expect(valid.getText()).toContain('false'); + }); + +
+ */ + 'url': urlInputType, - return $q.reject(resp); - } - } - handleRequestFn.totalPendingRequests = 0; + /** + * @ngdoc input + * @name input[email] + * + * @description + * Text input with email validation. Sets the `email` validation error key if not a valid email + * address. + * + *
+ * **Note:** `input[email]` uses a regex to validate email addresses that is derived from the regex + * used in Chromium. If you need stricter validation (e.g. requiring a top-level domain), you can + * use `ng-pattern` or modify the built-in validators (see the {@link guide/forms Forms guide}) + *
+ * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. Setting the attribute to a negative or non-numeric value, allows view values of + * any length. + * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string + * that contains the regular expression body that will be converted to a regular expression + * as in the ngPattern directive. + * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue} + * does not match a RegExp found by evaluating the Angular expression given in the attribute value. + * If the expression evaluates to a RegExp object, then this is used directly. + * If the expression evaluates to a string, then it will be converted to a RegExp + * after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to + * `new RegExp('^abc$')`.
+ * **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to + * start at the index of the last search's match, thus not taking the whole input value into + * account. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+ +
+ + Required! + + Not valid email! +
+ text = {{email.text}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
+ myForm.$error.email = {{!!myForm.$error.email}}
+
+
+ + var text = element(by.binding('email.text')); + var valid = element(by.binding('myForm.input.$valid')); + var input = element(by.model('email.text')); - return handleRequestFn; - } - ]; -} + it('should initialize to model', function() { + expect(text.getText()).toContain('me@example.com'); + expect(valid.getText()).toContain('true'); + }); -/** @this */ -function $$TestabilityProvider() { - this.$get = ['$rootScope', '$browser', '$location', - function($rootScope, $browser, $location) { + it('should be invalid if empty', function() { + input.clear(); + input.sendKeys(''); + expect(text.getText()).toEqual('text ='); + expect(valid.getText()).toContain('false'); + }); - /** - * @name $testability - * - * @description - * The private $$testability service provides a collection of methods for use when debugging - * or by automated test and debugging tools. - */ - var testability = {}; + it('should be invalid if not email', function() { + input.clear(); + input.sendKeys('xxx'); - /** - * @name $$testability#findBindings - * - * @description - * Returns an array of elements that are bound (via ng-bind or {{}}) - * to expressions matching the input. - * - * @param {Element} element The element root to search from. - * @param {string} expression The binding expression to match. - * @param {boolean} opt_exactMatch If true, only returns exact matches - * for the expression. Filters and whitespace are ignored. - */ - testability.findBindings = function(element, expression, opt_exactMatch) { - var bindings = element.getElementsByClassName('ng-binding'); - var matches = []; - forEach(bindings, function(binding) { - var dataBinding = angular.element(binding).data('$binding'); - if (dataBinding) { - forEach(dataBinding, function(bindingName) { - if (opt_exactMatch) { - var matcher = new RegExp('(^|\\s)' + escapeForRegexp(expression) + '(\\s|\\||$)'); - if (matcher.test(bindingName)) { - matches.push(binding); - } - } else { - if (bindingName.indexOf(expression) !== -1) { - matches.push(binding); - } - } + expect(valid.getText()).toContain('false'); }); - } - }); - return matches; - }; - - /** - * @name $$testability#findModels - * - * @description - * Returns an array of elements that are two-way found via ng-model to - * expressions matching the input. - * - * @param {Element} element The element root to search from. - * @param {string} expression The model expression to match. - * @param {boolean} opt_exactMatch If true, only returns exact matches - * for the expression. - */ - testability.findModels = function(element, expression, opt_exactMatch) { - var prefixes = ['ng-', 'data-ng-', 'ng\\:']; - for (var p = 0; p < prefixes.length; ++p) { - var attributeEquals = opt_exactMatch ? '=' : '*='; - var selector = '[' + prefixes[p] + 'model' + attributeEquals + '"' + expression + '"]'; - var elements = element.querySelectorAll(selector); - if (elements.length) { - return elements; - } - } - }; + +
+ */ + 'email': emailInputType, - /** - * @name $$testability#getLocation - * - * @description - * Shortcut for getting the location in a browser agnostic way. Returns - * the path, search, and hash. (e.g. /path?a=b#hash) - */ - testability.getLocation = function() { - return $location.url(); - }; - /** - * @name $$testability#setLocation - * - * @description - * Shortcut for navigating to a location without doing a full page reload. - * - * @param {string} url The location url (path, search and hash, - * e.g. /path?a=b#hash) to go to. - */ - testability.setLocation = function(url) { - if (url !== $location.url()) { - $location.url(url); - $rootScope.$digest(); - } - }; + /** + * @ngdoc input + * @name input[radio] + * + * @description + * HTML radio button. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string} value The value to which the `ngModel` expression should be set when selected. + * Note that `value` only supports `string` values, i.e. the scope model needs to be a string, + * too. Use `ngValue` if you need complex models (`number`, `object`, ...). + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * @param {string} ngValue Angular expression to which `ngModel` will be be set when the radio + * is selected. Should be used instead of the `value` attribute if you need + * a non-string `ngModel` (`boolean`, `array`, ...). + * + * @example + + + +
+
+
+
+ color = {{color.name | json}}
+
+ Note that `ng-value="specialValue"` sets radio item's value to be the value of `$scope.specialValue`. +
+ + it('should change state', function() { + var inputs = element.all(by.model('color.name')); + var color = element(by.binding('color.name')); - /** - * @name $$testability#whenStable - * - * @description - * Calls the callback when $timeout and $http requests are completed. - * - * @param {function} callback - */ - testability.whenStable = function(callback) { - $browser.notifyWhenNoOutstandingRequests(callback); - }; + expect(color.getText()).toContain('blue'); - return testability; - }]; -} + inputs.get(0).click(); + expect(color.getText()).toContain('red'); -/** @this */ -function $TimeoutProvider() { - this.$get = ['$rootScope', '$browser', '$q', '$$q', '$exceptionHandler', - function($rootScope, $browser, $q, $$q, $exceptionHandler) { + inputs.get(1).click(); + expect(color.getText()).toContain('green'); + }); + +
+ */ + 'radio': radioInputType, - var deferreds = {}; + /** + * @ngdoc input + * @name input[range] + * + * @description + * Native range input with validation and transformation. + * + * The model for the range input must always be a `Number`. + * + * IE9 and other browsers that do not support the `range` type fall back + * to a text input without any default values for `min`, `max` and `step`. Model binding, + * validation and number parsing are nevertheless supported. + * + * Browsers that support range (latest Chrome, Safari, Firefox, Edge) treat `input[range]` + * in a way that never allows the input to hold an invalid value. That means: + * - any non-numerical value is set to `(max + min) / 2`. + * - any numerical value that is less than the current min val, or greater than the current max val + * is set to the min / max val respectively. + * - additionally, the current `step` is respected, so the nearest value that satisfies a step + * is used. + * + * See the [HTML Spec on input[type=range]](https://www.w3.org/TR/html5/forms.html#range-state-(type=range)) + * for more info. + * + * This has the following consequences for Angular: + * + * Since the element value should always reflect the current model value, a range input + * will set the bound ngModel expression to the value that the browser has set for the + * input element. For example, in the following input ``, + * if the application sets `model.value = null`, the browser will set the input to `'50'`. + * Angular will then set the model to `50`, to prevent input and model value being out of sync. + * + * That means the model for range will immediately be set to `50` after `ngModel` has been + * initialized. It also means a range input can never have the required error. + * + * This does not only affect changes to the model value, but also to the values of the `min`, + * `max`, and `step` attributes. When these change in a way that will cause the browser to modify + * the input value, Angular will also update the model value. + * + * Automatic value adjustment also means that a range input element can never have the `required`, + * `min`, or `max` errors. + * + * However, `step` is currently only fully implemented by Firefox. Other browsers have problems + * when the step value changes dynamically - they do not adjust the element value correctly, but + * instead may set the `stepMismatch` error. If that's the case, the Angular will set the `step` + * error on the input, and set the model to `undefined`. + * + * Note that `input[range]` is not compatible with`ngMax`, `ngMin`, and `ngStep`, because they do + * not set the `min` and `max` attributes, which means that the browser won't automatically adjust + * the input value based on their values, and will always assume min = 0, max = 100, and step = 1. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} min Sets the `min` validation to ensure that the value entered is greater + * than `min`. Can be interpolated. + * @param {string=} max Sets the `max` validation to ensure that the value entered is less than `max`. + * Can be interpolated. + * @param {string=} step Sets the `step` validation to ensure that the value entered matches the `step` + * Can be interpolated. + * @param {string=} ngChange Angular expression to be executed when the ngModel value changes due + * to user interaction with the input element. + * @param {expression=} ngChecked If the expression is truthy, then the `checked` attribute will be set on the + * element. **Note** : `ngChecked` should not be used alongside `ngModel`. + * Checkout {@link ng.directive:ngChecked ngChecked} for usage. + * + * @example + + + +
+ Model as range: +
+ Model as number:
+ Min:
+ Max:
+ value = {{value}}
+ myForm.range.$valid = {{myForm.range.$valid}}
+ myForm.range.$error = {{myForm.range.$error}} +
+
+
- /** - * @ngdoc service - * @name $timeout - * - * @description - * Angular's wrapper for `window.setTimeout`. The `fn` function is wrapped into a try/catch - * block and delegates any exceptions to - * {@link ng.$exceptionHandler $exceptionHandler} service. - * - * The return value of calling `$timeout` is a promise, which will be resolved when - * the delay has passed and the timeout function, if provided, is executed. - * - * To cancel a timeout request, call `$timeout.cancel(promise)`. - * - * In tests you can use {@link ngMock.$timeout `$timeout.flush()`} to - * synchronously flush the queue of deferred functions. - * - * If you only want a promise that will be resolved after some specified delay - * then you can call `$timeout` without the `fn` function. - * - * @param {function()=} fn A function, whose execution should be delayed. - * @param {number=} [delay=0] Delay in milliseconds. - * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise - * will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block. - * @param {...*=} Pass additional parameters to the executed function. - * @returns {Promise} Promise that will be resolved when the timeout is reached. The promise - * will be resolved with the return value of the `fn` function. - * - */ - function timeout(fn, delay, invokeApply) { - if (!isFunction(fn)) { - invokeApply = delay; - delay = fn; - fn = noop; - } + * ## Range Input with ngMin & ngMax attributes - var args = sliceArgs(arguments, 3), - skipApply = (isDefined(invokeApply) && !invokeApply), - deferred = (skipApply ? $$q : $q).defer(), - promise = deferred.promise, - timeoutId; + * @example + + + +
+ Model as range: +
+ Model as number:
+ Min:
+ Max:
+ value = {{value}}
+ myForm.range.$valid = {{myForm.range.$valid}}
+ myForm.range.$error = {{myForm.range.$error}} +
+
+
- timeoutId = $browser.defer(function() { - try { - deferred.resolve(fn.apply(null, args)); - } catch (e) { - deferred.reject(e); - $exceptionHandler(e); - } finally { - delete deferreds[promise.$$timeoutId]; - } + */ + 'range': rangeInputType, - if (!skipApply) $rootScope.$apply(); - }, delay); + /** + * @ngdoc input + * @name input[checkbox] + * + * @description + * HTML checkbox. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {expression=} ngTrueValue The value to which the expression should be set when selected. + * @param {expression=} ngFalseValue The value to which the expression should be set when not selected. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * + * @example + + + +
+
+
+ value1 = {{checkboxModel.value1}}
+ value2 = {{checkboxModel.value2}}
+
+
+ + it('should change state', function() { + var value1 = element(by.binding('checkboxModel.value1')); + var value2 = element(by.binding('checkboxModel.value2')); - promise.$$timeoutId = timeoutId; - deferreds[timeoutId] = deferred; + expect(value1.getText()).toContain('true'); + expect(value2.getText()).toContain('YES'); - return promise; + element(by.model('checkboxModel.value1')).click(); + element(by.model('checkboxModel.value2')).click(); + + expect(value1.getText()).toContain('false'); + expect(value2.getText()).toContain('NO'); + }); + +
+ */ + 'checkbox': checkboxInputType, + + 'hidden': noop, + 'button': noop, + 'submit': noop, + 'reset': noop, + 'file': noop +}; + +function stringBasedInputType(ctrl) { + ctrl.$formatters.push(function(value) { + return ctrl.$isEmpty(value) ? value : value.toString(); + }); +} + +function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { + baseInputType(scope, element, attr, ctrl, $sniffer, $browser); + stringBasedInputType(ctrl); +} + +function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) { + var type = lowercase(element[0].type); + + // In composition mode, users are still inputting intermediate text buffer, + // hold the listener until composition is done. + // More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent + if (!$sniffer.android) { + var composing = false; + + element.on('compositionstart', function() { + composing = true; + }); + + element.on('compositionend', function() { + composing = false; + listener(); + }); + } + + var timeout; + + var listener = function(ev) { + if (timeout) { + $browser.defer.cancel(timeout); + timeout = null; } + if (composing) return; + var value = element.val(), + event = ev && ev.type; + // By default we will trim the value + // If the attribute ng-trim exists we will avoid trimming + // If input type is 'password', the value is never trimmed + if (type !== 'password' && (!attr.ngTrim || attr.ngTrim !== 'false')) { + value = trim(value); + } - /** - * @ngdoc method - * @name $timeout#cancel - * - * @description - * Cancels a task associated with the `promise`. As a result of this, the promise will be - * resolved with a rejection. - * - * @param {Promise=} promise Promise returned by the `$timeout` function. - * @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully - * canceled. - */ - timeout.cancel = function(promise) { - if (promise && promise.$$timeoutId in deferreds) { - // Timeout cancels should not report an unhandled promise. - markQExceptionHandled(deferreds[promise.$$timeoutId].promise); - deferreds[promise.$$timeoutId].reject('canceled'); - delete deferreds[promise.$$timeoutId]; - return $browser.defer.cancel(promise.$$timeoutId); + // If a control is suffering from bad input (due to native validators), browsers discard its + // value, so it may be necessary to revalidate (by calling $setViewValue again) even if the + // control's value is the same empty value twice in a row. + if (ctrl.$viewValue !== value || (value === '' && ctrl.$$hasNativeValidators)) { + ctrl.$setViewValue(value, event); + } + }; + + // if the browser does support "input" event, we are fine - except on IE9 which doesn't fire the + // input event on backspace, delete or cut + if ($sniffer.hasEvent('input')) { + element.on('input', listener); + } else { + var deferListener = function(ev, input, origValue) { + if (!timeout) { + timeout = $browser.defer(function() { + timeout = null; + if (!input || input.value !== origValue) { + listener(ev); + } + }); } - return false; }; - return timeout; - }]; -} - -// NOTE: The usage of window and document instead of $window and $document here is -// deliberate. This service depends on the specific behavior of anchor nodes created by the -// browser (resolving and parsing URLs) that is unlikely to be provided by mock objects and -// cause us to break tests. In addition, when the browser resolves a URL for XHR, it -// doesn't know about mocked locations and resolves URLs to the real document - which is -// exactly the behavior needed here. There is little value is mocking these out for this -// service. -var urlParsingNode = window.document.createElement('a'); -var originUrl = urlResolve(window.location.href); + element.on('keydown', /** @this */ function(event) { + var key = event.keyCode; + // ignore + // command modifiers arrows + if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return; -/** - * - * Implementation Notes for non-IE browsers - * ---------------------------------------- - * Assigning a URL to the href property of an anchor DOM node, even one attached to the DOM, - * results both in the normalizing and parsing of the URL. Normalizing means that a relative - * URL will be resolved into an absolute URL in the context of the application document. - * Parsing means that the anchor node's host, hostname, protocol, port, pathname and related - * properties are all populated to reflect the normalized URL. This approach has wide - * compatibility - Safari 1+, Mozilla 1+ etc. See - * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html - * - * Implementation Notes for IE - * --------------------------- - * IE <= 10 normalizes the URL when assigned to the anchor node similar to the other - * browsers. However, the parsed components will not be set if the URL assigned did not specify - * them. (e.g. if you assign a.href = "foo", then a.protocol, a.host, etc. will be empty.) We - * work around that by performing the parsing in a 2nd step by taking a previously normalized - * URL (e.g. by assigning to a.href) and assigning it a.href again. This correctly populates the - * properties such as protocol, hostname, port, etc. - * - * References: - * http://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement - * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html - * http://url.spec.whatwg.org/#urlutils - * https://github.com/angular/angular.js/pull/2902 - * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/ - * - * @kind function - * @param {string} url The URL to be parsed. - * @description Normalizes and parses a URL. - * @returns {object} Returns the normalized URL as a dictionary. - * - * | member name | Description | - * |---------------|----------------| - * | href | A normalized version of the provided URL if it was not an absolute URL | - * | protocol | The protocol including the trailing colon | - * | host | The host and port (if the port is non-default) of the normalizedUrl | - * | search | The search params, minus the question mark | - * | hash | The hash string, minus the hash symbol - * | hostname | The hostname - * | port | The port, without ":" - * | pathname | The pathname, beginning with "/" - * - */ -function urlResolve(url) { - var href = url; + deferListener(event, this, this.value); + }); - // Support: IE 9-11 only - if (msie) { - // Normalize before parse. Refer Implementation Notes on why this is - // done in two steps on IE. - urlParsingNode.setAttribute('href', href); - href = urlParsingNode.href; + // if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it + if ($sniffer.hasEvent('paste')) { + element.on('paste cut', deferListener); + } } - urlParsingNode.setAttribute('href', href); + // if user paste into input using mouse on older browser + // or form autocomplete on newer browser, we need "change" event to catch it + element.on('change', listener); - // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils - return { - href: urlParsingNode.href, - protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '', - host: urlParsingNode.host, - search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '', - hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '', - hostname: urlParsingNode.hostname, - port: urlParsingNode.port, - pathname: (urlParsingNode.pathname.charAt(0) === '/') - ? urlParsingNode.pathname - : '/' + urlParsingNode.pathname + // Some native input types (date-family) have the ability to change validity without + // firing any input/change events. + // For these event types, when native validators are present and the browser supports the type, + // check for validity changes on various DOM events. + if (PARTIAL_VALIDATION_TYPES[type] && ctrl.$$hasNativeValidators && type === attr.type) { + element.on(PARTIAL_VALIDATION_EVENTS, /** @this */ function(ev) { + if (!timeout) { + var validity = this[VALIDITY_STATE_PROPERTY]; + var origBadInput = validity.badInput; + var origTypeMismatch = validity.typeMismatch; + timeout = $browser.defer(function() { + timeout = null; + if (validity.badInput !== origBadInput || validity.typeMismatch !== origTypeMismatch) { + listener(ev); + } + }); + } + }); + } + + ctrl.$render = function() { + // Workaround for Firefox validation #12102. + var value = ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue; + if (element.val() !== value) { + element.val(value); + } }; } -/** - * Parse a request URL and determine whether this is a same-origin request as the application document. - * - * @param {string|object} requestUrl The url of the request as a string that will be resolved - * or a parsed URL object. - * @returns {boolean} Whether the request is for the same origin as the application document. - */ -function urlIsSameOrigin(requestUrl) { - var parsed = (isString(requestUrl)) ? urlResolve(requestUrl) : requestUrl; - return (parsed.protocol === originUrl.protocol && - parsed.host === originUrl.host); -} +function weekParser(isoWeek, existingDate) { + if (isDate(isoWeek)) { + return isoWeek; + } -/** - * @ngdoc service - * @name $window - * @this - * - * @description - * A reference to the browser's `window` object. While `window` - * is globally available in JavaScript, it causes testability problems, because - * it is a global variable. In angular we always refer to it through the - * `$window` service, so it may be overridden, removed or mocked for testing. - * - * Expressions, like the one defined for the `ngClick` directive in the example - * below, are evaluated with respect to the current scope. Therefore, there is - * no risk of inadvertently coding in a dependency on a global value in such an - * expression. - * - * @example - - - -
- - -
-
- - it('should display the greeting in the input box', function() { - element(by.model('greeting')).sendKeys('Hello, E2E Tests'); - // If we click the button it will block the test runner - // element(':button').click(); - }); - -
- */ -function $WindowProvider() { - this.$get = valueFn(window); -} + if (isString(isoWeek)) { + WEEK_REGEXP.lastIndex = 0; + var parts = WEEK_REGEXP.exec(isoWeek); + if (parts) { + var year = +parts[1], + week = +parts[2], + hours = 0, + minutes = 0, + seconds = 0, + milliseconds = 0, + firstThurs = getFirstThursdayOfYear(year), + addDays = (week - 1) * 7; -/** - * @name $$cookieReader - * @requires $document - * - * @description - * This is a private service for reading cookies used by $http and ngCookies - * - * @return {Object} a key/value map of the current cookies - */ -function $$CookieReader($document) { - var rawDocument = $document[0] || {}; - var lastCookies = {}; - var lastCookieString = ''; + if (existingDate) { + hours = existingDate.getHours(); + minutes = existingDate.getMinutes(); + seconds = existingDate.getSeconds(); + milliseconds = existingDate.getMilliseconds(); + } - function safeGetCookie(rawDocument) { - try { - return rawDocument.cookie || ''; - } catch (e) { - return ''; + return new Date(year, 0, firstThurs.getDate() + addDays, hours, minutes, seconds, milliseconds); } } - function safeDecodeURIComponent(str) { - try { - return decodeURIComponent(str); - } catch (e) { - return str; + return NaN; +} + +function createDateParser(regexp, mapping) { + return function(iso, date) { + var parts, map; + + if (isDate(iso)) { + return iso; } - } - return function() { - var cookieArray, cookie, i, index, name; - var currentCookieString = safeGetCookie(rawDocument); + if (isString(iso)) { + // When a date is JSON'ified to wraps itself inside of an extra + // set of double quotes. This makes the date parsing code unable + // to match the date string and parse it as a date. + if (iso.charAt(0) === '"' && iso.charAt(iso.length - 1) === '"') { + iso = iso.substring(1, iso.length - 1); + } + if (ISO_DATE_REGEXP.test(iso)) { + return new Date(iso); + } + regexp.lastIndex = 0; + parts = regexp.exec(iso); - if (currentCookieString !== lastCookieString) { - lastCookieString = currentCookieString; - cookieArray = lastCookieString.split('; '); - lastCookies = {}; + if (parts) { + parts.shift(); + if (date) { + map = { + yyyy: date.getFullYear(), + MM: date.getMonth() + 1, + dd: date.getDate(), + HH: date.getHours(), + mm: date.getMinutes(), + ss: date.getSeconds(), + sss: date.getMilliseconds() / 1000 + }; + } else { + map = { yyyy: 1970, MM: 1, dd: 1, HH: 0, mm: 0, ss: 0, sss: 0 }; + } - for (i = 0; i < cookieArray.length; i++) { - cookie = cookieArray[i]; - index = cookie.indexOf('='); - if (index > 0) { //ignore nameless cookies - name = safeDecodeURIComponent(cookie.substring(0, index)); - // the first value that is seen for a cookie is the most - // specific one. values for the same cookie name that - // follow are for less specific paths. - if (isUndefined(lastCookies[name])) { - lastCookies[name] = safeDecodeURIComponent(cookie.substring(index + 1)); + forEach(parts, function(part, index) { + if (index < mapping.length) { + map[mapping[index]] = +part; } + }); + return new Date(map.yyyy, map.MM - 1, map.dd, map.HH, map.mm, map.ss || 0, map.sss * 1000 || 0); + } + } + + return NaN; + }; +} + +function createDateInputType(type, regexp, parseDate, format) { + return function dynamicDateInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter) { + badInputChecker(scope, element, attr, ctrl); + baseInputType(scope, element, attr, ctrl, $sniffer, $browser); + var timezone = ctrl && ctrl.$options.getOption('timezone'); + var previousDate; + + ctrl.$$parserName = type; + ctrl.$parsers.push(function(value) { + if (ctrl.$isEmpty(value)) return null; + if (regexp.test(value)) { + // Note: We cannot read ctrl.$modelValue, as there might be a different + // parser/formatter in the processing chain so that the model + // contains some different data format! + var parsedDate = parseDate(value, previousDate); + if (timezone) { + parsedDate = convertTimezoneToLocal(parsedDate, timezone); + } + return parsedDate; + } + return undefined; + }); + + ctrl.$formatters.push(function(value) { + if (value && !isDate(value)) { + throw ngModelMinErr('datefmt', 'Expected `{0}` to be a date', value); + } + if (isValidDate(value)) { + previousDate = value; + if (previousDate && timezone) { + previousDate = convertTimezoneToLocal(previousDate, timezone, true); } + return $filter('date')(value, format, timezone); + } else { + previousDate = null; + return ''; } + }); + + if (isDefined(attr.min) || attr.ngMin) { + var minVal; + ctrl.$validators.min = function(value) { + return !isValidDate(value) || isUndefined(minVal) || parseDate(value) >= minVal; + }; + attr.$observe('min', function(val) { + minVal = parseObservedDateValue(val); + ctrl.$validate(); + }); + } + + if (isDefined(attr.max) || attr.ngMax) { + var maxVal; + ctrl.$validators.max = function(value) { + return !isValidDate(value) || isUndefined(maxVal) || parseDate(value) <= maxVal; + }; + attr.$observe('max', function(val) { + maxVal = parseObservedDateValue(val); + ctrl.$validate(); + }); + } + + function isValidDate(value) { + // Invalid Date: getTime() returns NaN + return value && !(value.getTime && value.getTime() !== value.getTime()); + } + + function parseObservedDateValue(val) { + return isDefined(val) && !isDate(val) ? parseDate(val) || undefined : val; } - return lastCookies; }; } -$$CookieReader.$inject = ['$document']; +function badInputChecker(scope, element, attr, ctrl) { + var node = element[0]; + var nativeValidation = ctrl.$$hasNativeValidators = isObject(node.validity); + if (nativeValidation) { + ctrl.$parsers.push(function(value) { + var validity = element.prop(VALIDITY_STATE_PROPERTY) || {}; + return validity.badInput || validity.typeMismatch ? undefined : value; + }); + } +} -/** @this */ -function $$CookieReaderProvider() { - this.$get = $$CookieReader; +function numberFormatterParser(ctrl) { + ctrl.$$parserName = 'number'; + ctrl.$parsers.push(function(value) { + if (ctrl.$isEmpty(value)) return null; + if (NUMBER_REGEXP.test(value)) return parseFloat(value); + return undefined; + }); + + ctrl.$formatters.push(function(value) { + if (!ctrl.$isEmpty(value)) { + if (!isNumber(value)) { + throw ngModelMinErr('numfmt', 'Expected `{0}` to be a number', value); + } + value = value.toString(); + } + return value; + }); } -/* global currencyFilter: true, - dateFilter: true, - filterFilter: true, - jsonFilter: true, - limitToFilter: true, - lowercaseFilter: true, - numberFilter: true, - orderByFilter: true, - uppercaseFilter: true, - */ +function parseNumberAttrVal(val) { + if (isDefined(val) && !isNumber(val)) { + val = parseFloat(val); + } + return !isNumberNaN(val) ? val : undefined; +} -/** - * @ngdoc provider - * @name $filterProvider - * @description - * - * Filters are just functions which transform input to an output. However filters need to be - * Dependency Injected. To achieve this a filter definition consists of a factory function which is - * annotated with dependencies and is responsible for creating a filter function. - * - *
- * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`. - * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace - * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores - * (`myapp_subsection_filterx`). - *
- * - * ```js - * // Filter registration - * function MyModule($provide, $filterProvider) { - * // create a service to demonstrate injection (not always needed) - * $provide.value('greet', function(name){ - * return 'Hello ' + name + '!'; - * }); - * - * // register a filter factory which uses the - * // greet service to demonstrate DI. - * $filterProvider.register('greet', function(greet){ - * // return the filter function which uses the greet service - * // to generate salutation - * return function(text) { - * // filters need to be forgiving so check input validity - * return text && greet(text) || text; - * }; - * }); - * } - * ``` - * - * The filter function is registered with the `$injector` under the filter name suffix with - * `Filter`. - * - * ```js - * it('should be the same instance', inject( - * function($filterProvider) { - * $filterProvider.register('reverse', function(){ - * return ...; - * }); - * }, - * function($filter, reverseFilter) { - * expect($filter('reverse')).toBe(reverseFilter); - * }); - * ``` - * - * - * For more information about how angular filters work, and how to create your own filters, see - * {@link guide/filter Filters} in the Angular Developer Guide. - */ +function isNumberInteger(num) { + // See http://stackoverflow.com/questions/14636536/how-to-check-if-a-variable-is-an-integer-in-javascript#14794066 + // (minus the assumption that `num` is a number) -/** - * @ngdoc service - * @name $filter - * @kind function - * @description - * Filters are used for formatting data displayed to the user. - * - * They can be used in view templates, controllers or services.Angular comes - * with a collection of [built-in filters](api/ng/filter), but it is easy to - * define your own as well. - * - * The general syntax in templates is as follows: - * - * ```html - * {{ expression [| filter_name[:parameter_value] ... ] }} - * ``` - * - * @param {String} name Name of the filter function to retrieve - * @return {Function} the filter function - * @example - - -
-

{{ originalText }}

-

{{ filteredText }}

-
-
+ // eslint-disable-next-line no-bitwise + return (num | 0) === num; +} - - angular.module('filterExample', []) - .controller('MainCtrl', function($scope, $filter) { - $scope.originalText = 'hello'; - $scope.filteredText = $filter('uppercase')($scope.originalText); - }); - -
- */ -$FilterProvider.$inject = ['$provide']; -/** @this */ -function $FilterProvider($provide) { - var suffix = 'Filter'; +function countDecimals(num) { + var numString = num.toString(); + var decimalSymbolIndex = numString.indexOf('.'); - /** - * @ngdoc method - * @name $filterProvider#register - * @param {string|Object} name Name of the filter function, or an object map of filters where - * the keys are the filter names and the values are the filter factories. - * - *
- * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`. - * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace - * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores - * (`myapp_subsection_filterx`). - *
- * @param {Function} factory If the first argument was a string, a factory function for the filter to be registered. - * @returns {Object} Registered filter instance, or if a map of filters was provided then a map - * of the registered filter instances. - */ - function register(name, factory) { - if (isObject(name)) { - var filters = {}; - forEach(name, function(filter, key) { - filters[key] = register(key, filter); - }); - return filters; - } else { - return $provide.factory(name + suffix, factory); + if (decimalSymbolIndex === -1) { + if (-1 < num && num < 1) { + // It may be in the exponential notation format (`1e-X`) + var match = /e-(\d+)$/.exec(numString); + + if (match) { + return Number(match[1]); + } } + + return 0; } - this.register = register; - this.$get = ['$injector', function($injector) { - return function(name) { - return $injector.get(name + suffix); - }; - }]; + return numString.length - decimalSymbolIndex - 1; +} - //////////////////////////////////////// +function isValidForStep(viewValue, stepBase, step) { + // At this point `stepBase` and `step` are expected to be non-NaN values + // and `viewValue` is expected to be a valid stringified number. + var value = Number(viewValue); - /* global - currencyFilter: false, - dateFilter: false, - filterFilter: false, - jsonFilter: false, - limitToFilter: false, - lowercaseFilter: false, - numberFilter: false, - orderByFilter: false, - uppercaseFilter: false - */ + var isNonIntegerValue = !isNumberInteger(value); + var isNonIntegerStepBase = !isNumberInteger(stepBase); + var isNonIntegerStep = !isNumberInteger(step); - register('currency', currencyFilter); - register('date', dateFilter); - register('filter', filterFilter); - register('json', jsonFilter); - register('limitTo', limitToFilter); - register('lowercase', lowercaseFilter); - register('number', numberFilter); - register('orderBy', orderByFilter); - register('uppercase', uppercaseFilter); + // Due to limitations in Floating Point Arithmetic (e.g. `0.3 - 0.2 !== 0.1` or + // `0.5 % 0.1 !== 0`), we need to convert all numbers to integers. + if (isNonIntegerValue || isNonIntegerStepBase || isNonIntegerStep) { + var valueDecimals = isNonIntegerValue ? countDecimals(value) : 0; + var stepBaseDecimals = isNonIntegerStepBase ? countDecimals(stepBase) : 0; + var stepDecimals = isNonIntegerStep ? countDecimals(step) : 0; + + var decimalCount = Math.max(valueDecimals, stepBaseDecimals, stepDecimals); + var multiplier = Math.pow(10, decimalCount); + + value = value * multiplier; + stepBase = stepBase * multiplier; + step = step * multiplier; + + if (isNonIntegerValue) value = Math.round(value); + if (isNonIntegerStepBase) stepBase = Math.round(stepBase); + if (isNonIntegerStep) step = Math.round(step); + } + + return (value - stepBase) % step === 0; } -/** - * @ngdoc filter - * @name filter - * @kind function - * - * @description - * Selects a subset of items from `array` and returns it as a new array. - * - * @param {Array} array The source array. - *
- * **Note**: If the array contains objects that reference themselves, filtering is not possible. - *
- * @param {string|Object|function()} expression The predicate to be used for selecting items from - * `array`. - * - * Can be one of: - * - * - `string`: The string is used for matching against the contents of the `array`. All strings or - * objects with string properties in `array` that match this string will be returned. This also - * applies to nested object properties. - * The predicate can be negated by prefixing the string with `!`. - * - * - `Object`: A pattern object can be used to filter specific properties on objects contained - * by `array`. For example `{name:"M", phone:"1"}` predicate will return an array of items - * which have property `name` containing "M" and property `phone` containing "1". A special - * property name (`$` by default) can be used (e.g. as in `{$: "text"}`) to accept a match - * against any property of the object or its nested object properties. That's equivalent to the - * simple substring match with a `string` as described above. The special property name can be - * overwritten, using the `anyPropertyKey` parameter. - * The predicate can be negated by prefixing the string with `!`. - * For example `{name: "!M"}` predicate will return an array of items which have property `name` - * not containing "M". - * - * Note that a named property will match properties on the same level only, while the special - * `$` property will match properties on the same level or deeper. E.g. an array item like - * `{name: {first: 'John', last: 'Doe'}}` will **not** be matched by `{name: 'John'}`, but - * **will** be matched by `{$: 'John'}`. - * - * - `function(value, index, array)`: A predicate function can be used to write arbitrary filters. - * The function is called for each element of the array, with the element, its index, and - * the entire array itself as arguments. - * - * The final result is an array of those elements that the predicate returned true for. - * - * @param {function(actual, expected)|true|false} [comparator] Comparator which is used in - * determining if values retrieved using `expression` (when it is not a function) should be - * considered a match based on the expected value (from the filter expression) and actual - * value (from the object in the array). - * - * Can be one of: - * - * - `function(actual, expected)`: - * The function will be given the object value and the predicate value to compare and - * should return true if both values should be considered equal. - * - * - `true`: A shorthand for `function(actual, expected) { return angular.equals(actual, expected)}`. - * This is essentially strict comparison of expected and actual. - * - * - `false`: A short hand for a function which will look for a substring match in a case - * insensitive way. Primitive values are converted to strings. Objects are not compared against - * primitives, unless they have a custom `toString` method (e.g. `Date` objects). - * - * - * Defaults to `false`. - * - * @param {string} [anyPropertyKey] The special property name that matches against any property. - * By default `$`. - * - * @example - - -
+function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { + badInputChecker(scope, element, attr, ctrl); + numberFormatterParser(ctrl); + baseInputType(scope, element, attr, ctrl, $sniffer, $browser); - - - - - - - -
NamePhone
{{friend.name}}{{friend.phone}}
-
-
-
-
-
- - - - - - -
NamePhone
{{friendObj.name}}{{friendObj.phone}}
-
- - var expectFriendNames = function(expectedNames, key) { - element.all(by.repeater(key + ' in friends').column(key + '.name')).then(function(arr) { - arr.forEach(function(wd, i) { - expect(wd.getText()).toMatch(expectedNames[i]); - }); - }); - }; + var minVal; + var maxVal; - it('should search across all fields when filtering with a string', function() { - var searchText = element(by.model('searchText')); - searchText.clear(); - searchText.sendKeys('m'); - expectFriendNames(['Mary', 'Mike', 'Adam'], 'friend'); + if (isDefined(attr.min) || attr.ngMin) { + ctrl.$validators.min = function(value) { + return ctrl.$isEmpty(value) || isUndefined(minVal) || value >= minVal; + }; - searchText.clear(); - searchText.sendKeys('76'); - expectFriendNames(['John', 'Julie'], 'friend'); - }); + attr.$observe('min', function(val) { + minVal = parseNumberAttrVal(val); + // TODO(matsko): implement validateLater to reduce number of validations + ctrl.$validate(); + }); + } - it('should search in specific fields when filtering with a predicate object', function() { - var searchAny = element(by.model('search.$')); - searchAny.clear(); - searchAny.sendKeys('i'); - expectFriendNames(['Mary', 'Mike', 'Julie', 'Juliette'], 'friendObj'); - }); - it('should use a equal comparison when comparator is true', function() { - var searchName = element(by.model('search.name')); - var strict = element(by.model('strict')); - searchName.clear(); - searchName.sendKeys('Julie'); - strict.click(); - expectFriendNames(['Julie'], 'friendObj'); - }); - -
- */ + if (isDefined(attr.max) || attr.ngMax) { + ctrl.$validators.max = function(value) { + return ctrl.$isEmpty(value) || isUndefined(maxVal) || value <= maxVal; + }; -function filterFilter() { - return function(array, expression, comparator, anyPropertyKey) { - if (!isArrayLike(array)) { - if (array == null) { - return array; - } else { - throw minErr('filter')('notarray', 'Expected array but received: {0}', array); + attr.$observe('max', function(val) { + maxVal = parseNumberAttrVal(val); + // TODO(matsko): implement validateLater to reduce number of validations + ctrl.$validate(); + }); + } + + if (isDefined(attr.step) || attr.ngStep) { + var stepVal; + ctrl.$validators.step = function(modelValue, viewValue) { + return ctrl.$isEmpty(viewValue) || isUndefined(stepVal) || + isValidForStep(viewValue, minVal || 0, stepVal); + }; + + attr.$observe('step', function(val) { + stepVal = parseNumberAttrVal(val); + // TODO(matsko): implement validateLater to reduce number of validations + ctrl.$validate(); + }); + } +} + +function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) { + badInputChecker(scope, element, attr, ctrl); + numberFormatterParser(ctrl); + baseInputType(scope, element, attr, ctrl, $sniffer, $browser); + + var supportsRange = ctrl.$$hasNativeValidators && element[0].type === 'range', + minVal = supportsRange ? 0 : undefined, + maxVal = supportsRange ? 100 : undefined, + stepVal = supportsRange ? 1 : undefined, + validity = element[0].validity, + hasMinAttr = isDefined(attr.min), + hasMaxAttr = isDefined(attr.max), + hasStepAttr = isDefined(attr.step); + + var originalRender = ctrl.$render; + + ctrl.$render = supportsRange && isDefined(validity.rangeUnderflow) && isDefined(validity.rangeOverflow) ? + //Browsers that implement range will set these values automatically, but reading the adjusted values after + //$render would cause the min / max validators to be applied with the wrong value + function rangeRender() { + originalRender(); + ctrl.$setViewValue(element.val()); + } : + originalRender; + + if (hasMinAttr) { + ctrl.$validators.min = supportsRange ? + // Since all browsers set the input to a valid value, we don't need to check validity + function noopMinValidator() { return true; } : + // non-support browsers validate the min val + function minValidator(modelValue, viewValue) { + return ctrl.$isEmpty(viewValue) || isUndefined(minVal) || viewValue >= minVal; + }; + + setInitialValueAndObserver('min', minChange); + } + + if (hasMaxAttr) { + ctrl.$validators.max = supportsRange ? + // Since all browsers set the input to a valid value, we don't need to check validity + function noopMaxValidator() { return true; } : + // non-support browsers validate the max val + function maxValidator(modelValue, viewValue) { + return ctrl.$isEmpty(viewValue) || isUndefined(maxVal) || viewValue <= maxVal; + }; + + setInitialValueAndObserver('max', maxChange); + } + + if (hasStepAttr) { + ctrl.$validators.step = supportsRange ? + function nativeStepValidator() { + // Currently, only FF implements the spec on step change correctly (i.e. adjusting the + // input element value to a valid value). It's possible that other browsers set the stepMismatch + // validity error instead, so we can at least report an error in that case. + return !validity.stepMismatch; + } : + // ngStep doesn't set the setp attr, so the browser doesn't adjust the input value as setting step would + function stepValidator(modelValue, viewValue) { + return ctrl.$isEmpty(viewValue) || isUndefined(stepVal) || + isValidForStep(viewValue, minVal || 0, stepVal); + }; + + setInitialValueAndObserver('step', stepChange); + } + + function setInitialValueAndObserver(htmlAttrName, changeFn) { + // interpolated attributes set the attribute value only after a digest, but we need the + // attribute value when the input is first rendered, so that the browser can adjust the + // input value based on the min/max value + element.attr(htmlAttrName, attr[htmlAttrName]); + attr.$observe(htmlAttrName, changeFn); + } + + function minChange(val) { + minVal = parseNumberAttrVal(val); + // ignore changes before model is initialized + if (isNumberNaN(ctrl.$modelValue)) { + return; + } + + if (supportsRange) { + var elVal = element.val(); + // IE11 doesn't set the el val correctly if the minVal is greater than the element value + if (minVal > elVal) { + elVal = minVal; + element.val(elVal); + } + ctrl.$setViewValue(elVal); + } else { + // TODO(matsko): implement validateLater to reduce number of validations + ctrl.$validate(); + } + } + + function maxChange(val) { + maxVal = parseNumberAttrVal(val); + // ignore changes before model is initialized + if (isNumberNaN(ctrl.$modelValue)) { + return; + } + + if (supportsRange) { + var elVal = element.val(); + // IE11 doesn't set the el val correctly if the maxVal is less than the element value + if (maxVal < elVal) { + element.val(maxVal); + // IE11 and Chrome don't set the value to the minVal when max < min + elVal = maxVal < minVal ? minVal : maxVal; } + ctrl.$setViewValue(elVal); + } else { + // TODO(matsko): implement validateLater to reduce number of validations + ctrl.$validate(); } + } - anyPropertyKey = anyPropertyKey || '$'; - var expressionType = getTypeForFilter(expression); - var predicateFn; - var matchAgainstAnyProp; + function stepChange(val) { + stepVal = parseNumberAttrVal(val); + // ignore changes before model is initialized + if (isNumberNaN(ctrl.$modelValue)) { + return; + } - switch (expressionType) { - case 'function': - predicateFn = expression; - break; - case 'boolean': - case 'null': - case 'number': - case 'string': - matchAgainstAnyProp = true; - // falls through - case 'object': - predicateFn = createPredicateFn(expression, comparator, anyPropertyKey, matchAgainstAnyProp); - break; - default: - return array; + // Some browsers don't adjust the input value correctly, but set the stepMismatch error + if (supportsRange && ctrl.$viewValue !== element.val()) { + ctrl.$setViewValue(element.val()); + } else { + // TODO(matsko): implement validateLater to reduce number of validations + ctrl.$validate(); } + } +} - return Array.prototype.filter.call(array, predicateFn); +function urlInputType(scope, element, attr, ctrl, $sniffer, $browser) { + // Note: no badInputChecker here by purpose as `url` is only a validation + // in browsers, i.e. we can always read out input.value even if it is not valid! + baseInputType(scope, element, attr, ctrl, $sniffer, $browser); + stringBasedInputType(ctrl); + + ctrl.$$parserName = 'url'; + ctrl.$validators.url = function(modelValue, viewValue) { + var value = modelValue || viewValue; + return ctrl.$isEmpty(value) || URL_REGEXP.test(value); }; } -// Helper functions for `filterFilter` -function createPredicateFn(expression, comparator, anyPropertyKey, matchAgainstAnyProp) { - var shouldMatchPrimitives = isObject(expression) && (anyPropertyKey in expression); - var predicateFn; +function emailInputType(scope, element, attr, ctrl, $sniffer, $browser) { + // Note: no badInputChecker here by purpose as `url` is only a validation + // in browsers, i.e. we can always read out input.value even if it is not valid! + baseInputType(scope, element, attr, ctrl, $sniffer, $browser); + stringBasedInputType(ctrl); - if (comparator === true) { - comparator = equals; - } else if (!isFunction(comparator)) { - comparator = function(actual, expected) { - if (isUndefined(actual)) { - // No substring matching against `undefined` - return false; - } - if ((actual === null) || (expected === null)) { - // No substring matching against `null`; only match against `null` - return actual === expected; - } - if (isObject(expected) || (isObject(actual) && !hasCustomToString(actual))) { - // Should not compare primitives against objects, unless they have custom `toString` method - return false; - } + ctrl.$$parserName = 'email'; + ctrl.$validators.email = function(modelValue, viewValue) { + var value = modelValue || viewValue; + return ctrl.$isEmpty(value) || EMAIL_REGEXP.test(value); + }; +} - actual = lowercase('' + actual); - expected = lowercase('' + expected); - return actual.indexOf(expected) !== -1; - }; +function radioInputType(scope, element, attr, ctrl) { + var doTrim = !attr.ngTrim || trim(attr.ngTrim) !== 'false'; + // make the name unique, if not defined + if (isUndefined(attr.name)) { + element.attr('name', nextUid()); } - predicateFn = function(item) { - if (shouldMatchPrimitives && !isObject(item)) { - return deepCompare(item, expression[anyPropertyKey], comparator, anyPropertyKey, false); + var listener = function(ev) { + var value; + if (element[0].checked) { + value = attr.value; + if (doTrim) { + value = trim(value); + } + ctrl.$setViewValue(value, ev && ev.type); } - return deepCompare(item, expression, comparator, anyPropertyKey, matchAgainstAnyProp); }; - return predicateFn; -} + element.on('click', listener); -function deepCompare(actual, expected, comparator, anyPropertyKey, matchAgainstAnyProp, dontMatchWholeObject) { - var actualType = getTypeForFilter(actual); - var expectedType = getTypeForFilter(expected); + ctrl.$render = function() { + var value = attr.value; + if (doTrim) { + value = trim(value); + } + element[0].checked = (value === ctrl.$viewValue); + }; - if ((expectedType === 'string') && (expected.charAt(0) === '!')) { - return !deepCompare(actual, expected.substring(1), comparator, anyPropertyKey, matchAgainstAnyProp); - } else if (isArray(actual)) { - // In case `actual` is an array, consider it a match - // if ANY of it's items matches `expected` - return actual.some(function(item) { - return deepCompare(item, expected, comparator, anyPropertyKey, matchAgainstAnyProp); - }); + attr.$observe('value', ctrl.$render); +} + +function parseConstantExpr($parse, context, name, expression, fallback) { + var parseFn; + if (isDefined(expression)) { + parseFn = $parse(expression); + if (!parseFn.constant) { + throw ngModelMinErr('constexpr', 'Expected constant expression for `{0}`, but saw ' + + '`{1}`.', name, expression); + } + return parseFn(context); } + return fallback; +} - switch (actualType) { - case 'object': - var key; - if (matchAgainstAnyProp) { - for (key in actual) { - // Under certain, rare, circumstances, key may not be a string and `charAt` will be undefined - // See: https://github.com/angular/angular.js/issues/15644 - if (key.charAt && (key.charAt(0) !== '$') && - deepCompare(actual[key], expected, comparator, anyPropertyKey, true)) { - return true; - } - } - return dontMatchWholeObject ? false : deepCompare(actual, expected, comparator, anyPropertyKey, false); - } else if (expectedType === 'object') { - for (key in expected) { - var expectedVal = expected[key]; - if (isFunction(expectedVal) || isUndefined(expectedVal)) { - continue; - } +function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter, $parse) { + var trueValue = parseConstantExpr($parse, scope, 'ngTrueValue', attr.ngTrueValue, true); + var falseValue = parseConstantExpr($parse, scope, 'ngFalseValue', attr.ngFalseValue, false); - var matchAnyProperty = key === anyPropertyKey; - var actualVal = matchAnyProperty ? actual : actual[key]; - if (!deepCompare(actualVal, expectedVal, comparator, anyPropertyKey, matchAnyProperty, matchAnyProperty)) { - return false; - } + var listener = function(ev) { + ctrl.$setViewValue(element[0].checked, ev && ev.type); + }; + + element.on('click', listener); + + ctrl.$render = function() { + element[0].checked = ctrl.$viewValue; + }; + + // Override the standard `$isEmpty` because the $viewValue of an empty checkbox is always set to `false` + // This is because of the parser below, which compares the `$modelValue` with `trueValue` to convert + // it to a boolean. + ctrl.$isEmpty = function(value) { + return value === false; + }; + + ctrl.$formatters.push(function(value) { + return equals(value, trueValue); + }); + + ctrl.$parsers.push(function(value) { + return value ? trueValue : falseValue; + }); +} + + +/** + * @ngdoc directive + * @name textarea + * @restrict E + * + * @description + * HTML textarea element control with angular data-binding. The data-binding and validation + * properties of this element are exactly the same as those of the + * {@link ng.directive:input input element}. + * + * @param {string} ngModel Assignable angular expression to data-bind to. + * @param {string=} name Property name of the form under which the control is published. + * @param {string=} required Sets `required` validation error key if the value is not entered. + * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to + * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of + * `required` when you want to data-bind to the `required` attribute. + * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than + * minlength. + * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than + * maxlength. Setting the attribute to a negative or non-numeric value, allows view values of any + * length. + * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue} + * does not match a RegExp found by evaluating the Angular expression given in the attribute value. + * If the expression evaluates to a RegExp object, then this is used directly. + * If the expression evaluates to a string, then it will be converted to a RegExp + * after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to + * `new RegExp('^abc$')`.
+ * **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to + * start at the index of the last search's match, thus not taking the whole input value into + * account. + * @param {string=} ngChange Angular expression to be executed when input changes due to user + * interaction with the input element. + * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input. + * + * @knownIssue + * + * When specifying the `placeholder` attribute of ` + *
{{ list | json }}
+ *
+ * + * it("should split the text by newlines", function() { + * var listInput = element(by.model('list')); + * var output = element(by.binding('list | json')); + * listInput.sendKeys('abc\ndef\nghi'); + * expect(output.getText()).toContain('[\n "abc",\n "def",\n "ghi"\n]'); + * }); + * + * + * + * @element input + * @param {string=} ngList optional delimiter that should be used to split the value. + */ +var ngListDirective = function() { + return { + restrict: 'A', + priority: 100, + require: 'ngModel', + link: function(scope, element, attr, ctrl) { + var ngList = attr.ngList || ', '; + var trimValues = attr.ngTrim !== 'false'; + var separator = trimValues ? trim(ngList) : ngList; + + var parse = function(viewValue) { + // If the viewValue is invalid (say required but empty) it will be `undefined` + if (isUndefined(viewValue)) return; + + var list = []; + + if (viewValue) { + forEach(viewValue.split(separator), function(value) { + if (value) list.push(trimValues ? trim(value) : value); + }); + } + + return list; + }; + + ctrl.$parsers.push(parse); + ctrl.$formatters.push(function(value) { + if (isArray(value)) { + return value.join(ngList); + } + + return undefined; + }); + + // Override the standard $isEmpty because an empty array means the input is empty. + ctrl.$isEmpty = function(value) { + return !value || !value.length; + }; + } + }; +}; + +/* global VALID_CLASS: true, + INVALID_CLASS: true, + PRISTINE_CLASS: true, + DIRTY_CLASS: true, + UNTOUCHED_CLASS: true, + TOUCHED_CLASS: true, + PENDING_CLASS: true, + addSetValidityMethod: true, + setupValidity: true, + defaultModelOptions: false +*/ + + +var VALID_CLASS = 'ng-valid', + INVALID_CLASS = 'ng-invalid', + PRISTINE_CLASS = 'ng-pristine', + DIRTY_CLASS = 'ng-dirty', + UNTOUCHED_CLASS = 'ng-untouched', + TOUCHED_CLASS = 'ng-touched', + EMPTY_CLASS = 'ng-empty', + NOT_EMPTY_CLASS = 'ng-not-empty'; + +var ngModelMinErr = minErr('ngModel'); + +/** + * @ngdoc type + * @name ngModel.NgModelController + * + * @property {*} $viewValue The actual value from the control's view. For `input` elements, this is a + * String. See {@link ngModel.NgModelController#$setViewValue} for information about when the $viewValue + * is set. + * + * @property {*} $modelValue The value in the model that the control is bound to. + * + * @property {Array.} $parsers Array of functions to execute, as a pipeline, whenever + * the control updates the ngModelController with a new {@link ngModel.NgModelController#$viewValue + `$viewValue`} from the DOM, usually via user input. + See {@link ngModel.NgModelController#$setViewValue `$setViewValue()`} for a detailed lifecycle explanation. + Note that the `$parsers` are not called when the bound ngModel expression changes programmatically. + + The functions are called in array order, each passing + its return value through to the next. The last return value is forwarded to the + {@link ngModel.NgModelController#$validators `$validators`} collection. + + Parsers are used to sanitize / convert the {@link ngModel.NgModelController#$viewValue + `$viewValue`}. + + Returning `undefined` from a parser means a parse error occurred. In that case, + no {@link ngModel.NgModelController#$validators `$validators`} will run and the `ngModel` + will be set to `undefined` unless {@link ngModelOptions `ngModelOptions.allowInvalid`} + is set to `true`. The parse error is stored in `ngModel.$error.parse`. + + This simple example shows a parser that would convert text input value to lowercase: + * ```js + * function parse(value) { + * if (value) { + * return value.toLowerCase(); + * } + * } + * ngModelController.$parsers.push(parse); + * ``` + + * + * @property {Array.} $formatters Array of functions to execute, as a pipeline, whenever + the bound ngModel expression changes programmatically. The `$formatters` are not called when the + value of the control is changed by user interaction. + + Formatters are used to format / convert the {@link ngModel.NgModelController#$modelValue + `$modelValue`} for display in the control. + + The functions are called in reverse array order, each passing the value through to the + next. The last return value is used as the actual DOM value. + + This simple example shows a formatter that would convert the model value to uppercase: + + * ```js + * function format(value) { + * if (value) { + * return value.toUpperCase(); + * } + * } + * ngModel.$formatters.push(format); + * ``` + * + * @property {Object.} $validators A collection of validators that are applied + * whenever the model value changes. The key value within the object refers to the name of the + * validator while the function refers to the validation operation. The validation operation is + * provided with the model value as an argument and must return a true or false value depending + * on the response of that validation. + * + * ```js + * ngModel.$validators.validCharacters = function(modelValue, viewValue) { + * var value = modelValue || viewValue; + * return /[0-9]+/.test(value) && + * /[a-z]+/.test(value) && + * /[A-Z]+/.test(value) && + * /\W+/.test(value); + * }; + * ``` + * + * @property {Object.} $asyncValidators A collection of validations that are expected to + * perform an asynchronous validation (e.g. a HTTP request). The validation function that is provided + * is expected to return a promise when it is run during the model validation process. Once the promise + * is delivered then the validation status will be set to true when fulfilled and false when rejected. + * When the asynchronous validators are triggered, each of the validators will run in parallel and the model + * value will only be updated once all validators have been fulfilled. As long as an asynchronous validator + * is unfulfilled, its key will be added to the controllers `$pending` property. Also, all asynchronous validators + * will only run once all synchronous validators have passed. + * + * Please note that if $http is used then it is important that the server returns a success HTTP response code + * in order to fulfill the validation and a status level of `4xx` in order to reject the validation. + * + * ```js + * ngModel.$asyncValidators.uniqueUsername = function(modelValue, viewValue) { + * var value = modelValue || viewValue; + * + * // Lookup user by username + * return $http.get('/api/users/' + value). + * then(function resolved() { + * //username exists, this means validation fails + * return $q.reject('exists'); + * }, function rejected() { + * //username does not exist, therefore this validation passes + * return true; + * }); + * }; + * ``` + * + * @property {Array.} $viewChangeListeners Array of functions to execute whenever the + * view value has changed. It is called with no arguments, and its return value is ignored. + * This can be used in place of additional $watches against the model value. + * + * @property {Object} $error An object hash with all failing validator ids as keys. + * @property {Object} $pending An object hash with all pending validator ids as keys. + * + * @property {boolean} $untouched True if control has not lost focus yet. + * @property {boolean} $touched True if control has lost focus. + * @property {boolean} $pristine True if user has not interacted with the control yet. + * @property {boolean} $dirty True if user has already interacted with the control. + * @property {boolean} $valid True if there is no error. + * @property {boolean} $invalid True if at least one error on the control. + * @property {string} $name The name attribute of the control. + * + * @description + * + * `NgModelController` provides API for the {@link ngModel `ngModel`} directive. + * The controller contains services for data-binding, validation, CSS updates, and value formatting + * and parsing. It purposefully does not contain any logic which deals with DOM rendering or + * listening to DOM events. + * Such DOM related logic should be provided by other directives which make use of + * `NgModelController` for data-binding to control elements. + * Angular provides this DOM logic for most {@link input `input`} elements. + * At the end of this page you can find a {@link ngModel.NgModelController#custom-control-example + * custom control example} that uses `ngModelController` to bind to `contenteditable` elements. + * + * @example + * ### Custom Control Example + * This example shows how to use `NgModelController` with a custom control to achieve + * data-binding. Notice how different directives (`contenteditable`, `ng-model`, and `required`) + * collaborate together to achieve the desired result. + * + * `contenteditable` is an HTML5 attribute, which tells the browser to let the element + * contents be edited in place by the user. + * + * We are using the {@link ng.service:$sce $sce} service here and include the {@link ngSanitize $sanitize} + * module to automatically remove "bad" content like inline event listener (e.g. ``). + * However, as we are using `$sce` the model can still decide to provide unsafe content if it marks + * that content using the `$sce` service. + * + * + + [contenteditable] { + border: 1px solid black; + background-color: white; + min-height: 20px; + } + + .ng-invalid { + border: 1px solid red; + } + + + + angular.module('customControl', ['ngSanitize']). + directive('contenteditable', ['$sce', function($sce) { + return { + restrict: 'A', // only activate on element attribute + require: '?ngModel', // get a hold of NgModelController + link: function(scope, element, attrs, ngModel) { + if (!ngModel) return; // do nothing if no ng-model + + // Specify how UI should be updated + ngModel.$render = function() { + element.html($sce.getTrustedHtml(ngModel.$viewValue || '')); + }; + + // Listen for change events to enable binding + element.on('blur keyup change', function() { + scope.$evalAsync(read); + }); + read(); // initialize + + // Write data to the model + function read() { + var html = element.html(); + // When we clear the content editable the browser leaves a
behind + // If strip-br attribute is provided then we strip this out + if (attrs.stripBr && html === '
') { + html = ''; + } + ngModel.$setViewValue(html); + } + } + }; + }]); +
+ +
+
Change me!
+ Required! +
+ +
+
+ + it('should data-bind and become invalid', function() { + if (browser.params.browser === 'safari' || browser.params.browser === 'firefox') { + // SafariDriver can't handle contenteditable + // and Firefox driver can't clear contenteditables very well + return; + } + var contentEditable = element(by.css('[contenteditable]')); + var content = 'Change me!'; + + expect(contentEditable.getText()).toEqual(content); + + contentEditable.clear(); + contentEditable.sendKeys(protractor.Key.BACK_SPACE); + expect(contentEditable.getText()).toEqual(''); + expect(contentEditable.getAttribute('class')).toMatch(/ng-invalid-required/); + }); + + *
+ * + * + */ +NgModelController.$inject = ['$scope', '$exceptionHandler', '$attrs', '$element', '$parse', '$animate', '$timeout', '$q', '$interpolate']; +function NgModelController($scope, $exceptionHandler, $attr, $element, $parse, $animate, $timeout, $q, $interpolate) { + this.$viewValue = Number.NaN; + this.$modelValue = Number.NaN; + this.$$rawModelValue = undefined; // stores the parsed modelValue / model set from scope regardless of validity. + this.$validators = {}; + this.$asyncValidators = {}; + this.$parsers = []; + this.$formatters = []; + this.$viewChangeListeners = []; + this.$untouched = true; + this.$touched = false; this.$pristine = true; + this.$dirty = false; this.$valid = true; this.$invalid = false; - this.$submitted = false; + this.$error = {}; // keep invalid keys here + this.$$success = {}; // keep valid keys here + this.$pending = undefined; // keep pending keys here + this.$name = $interpolate($attr.name || '', false)($scope); this.$$parentForm = nullFormCtrl; + this.$options = defaultModelOptions; + + this.$$parsedNgModel = $parse($attr.ngModel); + this.$$parsedNgModelAssign = this.$$parsedNgModel.assign; + this.$$ngModelGet = this.$$parsedNgModel; + this.$$ngModelSet = this.$$parsedNgModelAssign; + this.$$pendingDebounce = null; + this.$$parserValid = undefined; + + this.$$currentValidationRunId = 0; + // https://github.com/angular/angular.js/issues/15833 + // Prevent `$$scope` from being iterated over by `copy` when NgModelController is deep watched + Object.defineProperty(this, '$$scope', {value: $scope}); + this.$$attr = $attr; this.$$element = $element; this.$$animate = $animate; + this.$$timeout = $timeout; + this.$$parse = $parse; + this.$$q = $q; + this.$$exceptionHandler = $exceptionHandler; setupValidity(this); + setupModelWatcher(this); } -FormController.prototype = { - /** - * @ngdoc method - * @name form.FormController#$rollbackViewValue - * - * @description - * Rollback all form controls pending updates to the `$modelValue`. - * - * Updates may be pending by a debounced event or because the input is waiting for a some future - * event defined in `ng-model-options`. This method is typically needed by the reset button of - * a form that uses `ng-model-options` to pend updates. - */ - $rollbackViewValue: function() { - forEach(this.$$controls, function(control) { - control.$rollbackViewValue(); - }); +NgModelController.prototype = { + $$initGetterSetters: function() { + if (this.$options.getOption('getterSetter')) { + var invokeModelGetter = this.$$parse(this.$$attr.ngModel + '()'), + invokeModelSetter = this.$$parse(this.$$attr.ngModel + '($$$p)'); + + this.$$ngModelGet = function($scope) { + var modelValue = this.$$parsedNgModel($scope); + if (isFunction(modelValue)) { + modelValue = invokeModelGetter($scope); + } + return modelValue; + }; + this.$$ngModelSet = function($scope, newValue) { + if (isFunction(this.$$parsedNgModel($scope))) { + invokeModelSetter($scope, {$$$p: newValue}); + } else { + this.$$parsedNgModelAssign($scope, newValue); + } + }; + } else if (!this.$$parsedNgModel.assign) { + throw ngModelMinErr('nonassign', 'Expression \'{0}\' is non-assignable. Element: {1}', + this.$$attr.ngModel, startingTag(this.$$element)); + } }, + /** * @ngdoc method - * @name form.FormController#$commitViewValue + * @name ngModel.NgModelController#$render * * @description - * Commit all form controls pending updates to the `$modelValue`. + * Called when the view needs to be updated. It is expected that the user of the ng-model + * directive will implement this method. * - * Updates may be pending by a debounced event or because the input is waiting for a some future - * event defined in `ng-model-options`. This method is rarely needed as `NgModelController` - * usually handles calling this in response to input events. + * The `$render()` method is invoked in the following situations: + * + * * `$rollbackViewValue()` is called. If we are rolling back the view value to the last + * committed value then `$render()` is called to update the input control. + * * The value referenced by `ng-model` is changed programmatically and both the `$modelValue` and + * the `$viewValue` are different from last time. + * + * Since `ng-model` does not do a deep watch, `$render()` is only invoked if the values of + * `$modelValue` and `$viewValue` are actually different from their previous values. If `$modelValue` + * or `$viewValue` are objects (rather than a string or number) then `$render()` will not be + * invoked if you only change a property on the objects. */ - $commitViewValue: function() { - forEach(this.$$controls, function(control) { - control.$commitViewValue(); - }); - }, + $render: noop, /** * @ngdoc method - * @name form.FormController#$addControl - * @param {object} control control object, either a {@link form.FormController} or an - * {@link ngModel.NgModelController} + * @name ngModel.NgModelController#$isEmpty * * @description - * Register a control with the form. Input elements using ngModelController do this automatically - * when they are linked. + * This is called when we need to determine if the value of an input is empty. * - * Note that the current state of the control will not be reflected on the new parent form. This - * is not an issue with normal use, as freshly compiled and linked controls are in a `$pristine` - * state. + * For instance, the required directive does this to work out if the input has data or not. * - * However, if the method is used programmatically, for example by adding dynamically created controls, - * or controls that have been previously removed without destroying their corresponding DOM element, - * it's the developers responsibility to make sure the current state propagates to the parent form. + * The default `$isEmpty` function checks whether the value is `undefined`, `''`, `null` or `NaN`. * - * For example, if an input control is added that is already `$dirty` and has `$error` properties, - * calling `$setDirty()` and `$validate()` afterwards will propagate the state to the parent form. + * You can override this for input directives whose concept of being empty is different from the + * default. The `checkboxInputType` directive does this because in its case a value of `false` + * implies empty. + * + * @param {*} value The value of the input to check for emptiness. + * @returns {boolean} True if `value` is "empty". */ - $addControl: function(control) { - // Breaking change - before, inputs whose name was "hasOwnProperty" were quietly ignored - // and not added to the scope. Now we throw an error. - assertNotHasOwnProperty(control.$name, 'input'); - this.$$controls.push(control); - - if (control.$name) { - this[control.$name] = control; - } - - control.$$parentForm = this; + $isEmpty: function(value) { + // eslint-disable-next-line no-self-compare + return isUndefined(value) || value === '' || value === null || value !== value; }, - // Private API: rename a form control - $$renameControl: function(control, newName) { - var oldName = control.$name; - - if (this[oldName] === control) { - delete this[oldName]; + $$updateEmptyClasses: function(value) { + if (this.$isEmpty(value)) { + this.$$animate.removeClass(this.$$element, NOT_EMPTY_CLASS); + this.$$animate.addClass(this.$$element, EMPTY_CLASS); + } else { + this.$$animate.removeClass(this.$$element, EMPTY_CLASS); + this.$$animate.addClass(this.$$element, NOT_EMPTY_CLASS); } - this[newName] = control; - control.$name = newName; }, /** * @ngdoc method - * @name form.FormController#$removeControl - * @param {object} control control object, either a {@link form.FormController} or an - * {@link ngModel.NgModelController} + * @name ngModel.NgModelController#$setPristine * * @description - * Deregister a control from the form. - * - * Input elements using ngModelController do this automatically when they are destroyed. + * Sets the control to its pristine state. * - * Note that only the removed control's validation state (`$errors`etc.) will be removed from the - * form. `$dirty`, `$submitted` states will not be changed, because the expected behavior can be - * different from case to case. For example, removing the only `$dirty` control from a form may or - * may not mean that the form is still `$dirty`. + * This method can be called to remove the `ng-dirty` class and set the control to its pristine + * state (`ng-pristine` class). A model is considered to be pristine when the control + * has not been changed from when first compiled. */ - $removeControl: function(control) { - if (control.$name && this[control.$name] === control) { - delete this[control.$name]; - } - forEach(this.$pending, function(value, name) { - // eslint-disable-next-line no-invalid-this - this.$setValidity(name, null, control); - }, this); - forEach(this.$error, function(value, name) { - // eslint-disable-next-line no-invalid-this - this.$setValidity(name, null, control); - }, this); - forEach(this.$$success, function(value, name) { - // eslint-disable-next-line no-invalid-this - this.$setValidity(name, null, control); - }, this); - - arrayRemove(this.$$controls, control); - control.$$parentForm = nullFormCtrl; + $setPristine: function() { + this.$dirty = false; + this.$pristine = true; + this.$$animate.removeClass(this.$$element, DIRTY_CLASS); + this.$$animate.addClass(this.$$element, PRISTINE_CLASS); }, /** * @ngdoc method - * @name form.FormController#$setDirty + * @name ngModel.NgModelController#$setDirty * * @description - * Sets the form to a dirty state. + * Sets the control to its dirty state. * - * This method can be called to add the 'ng-dirty' class and set the form to a dirty - * state (ng-dirty class). This method will also propagate to parent forms. + * This method can be called to remove the `ng-pristine` class and set the control to its dirty + * state (`ng-dirty` class). A model is considered to be dirty when the control has been changed + * from when first compiled. */ $setDirty: function() { - this.$$animate.removeClass(this.$$element, PRISTINE_CLASS); - this.$$animate.addClass(this.$$element, DIRTY_CLASS); this.$dirty = true; this.$pristine = false; + this.$$animate.removeClass(this.$$element, PRISTINE_CLASS); + this.$$animate.addClass(this.$$element, DIRTY_CLASS); this.$$parentForm.$setDirty(); }, /** * @ngdoc method - * @name form.FormController#$setPristine + * @name ngModel.NgModelController#$setUntouched * * @description - * Sets the form to its pristine state. - * - * This method sets the form's `$pristine` state to true, the `$dirty` state to false, removes - * the `ng-dirty` class and adds the `ng-pristine` class. Additionally, it sets the `$submitted` - * state to false. - * - * This method will also propagate to all the controls contained in this form. + * Sets the control to its untouched state. * - * Setting a form back to a pristine state is often useful when we want to 'reuse' a form after - * saving or resetting it. + * This method can be called to remove the `ng-touched` class and set the control to its + * untouched state (`ng-untouched` class). Upon compilation, a model is set as untouched + * by default, however this function can be used to restore that state if the model has + * already been touched by the user. */ - $setPristine: function() { - this.$$animate.setClass(this.$$element, PRISTINE_CLASS, DIRTY_CLASS + ' ' + SUBMITTED_CLASS); - this.$dirty = false; - this.$pristine = true; - this.$submitted = false; - forEach(this.$$controls, function(control) { - control.$setPristine(); - }); + $setUntouched: function() { + this.$touched = false; + this.$untouched = true; + this.$$animate.setClass(this.$$element, UNTOUCHED_CLASS, TOUCHED_CLASS); }, /** * @ngdoc method - * @name form.FormController#$setUntouched + * @name ngModel.NgModelController#$setTouched * * @description - * Sets the form to its untouched state. - * - * This method can be called to remove the 'ng-touched' class and set the form controls to their - * untouched state (ng-untouched class). + * Sets the control to its touched state. * - * Setting a form controls back to their untouched state is often useful when setting the form - * back to its pristine state. + * This method can be called to remove the `ng-untouched` class and set the control to its + * touched state (`ng-touched` class). A model is considered to be touched when the user has + * first focused the control element and then shifted focus away from the control (blur event). */ - $setUntouched: function() { - forEach(this.$$controls, function(control) { - control.$setUntouched(); - }); + $setTouched: function() { + this.$touched = true; + this.$untouched = false; + this.$$animate.setClass(this.$$element, TOUCHED_CLASS, UNTOUCHED_CLASS); }, /** * @ngdoc method - * @name form.FormController#$setSubmitted + * @name ngModel.NgModelController#$rollbackViewValue * * @description - * Sets the form to its submitted state. - */ - $setSubmitted: function() { - this.$$animate.addClass(this.$$element, SUBMITTED_CLASS); - this.$submitted = true; - this.$$parentForm.$setSubmitted(); - } -}; - -/** - * @ngdoc method - * @name form.FormController#$setValidity - * - * @description - * Change the validity state of the form, and notify the parent form (if any). - * - * Application developers will rarely need to call this method directly. It is used internally, by - * {@link ngModel.NgModelController#$setValidity NgModelController.$setValidity()}, to propagate a - * control's validity state to the parent `FormController`. - * - * @param {string} validationErrorKey Name of the validator. The `validationErrorKey` will be - * assigned to either `$error[validationErrorKey]` or `$pending[validationErrorKey]` (for - * unfulfilled `$asyncValidators`), so that it is available for data-binding. The - * `validationErrorKey` should be in camelCase and will get converted into dash-case for - * class name. Example: `myError` will result in `ng-valid-my-error` and - * `ng-invalid-my-error` classes and can be bound to as `{{ someForm.$error.myError }}`. - * @param {boolean} isValid Whether the current state is valid (true), invalid (false), pending - * (undefined), or skipped (null). Pending is used for unfulfilled `$asyncValidators`. - * Skipped is used by AngularJS when validators do not run because of parse errors and when - * `$asyncValidators` do not run because any of the `$validators` failed. - * @param {NgModelController | FormController} controller - The controller whose validity state is - * triggering the change. - */ -addSetValidityMethod({ - clazz: FormController, - set: function(object, property, controller) { - var list = object[property]; - if (!list) { - object[property] = [controller]; - } else { - var index = list.indexOf(controller); - if (index === -1) { - list.push(controller); - } - } - }, - unset: function(object, property, controller) { - var list = object[property]; - if (!list) { - return; - } - arrayRemove(list, controller); - if (list.length === 0) { - delete object[property]; - } - } -}); - -/** - * @ngdoc directive - * @name ngForm - * @restrict EAC + * Cancel an update and reset the input element's value to prevent an update to the `$modelValue`, + * which may be caused by a pending debounced event or because the input is waiting for some + * future event. + * + * If you have an input that uses `ng-model-options` to set up debounced updates or updates that + * depend on special events such as `blur`, there can be a period when the `$viewValue` is out of + * sync with the ngModel's `$modelValue`. + * + * In this case, you can use `$rollbackViewValue()` to manually cancel the debounced / future update + * and reset the input to the last committed view value. + * + * It is also possible that you run into difficulties if you try to update the ngModel's `$modelValue` + * programmatically before these debounced/future events have resolved/occurred, because Angular's + * dirty checking mechanism is not able to tell whether the model has actually changed or not. + * + * The `$rollbackViewValue()` method should be called before programmatically changing the model of an + * input which may have such events pending. This is important in order to make sure that the + * input field will be updated with the new model value and any pending operations are cancelled. + * + * + * + * angular.module('cancel-update-example', []) + * + * .controller('CancelUpdateController', ['$scope', function($scope) { + * $scope.model = {value1: '', value2: ''}; + * + * $scope.setEmpty = function(e, value, rollback) { + * if (e.keyCode === 27) { + * e.preventDefault(); + * if (rollback) { + * $scope.myForm[value].$rollbackViewValue(); + * } + * $scope.model[value] = ''; + * } + * }; + * }]); + * + * + *
+ *

Both of these inputs are only updated if they are blurred. Hitting escape should + * empty them. Follow these steps and observe the difference:

+ *
    + *
  1. Type something in the input. You will see that the model is not yet updated
  2. + *
  3. Press the Escape key. + *
      + *
    1. In the first example, nothing happens, because the model is already '', and no + * update is detected. If you blur the input, the model will be set to the current view. + *
    2. + *
    3. In the second example, the pending update is cancelled, and the input is set back + * to the last committed view value (''). Blurring the input does nothing. + *
    4. + *
    + *
  4. + *
+ * + *
+ *
+ *

Without $rollbackViewValue():

+ * + * value1: "{{ model.value1 }}" + *
+ * + *
+ *

With $rollbackViewValue():

+ * + * value2: "{{ model.value2 }}" + *
+ *
+ *
+ *
+ + div { + display: table-cell; + } + div:nth-child(1) { + padding-right: 30px; + } + + + *
+ */ + $rollbackViewValue: function() { + this.$$timeout.cancel(this.$$pendingDebounce); + this.$viewValue = this.$$lastCommittedViewValue; + this.$render(); + }, + + /** + * @ngdoc method + * @name ngModel.NgModelController#$validate + * + * @description + * Runs each of the registered validators (first synchronous validators and then + * asynchronous validators). + * If the validity changes to invalid, the model will be set to `undefined`, + * unless {@link ngModelOptions `ngModelOptions.allowInvalid`} is `true`. + * If the validity changes to valid, it will set the model to the last available valid + * `$modelValue`, i.e. either the last parsed value or the last value set from the scope. + */ + $validate: function() { + // ignore $validate before model is initialized + if (isNumberNaN(this.$modelValue)) { + return; + } + + var viewValue = this.$$lastCommittedViewValue; + // Note: we use the $$rawModelValue as $modelValue might have been + // set to undefined during a view -> model update that found validation + // errors. We can't parse the view here, since that could change + // the model although neither viewValue nor the model on the scope changed + var modelValue = this.$$rawModelValue; + + var prevValid = this.$valid; + var prevModelValue = this.$modelValue; + + var allowInvalid = this.$options.getOption('allowInvalid'); + + var that = this; + this.$$runValidators(modelValue, viewValue, function(allValid) { + // If there was no change in validity, don't update the model + // This prevents changing an invalid modelValue to undefined + if (!allowInvalid && prevValid !== allValid) { + // Note: Don't check this.$valid here, as we could have + // external validators (e.g. calculated on the server), + // that just call $setValidity and need the model value + // to calculate their validity. + that.$modelValue = allValid ? modelValue : undefined; + + if (that.$modelValue !== prevModelValue) { + that.$$writeModelToScope(); + } + } + }); + }, + + $$runValidators: function(modelValue, viewValue, doneCallback) { + this.$$currentValidationRunId++; + var localValidationRunId = this.$$currentValidationRunId; + var that = this; + + // check parser error + if (!processParseErrors()) { + validationDone(false); + return; + } + if (!processSyncValidators()) { + validationDone(false); + return; + } + processAsyncValidators(); + + function processParseErrors() { + var errorKey = that.$$parserName || 'parse'; + if (isUndefined(that.$$parserValid)) { + setValidity(errorKey, null); + } else { + if (!that.$$parserValid) { + forEach(that.$validators, function(v, name) { + setValidity(name, null); + }); + forEach(that.$asyncValidators, function(v, name) { + setValidity(name, null); + }); + } + // Set the parse error last, to prevent unsetting it, should a $validators key == parserName + setValidity(errorKey, that.$$parserValid); + return that.$$parserValid; + } + return true; + } + + function processSyncValidators() { + var syncValidatorsValid = true; + forEach(that.$validators, function(validator, name) { + var result = Boolean(validator(modelValue, viewValue)); + syncValidatorsValid = syncValidatorsValid && result; + setValidity(name, result); + }); + if (!syncValidatorsValid) { + forEach(that.$asyncValidators, function(v, name) { + setValidity(name, null); + }); + return false; + } + return true; + } + + function processAsyncValidators() { + var validatorPromises = []; + var allValid = true; + forEach(that.$asyncValidators, function(validator, name) { + var promise = validator(modelValue, viewValue); + if (!isPromiseLike(promise)) { + throw ngModelMinErr('nopromise', + 'Expected asynchronous validator to return a promise but got \'{0}\' instead.', promise); + } + setValidity(name, undefined); + validatorPromises.push(promise.then(function() { + setValidity(name, true); + }, function() { + allValid = false; + setValidity(name, false); + })); + }); + if (!validatorPromises.length) { + validationDone(true); + } else { + that.$$q.all(validatorPromises).then(function() { + validationDone(allValid); + }, noop); + } + } + + function setValidity(name, isValid) { + if (localValidationRunId === that.$$currentValidationRunId) { + that.$setValidity(name, isValid); + } + } + + function validationDone(allValid) { + if (localValidationRunId === that.$$currentValidationRunId) { + + doneCallback(allValid); + } + } + }, + + /** + * @ngdoc method + * @name ngModel.NgModelController#$commitViewValue + * + * @description + * Commit a pending update to the `$modelValue`. + * + * Updates may be pending by a debounced event or because the input is waiting for a some future + * event defined in `ng-model-options`. this method is rarely needed as `NgModelController` + * usually handles calling this in response to input events. + */ + $commitViewValue: function() { + var viewValue = this.$viewValue; + + this.$$timeout.cancel(this.$$pendingDebounce); + + // If the view value has not changed then we should just exit, except in the case where there is + // a native validator on the element. In this case the validation state may have changed even though + // the viewValue has stayed empty. + if (this.$$lastCommittedViewValue === viewValue && (viewValue !== '' || !this.$$hasNativeValidators)) { + return; + } + this.$$updateEmptyClasses(viewValue); + this.$$lastCommittedViewValue = viewValue; + + // change to dirty + if (this.$pristine) { + this.$setDirty(); + } + this.$$parseAndValidate(); + }, + + $$parseAndValidate: function() { + var viewValue = this.$$lastCommittedViewValue; + var modelValue = viewValue; + var that = this; + + this.$$parserValid = isUndefined(modelValue) ? undefined : true; + + if (this.$$parserValid) { + for (var i = 0; i < this.$parsers.length; i++) { + modelValue = this.$parsers[i](modelValue); + if (isUndefined(modelValue)) { + this.$$parserValid = false; + break; + } + } + } + if (isNumberNaN(this.$modelValue)) { + // this.$modelValue has not been touched yet... + this.$modelValue = this.$$ngModelGet(this.$$scope); + } + var prevModelValue = this.$modelValue; + var allowInvalid = this.$options.getOption('allowInvalid'); + this.$$rawModelValue = modelValue; + + if (allowInvalid) { + this.$modelValue = modelValue; + writeToModelIfNeeded(); + } + + // Pass the $$lastCommittedViewValue here, because the cached viewValue might be out of date. + // This can happen if e.g. $setViewValue is called from inside a parser + this.$$runValidators(modelValue, this.$$lastCommittedViewValue, function(allValid) { + if (!allowInvalid) { + // Note: Don't check this.$valid here, as we could have + // external validators (e.g. calculated on the server), + // that just call $setValidity and need the model value + // to calculate their validity. + that.$modelValue = allValid ? modelValue : undefined; + writeToModelIfNeeded(); + } + }); + + function writeToModelIfNeeded() { + if (that.$modelValue !== prevModelValue) { + that.$$writeModelToScope(); + } + } + }, + + $$writeModelToScope: function() { + this.$$ngModelSet(this.$$scope, this.$modelValue); + forEach(this.$viewChangeListeners, function(listener) { + try { + listener(); + } catch (e) { + // eslint-disable-next-line no-invalid-this + this.$$exceptionHandler(e); + } + }, this); + }, + + /** + * @ngdoc method + * @name ngModel.NgModelController#$setViewValue + * + * @description + * Update the view value. + * + * This method should be called when a control wants to change the view value; typically, + * this is done from within a DOM event handler. For example, the {@link ng.directive:input input} + * directive calls it when the value of the input changes and {@link ng.directive:select select} + * calls it when an option is selected. + * + * When `$setViewValue` is called, the new `value` will be staged for committing through the `$parsers` + * and `$validators` pipelines. If there are no special {@link ngModelOptions} specified then the staged + * value is sent directly for processing through the `$parsers` pipeline. After this, the `$validators` and + * `$asyncValidators` are called and the value is applied to `$modelValue`. + * Finally, the value is set to the **expression** specified in the `ng-model` attribute and + * all the registered change listeners, in the `$viewChangeListeners` list are called. + * + * In case the {@link ng.directive:ngModelOptions ngModelOptions} directive is used with `updateOn` + * and the `default` trigger is not listed, all those actions will remain pending until one of the + * `updateOn` events is triggered on the DOM element. + * All these actions will be debounced if the {@link ng.directive:ngModelOptions ngModelOptions} + * directive is used with a custom debounce for this particular event. + * Note that a `$digest` is only triggered once the `updateOn` events are fired, or if `debounce` + * is specified, once the timer runs out. + * + * When used with standard inputs, the view value will always be a string (which is in some cases + * parsed into another type, such as a `Date` object for `input[date]`.) + * However, custom controls might also pass objects to this method. In this case, we should make + * a copy of the object before passing it to `$setViewValue`. This is because `ngModel` does not + * perform a deep watch of objects, it only looks for a change of identity. If you only change + * the property of the object then ngModel will not realize that the object has changed and + * will not invoke the `$parsers` and `$validators` pipelines. For this reason, you should + * not change properties of the copy once it has been passed to `$setViewValue`. + * Otherwise you may cause the model value on the scope to change incorrectly. + * + *
+ * In any case, the value passed to the method should always reflect the current value + * of the control. For example, if you are calling `$setViewValue` for an input element, + * you should pass the input DOM value. Otherwise, the control and the scope model become + * out of sync. It's also important to note that `$setViewValue` does not call `$render` or change + * the control's DOM value in any way. If we want to change the control's DOM value + * programmatically, we should update the `ngModel` scope expression. Its new value will be + * picked up by the model controller, which will run it through the `$formatters`, `$render` it + * to update the DOM, and finally call `$validate` on it. + *
+ * + * @param {*} value value from the view. + * @param {string} trigger Event that triggered the update. + */ + $setViewValue: function(value, trigger) { + this.$viewValue = value; + if (this.$options.getOption('updateOnDefault')) { + this.$$debounceViewValueCommit(trigger); + } + }, + + $$debounceViewValueCommit: function(trigger) { + var debounceDelay = this.$options.getOption('debounce'); + + if (isNumber(debounceDelay[trigger])) { + debounceDelay = debounceDelay[trigger]; + } else if (isNumber(debounceDelay['default'])) { + debounceDelay = debounceDelay['default']; + } + + this.$$timeout.cancel(this.$$pendingDebounce); + var that = this; + if (debounceDelay > 0) { // this fails if debounceDelay is an object + this.$$pendingDebounce = this.$$timeout(function() { + that.$commitViewValue(); + }, debounceDelay); + } else if (this.$$scope.$root.$$phase) { + this.$commitViewValue(); + } else { + this.$$scope.$apply(function() { + that.$commitViewValue(); + }); + } + }, + + /** + * @ngdoc method + * + * @name ngModel.NgModelController#$overrideModelOptions + * + * @description + * + * Override the current model options settings programmatically. + * + * The previous `ModelOptions` value will not be modified. Instead, a + * new `ModelOptions` object will inherit from the previous one overriding + * or inheriting settings that are defined in the given parameter. + * + * See {@link ngModelOptions} for information about what options can be specified + * and how model option inheritance works. + * + * @param {Object} options a hash of settings to override the previous options + * + */ + $overrideModelOptions: function(options) { + this.$options = this.$options.createChild(options); + } +}; + +function setupModelWatcher(ctrl) { + // model -> value + // Note: we cannot use a normal scope.$watch as we want to detect the following: + // 1. scope value is 'a' + // 2. user enters 'b' + // 3. ng-change kicks in and reverts scope value to 'a' + // -> scope value did not change since the last digest as + // ng-change executes in apply phase + // 4. view should be changed back to 'a' + ctrl.$$scope.$watch(function ngModelWatch(scope) { + var modelValue = ctrl.$$ngModelGet(scope); + + // if scope model value and ngModel value are out of sync + // TODO(perf): why not move this to the action fn? + if (modelValue !== ctrl.$modelValue && + // checks for NaN is needed to allow setting the model to NaN when there's an asyncValidator + // eslint-disable-next-line no-self-compare + (ctrl.$modelValue === ctrl.$modelValue || modelValue === modelValue) + ) { + ctrl.$modelValue = ctrl.$$rawModelValue = modelValue; + ctrl.$$parserValid = undefined; + + var formatters = ctrl.$formatters, + idx = formatters.length; + + var viewValue = modelValue; + while (idx--) { + viewValue = formatters[idx](viewValue); + } + if (ctrl.$viewValue !== viewValue) { + ctrl.$$updateEmptyClasses(viewValue); + ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue; + ctrl.$render(); + + // It is possible that model and view value have been updated during render + ctrl.$$runValidators(ctrl.$modelValue, ctrl.$viewValue, noop); + } + } + + return modelValue; + }); +} + +/** + * @ngdoc method + * @name ngModel.NgModelController#$setValidity * * @description - * Nestable alias of {@link ng.directive:form `form`} directive. HTML - * does not allow nesting of form elements. It is useful to nest forms, for example if the validity of a - * sub-group of controls needs to be determined. - * - * Note: the purpose of `ngForm` is to group controls, - * but not to be a replacement for the `
` tag with all of its capabilities - * (e.g. posting to the server, ...). + * Change the validity state, and notify the form. * - * @param {string=} ngForm|name Name of the form. If specified, the form controller will be published into - * related scope, under this name. + * This method can be called within $parsers/$formatters or a custom validation implementation. + * However, in most cases it should be sufficient to use the `ngModel.$validators` and + * `ngModel.$asyncValidators` collections which will call `$setValidity` automatically. * + * @param {string} validationErrorKey Name of the validator. The `validationErrorKey` will be assigned + * to either `$error[validationErrorKey]` or `$pending[validationErrorKey]` + * (for unfulfilled `$asyncValidators`), so that it is available for data-binding. + * The `validationErrorKey` should be in camelCase and will get converted into dash-case + * for class name. Example: `myError` will result in `ng-valid-my-error` and `ng-invalid-my-error` + * classes and can be bound to as `{{ someForm.someControl.$error.myError }}`. + * @param {boolean} isValid Whether the current state is valid (true), invalid (false), pending (undefined), + * or skipped (null). Pending is used for unfulfilled `$asyncValidators`. + * Skipped is used by Angular when validators do not run because of parse errors and + * when `$asyncValidators` do not run because any of the `$validators` failed. */ +addSetValidityMethod({ + clazz: NgModelController, + set: function(object, property) { + object[property] = true; + }, + unset: function(object, property) { + delete object[property]; + } +}); - /** + +/** * @ngdoc directive - * @name form - * @restrict E + * @name ngModel + * + * @element input + * @priority 1 * * @description - * Directive that instantiates - * {@link form.FormController FormController}. + * The `ngModel` directive binds an `input`,`select`, `textarea` (or custom form control) to a + * property on the scope using {@link ngModel.NgModelController NgModelController}, + * which is created and exposed by this directive. * - * If the `name` attribute is specified, the form controller is published onto the current scope under - * this name. + * `ngModel` is responsible for: * - * # Alias: {@link ng.directive:ngForm `ngForm`} + * - Binding the view into the model, which other directives such as `input`, `textarea` or `select` + * require. + * - Providing validation behavior (i.e. required, number, email, url). + * - Keeping the state of the control (valid/invalid, dirty/pristine, touched/untouched, validation errors). + * - Setting related css classes on the element (`ng-valid`, `ng-invalid`, `ng-dirty`, `ng-pristine`, `ng-touched`, + * `ng-untouched`, `ng-empty`, `ng-not-empty`) including animations. + * - Registering the control with its parent {@link ng.directive:form form}. * - * In Angular, forms can be nested. This means that the outer form is valid when all of the child - * forms are valid as well. However, browsers do not allow nesting of `` elements, so - * Angular provides the {@link ng.directive:ngForm `ngForm`} directive, which behaves identically to - * `form` but can be nested. Nested forms can be useful, for example, if the validity of a sub-group - * of controls needs to be determined. + * Note: `ngModel` will try to bind to the property given by evaluating the expression on the + * current scope. If the property doesn't already exist on this scope, it will be created + * implicitly and added to the scope. * - * # CSS classes - * - `ng-valid` is set if the form is valid. - * - `ng-invalid` is set if the form is invalid. - * - `ng-pending` is set if the form is pending. - * - `ng-pristine` is set if the form is pristine. - * - `ng-dirty` is set if the form is dirty. - * - `ng-submitted` is set if the form was submitted. + * For best practices on using `ngModel`, see: * - * Keep in mind that ngAnimate can detect each of these classes when added and removed. + * - [Understanding Scopes](https://github.com/angular/angular.js/wiki/Understanding-Scopes) * + * For basic examples, how to use `ngModel`, see: * - * # Submitting a form and preventing the default action + * - {@link ng.directive:input input} + * - {@link input[text] text} + * - {@link input[checkbox] checkbox} + * - {@link input[radio] radio} + * - {@link input[number] number} + * - {@link input[email] email} + * - {@link input[url] url} + * - {@link input[date] date} + * - {@link input[datetime-local] datetime-local} + * - {@link input[time] time} + * - {@link input[month] month} + * - {@link input[week] week} + * - {@link ng.directive:select select} + * - {@link ng.directive:textarea textarea} * - * Since the role of forms in client-side Angular applications is different than in classical - * roundtrip apps, it is desirable for the browser not to translate the form submission into a full - * page reload that sends the data to the server. Instead some javascript logic should be triggered - * to handle the form submission in an application-specific way. + * # Complex Models (objects or collections) * - * For this reason, Angular prevents the default action (form submission to the server) unless the - * `` element has an `action` attribute specified. + * By default, `ngModel` watches the model by reference, not value. This is important to know when + * binding inputs to models that are objects (e.g. `Date`) or collections (e.g. arrays). If only properties of the + * object or collection change, `ngModel` will not be notified and so the input will not be re-rendered. * - * You can use one of the following two ways to specify what javascript method should be called when - * a form is submitted: + * The model must be assigned an entirely new object or collection before a re-rendering will occur. * - * - {@link ng.directive:ngSubmit ngSubmit} directive on the form element - * - {@link ng.directive:ngClick ngClick} directive on the first - * button or input field of type submit (input[type=submit]) + * Some directives have options that will cause them to use a custom `$watchCollection` on the model expression + * - for example, `ngOptions` will do so when a `track by` clause is included in the comprehension expression or + * if the select is given the `multiple` attribute. * - * To prevent double execution of the handler, use only one of the {@link ng.directive:ngSubmit ngSubmit} - * or {@link ng.directive:ngClick ngClick} directives. - * This is because of the following form submission rules in the HTML specification: + * The `$watchCollection()` method only does a shallow comparison, meaning that changing properties deeper than the + * first level of the object (or only changing the properties of an item in the collection if it's an array) will still + * not trigger a re-rendering of the model. * - * - If a form has only one input field then hitting enter in this field triggers form submit - * (`ngSubmit`) - * - if a form has 2+ input fields and no buttons or input[type=submit] then hitting enter - * doesn't trigger submit - * - if a form has one or more input fields and one or more buttons or input[type=submit] then - * hitting enter in any of the input fields will trigger the click handler on the *first* button or - * input[type=submit] (`ngClick`) *and* a submit handler on the enclosing form (`ngSubmit`) + * # CSS classes + * The following CSS classes are added and removed on the associated input/select/textarea element + * depending on the validity of the model. * - * Any pending `ngModelOptions` changes will take place immediately when an enclosing form is - * submitted. Note that `ngClick` events will occur before the model is updated. Use `ngSubmit` - * to have access to the updated model. + * - `ng-valid`: the model is valid + * - `ng-invalid`: the model is invalid + * - `ng-valid-[key]`: for each valid key added by `$setValidity` + * - `ng-invalid-[key]`: for each invalid key added by `$setValidity` + * - `ng-pristine`: the control hasn't been interacted with yet + * - `ng-dirty`: the control has been interacted with + * - `ng-touched`: the control has been blurred + * - `ng-untouched`: the control hasn't been blurred + * - `ng-pending`: any `$asyncValidators` are unfulfilled + * - `ng-empty`: the view does not contain a value or the value is deemed "empty", as defined + * by the {@link ngModel.NgModelController#$isEmpty} method + * - `ng-not-empty`: the view contains a non-empty value + * + * Keep in mind that ngAnimate can detect each of these classes when added and removed. * * ## Animation Hooks * - * Animations in ngForm are triggered when any of the associated CSS classes are added and removed. - * These classes are: `.ng-pristine`, `.ng-dirty`, `.ng-invalid` and `.ng-valid` as well as any - * other validations that are performed within the form. Animations in ngForm are similar to how - * they work in ngClass and animations can be hooked into using CSS transitions, keyframes as well - * as JS animations. + * Animations within models are triggered when any of the associated CSS classes are added and removed + * on the input element which is attached to the model. These classes include: `.ng-pristine`, `.ng-dirty`, + * `.ng-invalid` and `.ng-valid` as well as any other validations that are performed on the model itself. + * The animations that are triggered within ngModel are similar to how they work in ngClass and + * animations can be hooked into using CSS transitions, keyframes as well as JS animations. * - * The following example shows a simple way to utilize CSS transitions to style a form element + * The following example shows a simple way to utilize CSS transitions to style an input element * that has been rendered as invalid after it has been validated: * *
  * //be sure to include ngAnimate as a module to hook into more
  * //advanced animations
- * .my-form {
+ * .my-input {
  *   transition:0.5s linear all;
  *   background: white;
  * }
- * .my-form.ng-invalid {
+ * .my-input.ng-invalid {
  *   background: red;
  *   color:white;
  * }
  * 
* * @example - - + * + - - userType: - Required!
- userType = {{userType}}
- myForm.input.$valid = {{myForm.input.$valid}}
- myForm.input.$error = {{myForm.input.$error}}
- myForm.$valid = {{myForm.$valid}}
- myForm.$error.required = {{!!myForm.$error.required}}
- -
- - it('should initialize to model', function() { - var userType = element(by.binding('userType')); - var valid = element(by.binding('myForm.input.$valid')); - - expect(userType.getText()).toContain('guest'); - expect(valid.getText()).toContain('true'); - }); - - it('should be invalid if empty', function() { - var userType = element(by.binding('userType')); - var valid = element(by.binding('myForm.input.$valid')); - var userInput = element(by.model('userType')); - - userInput.clear(); - userInput.sendKeys(''); - - expect(userType.getText()).toEqual('userType ='); - expect(valid.getText()).toContain('false'); - }); - -
+

+ Update input to see transitions when valid/invalid. + Integer is a valid value. +

+
+ +
+
+ *
* - * @param {string=} name Name of the form. If specified, the form controller will be published into - * related scope, under this name. + * ## Binding to a getter/setter + * + * Sometimes it's helpful to bind `ngModel` to a getter/setter function. A getter/setter is a + * function that returns a representation of the model when called with zero arguments, and sets + * the internal state of a model when called with an argument. It's sometimes useful to use this + * for models that have an internal representation that's different from what the model exposes + * to the view. + * + *
+ * **Best Practice:** It's best to keep getters fast because Angular is likely to call them more + * frequently than other parts of your code. + *
+ * + * You use this behavior by adding `ng-model-options="{ getterSetter: true }"` to an element that + * has `ng-model` attached to it. You can also add `ng-model-options="{ getterSetter: true }"` to + * a `
`, which will enable this behavior for all ``s within it. See + * {@link ng.directive:ngModelOptions `ngModelOptions`} for more. + * + * The following example shows how to use `ngModel` with a getter/setter: + * + * @example + * + +
+ + + +
user.name = 
+
+
+ + angular.module('getterSetterExample', []) + .controller('ExampleController', ['$scope', function($scope) { + var _name = 'Brian'; + $scope.user = { + name: function(newName) { + // Note that newName can be undefined for two reasons: + // 1. Because it is called as a getter and thus called with no arguments + // 2. Because the property should actually be set to undefined. This happens e.g. if the + // input is invalid + return arguments.length ? (_name = newName) : _name; + } + }; + }]); + + *
*/ -var formDirectiveFactory = function(isNgForm) { - return ['$timeout', '$parse', function($timeout, $parse) { - var formDirective = { - name: 'form', - restrict: isNgForm ? 'EAC' : 'E', - require: ['form', '^^?form'], //first is the form's own ctrl, second is an optional parent form - controller: FormController, - compile: function ngFormCompile(formElement, attr) { - // Setup initial state of the control - formElement.addClass(PRISTINE_CLASS).addClass(VALID_CLASS); - - var nameAttr = attr.name ? 'name' : (isNgForm && attr.ngForm ? 'ngForm' : false); +var ngModelDirective = ['$rootScope', function($rootScope) { + return { + restrict: 'A', + require: ['ngModel', '^?form', '^?ngModelOptions'], + controller: NgModelController, + // Prelink needs to run before any input directive + // so that we can set the NgModelOptions in NgModelController + // before anyone else uses it. + priority: 1, + compile: function ngModelCompile(element) { + // Setup initial state of the control + element.addClass(PRISTINE_CLASS).addClass(UNTOUCHED_CLASS).addClass(VALID_CLASS); - return { - pre: function ngFormPreLink(scope, formElement, attr, ctrls) { - var controller = ctrls[0]; + return { + pre: function ngModelPreLink(scope, element, attr, ctrls) { + var modelCtrl = ctrls[0], + formCtrl = ctrls[1] || modelCtrl.$$parentForm, + optionsCtrl = ctrls[2]; - // if `action` attr is not present on the form, prevent the default action (submission) - if (!('action' in attr)) { - // we can't use jq events because if a form is destroyed during submission the default - // action is not prevented. see #1238 - // - // IE 9 is not affected because it doesn't fire a submit event and try to do a full - // page reload if the form was destroyed by submission of the form via a click handler - // on a button in the form. Looks like an IE9 specific bug. - var handleFormSubmission = function(event) { - scope.$apply(function() { - controller.$commitViewValue(); - controller.$setSubmitted(); - }); + if (optionsCtrl) { + modelCtrl.$options = optionsCtrl.$options; + } - event.preventDefault(); - }; + modelCtrl.$$initGetterSetters(); - formElement[0].addEventListener('submit', handleFormSubmission); + // notify others, especially parent forms + formCtrl.$addControl(modelCtrl); - // unregister the preventDefault listener so that we don't not leak memory but in a - // way that will achieve the prevention of the default action. - formElement.on('$destroy', function() { - $timeout(function() { - formElement[0].removeEventListener('submit', handleFormSubmission); - }, 0, false); - }); + attr.$observe('name', function(newValue) { + if (modelCtrl.$name !== newValue) { + modelCtrl.$$parentForm.$$renameControl(modelCtrl, newValue); } + }); - var parentFormCtrl = ctrls[1] || controller.$$parentForm; - parentFormCtrl.$addControl(controller); - - var setter = nameAttr ? getSetter(controller.$name) : noop; - - if (nameAttr) { - setter(scope, controller); - attr.$observe(nameAttr, function(newValue) { - if (controller.$name === newValue) return; - setter(scope, undefined); - controller.$$parentForm.$$renameControl(controller, newValue); - setter = getSetter(controller.$name); - setter(scope, controller); - }); - } - formElement.on('$destroy', function() { - controller.$$parentForm.$removeControl(controller); - setter(scope, undefined); - extend(controller, nullFormCtrl); //stop propagating child destruction handlers upwards + scope.$on('$destroy', function() { + modelCtrl.$$parentForm.$removeControl(modelCtrl); + }); + }, + post: function ngModelPostLink(scope, element, attr, ctrls) { + var modelCtrl = ctrls[0]; + if (modelCtrl.$options.getOption('updateOn')) { + element.on(modelCtrl.$options.getOption('updateOn'), function(ev) { + modelCtrl.$$debounceViewValueCommit(ev && ev.type); }); } - }; - } - }; - return formDirective; + function setTouched() { + modelCtrl.$setTouched(); + } - function getSetter(expression) { - if (expression === '') { - //create an assignable expression, so forms with an empty name can be renamed later - return $parse('this[""]').assign; - } - return $parse(expression).assign || noop; + element.on('blur', function() { + if (modelCtrl.$touched) return; + + if ($rootScope.$$phase) { + scope.$evalAsync(setTouched); + } else { + scope.$apply(setTouched); + } + }); + } + }; } - }]; -}; + }; +}]; -var formDirective = formDirectiveFactory(); -var ngFormDirective = formDirectiveFactory(true); +/* exported defaultModelOptions */ +var defaultModelOptions; +var DEFAULT_REGEXP = /(\s+|^)default(\s+|$)/; +/** + * @ngdoc type + * @name ModelOptions + * @description + * A container for the options set by the {@link ngModelOptions} directive + */ +function ModelOptions(options) { + this.$$options = options; +} +ModelOptions.prototype = { -// helper methods -function setupValidity(instance) { - instance.$$classCache = {}; - instance.$$classCache[INVALID_CLASS] = !(instance.$$classCache[VALID_CLASS] = instance.$$element.hasClass(VALID_CLASS)); -} -function addSetValidityMethod(context) { - var clazz = context.clazz, - set = context.set, - unset = context.unset; + /** + * @ngdoc method + * @name ModelOptions#getOption + * @param {string} name the name of the option to retrieve + * @returns {*} the value of the option + * @description + * Returns the value of the given option + */ + getOption: function(name) { + return this.$$options[name]; + }, - clazz.prototype.$setValidity = function(validationErrorKey, state, controller) { - if (isUndefined(state)) { - createAndSet(this, '$pending', validationErrorKey, controller); - } else { - unsetAndCleanup(this, '$pending', validationErrorKey, controller); - } - if (!isBoolean(state)) { - unset(this.$error, validationErrorKey, controller); - unset(this.$$success, validationErrorKey, controller); - } else { - if (state) { - unset(this.$error, validationErrorKey, controller); - set(this.$$success, validationErrorKey, controller); - } else { - set(this.$error, validationErrorKey, controller); - unset(this.$$success, validationErrorKey, controller); - } - } - if (this.$pending) { - cachedToggleClass(this, PENDING_CLASS, true); - this.$valid = this.$invalid = undefined; - toggleValidationCss(this, '', null); - } else { - cachedToggleClass(this, PENDING_CLASS, false); - this.$valid = isObjectEmpty(this.$error); - this.$invalid = !this.$valid; - toggleValidationCss(this, '', this.$valid); - } + /** + * @ngdoc method + * @name ModelOptions#createChild + * @param {Object} options a hash of options for the new child that will override the parent's options + * @return {ModelOptions} a new `ModelOptions` object initialized with the given options. + */ + createChild: function(options) { + var inheritAll = false; - // re-read the state as the set/unset methods could have - // combined state in this.$error[validationError] (used for forms), - // where setting/unsetting only increments/decrements the value, - // and does not replace it. - var combinedState; - if (this.$pending && this.$pending[validationErrorKey]) { - combinedState = undefined; - } else if (this.$error[validationErrorKey]) { - combinedState = false; - } else if (this.$$success[validationErrorKey]) { - combinedState = true; - } else { - combinedState = null; - } + // make a shallow copy + options = extend({}, options); - toggleValidationCss(this, validationErrorKey, combinedState); - this.$$parentForm.$setValidity(validationErrorKey, combinedState, this); - }; + // Inherit options from the parent if specified by the value `"$inherit"` + forEach(options, /* @this */ function(option, key) { + if (option === '$inherit') { + if (key === '*') { + inheritAll = true; + } else { + options[key] = this.$$options[key]; + // `updateOn` is special so we must also inherit the `updateOnDefault` option + if (key === 'updateOn') { + options.updateOnDefault = this.$$options.updateOnDefault; + } + } + } else { + if (key === 'updateOn') { + // If the `updateOn` property contains the `default` event then we have to remove + // it from the event list and set the `updateOnDefault` flag. + options.updateOnDefault = false; + options[key] = trim(option.replace(DEFAULT_REGEXP, function() { + options.updateOnDefault = true; + return ' '; + })); + } + } + }, this); - function createAndSet(ctrl, name, value, controller) { - if (!ctrl[name]) { - ctrl[name] = {}; + if (inheritAll) { + // We have a property of the form: `"*": "$inherit"` + delete options['*']; + defaults(options, this.$$options); } - set(ctrl[name], value, controller); - } - function unsetAndCleanup(ctrl, name, value, controller) { - if (ctrl[name]) { - unset(ctrl[name], value, controller); - } - if (isObjectEmpty(ctrl[name])) { - ctrl[name] = undefined; - } - } + // Finally add in any missing defaults + defaults(options, defaultModelOptions.$$options); - function cachedToggleClass(ctrl, className, switchValue) { - if (switchValue && !ctrl.$$classCache[className]) { - ctrl.$$animate.addClass(ctrl.$$element, className); - ctrl.$$classCache[className] = true; - } else if (!switchValue && ctrl.$$classCache[className]) { - ctrl.$$animate.removeClass(ctrl.$$element, className); - ctrl.$$classCache[className] = false; - } + return new ModelOptions(options); } +}; - function toggleValidationCss(ctrl, validationErrorKey, isValid) { - validationErrorKey = validationErrorKey ? '-' + snake_case(validationErrorKey, '-') : ''; - cachedToggleClass(ctrl, VALID_CLASS + validationErrorKey, isValid === true); - cachedToggleClass(ctrl, INVALID_CLASS + validationErrorKey, isValid === false); +defaultModelOptions = new ModelOptions({ + updateOn: '', + updateOnDefault: true, + debounce: 0, + getterSetter: false, + allowInvalid: false, + timezone: null +}); + + +/** + * @ngdoc directive + * @name ngModelOptions + * + * @description + * This directive allows you to modify the behaviour of {@link ngModel} directives within your + * application. You can specify an `ngModelOptions` directive on any element. All {@link ngModel} + * directives will use the options of their nearest `ngModelOptions` ancestor. + * + * The `ngModelOptions` settings are found by evaluating the value of the attribute directive as + * an Angular expression. This expression should evaluate to an object, whose properties contain + * the settings. For example: `
+ *
+ * + *
+ *
+ * ``` + * + * the `input` element will have the following settings + * + * ```js + * { allowInvalid: true, updateOn: 'default', debounce: 0 } + * ``` + * + * Notice that the `debounce` setting was not inherited and used the default value instead. + * + * You can specify that all undefined settings are automatically inherited from an ancestor by + * including a property with key of `"*"` and value of `"$inherit"`. + * + * For example given the following fragment of HTML + * + * + * ```html + *
+ *
+ * + *
+ *
+ * ``` + * + * the `input` element will have the following settings + * + * ```js + * { allowInvalid: true, updateOn: 'default', debounce: 200 } + * ``` + * + * Notice that the `debounce` setting now inherits the value from the outer `
` element. + * + * If you are creating a reusable component then you should be careful when using `"*": "$inherit"` + * since you may inadvertently inherit a setting in the future that changes the behavior of your component. + * + * + * ## Triggering and debouncing model updates + * + * The `updateOn` and `debounce` properties allow you to specify a custom list of events that will + * trigger a model update and/or a debouncing delay so that the actual update only takes place when + * a timer expires; this timer will be reset after another change takes place. + * + * Given the nature of `ngModelOptions`, the value displayed inside input fields in the view might + * be different from the value in the actual model. This means that if you update the model you + * should also invoke {@link ngModel.NgModelController#$rollbackViewValue} on the relevant input field in + * order to make sure it is synchronized with the model and that any debounced action is canceled. + * + * The easiest way to reference the control's {@link ngModel.NgModelController#$rollbackViewValue} + * method is by making sure the input is placed inside a form that has a `name` attribute. This is + * important because `form` controllers are published to the related scope under the name in their + * `name` attribute. + * + * Any pending changes will take place immediately when an enclosing form is submitted via the + * `submit` event. Note that `ngClick` events will occur before the model is updated. Use `ngSubmit` + * to have access to the updated model. + * + * The following example shows how to override immediate updates. Changes on the inputs within the + * form will update the model only when the control loses focus (blur event). If `escape` key is + * pressed while the input field is focused, the value is reset to the value in the current model. + * + * + * + *
+ *
+ *
+ *
+ *
+ *
user.name = 
+ *
+ *
+ * + * angular.module('optionsExample', []) + * .controller('ExampleController', ['$scope', function($scope) { + * $scope.user = { name: 'say', data: '' }; + * + * $scope.cancel = function(e) { + * if (e.keyCode === 27) { + * $scope.userForm.userName.$rollbackViewValue(); + * } + * }; + * }]); + * + * + * var model = element(by.binding('user.name')); + * var input = element(by.model('user.name')); + * var other = element(by.model('user.data')); + * + * it('should allow custom events', function() { + * input.sendKeys(' hello'); + * input.click(); + * expect(model.getText()).toEqual('say'); + * other.click(); + * expect(model.getText()).toEqual('say hello'); + * }); + * + * it('should $rollbackViewValue when model changes', function() { + * input.sendKeys(' hello'); + * expect(input.getAttribute('value')).toEqual('say hello'); + * input.sendKeys(protractor.Key.ESCAPE); + * expect(input.getAttribute('value')).toEqual('say'); + * other.click(); + * expect(model.getText()).toEqual('say'); + * }); + * + *
+ * + * The next example shows how to debounce model changes. Model will be updated only 1 sec after last change. + * If the `Clear` button is pressed, any debounced action is canceled and the value becomes empty. + * + * + * + *
+ *
+ * Name: + * + *
+ *
+ *
user.name = 
+ *
+ *
+ * + * angular.module('optionsExample', []) + * .controller('ExampleController', ['$scope', function($scope) { + * $scope.user = { name: 'say' }; + * }]); + * + *
+ * + * ## Model updates and validation + * + * The default behaviour in `ngModel` is that the model value is set to `undefined` when the + * validation determines that the value is invalid. By setting the `allowInvalid` property to true, + * the model will still be updated even if the value is invalid. + * + * + * ## Connecting to the scope + * + * By setting the `getterSetter` property to true you are telling ngModel that the `ngModel` expression + * on the scope refers to a "getter/setter" function rather than the value itself. + * + * The following example shows how to bind to getter/setters: + * + * + * + *
+ *
+ * + *
+ *
user.name = 
+ *
+ *
+ * + * angular.module('getterSetterExample', []) + * .controller('ExampleController', ['$scope', function($scope) { + * var _name = 'Brian'; + * $scope.user = { + * name: function(newName) { + * return angular.isDefined(newName) ? (_name = newName) : _name; + * } + * }; + * }]); + * + *
+ * + * + * ## Specifying timezones + * + * You can specify the timezone that date/time input directives expect by providing its name in the + * `timezone` property. + * + * @param {Object} ngModelOptions options to apply to {@link ngModel} directives on this element and + * and its descendents. Valid keys are: + * - `updateOn`: string specifying which event should the input be bound to. You can set several + * events using an space delimited list. There is a special event called `default` that + * matches the default events belonging to the control. + * - `debounce`: integer value which contains the debounce model update value in milliseconds. A + * value of 0 triggers an immediate update. If an object is supplied instead, you can specify a + * custom value for each event. For example: + * ``` + * ng-model-options="{ + * updateOn: 'default blur', + * debounce: { 'default': 500, 'blur': 0 } + * }" + * ``` + * - `allowInvalid`: boolean value which indicates that the model can be set with values that did + * not validate correctly instead of the default behavior of setting the model to undefined. + * - `getterSetter`: boolean value which determines whether or not to treat functions bound to + * `ngModel` as getters/setters. + * - `timezone`: Defines the timezone to be used to read/write the `Date` instance in the model for + * ``, ``, ... . It understands UTC/GMT and the + * continental US time zone abbreviations, but for general use, use a time zone offset, for + * example, `'+0430'` (4 hours, 30 minutes east of the Greenwich meridian) + * If not specified, the timezone of the browser will be used. + * + */ +var ngModelOptionsDirective = function() { + NgModelOptionsController.$inject = ['$attrs', '$scope']; + function NgModelOptionsController($attrs, $scope) { + this.$$attrs = $attrs; + this.$$scope = $scope; } -} + NgModelOptionsController.prototype = { + $onInit: function() { + var parentOptions = this.parentCtrl ? this.parentCtrl.$options : defaultModelOptions; + var modelOptionsDefinition = this.$$scope.$eval(this.$$attrs.ngModelOptions); -function isObjectEmpty(obj) { - if (obj) { - for (var prop in obj) { - if (obj.hasOwnProperty(prop)) { - return false; - } + this.$options = parentOptions.createChild(modelOptionsDefinition); } - } - return true; -} + }; -/* global - VALID_CLASS: false, - INVALID_CLASS: false, - PRISTINE_CLASS: false, - DIRTY_CLASS: false, - ngModelMinErr: false -*/ + return { + restrict: 'A', + // ngModelOptions needs to run before ngModel and input directives + priority: 10, + require: {parentCtrl: '?^^ngModelOptions'}, + bindToController: true, + controller: NgModelOptionsController + }; +}; -// Regex code was initially obtained from SO prior to modification: https://stackoverflow.com/questions/3143070/javascript-regex-iso-datetime#answer-3143231 -var ISO_DATE_REGEXP = /^\d{4,}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+(?:[+-][0-2]\d:[0-5]\d|Z)$/; -// See valid URLs in RFC3987 (http://tools.ietf.org/html/rfc3987) -// Note: We are being more lenient, because browsers are too. -// 1. Scheme -// 2. Slashes -// 3. Username -// 4. Password -// 5. Hostname -// 6. Port -// 7. Path -// 8. Query -// 9. Fragment -// 1111111111111111 222 333333 44444 55555555555555555555555 666 77777777 8888888 999 -var URL_REGEXP = /^[a-z][a-z\d.+-]*:\/*(?:[^:@]+(?::[^@]+)?@)?(?:[^\s:/?#]+|\[[a-f\d:]+])(?::\d+)?(?:\/[^?#]*)?(?:\?[^#]*)?(?:#.*)?$/i; -// eslint-disable-next-line max-len -var EMAIL_REGEXP = /^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/; -var NUMBER_REGEXP = /^\s*(-|\+)?(\d+|(\d*(\.\d*)))([eE][+-]?\d+)?\s*$/; -var DATE_REGEXP = /^(\d{4,})-(\d{2})-(\d{2})$/; -var DATETIMELOCAL_REGEXP = /^(\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/; -var WEEK_REGEXP = /^(\d{4,})-W(\d\d)$/; -var MONTH_REGEXP = /^(\d{4,})-(\d\d)$/; -var TIME_REGEXP = /^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/; -var PARTIAL_VALIDATION_EVENTS = 'keydown wheel mousedown'; -var PARTIAL_VALIDATION_TYPES = createMap(); -forEach('date,datetime-local,month,time,week'.split(','), function(type) { - PARTIAL_VALIDATION_TYPES[type] = true; -}); +// shallow copy over values from `src` that are not already specified on `dst` +function defaults(dst, src) { + forEach(src, function(value, key) { + if (!isDefined(dst[key])) { + dst[key] = value; + } + }); +} -var inputType = { +/** + * @ngdoc directive + * @name ngNonBindable + * @restrict AC + * @priority 1000 + * + * @description + * The `ngNonBindable` directive tells Angular not to compile or bind the contents of the current + * DOM element. This is useful if the element contains what appears to be Angular directives and + * bindings but which should be ignored by Angular. This could be the case if you have a site that + * displays snippets of code, for instance. + * + * @element ANY + * + * @example + * In this example there are two locations where a simple interpolation binding (`{{}}`) is present, + * but the one wrapped in `ngNonBindable` is left alone. + * + * @example + + +
Normal: {{1 + 2}}
+
Ignored: {{1 + 2}}
+
+ + it('should check ng-non-bindable', function() { + expect(element(by.binding('1 + 2')).getText()).toContain('3'); + expect(element.all(by.css('div')).last().getText()).toMatch(/1 \+ 2/); + }); + +
+ */ +var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 }); - /** - * @ngdoc input - * @name input[text] - * - * @description - * Standard HTML text input with angular data binding, inherited by most of the `input` elements. - * - * - * @param {string} ngModel Assignable angular expression to data-bind to. - * @param {string=} name Property name of the form under which the control is published. - * @param {string=} required Adds `required` validation error key if the value is not entered. - * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to - * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of - * `required` when you want to data-bind to the `required` attribute. - * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than - * minlength. - * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than - * maxlength. Setting the attribute to a negative or non-numeric value, allows view values of - * any length. - * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string - * that contains the regular expression body that will be converted to a regular expression - * as in the ngPattern directive. - * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue} - * does not match a RegExp found by evaluating the Angular expression given in the attribute value. - * If the expression evaluates to a RegExp object, then this is used directly. - * If the expression evaluates to a string, then it will be converted to a RegExp - * after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to - * `new RegExp('^abc$')`.
- * **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to - * start at the index of the last search's match, thus not taking the whole input value into - * account. - * @param {string=} ngChange Angular expression to be executed when input changes due to user - * interaction with the input element. - * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input. - * This parameter is ignored for input[type=password] controls, which will never trim the - * input. - * - * @example - - - -
- -
- - Required! - - Single word only! -
- text = {{example.text}}
- myForm.input.$valid = {{myForm.input.$valid}}
- myForm.input.$error = {{myForm.input.$error}}
- myForm.$valid = {{myForm.$valid}}
- myForm.$error.required = {{!!myForm.$error.required}}
-
-
- - var text = element(by.binding('example.text')); - var valid = element(by.binding('myForm.input.$valid')); - var input = element(by.model('example.text')); +/* exported ngOptionsDirective */ - it('should initialize to model', function() { - expect(text.getText()).toContain('guest'); - expect(valid.getText()).toContain('true'); - }); +/* global jqLiteRemove */ - it('should be invalid if empty', function() { - input.clear(); - input.sendKeys(''); +var ngOptionsMinErr = minErr('ngOptions'); - expect(text.getText()).toEqual('text ='); - expect(valid.getText()).toContain('false'); - }); +/** + * @ngdoc directive + * @name ngOptions + * @restrict A + * + * @description + * + * The `ngOptions` attribute can be used to dynamically generate a list of `` + * DOM element. + * * `disable`: The result of this expression will be used to disable the rendered ` -
- */ - 'date': createDateInputType('date', DATE_REGEXP, - createDateParser(DATE_REGEXP, ['yyyy', 'MM', 'dd']), - 'yyyy-MM-dd'), - /** - * @ngdoc input - * @name input[datetime-local] - * - * @description - * Input with datetime validation and transformation. In browsers that do not yet support - * the HTML5 date input, a text element will be used. In that case, the text must be entered in a valid ISO-8601 - * local datetime format (yyyy-MM-ddTHH:mm:ss), for example: `2010-12-28T14:57:00`. - * - * The model must always be a Date object, otherwise Angular will throw an error. - * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string. - * - * The timezone to be used to read/write the `Date` instance in the model can be defined using - * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser. - * - * @param {string} ngModel Assignable angular expression to data-bind to. - * @param {string=} name Property name of the form under which the control is published. - * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. - * This must be a valid ISO datetime format (yyyy-MM-ddTHH:mm:ss). You can also use interpolation - * inside this attribute (e.g. `min="{{minDatetimeLocal | date:'yyyy-MM-ddTHH:mm:ss'}}"`). - * Note that `min` will also add native HTML5 constraint validation. - * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. - * This must be a valid ISO datetime format (yyyy-MM-ddTHH:mm:ss). You can also use interpolation - * inside this attribute (e.g. `max="{{maxDatetimeLocal | date:'yyyy-MM-ddTHH:mm:ss'}}"`). - * Note that `max` will also add native HTML5 constraint validation. - * @param {(date|string)=} ngMin Sets the `min` validation error key to the Date / ISO datetime string - * the `ngMin` expression evaluates to. Note that it does not set the `min` attribute. - * @param {(date|string)=} ngMax Sets the `max` validation error key to the Date / ISO datetime string - * the `ngMax` expression evaluates to. Note that it does not set the `max` attribute. - * @param {string=} required Sets `required` validation error key if the value is not entered. - * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to - * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of - * `required` when you want to data-bind to the `required` attribute. - * @param {string=} ngChange Angular expression to be executed when input changes due to user - * interaction with the input element. - * - * @example - - - -
- - -
- - Required! - - Not a valid date! -
- value = {{example.value | date: "yyyy-MM-ddTHH:mm:ss"}}
- myForm.input.$valid = {{myForm.input.$valid}}
- myForm.input.$error = {{myForm.input.$error}}
- myForm.$valid = {{myForm.$valid}}
- myForm.$error.required = {{!!myForm.$error.required}}
-
-
- - var value = element(by.binding('example.value | date: "yyyy-MM-ddTHH:mm:ss"')); - var valid = element(by.binding('myForm.input.$valid')); +var ngOptionsDirective = ['$compile', '$document', '$parse', function($compile, $document, $parse) { - // currently protractor/webdriver does not support - // sending keys to all known HTML5 input controls - // for various browsers (https://github.com/angular/protractor/issues/562). - function setInput(val) { - // set the value of the element and force validation. - var scr = "var ipt = document.getElementById('exampleInput'); " + - "ipt.value = '" + val + "';" + - "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });"; - browser.executeScript(scr); - } + function parseOptionsExpression(optionsExp, selectElement, scope) { - it('should initialize to model', function() { - expect(value.getText()).toContain('2010-12-28T14:57:00'); - expect(valid.getText()).toContain('myForm.input.$valid = true'); - }); + var match = optionsExp.match(NG_OPTIONS_REGEXP); + if (!(match)) { + throw ngOptionsMinErr('iexp', + 'Expected expression in form of ' + + '\'_select_ (as _label_)? for (_key_,)?_value_ in _collection_\'' + + ' but got \'{0}\'. Element: {1}', + optionsExp, startingTag(selectElement)); + } - it('should be invalid if empty', function() { - setInput(''); - expect(value.getText()).toEqual('value ='); - expect(valid.getText()).toContain('myForm.input.$valid = false'); - }); + // Extract the parts from the ngOptions expression - it('should be invalid if over max', function() { - setInput('2015-01-01T23:59:00'); - expect(value.getText()).toContain(''); - expect(valid.getText()).toContain('myForm.input.$valid = false'); - }); - -
- */ - 'datetime-local': createDateInputType('datetimelocal', DATETIMELOCAL_REGEXP, - createDateParser(DATETIMELOCAL_REGEXP, ['yyyy', 'MM', 'dd', 'HH', 'mm', 'ss', 'sss']), - 'yyyy-MM-ddTHH:mm:ss.sss'), + // The variable name for the value of the item in the collection + var valueName = match[5] || match[7]; + // The variable name for the key of the item in the collection + var keyName = match[6]; - /** - * @ngdoc input - * @name input[time] - * - * @description - * Input with time validation and transformation. In browsers that do not yet support - * the HTML5 time input, a text element will be used. In that case, the text must be entered in a valid ISO-8601 - * local time format (HH:mm:ss), for example: `14:57:00`. Model must be a Date object. This binding will always output a - * Date object to the model of January 1, 1970, or local date `new Date(1970, 0, 1, HH, mm, ss)`. - * - * The model must always be a Date object, otherwise Angular will throw an error. - * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string. - * - * The timezone to be used to read/write the `Date` instance in the model can be defined using - * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser. - * - * @param {string} ngModel Assignable angular expression to data-bind to. - * @param {string=} name Property name of the form under which the control is published. - * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. - * This must be a valid ISO time format (HH:mm:ss). You can also use interpolation inside this - * attribute (e.g. `min="{{minTime | date:'HH:mm:ss'}}"`). Note that `min` will also add - * native HTML5 constraint validation. - * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. - * This must be a valid ISO time format (HH:mm:ss). You can also use interpolation inside this - * attribute (e.g. `max="{{maxTime | date:'HH:mm:ss'}}"`). Note that `max` will also add - * native HTML5 constraint validation. - * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO time string the - * `ngMin` expression evaluates to. Note that it does not set the `min` attribute. - * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO time string the - * `ngMax` expression evaluates to. Note that it does not set the `max` attribute. - * @param {string=} required Sets `required` validation error key if the value is not entered. - * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to - * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of - * `required` when you want to data-bind to the `required` attribute. - * @param {string=} ngChange Angular expression to be executed when input changes due to user - * interaction with the input element. - * - * @example - - - -
- - -
- - Required! - - Not a valid date! -
- value = {{example.value | date: "HH:mm:ss"}}
- myForm.input.$valid = {{myForm.input.$valid}}
- myForm.input.$error = {{myForm.input.$error}}
- myForm.$valid = {{myForm.$valid}}
- myForm.$error.required = {{!!myForm.$error.required}}
-
-
- - var value = element(by.binding('example.value | date: "HH:mm:ss"')); - var valid = element(by.binding('myForm.input.$valid')); + // An expression that generates the viewValue for an option if there is a label expression + var selectAs = / as /.test(match[0]) && match[1]; + // An expression that is used to track the id of each object in the options collection + var trackBy = match[9]; + // An expression that generates the viewValue for an option if there is no label expression + var valueFn = $parse(match[2] ? match[1] : valueName); + var selectAsFn = selectAs && $parse(selectAs); + var viewValueFn = selectAsFn || valueFn; + var trackByFn = trackBy && $parse(trackBy); - // currently protractor/webdriver does not support - // sending keys to all known HTML5 input controls - // for various browsers (https://github.com/angular/protractor/issues/562). - function setInput(val) { - // set the value of the element and force validation. - var scr = "var ipt = document.getElementById('exampleInput'); " + - "ipt.value = '" + val + "';" + - "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });"; - browser.executeScript(scr); - } + // Get the value by which we are going to track the option + // if we have a trackFn then use that (passing scope and locals) + // otherwise just hash the given viewValue + var getTrackByValueFn = trackBy ? + function(value, locals) { return trackByFn(scope, locals); } : + function getHashOfValue(value) { return hashKey(value); }; + var getTrackByValue = function(value, key) { + return getTrackByValueFn(value, getLocals(value, key)); + }; - it('should initialize to model', function() { - expect(value.getText()).toContain('14:57:00'); - expect(valid.getText()).toContain('myForm.input.$valid = true'); - }); + var displayFn = $parse(match[2] || match[1]); + var groupByFn = $parse(match[3] || ''); + var disableWhenFn = $parse(match[4] || ''); + var valuesFn = $parse(match[8]); - it('should be invalid if empty', function() { - setInput(''); - expect(value.getText()).toEqual('value ='); - expect(valid.getText()).toContain('myForm.input.$valid = false'); - }); + var locals = {}; + var getLocals = keyName ? function(value, key) { + locals[keyName] = key; + locals[valueName] = value; + return locals; + } : function(value) { + locals[valueName] = value; + return locals; + }; - it('should be invalid if over max', function() { - setInput('23:59:00'); - expect(value.getText()).toContain(''); - expect(valid.getText()).toContain('myForm.input.$valid = false'); - }); - -
- */ - 'time': createDateInputType('time', TIME_REGEXP, - createDateParser(TIME_REGEXP, ['HH', 'mm', 'ss', 'sss']), - 'HH:mm:ss.sss'), - /** - * @ngdoc input - * @name input[week] - * - * @description - * Input with week-of-the-year validation and transformation to Date. In browsers that do not yet support - * the HTML5 week input, a text element will be used. In that case, the text must be entered in a valid ISO-8601 - * week format (yyyy-W##), for example: `2013-W02`. - * - * The model must always be a Date object, otherwise Angular will throw an error. - * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string. - * - * The timezone to be used to read/write the `Date` instance in the model can be defined using - * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser. - * - * @param {string} ngModel Assignable angular expression to data-bind to. - * @param {string=} name Property name of the form under which the control is published. - * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. - * This must be a valid ISO week format (yyyy-W##). You can also use interpolation inside this - * attribute (e.g. `min="{{minWeek | date:'yyyy-Www'}}"`). Note that `min` will also add - * native HTML5 constraint validation. - * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. - * This must be a valid ISO week format (yyyy-W##). You can also use interpolation inside this - * attribute (e.g. `max="{{maxWeek | date:'yyyy-Www'}}"`). Note that `max` will also add - * native HTML5 constraint validation. - * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO week string - * the `ngMin` expression evaluates to. Note that it does not set the `min` attribute. - * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO week string - * the `ngMax` expression evaluates to. Note that it does not set the `max` attribute. - * @param {string=} required Sets `required` validation error key if the value is not entered. - * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to - * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of - * `required` when you want to data-bind to the `required` attribute. - * @param {string=} ngChange Angular expression to be executed when input changes due to user - * interaction with the input element. - * - * @example - - - -
- -
- - Required! - - Not a valid date! -
- value = {{example.value | date: "yyyy-Www"}}
- myForm.input.$valid = {{myForm.input.$valid}}
- myForm.input.$error = {{myForm.input.$error}}
- myForm.$valid = {{myForm.$valid}}
- myForm.$error.required = {{!!myForm.$error.required}}
-
-
- - var value = element(by.binding('example.value | date: "yyyy-Www"')); - var valid = element(by.binding('myForm.input.$valid')); + function Option(selectValue, viewValue, label, group, disabled) { + this.selectValue = selectValue; + this.viewValue = viewValue; + this.label = label; + this.group = group; + this.disabled = disabled; + } - // currently protractor/webdriver does not support - // sending keys to all known HTML5 input controls - // for various browsers (https://github.com/angular/protractor/issues/562). - function setInput(val) { - // set the value of the element and force validation. - var scr = "var ipt = document.getElementById('exampleInput'); " + - "ipt.value = '" + val + "';" + - "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });"; - browser.executeScript(scr); + function getOptionValuesKeys(optionValues) { + var optionValuesKeys; + + if (!keyName && isArrayLike(optionValues)) { + optionValuesKeys = optionValues; + } else { + // if object, extract keys, in enumeration order, unsorted + optionValuesKeys = []; + for (var itemKey in optionValues) { + if (optionValues.hasOwnProperty(itemKey) && itemKey.charAt(0) !== '$') { + optionValuesKeys.push(itemKey); + } + } } + return optionValuesKeys; + } - it('should initialize to model', function() { - expect(value.getText()).toContain('2013-W01'); - expect(valid.getText()).toContain('myForm.input.$valid = true'); - }); + return { + trackBy: trackBy, + getTrackByValue: getTrackByValue, + getWatchables: $parse(valuesFn, function(optionValues) { + // Create a collection of things that we would like to watch (watchedArray) + // so that they can all be watched using a single $watchCollection + // that only runs the handler once if anything changes + var watchedArray = []; + optionValues = optionValues || []; - it('should be invalid if empty', function() { - setInput(''); - expect(value.getText()).toEqual('value ='); - expect(valid.getText()).toContain('myForm.input.$valid = false'); - }); + var optionValuesKeys = getOptionValuesKeys(optionValues); + var optionValuesLength = optionValuesKeys.length; + for (var index = 0; index < optionValuesLength; index++) { + var key = (optionValues === optionValuesKeys) ? index : optionValuesKeys[index]; + var value = optionValues[key]; - it('should be invalid if over max', function() { - setInput('2015-W01'); - expect(value.getText()).toContain(''); - expect(valid.getText()).toContain('myForm.input.$valid = false'); - }); - -
- */ - 'week': createDateInputType('week', WEEK_REGEXP, weekParser, 'yyyy-Www'), + var locals = getLocals(value, key); + var selectValue = getTrackByValueFn(value, locals); + watchedArray.push(selectValue); - /** - * @ngdoc input - * @name input[month] - * - * @description - * Input with month validation and transformation. In browsers that do not yet support - * the HTML5 month input, a text element will be used. In that case, the text must be entered in a valid ISO-8601 - * month format (yyyy-MM), for example: `2009-01`. - * - * The model must always be a Date object, otherwise Angular will throw an error. - * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string. - * If the model is not set to the first of the month, the next view to model update will set it - * to the first of the month. - * - * The timezone to be used to read/write the `Date` instance in the model can be defined using - * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser. - * - * @param {string} ngModel Assignable angular expression to data-bind to. - * @param {string=} name Property name of the form under which the control is published. - * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. - * This must be a valid ISO month format (yyyy-MM). You can also use interpolation inside this - * attribute (e.g. `min="{{minMonth | date:'yyyy-MM'}}"`). Note that `min` will also add - * native HTML5 constraint validation. - * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. - * This must be a valid ISO month format (yyyy-MM). You can also use interpolation inside this - * attribute (e.g. `max="{{maxMonth | date:'yyyy-MM'}}"`). Note that `max` will also add - * native HTML5 constraint validation. - * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO week string - * the `ngMin` expression evaluates to. Note that it does not set the `min` attribute. - * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO week string - * the `ngMax` expression evaluates to. Note that it does not set the `max` attribute. + // Only need to watch the displayFn if there is a specific label expression + if (match[2] || match[1]) { + var label = displayFn(scope, locals); + watchedArray.push(label); + } - * @param {string=} required Sets `required` validation error key if the value is not entered. - * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to - * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of - * `required` when you want to data-bind to the `required` attribute. - * @param {string=} ngChange Angular expression to be executed when input changes due to user - * interaction with the input element. - * - * @example - - - -
- - -
- - Required! - - Not a valid month! -
- value = {{example.value | date: "yyyy-MM"}}
- myForm.input.$valid = {{myForm.input.$valid}}
- myForm.input.$error = {{myForm.input.$error}}
- myForm.$valid = {{myForm.$valid}}
- myForm.$error.required = {{!!myForm.$error.required}}
-
-
- - var value = element(by.binding('example.value | date: "yyyy-MM"')); - var valid = element(by.binding('myForm.input.$valid')); + // Only need to watch the disableWhenFn if there is a specific disable expression + if (match[4]) { + var disableWhen = disableWhenFn(scope, locals); + watchedArray.push(disableWhen); + } + } + return watchedArray; + }), - // currently protractor/webdriver does not support - // sending keys to all known HTML5 input controls - // for various browsers (https://github.com/angular/protractor/issues/562). - function setInput(val) { - // set the value of the element and force validation. - var scr = "var ipt = document.getElementById('exampleInput'); " + - "ipt.value = '" + val + "';" + - "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });"; - browser.executeScript(scr); - } + getOptions: function() { - it('should initialize to model', function() { - expect(value.getText()).toContain('2013-10'); - expect(valid.getText()).toContain('myForm.input.$valid = true'); - }); + var optionItems = []; + var selectValueMap = {}; - it('should be invalid if empty', function() { - setInput(''); - expect(value.getText()).toEqual('value ='); - expect(valid.getText()).toContain('myForm.input.$valid = false'); - }); + // The option values were already computed in the `getWatchables` fn, + // which must have been called to trigger `getOptions` + var optionValues = valuesFn(scope) || []; + var optionValuesKeys = getOptionValuesKeys(optionValues); + var optionValuesLength = optionValuesKeys.length; - it('should be invalid if over max', function() { - setInput('2015-01'); - expect(value.getText()).toContain(''); - expect(valid.getText()).toContain('myForm.input.$valid = false'); - }); - -
- */ - 'month': createDateInputType('month', MONTH_REGEXP, - createDateParser(MONTH_REGEXP, ['yyyy', 'MM']), - 'yyyy-MM'), + for (var index = 0; index < optionValuesLength; index++) { + var key = (optionValues === optionValuesKeys) ? index : optionValuesKeys[index]; + var value = optionValues[key]; + var locals = getLocals(value, key); + var viewValue = viewValueFn(scope, locals); + var selectValue = getTrackByValueFn(viewValue, locals); + var label = displayFn(scope, locals); + var group = groupByFn(scope, locals); + var disabled = disableWhenFn(scope, locals); + var optionItem = new Option(selectValue, viewValue, label, group, disabled); - /** - * @ngdoc input - * @name input[number] - * - * @description - * Text input with number validation and transformation. Sets the `number` validation - * error if not a valid number. - * - *
- * The model must always be of type `number` otherwise Angular will throw an error. - * Be aware that a string containing a number is not enough. See the {@link ngModel:numfmt} - * error docs for more information and an example of how to convert your model if necessary. - *
- * - * ## Issues with HTML5 constraint validation - * - * In browsers that follow the - * [HTML5 specification](https://html.spec.whatwg.org/multipage/forms.html#number-state-%28type=number%29), - * `input[number]` does not work as expected with {@link ngModelOptions `ngModelOptions.allowInvalid`}. - * If a non-number is entered in the input, the browser will report the value as an empty string, - * which means the view / model values in `ngModel` and subsequently the scope value - * will also be an empty string. - * - * - * @param {string} ngModel Assignable angular expression to data-bind to. - * @param {string=} name Property name of the form under which the control is published. - * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. - * Can be interpolated. - * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. - * Can be interpolated. - * @param {string=} ngMin Like `min`, sets the `min` validation error key if the value entered is less than `ngMin`, - * but does not trigger HTML5 native validation. Takes an expression. - * @param {string=} ngMax Like `max`, sets the `max` validation error key if the value entered is greater than `ngMax`, - * but does not trigger HTML5 native validation. Takes an expression. - * @param {string=} step Sets the `step` validation error key if the value entered does not fit the `step` constraint. - * Can be interpolated. - * @param {string=} ngStep Like `step`, sets the `step` validation error key if the value entered does not fit the `ngStep` constraint, - * but does not trigger HTML5 native validation. Takes an expression. - * @param {string=} required Sets `required` validation error key if the value is not entered. - * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to - * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of - * `required` when you want to data-bind to the `required` attribute. - * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than - * minlength. - * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than - * maxlength. Setting the attribute to a negative or non-numeric value, allows view values of - * any length. - * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string - * that contains the regular expression body that will be converted to a regular expression - * as in the ngPattern directive. - * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue} - * does not match a RegExp found by evaluating the Angular expression given in the attribute value. - * If the expression evaluates to a RegExp object, then this is used directly. - * If the expression evaluates to a string, then it will be converted to a RegExp - * after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to - * `new RegExp('^abc$')`.
- * **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to - * start at the index of the last search's match, thus not taking the whole input value into - * account. - * @param {string=} ngChange Angular expression to be executed when input changes due to user - * interaction with the input element. - * - * @example - - - -
- -
- - Required! - - Not valid number! -
- value = {{example.value}}
- myForm.input.$valid = {{myForm.input.$valid}}
- myForm.input.$error = {{myForm.input.$error}}
- myForm.$valid = {{myForm.$valid}}
- myForm.$error.required = {{!!myForm.$error.required}}
-
-
- - var value = element(by.binding('example.value')); - var valid = element(by.binding('myForm.input.$valid')); - var input = element(by.model('example.value')); + optionItems.push(optionItem); + selectValueMap[selectValue] = optionItem; + } - it('should initialize to model', function() { - expect(value.getText()).toContain('12'); - expect(valid.getText()).toContain('true'); - }); + return { + items: optionItems, + selectValueMap: selectValueMap, + getOptionFromViewValue: function(value) { + return selectValueMap[getTrackByValue(value)]; + }, + getViewValueFromOption: function(option) { + // If the viewValue could be an object that may be mutated by the application, + // we need to make a copy and not return the reference to the value on the option. + return trackBy ? copy(option.viewValue) : option.viewValue; + } + }; + } + }; + } - it('should be invalid if empty', function() { - input.clear(); - input.sendKeys(''); - expect(value.getText()).toEqual('value ='); - expect(valid.getText()).toContain('false'); - }); - it('should be invalid if over max', function() { - input.clear(); - input.sendKeys('123'); - expect(value.getText()).toEqual('value ='); - expect(valid.getText()).toContain('false'); - }); - -
- */ - 'number': numberInputType, + // Support: IE 9 only + // We can't just jqLite('
* * - * it('should check controller as', function() { - * var container = element(by.id('ctrl-as-exmpl')); - * expect(container.element(by.model('settings.name')) - * .getAttribute('value')).toBe('John Smith'); - * - * var firstRepeat = - * container.element(by.repeater('contact in settings.contacts').row(0)); - * var secondRepeat = - * container.element(by.repeater('contact in settings.contacts').row(1)); - * - * expect(firstRepeat.element(by.model('contact.value')).getAttribute('value')) - * .toBe('408 555 1212'); - * - * expect(secondRepeat.element(by.model('contact.value')).getAttribute('value')) - * .toBe('john.smith@example.org'); - * - * firstRepeat.element(by.buttonText('clear')).click(); - * - * expect(firstRepeat.element(by.model('contact.value')).getAttribute('value')) - * .toBe(''); - * - * container.element(by.buttonText('add')).click(); - * - * expect(container.element(by.repeater('contact in settings.contacts').row(2)) - * .element(by.model('contact.value')) - * .getAttribute('value')) - * .toBe('yourname@example.org'); - * }); + * it('should have transcluded', function() { + * var titleElement = element(by.model('title')); + * titleElement.clear(); + * titleElement.sendKeys('TITLE'); + * var textElement = element(by.model('text')); + * textElement.clear(); + * textElement.sendKeys('TEXT'); + * expect(element(by.binding('title')).getText()).toEqual('TITLE'); + * expect(element(by.binding('text')).getText()).toEqual('TEXT'); + * }); * * * - * This example demonstrates the "attach to `$scope`" style of controller. - * - * - * - *
- * - *
- * Contact: - *
    - *
  • - * - * - * - * - *
  • - *
  • [ ]
  • - *
- *
- *
- * - * angular.module('controllerExample', []) - * .controller('SettingsController2', ['$scope', SettingsController2]); - * - * function SettingsController2($scope) { - * $scope.name = 'John Smith'; - * $scope.contacts = [ - * {type:'phone', value:'408 555 1212'}, - * {type:'email', value:'john.smith@example.org'} - * ]; + * @example + * ### Transclude fallback content + * This example shows how to use `NgTransclude` with fallback content, that + * is displayed if no transcluded content is provided. * - * $scope.greet = function() { - * alert($scope.name); - * }; - * - * $scope.addContact = function() { - * $scope.contacts.push({type:'email', value:'yourname@example.org'}); - * }; - * - * $scope.removeContact = function(contactToRemove) { - * var index = $scope.contacts.indexOf(contactToRemove); - * $scope.contacts.splice(index, 1); - * }; - * - * $scope.clearContact = function(contact) { - * contact.type = 'phone'; - * contact.value = ''; - * }; - * } - * - * - * it('should check controller', function() { - * var container = element(by.id('ctrl-exmpl')); - * - * expect(container.element(by.model('name')) - * .getAttribute('value')).toBe('John Smith'); - * - * var firstRepeat = - * container.element(by.repeater('contact in contacts').row(0)); - * var secondRepeat = - * container.element(by.repeater('contact in contacts').row(1)); - * - * expect(firstRepeat.element(by.model('contact.value')).getAttribute('value')) - * .toBe('408 555 1212'); - * expect(secondRepeat.element(by.model('contact.value')).getAttribute('value')) - * .toBe('john.smith@example.org'); - * - * firstRepeat.element(by.buttonText('clear')).click(); - * - * expect(firstRepeat.element(by.model('contact.value')).getAttribute('value')) - * .toBe(''); - * - * container.element(by.buttonText('add')).click(); + * + * + * + * + * + * + * + * Button2 + * + * + * + * it('should have different transclude element content', function() { + * expect(element(by.id('fallback')).getText()).toBe('Button1'); + * expect(element(by.id('modified')).getText()).toBe('Button2'); + * }); + * + * * - * expect(container.element(by.repeater('contact in contacts').row(2)) - * .element(by.model('contact.value')) - * .getAttribute('value')) - * .toBe('yourname@example.org'); - * }); - * - *
- + * @example + * ### Multi-slot transclusion + * This example demonstrates using multi-slot transclusion in a component directive. + * + * + * + *
+ *
+ *
+ * + * {{title}} + *

{{text}}

+ *
+ *
+ *
+ * + * angular.module('multiSlotTranscludeExample', []) + * .directive('pane', function() { + * return { + * restrict: 'E', + * transclude: { + * 'title': '?paneTitle', + * 'body': 'paneBody', + * 'footer': '?paneFooter' + * }, + * template: '
' + + * '
Fallback Title
' + + * '
' + + * '' + + * '
' + * }; + * }) + * .controller('ExampleController', ['$scope', function($scope) { + * $scope.title = 'Lorem Ipsum'; + * $scope.link = 'https://google.com'; + * $scope.text = 'Neque porro quisquam est qui dolorem ipsum quia dolor...'; + * }]); + *
+ * + * it('should have transcluded the title and the body', function() { + * var titleElement = element(by.model('title')); + * titleElement.clear(); + * titleElement.sendKeys('TITLE'); + * var textElement = element(by.model('text')); + * textElement.clear(); + * textElement.sendKeys('TEXT'); + * expect(element(by.css('.title')).getText()).toEqual('TITLE'); + * expect(element(by.binding('text')).getText()).toEqual('TEXT'); + * expect(element(by.css('.footer')).getText()).toEqual('Fallback Footer'); + * }); + * + *
*/ -var ngControllerDirective = [function() { +var ngTranscludeMinErr = minErr('ngTransclude'); +var ngTranscludeDirective = ['$compile', function($compile) { return { - restrict: 'A', - scope: true, - controller: '@', - priority: 500 + restrict: 'EAC', + terminal: true, + compile: function ngTranscludeCompile(tElement) { + + // Remove and cache any original content to act as a fallback + var fallbackLinkFn = $compile(tElement.contents()); + tElement.empty(); + + return function ngTranscludePostLink($scope, $element, $attrs, controller, $transclude) { + + if (!$transclude) { + throw ngTranscludeMinErr('orphan', + 'Illegal use of ngTransclude directive in the template! ' + + 'No parent directive that requires a transclusion found. ' + + 'Element: {0}', + startingTag($element)); + } + + + // If the attribute is of the form: `ng-transclude="ng-transclude"` then treat it like the default + if ($attrs.ngTransclude === $attrs.$attr.ngTransclude) { + $attrs.ngTransclude = ''; + } + var slotName = $attrs.ngTransclude || $attrs.ngTranscludeSlot; + + // If the slot is required and no transclusion content is provided then this call will throw an error + $transclude(ngTranscludeCloneAttachFn, null, slotName); + + // If the slot is optional and no transclusion content is provided then use the fallback content + if (slotName && !$transclude.isSlotFilled(slotName)) { + useFallbackContent(); + } + + function ngTranscludeCloneAttachFn(clone, transcludedScope) { + if (clone.length && notWhitespace(clone)) { + $element.append(clone); + } else { + useFallbackContent(); + // There is nothing linked against the transcluded scope since no content was available, + // so it should be safe to clean up the generated scope. + transcludedScope.$destroy(); + } + } + + function useFallbackContent() { + // Since this is the fallback content rather than the transcluded content, + // we link against the scope of this directive rather than the transcluded scope + fallbackLinkFn($scope, function(clone) { + $element.append(clone); + }); + } + + function notWhitespace(nodes) { + for (var i = 0, ii = nodes.length; i < ii; i++) { + var node = nodes[i]; + if (node.nodeType !== NODE_TYPE_TEXT || node.nodeValue.trim()) { + return true; + } + } + } + }; + } }; }]; /** * @ngdoc directive - * @name ngCsp + * @name script + * @restrict E * - * @restrict A - * @element ANY * @description + * Load the content of a ` + + Load inlined template +
+ + + it('should load template defined inside script tag', function() { + element(by.css('#tpl-link')).click(); + expect(element(by.css('#tpl-content')).getText()).toMatch(/Content of the template/); + }); + + + */ +var scriptDirective = ['$templateCache', function($templateCache) { + return { + restrict: 'E', + terminal: true, + compile: function(element, attr) { + if (attr.type === 'text/ng-template') { + var templateUrl = attr.id, + text = element[0].text; + + $templateCache.put(templateUrl, text); + } + } + }; +}]; + +/* exported selectDirective, optionDirective */ + +var noopNgModelController = { $setViewValue: noop, $render: noop }; + +function setOptionSelectedStatus(optionEl, value) { + optionEl.prop('selected', value); + /** + * When unselecting an option, setting the property to null / false should be enough + * However, screenreaders might react to the selected attribute instead, see + * https://github.com/angular/angular.js/issues/14419 + * Note: "selected" is a boolean attr and will be removed when the "value" arg in attr() is false + * or null + */ + optionEl.attr('selected', value); +} + +/** + * @ngdoc type + * @name select.SelectController * - * This is necessary when developing things like Google Chrome Extensions or Universal Windows Apps. + * @description + * The controller for the {@link ng.select select} directive. The controller exposes + * a few utility methods that can be used to augment the behavior of a regular or an + * {@link ng.ngOptions ngOptions} select element. * + * @example + * ### Set a custom error when the unknown option is selected * - * The following default rules in CSP affect Angular: + * This example sets a custom error "unknownValue" on the ngModelController + * when the select element's unknown option is selected, i.e. when the model is set to a value + * that is not matched by any option. * - * * The use of `eval()`, `Function(string)` and similar functions to dynamically create and execute - * code from strings is forbidden. Angular makes use of this in the {@link $parse} service to - * provide a 30% increase in the speed of evaluating Angular expressions. (This CSP rule can be - * disabled with the CSP keyword `unsafe-eval`, but it is generally not recommended as it would - * weaken the protections offered by CSP.) + * + * + *
+ *
+ *
+ *
+ * Error: The current model doesn't match any option * - * * The use of inline resources, such as inline ` - - Enter text and hit enter: - - -
list={{list}}
-
- - - it('should check ng-submit', function() { - expect(element(by.binding('list')).getText()).toBe('list=[]'); - element(by.css('#submit')).click(); - expect(element(by.binding('list')).getText()).toContain('hello'); - expect(element(by.model('text')).getAttribute('value')).toBe(''); - }); - it('should ignore empty strings', function() { - expect(element(by.binding('list')).getText()).toBe('list=[]'); - element(by.css('#submit')).click(); - element(by.css('#submit')).click(); - expect(element(by.binding('list')).getText()).toContain('hello'); - }); - - - */ -/** - * @ngdoc directive - * @name ngFocus - * - * @description - * Specify custom behavior on focus event. - * - * Note: As the `focus` event is executed synchronously when calling `input.focus()` - * AngularJS executes the expression using `scope.$evalAsync` if the event is fired - * during an `$apply` to ensure a consistent state. - * - * @element window, input, select, textarea, a - * @priority 0 - * @param {expression} ngFocus {@link guide/expression Expression} to evaluate upon - * focus. ({@link guide/expression#-event- Event object is available as `$event`}) - * - * @example - * See {@link ng.directive:ngClick ngClick} - */ + self.registerOption = function(optionScope, optionElement, optionAttrs, interpolateValueFn, interpolateTextFn) { + + if (optionAttrs.$attr.ngValue) { + // The value attribute is set by ngValue + var oldVal, hashedVal = NaN; + optionAttrs.$observe('value', function valueAttributeObserveAction(newVal) { + + var removal; + var previouslySelected = optionElement.prop('selected'); + + if (isDefined(hashedVal)) { + self.removeOption(oldVal); + delete self.selectValueMap[hashedVal]; + removal = true; + } + + hashedVal = hashKey(newVal); + oldVal = newVal; + self.selectValueMap[hashedVal] = newVal; + self.addOption(newVal, optionElement); + // Set the attribute directly instead of using optionAttrs.$set - this stops the observer + // from firing a second time. Other $observers on value will also get the result of the + // ngValue expression, not the hashed value + optionElement.attr('value', hashedVal); + + if (removal && previouslySelected) { + scheduleViewValueUpdate(); + } + + }); + } else if (interpolateValueFn) { + // The value attribute is interpolated + optionAttrs.$observe('value', function valueAttributeObserveAction(newVal) { + // This method is overwritten in ngOptions and has side-effects! + self.readValue(); + + var removal; + var previouslySelected = optionElement.prop('selected'); + + if (isDefined(oldVal)) { + self.removeOption(oldVal); + removal = true; + } + oldVal = newVal; + self.addOption(newVal, optionElement); + + if (removal && previouslySelected) { + scheduleViewValueUpdate(); + } + }); + } else if (interpolateTextFn) { + // The text content is interpolated + optionScope.$watch(interpolateTextFn, function interpolateWatchAction(newVal, oldVal) { + optionAttrs.$set('value', newVal); + var previouslySelected = optionElement.prop('selected'); + if (oldVal !== newVal) { + self.removeOption(oldVal); + } + self.addOption(newVal, optionElement); + + if (oldVal && previouslySelected) { + scheduleViewValueUpdate(); + } + }); + } else { + // The value attribute is static + self.addOption(optionAttrs.value, optionElement); + } + + + optionAttrs.$observe('disabled', function(newVal) { + + // Since model updates will also select disabled options (like ngOptions), + // we only have to handle options becoming disabled, not enabled + + if (newVal === 'true' || newVal && optionElement.prop('selected')) { + if (self.multiple) { + scheduleViewValueUpdate(true); + } else { + self.ngModelCtrl.$setViewValue(null); + self.ngModelCtrl.$render(); + } + } + }); + + optionElement.on('$destroy', function() { + var currentValue = self.readValue(); + var removeValue = optionAttrs.value; + + self.removeOption(removeValue); + scheduleRender(); + + if (self.multiple && currentValue && currentValue.indexOf(removeValue) !== -1 || + currentValue === removeValue + ) { + // When multiple (selected) options are destroyed at the same time, we don't want + // to run a model update for each of them. Instead, run a single update in the $$postDigest + scheduleViewValueUpdate(true); + } + }); + }; +}]; /** * @ngdoc directive - * @name ngBlur + * @name select + * @restrict E * * @description - * Specify custom behavior on blur event. + * HTML `select` element with angular data-binding. * - * A [blur event](https://developer.mozilla.org/en-US/docs/Web/Events/blur) fires when - * an element has lost focus. + * The `select` directive is used together with {@link ngModel `ngModel`} to provide data-binding + * between the scope and the `` menu is selected, the value of the selected option will be bound + * to the model identified by the `ngModel` directive. With static or repeated options, this is + * the content of the `value` attribute or the textContent of the `