Misc code cleanup in webclient. Updated dependencies and some minor errors. Added license changes

This commit is contained in:
thewebkid 2015-03-17 21:28:31 -07:00
Родитель 6629d342f6
Коммит 256aabcb40
15 изменённых файлов: 259 добавлений и 200 удалений

Двоичные данные
App_Readme/WURFL Quick Guide_v1_5.pdf

Двоичный файл не отображается.

Двоичные данные
App_Readme/WURFL-v1.5.3.chm

Двоичный файл не отображается.

Просмотреть файл

@ -32,7 +32,10 @@
} }
</style> </style>
<script src="sdk/wwtsdk<%= Debug ? "" : ".min" %>.js"></script> <%--<script src="sdk/old/wwtsdk_old.debug.js"></script>
<script src="sdk/wwtsdk.js"></script>
<script src="sdk/wwtsdk<%= Debug ? "" : ".min" %>.js"></script>--%>
<script src="sdk/wwtsdk.js"></script>
<% if (Debug || DebugChrome) <% if (Debug || DebugChrome)
{ %> { %>
@ -78,8 +81,8 @@
<script src="<%= ResourcesLocation %>/controllers/tabs/SettingsController.js?v=<%= ResourcesVersion%>"></script> <script src="<%= ResourcesLocation %>/controllers/tabs/SettingsController.js?v=<%= ResourcesVersion%>"></script>
<script src="<%= ResourcesLocation %>/controllers/tabs/ToursController.js?v=<%= ResourcesVersion%>"></script> <script src="<%= ResourcesLocation %>/controllers/tabs/ToursController.js?v=<%= ResourcesVersion%>"></script>
<script src="<%= ResourcesLocation %>/controllers/tabs/ViewController.js?v=<%= ResourcesVersion%>"></script> <script src="<%= ResourcesLocation %>/controllers/tabs/ViewController.js?v=<%= ResourcesVersion%>"></script>
<script src="<%= ResourcesLocation%>/controls/move.js?v=<%= ResourcesVersion%>"></script> <script src="<%= ResourcesLocation %>/controls/move.js?v=<%= ResourcesVersion%>"></script>
<script src="<%= ResourcesLocation%>/controls/util.js?v=<%= ResourcesVersion%>"></script> <script src="<%= ResourcesLocation %>/controls/util.js?v=<%= ResourcesVersion%>"></script>
<% } <% }
else else
{ %> { %>

Просмотреть файл

@ -17,6 +17,7 @@ public partial class Default : System.Web.UI.Page
public string DebugQs = "?v=" + ConfigurationManager.AppSettings["ResourcesVersion"]; public string DebugQs = "?v=" + ConfigurationManager.AppSettings["ResourcesVersion"];
public string BodyClass; public string BodyClass;
public string SDKLocation = "http://www.worldwidetelescope.org/scripts/wwtsdk.aspx"; public string SDKLocation = "http://www.worldwidetelescope.org/scripts/wwtsdk.aspx";
public enum Clients public enum Clients
{ {
Html5 = 0, Html5 = 0,
@ -104,7 +105,6 @@ public partial class Default : System.Web.UI.Page
cookie.Value = "WWT"; cookie.Value = "WWT";
} }
HttpContext.Current.Response.Cookies.Add(cookie); HttpContext.Current.Response.Cookies.Add(cookie);
} }

Просмотреть файл

@ -341,7 +341,7 @@ module.exports = function(grunt) {
src: ['*.md'],//keep 2 copies of the readme - one for git page and one for inside IDE src: ['*.md'],//keep 2 copies of the readme - one for git page and one for inside IDE
dest: '../', dest: '../',
expand: true expand: true
} }//cdn.worldwidetelescope.org/html5sdk/x.x.x/wwtsdk[.min].js
] ]
} }
}, },

Просмотреть файл

@ -2,14 +2,14 @@
"name": "WWTWebClient", "name": "WWTWebClient",
"description": "WorldWide Telescope Web Client", "description": "WorldWide Telescope Web Client",
"version": "5.2.4", "version": "5.2.4",
"private": "true", "private": true,
"dependencies": { "dependencies": {
"jquery": "~2.1.3", "jquery": "~2.1.3",
"angular": "~1.3.10", "angular": "~1.3.14",
"angular-animate": "~1.3.10", "angular-animate": "~1.3.14",
"angular-cookies": "~1.3.10", "angular-cookies": "~1.3.14",
"angular-route": "~1.3.10", "angular-route": "~1.3.14",
"angular-touch": "~1.3.10", "angular-touch": "~1.3.14",
"angular-strap": "~2.1.6", "angular-strap": "~2.1.6",
"bootstrap": "~3.3.2" "bootstrap": "~3.3.2"
} }

Просмотреть файл

@ -35,31 +35,6 @@
wwt.resize(); wwt.resize();
} }
//var filterNode = new treeNode({
// name: $scope.getFromEn('Filter'),
// children: constellations,
// collapsed:true
//});
//var picturesFilter = wwt.clone(filterNode);
//picturesFilter.action = 'constellationArtFilter';
//var boundriesFilter = wwt.clone(filterNode);
//boundriesFilter.action = 'constellationBoundariesFilter';
//var figuresFilter = wwt.clone(filterNode);
//figuresFilter.action = 'constellationFiguresFilter';
//function setParentRef(parentNode) {
// $.each(parentNode.children, function(i,item) {
// item.parentRef = parentNode;
// });
//}
//setParentRef(picturesFilter);
//setParentRef(boundriesFilter);
//setParentRef(figuresFilter);
//console.log(filterNode);
var initTree = function() { var initTree = function() {
return new treeNode({ return new treeNode({
v: version, v: version,
@ -248,8 +223,6 @@
var invokeSetting = function(node) { var invokeSetting = function(node) {
if (node.action) { if (node.action) {
try { try {
//var bool = node.checked ? 'true' : 'false';
//eval('wwt.wc.settings.set_' + node.action + '(' + bool + ')');
wwt.wc.settings['set_' + node.action](node.checked); wwt.wc.settings['set_' + node.action](node.checked);
} catch (er) { } catch (er) {
util.log(er, node.action); util.log(er, node.action);

Просмотреть файл

@ -9,31 +9,27 @@
sessionId = null, sessionId = null,
submissionId = null, submissionId = null,
jobId = null, jobId = null,
calibration = null, debug = debugFlag,
jobStatus = null,
errorData = null;
debug = debugFlag;
login(); login();
} }
}; };
var statusTypes = { var statusTypes = {
connecting: 'Connecting', connecting: 'Connecting',
connected: 'Connect Success', connected: 'Connect Success',
connectFail: 'Connection Failed', connectFail: 'Connection Failed',
uploading: 'Uploading Image', uploading: 'Uploading Image',
uploadSuccess: 'Upload Success', uploadSuccess: 'Upload Success',
uploadFail: 'Upload Failed', uploadFail: 'Upload Failed',
statusCheck: 'Checking Status', statusCheck: 'Checking Status',
statusCheckFail: 'Status Check Failed', statusCheckFail: 'Status Check Failed',
jobFound: 'Job Found', jobFound: 'Job Found',
jobStatusCheck: 'Checking Job Status', jobStatusCheck: 'Checking Job Status',
jobFail: 'Could Not Resolve Image', jobFail: 'Could Not Resolve Image',
jobStatus: 'Solving Image', jobStatus: 'Solving Image',
jobSuccess: 'Job Succeeded', jobSuccess: 'Job Succeeded',
calibrationFail: 'Calibration Results Failed' calibrationFail: 'Calibration Results Failed'
} };
var uploadUrl, // "http://www.noao.edu/outreach/aop/observers/m51rolfe.jpg", var uploadUrl, // "http://www.noao.edu/outreach/aop/observers/m51rolfe.jpg",
statusCallback, statusCallback,
sessionId = null, sessionId = null,

Просмотреть файл

@ -1,6 +1,6 @@
wwt.app.directive("localize", ['Localization', '$rootScope', 'AppState','Util', function (loc, $rootScope,appState,util) { wwt.app.directive("localize", ['Localization', '$rootScope', 'AppState','Util', function (loc, $rootScope,appState,util) {
return function ($scope, element, attrs) { return function ($scope, element, attrs) {
if (appState.get('language') != 'EN') { if (appState.get('language') !== 'EN') {
//if ($rootScope.languagePromise) { //if ($rootScope.languagePromise) {
$rootScope.languagePromise.then(function() { $rootScope.languagePromise.then(function() {
replaceText(false); replaceText(false);

5
ext/angular-animate.js поставляемый
Просмотреть файл

@ -1,5 +1,5 @@
/** /**
* @license AngularJS v1.3.10 * @license AngularJS v1.3.14
* (c) 2010-2014 Google, Inc. http://angularjs.org * (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT * License: MIT
*/ */
@ -1333,8 +1333,7 @@ angular.module('ngAnimate', ['ng'])
} else if (lastAnimation.event == 'setClass') { } else if (lastAnimation.event == 'setClass') {
animationsToCancel.push(lastAnimation); animationsToCancel.push(lastAnimation);
cleanup(element, className); cleanup(element, className);
} } else if (runningAnimations[className]) {
else if (runningAnimations[className]) {
var current = runningAnimations[className]; var current = runningAnimations[className];
if (current.event == animationEvent) { if (current.event == animationEvent) {
skipAnimation = true; skipAnimation = true;

2
ext/angular-cookies.js поставляемый
Просмотреть файл

@ -1,5 +1,5 @@
/** /**
* @license AngularJS v1.3.10 * @license AngularJS v1.3.14
* (c) 2010-2014 Google, Inc. http://angularjs.org * (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT * License: MIT
*/ */

16
ext/angular-route.js поставляемый
Просмотреть файл

@ -1,5 +1,5 @@
/** /**
* @license AngularJS v1.3.10 * @license AngularJS v1.3.14
* (c) 2010-2014 Google, Inc. http://angularjs.org * (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT * License: MIT
*/ */
@ -482,21 +482,15 @@ function $RouteProvider() {
* definitions will be interpolated into the location's path, while * definitions will be interpolated into the location's path, while
* remaining properties will be treated as query params. * remaining properties will be treated as query params.
* *
* @param {Object} newParams mapping of URL parameter names to values * @param {!Object<string, string>} newParams mapping of URL parameter names to values
*/ */
updateParams: function(newParams) { updateParams: function(newParams) {
if (this.current && this.current.$$route) { if (this.current && this.current.$$route) {
var searchParams = {}, self=this;
angular.forEach(Object.keys(newParams), function(key) {
if (!self.current.pathParams[key]) searchParams[key] = newParams[key];
});
newParams = angular.extend({}, this.current.params, newParams); newParams = angular.extend({}, this.current.params, newParams);
$location.path(interpolate(this.current.$$route.originalPath, newParams)); $location.path(interpolate(this.current.$$route.originalPath, newParams));
$location.search(angular.extend({}, $location.search(), searchParams)); // interpolate modifies newParams, only query params are left
} $location.search(newParams);
else { } else {
throw $routeMinErr('norout', 'Tried updating route when with no current route'); throw $routeMinErr('norout', 'Tried updating route when with no current route');
} }
} }

2
ext/angular-touch.js поставляемый
Просмотреть файл

@ -1,5 +1,5 @@
/** /**
* @license AngularJS v1.3.10 * @license AngularJS v1.3.14
* (c) 2010-2014 Google, Inc. http://angularjs.org * (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT * License: MIT
*/ */

328
ext/angular.js поставляемый
Просмотреть файл

@ -1,5 +1,5 @@
/** /**
* @license AngularJS v1.3.10 * @license AngularJS v1.3.14
* (c) 2010-2014 Google, Inc. http://angularjs.org * (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT * License: MIT
*/ */
@ -54,7 +54,7 @@ function minErr(module, ErrorConstructor) {
return match; return match;
}); });
message = message + '\nhttp://errors.angularjs.org/1.3.10/' + message = message + '\nhttp://errors.angularjs.org/1.3.14/' +
(module ? module + '/' : '') + code; (module ? module + '/' : '') + code;
for (i = 2; i < arguments.length; i++) { for (i = 2; i < arguments.length; i++) {
message = message + (i == 2 ? '?' : '&') + 'p' + (i - 2) + '=' + message = message + (i == 2 ? '?' : '&') + 'p' + (i - 2) + '=' +
@ -381,8 +381,7 @@ function nextUid() {
function setHashKey(obj, h) { function setHashKey(obj, h) {
if (h) { if (h) {
obj.$$hashKey = h; obj.$$hashKey = h;
} } else {
else {
delete obj.$$hashKey; delete obj.$$hashKey;
} }
} }
@ -691,7 +690,7 @@ function isElement(node) {
function makeMap(str) { function makeMap(str) {
var obj = {}, items = str.split(","), i; var obj = {}, items = str.split(","), i;
for (i = 0; i < items.length; i++) for (i = 0; i < items.length; i++)
obj[ items[i] ] = true; obj[items[i]] = true;
return obj; return obj;
} }
@ -1472,8 +1471,12 @@ function bootstrap(element, modules, config) {
forEach(extraModules, function(module) { forEach(extraModules, function(module) {
modules.push(module); modules.push(module);
}); });
doBootstrap(); return doBootstrap();
}; };
if (isFunction(angular.resumeDeferredBootstrap)) {
angular.resumeDeferredBootstrap();
}
} }
/** /**
@ -2118,11 +2121,11 @@ function toDebugString(obj) {
* - `codeName` `{string}` Code name of the release, such as "jiggling-armfat". * - `codeName` `{string}` Code name of the release, such as "jiggling-armfat".
*/ */
var version = { var version = {
full: '1.3.10', // all of these placeholder strings will be replaced by grunt's full: '1.3.14', // all of these placeholder strings will be replaced by grunt's
major: 1, // package task major: 1, // package task
minor: 3, minor: 3,
dot: 10, dot: 14,
codeName: 'heliotropic-sundial' codeName: 'instantaneous-browserification'
}; };
@ -4157,7 +4160,7 @@ function createInjector(modulesToLoad, strictDi) {
} }
var args = [], var args = [],
$inject = annotate(fn, strictDi, serviceName), $inject = createInjector.$$annotate(fn, strictDi, serviceName),
length, i, length, i,
key; key;
@ -4196,7 +4199,7 @@ function createInjector(modulesToLoad, strictDi) {
invoke: invoke, invoke: invoke,
instantiate: instantiate, instantiate: instantiate,
get: getService, get: getService,
annotate: annotate, annotate: createInjector.$$annotate,
has: function(name) { has: function(name) {
return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name); return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name);
} }
@ -7870,8 +7873,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
afterTemplateChildLinkFn, afterTemplateChildLinkFn,
beforeTemplateCompileNode = $compileNode[0], beforeTemplateCompileNode = $compileNode[0],
origAsyncDirective = directives.shift(), origAsyncDirective = directives.shift(),
// The fact that we have to copy and patch the directive seems wrong! derivedSyncDirective = inherit(origAsyncDirective, {
derivedSyncDirective = extend({}, origAsyncDirective, {
templateUrl: null, transclude: null, replace: null, $$originalDirective: origAsyncDirective templateUrl: null, transclude: null, replace: null, $$originalDirective: origAsyncDirective
}), }),
templateUrl = (isFunction(origAsyncDirective.templateUrl)) templateUrl = (isFunction(origAsyncDirective.templateUrl))
@ -8324,6 +8326,8 @@ function removeComments(jqNodes) {
return jqNodes; return jqNodes;
} }
var $controllerMinErr = minErr('$controller');
/** /**
* @ngdoc provider * @ngdoc provider
* @name $controllerProvider * @name $controllerProvider
@ -8411,7 +8415,12 @@ function $ControllerProvider() {
} }
if (isString(expression)) { if (isString(expression)) {
match = expression.match(CNTRL_REG), match = expression.match(CNTRL_REG);
if (!match) {
throw $controllerMinErr('ctrlfmt',
"Badly formed controller string '{0}'. " +
"Must match `__name__ as __id__` or `__name__`.", expression);
}
constructor = match[1], constructor = match[1],
identifier = identifier || match[3]; identifier = identifier || match[3];
expression = controllers.hasOwnProperty(constructor) expression = controllers.hasOwnProperty(constructor)
@ -11320,7 +11329,7 @@ function $LocationProvider() {
// TODO(vojta): rewrite link when opening in new tab/window (in legacy browser) // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser)
// currently we open nice url link and redirect then // currently we open nice url link and redirect then
if (!html5Mode.rewriteLinks || event.ctrlKey || event.metaKey || event.which == 2) return; if (!html5Mode.rewriteLinks || event.ctrlKey || event.metaKey || event.shiftKey || event.which == 2 || event.button == 2) return;
var elm = jqLite(event.target); var elm = jqLite(event.target);
@ -11362,7 +11371,7 @@ function $LocationProvider() {
// rewrite hashbang url <> html5 url // rewrite hashbang url <> html5 url
if ($location.absUrl() != initialUrl) { if (trimEmptyHash($location.absUrl()) != trimEmptyHash(initialUrl)) {
$browser.url($location.absUrl(), true); $browser.url($location.absUrl(), true);
} }
@ -12336,6 +12345,11 @@ Parser.prototype = {
? fn.apply(context, args) ? fn.apply(context, args)
: fn(args[0], args[1], args[2], args[3], args[4]); : fn(args[0], args[1], args[2], args[3], args[4]);
if (args) {
// Free-up the memory (arguments of the last function call).
args.length = 0;
}
return ensureSafeObject(v, expressionText); return ensureSafeObject(v, expressionText);
}; };
}, },
@ -13207,8 +13221,7 @@ function qFactory(nextTick, exceptionHandler) {
'qcycle', 'qcycle',
"Expected promise to be resolved with value other than itself '{0}'", "Expected promise to be resolved with value other than itself '{0}'",
val)); val));
} } else {
else {
this.$$resolve(val); this.$$resolve(val);
} }
@ -17665,6 +17678,9 @@ var htmlAnchorDirective = valueFn({
compile: function(element, attr) { compile: function(element, attr) {
if (!attr.href && !attr.xlinkHref && !attr.name) { if (!attr.href && !attr.xlinkHref && !attr.name) {
return function(scope, element) { return function(scope, element) {
// If the linked element is not an anchor tag anymore, do nothing
if (element[0].nodeName.toLowerCase() !== 'a') return;
// SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute. // SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.
var href = toString.call(element.prop('href')) === '[object SVGAnimatedString]' ? var href = toString.call(element.prop('href')) === '[object SVGAnimatedString]' ?
'xlink:href' : 'href'; 'xlink:href' : 'href';
@ -17838,20 +17854,23 @@ var htmlAnchorDirective = valueFn({
* *
* @description * @description
* *
* We shouldn't do this, because it will make the button enabled on Chrome/Firefox but not on IE8 and older IEs: * This directive sets the `disabled` attribute on the element if the
* {@link guide/expression expression} inside `ngDisabled` evaluates to truthy.
*
* A special directive is necessary because we cannot use interpolation inside the `disabled`
* attribute. The following example would make the button enabled on Chrome/Firefox
* but not on older IEs:
*
* ```html * ```html
* <div ng-init="scope = { isDisabled: false }"> * <div ng-init="isDisabled = false">
* <button disabled="{{scope.isDisabled}}">Disabled</button> * <button disabled="{{isDisabled}}">Disabled</button>
* </div> * </div>
* ``` * ```
* *
* The HTML specification does not require browsers to preserve the values of boolean attributes * This is because the HTML specification does not require browsers to preserve the values of
* such as disabled. (Their presence means true and their absence means false.) * boolean attributes such as `disabled` (Their presence means true and their absence means false.)
* If we put an Angular interpolation expression into such an attribute then the * If we put an Angular interpolation expression into such an attribute then the
* binding information would be lost when the browser removes the attribute. * binding information would be lost when the browser removes the attribute.
* The `ngDisabled` directive solves this problem for the `disabled` attribute.
* This complementary directive is not removed by the browser and so provides
* a permanent reliable place to store the binding information.
* *
* @example * @example
<example> <example>
@ -17870,7 +17889,7 @@ var htmlAnchorDirective = valueFn({
* *
* @element INPUT * @element INPUT
* @param {expression} ngDisabled If the {@link guide/expression expression} is truthy, * @param {expression} ngDisabled If the {@link guide/expression expression} is truthy,
* then special attribute "disabled" will be set on the element * then the `disabled` attribute will be set on the element
*/ */
@ -18683,19 +18702,21 @@ var inputType = {
<script> <script>
angular.module('textInputExample', []) angular.module('textInputExample', [])
.controller('ExampleController', ['$scope', function($scope) { .controller('ExampleController', ['$scope', function($scope) {
$scope.text = 'guest'; $scope.example = {
$scope.word = /^\s*\w*\s*$/; text: 'guest',
word: /^\s*\w*\s*$/
};
}]); }]);
</script> </script>
<form name="myForm" ng-controller="ExampleController"> <form name="myForm" ng-controller="ExampleController">
Single word: <input type="text" name="input" ng-model="text" Single word: <input type="text" name="input" ng-model="example.text"
ng-pattern="word" required ng-trim="false"> ng-pattern="example.word" required ng-trim="false">
<span class="error" ng-show="myForm.input.$error.required"> <span class="error" ng-show="myForm.input.$error.required">
Required!</span> Required!</span>
<span class="error" ng-show="myForm.input.$error.pattern"> <span class="error" ng-show="myForm.input.$error.pattern">
Single word only!</span> Single word only!</span>
<tt>text = {{text}}</tt><br/> <tt>text = {{example.text}}</tt><br/>
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/> <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/> <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/> <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
@ -18703,9 +18724,9 @@ var inputType = {
</form> </form>
</file> </file>
<file name="protractor.js" type="protractor"> <file name="protractor.js" type="protractor">
var text = element(by.binding('text')); var text = element(by.binding('example.text'));
var valid = element(by.binding('myForm.input.$valid')); var valid = element(by.binding('myForm.input.$valid'));
var input = element(by.model('text')); var input = element(by.model('example.text'));
it('should initialize to model', function() { it('should initialize to model', function() {
expect(text.getText()).toContain('guest'); expect(text.getText()).toContain('guest');
@ -18767,18 +18788,20 @@ var inputType = {
<script> <script>
angular.module('dateInputExample', []) angular.module('dateInputExample', [])
.controller('DateController', ['$scope', function($scope) { .controller('DateController', ['$scope', function($scope) {
$scope.value = new Date(2013, 9, 22); $scope.example = {
value: new Date(2013, 9, 22)
};
}]); }]);
</script> </script>
<form name="myForm" ng-controller="DateController as dateCtrl"> <form name="myForm" ng-controller="DateController as dateCtrl">
Pick a date in 2013: Pick a date in 2013:
<input type="date" id="exampleInput" name="input" ng-model="value" <input type="date" id="exampleInput" name="input" ng-model="example.value"
placeholder="yyyy-MM-dd" min="2013-01-01" max="2013-12-31" required /> placeholder="yyyy-MM-dd" min="2013-01-01" max="2013-12-31" required />
<span class="error" ng-show="myForm.input.$error.required"> <span class="error" ng-show="myForm.input.$error.required">
Required!</span> Required!</span>
<span class="error" ng-show="myForm.input.$error.date"> <span class="error" ng-show="myForm.input.$error.date">
Not a valid date!</span> Not a valid date!</span>
<tt>value = {{value | date: "yyyy-MM-dd"}}</tt><br/> <tt>value = {{example.value | date: "yyyy-MM-dd"}}</tt><br/>
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/> <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/> <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/> <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
@ -18786,9 +18809,9 @@ var inputType = {
</form> </form>
</file> </file>
<file name="protractor.js" type="protractor"> <file name="protractor.js" type="protractor">
var value = element(by.binding('value | date: "yyyy-MM-dd"')); var value = element(by.binding('example.value | date: "yyyy-MM-dd"'));
var valid = element(by.binding('myForm.input.$valid')); var valid = element(by.binding('myForm.input.$valid'));
var input = element(by.model('value')); var input = element(by.model('example.value'));
// currently protractor/webdriver does not support // currently protractor/webdriver does not support
// sending keys to all known HTML5 input controls // sending keys to all known HTML5 input controls
@ -18858,18 +18881,20 @@ var inputType = {
<script> <script>
angular.module('dateExample', []) angular.module('dateExample', [])
.controller('DateController', ['$scope', function($scope) { .controller('DateController', ['$scope', function($scope) {
$scope.value = new Date(2010, 11, 28, 14, 57); $scope.example = {
value: new Date(2010, 11, 28, 14, 57)
};
}]); }]);
</script> </script>
<form name="myForm" ng-controller="DateController as dateCtrl"> <form name="myForm" ng-controller="DateController as dateCtrl">
Pick a date between in 2013: Pick a date between in 2013:
<input type="datetime-local" id="exampleInput" name="input" ng-model="value" <input type="datetime-local" id="exampleInput" name="input" ng-model="example.value"
placeholder="yyyy-MM-ddTHH:mm:ss" min="2001-01-01T00:00:00" max="2013-12-31T00:00:00" required /> placeholder="yyyy-MM-ddTHH:mm:ss" min="2001-01-01T00:00:00" max="2013-12-31T00:00:00" required />
<span class="error" ng-show="myForm.input.$error.required"> <span class="error" ng-show="myForm.input.$error.required">
Required!</span> Required!</span>
<span class="error" ng-show="myForm.input.$error.datetimelocal"> <span class="error" ng-show="myForm.input.$error.datetimelocal">
Not a valid date!</span> Not a valid date!</span>
<tt>value = {{value | date: "yyyy-MM-ddTHH:mm:ss"}}</tt><br/> <tt>value = {{example.value | date: "yyyy-MM-ddTHH:mm:ss"}}</tt><br/>
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/> <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/> <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/> <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
@ -18877,9 +18902,9 @@ var inputType = {
</form> </form>
</file> </file>
<file name="protractor.js" type="protractor"> <file name="protractor.js" type="protractor">
var value = element(by.binding('value | date: "yyyy-MM-ddTHH:mm:ss"')); var value = element(by.binding('example.value | date: "yyyy-MM-ddTHH:mm:ss"'));
var valid = element(by.binding('myForm.input.$valid')); var valid = element(by.binding('myForm.input.$valid'));
var input = element(by.model('value')); var input = element(by.model('example.value'));
// currently protractor/webdriver does not support // currently protractor/webdriver does not support
// sending keys to all known HTML5 input controls // sending keys to all known HTML5 input controls
@ -18950,18 +18975,20 @@ var inputType = {
<script> <script>
angular.module('timeExample', []) angular.module('timeExample', [])
.controller('DateController', ['$scope', function($scope) { .controller('DateController', ['$scope', function($scope) {
$scope.value = new Date(1970, 0, 1, 14, 57, 0); $scope.example = {
value: new Date(1970, 0, 1, 14, 57, 0)
};
}]); }]);
</script> </script>
<form name="myForm" ng-controller="DateController as dateCtrl"> <form name="myForm" ng-controller="DateController as dateCtrl">
Pick a between 8am and 5pm: Pick a between 8am and 5pm:
<input type="time" id="exampleInput" name="input" ng-model="value" <input type="time" id="exampleInput" name="input" ng-model="example.value"
placeholder="HH:mm:ss" min="08:00:00" max="17:00:00" required /> placeholder="HH:mm:ss" min="08:00:00" max="17:00:00" required />
<span class="error" ng-show="myForm.input.$error.required"> <span class="error" ng-show="myForm.input.$error.required">
Required!</span> Required!</span>
<span class="error" ng-show="myForm.input.$error.time"> <span class="error" ng-show="myForm.input.$error.time">
Not a valid date!</span> Not a valid date!</span>
<tt>value = {{value | date: "HH:mm:ss"}}</tt><br/> <tt>value = {{example.value | date: "HH:mm:ss"}}</tt><br/>
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/> <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/> <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/> <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
@ -18969,9 +18996,9 @@ var inputType = {
</form> </form>
</file> </file>
<file name="protractor.js" type="protractor"> <file name="protractor.js" type="protractor">
var value = element(by.binding('value | date: "HH:mm:ss"')); var value = element(by.binding('example.value | date: "HH:mm:ss"'));
var valid = element(by.binding('myForm.input.$valid')); var valid = element(by.binding('myForm.input.$valid'));
var input = element(by.model('value')); var input = element(by.model('example.value'));
// currently protractor/webdriver does not support // currently protractor/webdriver does not support
// sending keys to all known HTML5 input controls // sending keys to all known HTML5 input controls
@ -19041,18 +19068,20 @@ var inputType = {
<script> <script>
angular.module('weekExample', []) angular.module('weekExample', [])
.controller('DateController', ['$scope', function($scope) { .controller('DateController', ['$scope', function($scope) {
$scope.value = new Date(2013, 0, 3); $scope.example = {
value: new Date(2013, 0, 3)
};
}]); }]);
</script> </script>
<form name="myForm" ng-controller="DateController as dateCtrl"> <form name="myForm" ng-controller="DateController as dateCtrl">
Pick a date between in 2013: Pick a date between in 2013:
<input id="exampleInput" type="week" name="input" ng-model="value" <input id="exampleInput" type="week" name="input" ng-model="example.value"
placeholder="YYYY-W##" min="2012-W32" max="2013-W52" required /> placeholder="YYYY-W##" min="2012-W32" max="2013-W52" required />
<span class="error" ng-show="myForm.input.$error.required"> <span class="error" ng-show="myForm.input.$error.required">
Required!</span> Required!</span>
<span class="error" ng-show="myForm.input.$error.week"> <span class="error" ng-show="myForm.input.$error.week">
Not a valid date!</span> Not a valid date!</span>
<tt>value = {{value | date: "yyyy-Www"}}</tt><br/> <tt>value = {{example.value | date: "yyyy-Www"}}</tt><br/>
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/> <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/> <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/> <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
@ -19060,9 +19089,9 @@ var inputType = {
</form> </form>
</file> </file>
<file name="protractor.js" type="protractor"> <file name="protractor.js" type="protractor">
var value = element(by.binding('value | date: "yyyy-Www"')); var value = element(by.binding('example.value | date: "yyyy-Www"'));
var valid = element(by.binding('myForm.input.$valid')); var valid = element(by.binding('myForm.input.$valid'));
var input = element(by.model('value')); var input = element(by.model('example.value'));
// currently protractor/webdriver does not support // currently protractor/webdriver does not support
// sending keys to all known HTML5 input controls // sending keys to all known HTML5 input controls
@ -19132,18 +19161,20 @@ var inputType = {
<script> <script>
angular.module('monthExample', []) angular.module('monthExample', [])
.controller('DateController', ['$scope', function($scope) { .controller('DateController', ['$scope', function($scope) {
$scope.value = new Date(2013, 9, 1); $scope.example = {
value: new Date(2013, 9, 1)
};
}]); }]);
</script> </script>
<form name="myForm" ng-controller="DateController as dateCtrl"> <form name="myForm" ng-controller="DateController as dateCtrl">
Pick a month int 2013: Pick a month in 2013:
<input id="exampleInput" type="month" name="input" ng-model="value" <input id="exampleInput" type="month" name="input" ng-model="example.value"
placeholder="yyyy-MM" min="2013-01" max="2013-12" required /> placeholder="yyyy-MM" min="2013-01" max="2013-12" required />
<span class="error" ng-show="myForm.input.$error.required"> <span class="error" ng-show="myForm.input.$error.required">
Required!</span> Required!</span>
<span class="error" ng-show="myForm.input.$error.month"> <span class="error" ng-show="myForm.input.$error.month">
Not a valid month!</span> Not a valid month!</span>
<tt>value = {{value | date: "yyyy-MM"}}</tt><br/> <tt>value = {{example.value | date: "yyyy-MM"}}</tt><br/>
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/> <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/> <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/> <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
@ -19151,9 +19182,9 @@ var inputType = {
</form> </form>
</file> </file>
<file name="protractor.js" type="protractor"> <file name="protractor.js" type="protractor">
var value = element(by.binding('value | date: "yyyy-MM"')); var value = element(by.binding('example.value | date: "yyyy-MM"'));
var valid = element(by.binding('myForm.input.$valid')); var valid = element(by.binding('myForm.input.$valid'));
var input = element(by.model('value')); var input = element(by.model('example.value'));
// currently protractor/webdriver does not support // currently protractor/webdriver does not support
// sending keys to all known HTML5 input controls // sending keys to all known HTML5 input controls
@ -19229,17 +19260,19 @@ var inputType = {
<script> <script>
angular.module('numberExample', []) angular.module('numberExample', [])
.controller('ExampleController', ['$scope', function($scope) { .controller('ExampleController', ['$scope', function($scope) {
$scope.value = 12; $scope.example = {
value: 12
};
}]); }]);
</script> </script>
<form name="myForm" ng-controller="ExampleController"> <form name="myForm" ng-controller="ExampleController">
Number: <input type="number" name="input" ng-model="value" Number: <input type="number" name="input" ng-model="example.value"
min="0" max="99" required> min="0" max="99" required>
<span class="error" ng-show="myForm.input.$error.required"> <span class="error" ng-show="myForm.input.$error.required">
Required!</span> Required!</span>
<span class="error" ng-show="myForm.input.$error.number"> <span class="error" ng-show="myForm.input.$error.number">
Not valid number!</span> Not valid number!</span>
<tt>value = {{value}}</tt><br/> <tt>value = {{example.value}}</tt><br/>
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/> <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/> <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/> <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
@ -19247,9 +19280,9 @@ var inputType = {
</form> </form>
</file> </file>
<file name="protractor.js" type="protractor"> <file name="protractor.js" type="protractor">
var value = element(by.binding('value')); var value = element(by.binding('example.value'));
var valid = element(by.binding('myForm.input.$valid')); var valid = element(by.binding('myForm.input.$valid'));
var input = element(by.model('value')); var input = element(by.model('example.value'));
it('should initialize to model', function() { it('should initialize to model', function() {
expect(value.getText()).toContain('12'); expect(value.getText()).toContain('12');
@ -19317,16 +19350,18 @@ var inputType = {
<script> <script>
angular.module('urlExample', []) angular.module('urlExample', [])
.controller('ExampleController', ['$scope', function($scope) { .controller('ExampleController', ['$scope', function($scope) {
$scope.text = 'http://google.com'; $scope.url = {
text: 'http://google.com'
};
}]); }]);
</script> </script>
<form name="myForm" ng-controller="ExampleController"> <form name="myForm" ng-controller="ExampleController">
URL: <input type="url" name="input" ng-model="text" required> URL: <input type="url" name="input" ng-model="url.text" required>
<span class="error" ng-show="myForm.input.$error.required"> <span class="error" ng-show="myForm.input.$error.required">
Required!</span> Required!</span>
<span class="error" ng-show="myForm.input.$error.url"> <span class="error" ng-show="myForm.input.$error.url">
Not valid url!</span> Not valid url!</span>
<tt>text = {{text}}</tt><br/> <tt>text = {{url.text}}</tt><br/>
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/> <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/> <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/> <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
@ -19335,9 +19370,9 @@ var inputType = {
</form> </form>
</file> </file>
<file name="protractor.js" type="protractor"> <file name="protractor.js" type="protractor">
var text = element(by.binding('text')); var text = element(by.binding('url.text'));
var valid = element(by.binding('myForm.input.$valid')); var valid = element(by.binding('myForm.input.$valid'));
var input = element(by.model('text')); var input = element(by.model('url.text'));
it('should initialize to model', function() { it('should initialize to model', function() {
expect(text.getText()).toContain('http://google.com'); expect(text.getText()).toContain('http://google.com');
@ -19406,16 +19441,18 @@ var inputType = {
<script> <script>
angular.module('emailExample', []) angular.module('emailExample', [])
.controller('ExampleController', ['$scope', function($scope) { .controller('ExampleController', ['$scope', function($scope) {
$scope.text = 'me@example.com'; $scope.email = {
text: 'me@example.com'
};
}]); }]);
</script> </script>
<form name="myForm" ng-controller="ExampleController"> <form name="myForm" ng-controller="ExampleController">
Email: <input type="email" name="input" ng-model="text" required> Email: <input type="email" name="input" ng-model="email.text" required>
<span class="error" ng-show="myForm.input.$error.required"> <span class="error" ng-show="myForm.input.$error.required">
Required!</span> Required!</span>
<span class="error" ng-show="myForm.input.$error.email"> <span class="error" ng-show="myForm.input.$error.email">
Not valid email!</span> Not valid email!</span>
<tt>text = {{text}}</tt><br/> <tt>text = {{email.text}}</tt><br/>
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/> <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/> <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/> <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
@ -19424,9 +19461,9 @@ var inputType = {
</form> </form>
</file> </file>
<file name="protractor.js" type="protractor"> <file name="protractor.js" type="protractor">
var text = element(by.binding('text')); var text = element(by.binding('email.text'));
var valid = element(by.binding('myForm.input.$valid')); var valid = element(by.binding('myForm.input.$valid'));
var input = element(by.model('text')); var input = element(by.model('email.text'));
it('should initialize to model', function() { it('should initialize to model', function() {
expect(text.getText()).toContain('me@example.com'); expect(text.getText()).toContain('me@example.com');
@ -19473,7 +19510,9 @@ var inputType = {
<script> <script>
angular.module('radioExample', []) angular.module('radioExample', [])
.controller('ExampleController', ['$scope', function($scope) { .controller('ExampleController', ['$scope', function($scope) {
$scope.color = 'blue'; $scope.color = {
name: 'blue'
};
$scope.specialValue = { $scope.specialValue = {
"id": "12345", "id": "12345",
"value": "green" "value": "green"
@ -19481,20 +19520,20 @@ var inputType = {
}]); }]);
</script> </script>
<form name="myForm" ng-controller="ExampleController"> <form name="myForm" ng-controller="ExampleController">
<input type="radio" ng-model="color" value="red"> Red <br/> <input type="radio" ng-model="color.name" value="red"> Red <br/>
<input type="radio" ng-model="color" ng-value="specialValue"> Green <br/> <input type="radio" ng-model="color.name" ng-value="specialValue"> Green <br/>
<input type="radio" ng-model="color" value="blue"> Blue <br/> <input type="radio" ng-model="color.name" value="blue"> Blue <br/>
<tt>color = {{color | json}}</tt><br/> <tt>color = {{color.name | json}}</tt><br/>
</form> </form>
Note that `ng-value="specialValue"` sets radio item's value to be the value of `$scope.specialValue`. Note that `ng-value="specialValue"` sets radio item's value to be the value of `$scope.specialValue`.
</file> </file>
<file name="protractor.js" type="protractor"> <file name="protractor.js" type="protractor">
it('should change state', function() { it('should change state', function() {
var color = element(by.binding('color')); var color = element(by.binding('color.name'));
expect(color.getText()).toContain('blue'); expect(color.getText()).toContain('blue');
element.all(by.model('color')).get(0).click(); element.all(by.model('color.name')).get(0).click();
expect(color.getText()).toContain('red'); expect(color.getText()).toContain('red');
}); });
@ -19524,28 +19563,30 @@ var inputType = {
<script> <script>
angular.module('checkboxExample', []) angular.module('checkboxExample', [])
.controller('ExampleController', ['$scope', function($scope) { .controller('ExampleController', ['$scope', function($scope) {
$scope.value1 = true; $scope.checkboxModel = {
$scope.value2 = 'YES' value1 : true,
value2 : 'YES'
};
}]); }]);
</script> </script>
<form name="myForm" ng-controller="ExampleController"> <form name="myForm" ng-controller="ExampleController">
Value1: <input type="checkbox" ng-model="value1"> <br/> Value1: <input type="checkbox" ng-model="checkboxModel.value1"> <br/>
Value2: <input type="checkbox" ng-model="value2" Value2: <input type="checkbox" ng-model="checkboxModel.value2"
ng-true-value="'YES'" ng-false-value="'NO'"> <br/> ng-true-value="'YES'" ng-false-value="'NO'"> <br/>
<tt>value1 = {{value1}}</tt><br/> <tt>value1 = {{checkboxModel.value1}}</tt><br/>
<tt>value2 = {{value2}}</tt><br/> <tt>value2 = {{checkboxModel.value2}}</tt><br/>
</form> </form>
</file> </file>
<file name="protractor.js" type="protractor"> <file name="protractor.js" type="protractor">
it('should change state', function() { it('should change state', function() {
var value1 = element(by.binding('value1')); var value1 = element(by.binding('checkboxModel.value1'));
var value2 = element(by.binding('value2')); var value2 = element(by.binding('checkboxModel.value2'));
expect(value1.getText()).toContain('true'); expect(value1.getText()).toContain('true');
expect(value2.getText()).toContain('YES'); expect(value2.getText()).toContain('YES');
element(by.model('value1')).click(); element(by.model('checkboxModel.value1')).click();
element(by.model('value2')).click(); element(by.model('checkboxModel.value2')).click();
expect(value1.getText()).toContain('false'); expect(value1.getText()).toContain('false');
expect(value2.getText()).toContain('NO'); expect(value2.getText()).toContain('NO');
@ -19850,7 +19891,7 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
return value; return value;
}); });
if (attr.min || attr.ngMin) { if (isDefined(attr.min) || attr.ngMin) {
var minVal; var minVal;
ctrl.$validators.min = function(value) { ctrl.$validators.min = function(value) {
return ctrl.$isEmpty(value) || isUndefined(minVal) || value >= minVal; return ctrl.$isEmpty(value) || isUndefined(minVal) || value >= minVal;
@ -19866,7 +19907,7 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
}); });
} }
if (attr.max || attr.ngMax) { if (isDefined(attr.max) || attr.ngMax) {
var maxVal; var maxVal;
ctrl.$validators.max = function(value) { ctrl.$validators.max = function(value) {
return ctrl.$isEmpty(value) || isUndefined(maxVal) || value <= maxVal; return ctrl.$isEmpty(value) || isUndefined(maxVal) || value <= maxVal;
@ -22254,7 +22295,7 @@ var ngIncludeFillContentDirective = ['$compile',
* **Note**: If you have assignment in `ngInit` along with {@link ng.$filter `$filter`}, make * **Note**: If you have assignment in `ngInit` along with {@link ng.$filter `$filter`}, make
* sure you have parenthesis for correct precedence: * sure you have parenthesis for correct precedence:
* <pre class="prettyprint"> * <pre class="prettyprint">
* <div ng-init="test1 = (data | orderBy:'name')"></div> * `<div ng-init="test1 = (data | orderBy:'name')"></div>`
* </pre> * </pre>
* </div> * </div>
* *
@ -22672,6 +22713,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
ngModelGet = parsedNgModel, ngModelGet = parsedNgModel,
ngModelSet = parsedNgModelAssign, ngModelSet = parsedNgModelAssign,
pendingDebounce = null, pendingDebounce = null,
parserValid,
ctrl = this; ctrl = this;
this.$$setOptions = function(options) { this.$$setOptions = function(options) {
@ -22944,16 +22986,12 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
// the model although neither viewValue nor the model on the scope changed // the model although neither viewValue nor the model on the scope changed
var modelValue = ctrl.$$rawModelValue; var modelValue = ctrl.$$rawModelValue;
// Check if the there's a parse error, so we don't unset it accidentially
var parserName = ctrl.$$parserName || 'parse';
var parserValid = ctrl.$error[parserName] ? false : undefined;
var prevValid = ctrl.$valid; var prevValid = ctrl.$valid;
var prevModelValue = ctrl.$modelValue; var prevModelValue = ctrl.$modelValue;
var allowInvalid = ctrl.$options && ctrl.$options.allowInvalid; var allowInvalid = ctrl.$options && ctrl.$options.allowInvalid;
ctrl.$$runValidators(parserValid, modelValue, viewValue, function(allValid) { ctrl.$$runValidators(modelValue, viewValue, function(allValid) {
// If there was no change in validity, don't update the model // If there was no change in validity, don't update the model
// This prevents changing an invalid modelValue to undefined // This prevents changing an invalid modelValue to undefined
if (!allowInvalid && prevValid !== allValid) { if (!allowInvalid && prevValid !== allValid) {
@ -22971,12 +23009,12 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
}; };
this.$$runValidators = function(parseValid, modelValue, viewValue, doneCallback) { this.$$runValidators = function(modelValue, viewValue, doneCallback) {
currentValidationRunId++; currentValidationRunId++;
var localValidationRunId = currentValidationRunId; var localValidationRunId = currentValidationRunId;
// check parser error // check parser error
if (!processParseErrors(parseValid)) { if (!processParseErrors()) {
validationDone(false); validationDone(false);
return; return;
} }
@ -22986,21 +23024,22 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
} }
processAsyncValidators(); processAsyncValidators();
function processParseErrors(parseValid) { function processParseErrors() {
var errorKey = ctrl.$$parserName || 'parse'; var errorKey = ctrl.$$parserName || 'parse';
if (parseValid === undefined) { if (parserValid === undefined) {
setValidity(errorKey, null); setValidity(errorKey, null);
} else { } else {
setValidity(errorKey, parseValid); if (!parserValid) {
if (!parseValid) {
forEach(ctrl.$validators, function(v, name) { forEach(ctrl.$validators, function(v, name) {
setValidity(name, null); setValidity(name, null);
}); });
forEach(ctrl.$asyncValidators, function(v, name) { forEach(ctrl.$asyncValidators, function(v, name) {
setValidity(name, null); setValidity(name, null);
}); });
return false;
} }
// Set the parse error last, to prevent unsetting it, should a $validators key == parserName
setValidity(errorKey, parserValid);
return parserValid;
} }
return true; return true;
} }
@ -23095,7 +23134,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
this.$$parseAndValidate = function() { this.$$parseAndValidate = function() {
var viewValue = ctrl.$$lastCommittedViewValue; var viewValue = ctrl.$$lastCommittedViewValue;
var modelValue = viewValue; var modelValue = viewValue;
var parserValid = isUndefined(modelValue) ? undefined : true; parserValid = isUndefined(modelValue) ? undefined : true;
if (parserValid) { if (parserValid) {
for (var i = 0; i < ctrl.$parsers.length; i++) { for (var i = 0; i < ctrl.$parsers.length; i++) {
@ -23121,7 +23160,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
// Pass the $$lastCommittedViewValue here, because the cached viewValue might be out of date. // 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 can happen if e.g. $setViewValue is called from inside a parser
ctrl.$$runValidators(parserValid, modelValue, ctrl.$$lastCommittedViewValue, function(allValid) { ctrl.$$runValidators(modelValue, ctrl.$$lastCommittedViewValue, function(allValid) {
if (!allowInvalid) { if (!allowInvalid) {
// Note: Don't check ctrl.$valid here, as we could have // Note: Don't check ctrl.$valid here, as we could have
// external validators (e.g. calculated on the server), // external validators (e.g. calculated on the server),
@ -23242,6 +23281,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
// TODO(perf): why not move this to the action fn? // TODO(perf): why not move this to the action fn?
if (modelValue !== ctrl.$modelValue) { if (modelValue !== ctrl.$modelValue) {
ctrl.$modelValue = ctrl.$$rawModelValue = modelValue; ctrl.$modelValue = ctrl.$$rawModelValue = modelValue;
parserValid = undefined;
var formatters = ctrl.$formatters, var formatters = ctrl.$formatters,
idx = formatters.length; idx = formatters.length;
@ -23254,7 +23294,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue; ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue;
ctrl.$render(); ctrl.$render();
ctrl.$$runValidators(undefined, modelValue, viewValue, noop); ctrl.$$runValidators(modelValue, viewValue, noop);
} }
} }
@ -24070,6 +24110,55 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
* when keys are deleted and reinstated. * when keys are deleted and reinstated.
* *
* *
* # Tracking and Duplicates
*
* When the contents of the collection change, `ngRepeat` makes the corresponding changes to the DOM:
*
* * When an item is added, a new instance of the template is added to the DOM.
* * When an item is removed, its template instance is removed from the DOM.
* * When items are reordered, their respective templates are reordered in the DOM.
*
* By default, `ngRepeat` does not allow duplicate items in arrays. This is because when
* there are duplicates, it is not possible to maintain a one-to-one mapping between collection
* items and DOM elements.
*
* If you do need to repeat duplicate items, you can substitute the default tracking behavior
* with your own using the `track by` expression.
*
* For example, you may track items by the index of each item in the collection, using the
* special scope property `$index`:
* ```html
* <div ng-repeat="n in [42, 42, 43, 43] track by $index">
* {{n}}
* </div>
* ```
*
* You may use arbitrary expressions in `track by`, including references to custom functions
* on the scope:
* ```html
* <div ng-repeat="n in [42, 42, 43, 43] track by myTrackingFunction(n)">
* {{n}}
* </div>
* ```
*
* If you are working with objects that have an identifier property, you can track
* by the identifier instead of the whole object. Should you reload your data later, `ngRepeat`
* will not have to rebuild the DOM elements for items it has already rendered, even if the
* JavaScript objects in the collection have been substituted for new ones:
* ```html
* <div ng-repeat="model in collection track by model.id">
* {{model.name}}
* </div>
* ```
*
* When no `track by` expression is provided, it is equivalent to tracking by the built-in
* `$id` function, which tracks items by their identity:
* ```html
* <div ng-repeat="obj in collection track by $id(obj)">
* {{obj.prop}}
* </div>
* ```
*
* # Special repeat start and end points * # Special repeat start and end points
* To repeat a series of elements instead of just one parent element, ngRepeat (as well as other ng directives) supports extending * To repeat a series of elements instead of just one parent element, ngRepeat (as well as other ng directives) supports extending
* the range of the repeater by defining explicit start and end points by using **ng-repeat-start** and **ng-repeat-end** respectively. * the range of the repeater by defining explicit start and end points by using **ng-repeat-start** and **ng-repeat-end** respectively.
@ -24137,12 +24226,12 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
* *
* For example: `(name, age) in {'adam':10, 'amalie':12}`. * For example: `(name, age) in {'adam':10, 'amalie':12}`.
* *
* * `variable in expression track by tracking_expression` You can also provide an optional tracking function * * `variable in expression track by tracking_expression` You can also provide an optional tracking expression
* which can be used to associate the objects in the collection with the DOM elements. If no tracking function * which can be used to associate the objects in the collection with the DOM elements. If no tracking expression
* is specified the ng-repeat associates elements by identity in the collection. It is an error to have * is specified, ng-repeat associates elements by identity. It is an error to have
* more than one tracking function to resolve to the same key. (This would mean that two distinct objects are * more than one tracking expression value resolve to the same key. (This would mean that two distinct objects are
* mapped to the same DOM element, which is not possible.) Filters should be applied to the expression, * mapped to the same DOM element, which is not possible.) If filters are used in the expression, they should be
* before specifying a tracking expression. * applied before the tracking expression.
* *
* For example: `item in items` is equivalent to `item in items track by $id(item)`. This implies that the DOM elements * For example: `item in items` is equivalent to `item in items track by $id(item)`. This implies that the DOM elements
* will be associated by item identity in the array. * will be associated by item identity in the array.
@ -24526,10 +24615,11 @@ var NG_HIDE_IN_PROGRESS_CLASS = 'ng-hide-animate';
* *
* By default, the `.ng-hide` class will style the element with `display: none!important`. If you wish to change * By default, the `.ng-hide` class will style the element with `display: none!important`. If you wish to change
* the hide behavior with ngShow/ngHide then this can be achieved by restating the styles for the `.ng-hide` * the hide behavior with ngShow/ngHide then this can be achieved by restating the styles for the `.ng-hide`
* class in CSS: * class CSS. Note that the selector that needs to be used is actually `.ng-hide:not(.ng-hide-animate)` to cope
* with extra animation classes that can be added.
* *
* ```css * ```css
* .ng-hide { * .ng-hide:not(.ng-hide-animate) {
* /&#42; this is just another form of hiding an element &#42;/ * /&#42; this is just another form of hiding an element &#42;/
* display: block!important; * display: block!important;
* position: absolute; * position: absolute;
@ -26045,7 +26135,7 @@ var maxlengthDirective = function() {
ctrl.$validate(); ctrl.$validate();
}); });
ctrl.$validators.maxlength = function(modelValue, viewValue) { ctrl.$validators.maxlength = function(modelValue, viewValue) {
return (maxlength < 0) || ctrl.$isEmpty(modelValue) || (viewValue.length <= maxlength); return (maxlength < 0) || ctrl.$isEmpty(viewValue) || (viewValue.length <= maxlength);
}; };
} }
}; };

Просмотреть файл

@ -271,6 +271,7 @@
<Content Include="package.json" /> <Content Include="package.json" />
<Content Include="sdk\mscorlib.dll" /> <Content Include="sdk\mscorlib.dll" />
<Content Include="sdk\mscorlib.xml" /> <Content Include="sdk\mscorlib.xml" />
<Content Include="sdk\old\wwtsdk_old.debug.js" />
<Content Include="sdk\Script.Web.dll" /> <Content Include="sdk\Script.Web.dll" />
<Content Include="sdk\Script.Web.xml" /> <Content Include="sdk\Script.Web.xml" />
<Content Include="sdk\ss.js" /> <Content Include="sdk\ss.js" />
@ -321,8 +322,6 @@
<Fakes Include="Fakes\Wurfl.fakes" /> <Fakes Include="Fakes\Wurfl.fakes" />
<Fakes Include="Fakes\Wurfl.Aspnet.Extensions.fakes" /> <Fakes Include="Fakes\Wurfl.Aspnet.Extensions.fakes" />
<Content Include="ext\angular-touch.min.js.map" /> <Content Include="ext\angular-touch.min.js.map" />
<Content Include="App_Readme\WURFL-v1.5.3.chm" />
<Content Include="App_Readme\WURFL Quick Guide_v1_5.pdf" />
<Content Include="App_Data\wurfl-latest.zip" /> <Content Include="App_Data\wurfl-latest.zip" />
<Content Include="packages.config" /> <Content Include="packages.config" />
<Content Include="ensurenpm.cmd" /> <Content Include="ensurenpm.cmd" />
@ -336,6 +335,9 @@
</None> </None>
<Content Include="README.md" /> <Content Include="README.md" />
<Content Include="sdk\wwtlib.scripts" /> <Content Include="sdk\wwtlib.scripts" />
<Content Include="sdk\wwtsdk.min.js.map">
<DependentUpon>wwtsdk.min.js</DependentUpon>
</Content>
<None Include="Web.Debug.config"> <None Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon> <DependentUpon>Web.config</DependentUpon>
</None> </None>
@ -343,7 +345,9 @@
<DependentUpon>Web.config</DependentUpon> <DependentUpon>Web.config</DependentUpon>
</None> </None>
<Content Include="webclient.sln.DotSettings" /> <Content Include="webclient.sln.DotSettings" />
<Content Include="Wise.wtml" /> <Content Include="Wise.wtml">
<SubType>Designer</SubType>
</Content>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Web.config" /> <Content Include="Web.config" />