Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 2c1bc3d

Browse files
committed
chore(ngSwitch): remove change attribute and update spec
2 parents 99c17ca + 202aed7 commit 2c1bc3d

23 files changed

+985
-363
lines changed

CHANGELOG.md

Lines changed: 321 additions & 0 deletions
Large diffs are not rendered by default.

compare-master-to-stable.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ then(allInSeries(function (branch) {
145145
line = line.split(' ');
146146
var sha = line.shift();
147147
var msg = line.join(' ');
148-
return sha + (msg.toLowerCase().indexOf('fix') === -1 ? ' ' : ' * ') + msg;
148+
return sha + ((/fix\([^\)]+\):/i.test(msg)) ? ' * ' : ' ') + msg;
149149
});
150150
branch.log = log.map(function (line) {
151151
return line.substr(41);

docs/app/e2e/docsAppE2E.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,29 @@
11
'use strict';
22

3+
var webdriver = require('protractor/node_modules/selenium-webdriver');
4+
35
describe('docs.angularjs.org', function () {
6+
7+
beforeEach(function() {
8+
// read and clear logs from previous tests
9+
browser.manage().logs().get('browser');
10+
});
11+
12+
13+
afterEach(function() {
14+
// verify that there were no console errors in the browser
15+
browser.manage().logs().get('browser').then(function(browserLog) {
16+
var filteredLog = browserLog.filter(function(logEntry) {
17+
return logEntry.level.value > webdriver.logging.Level.WARNING.value;
18+
});
19+
expect(filteredLog.length).toEqual(0);
20+
if (filteredLog.length) {
21+
console.log('browser console errors: ' + require('util').inspect(filteredLog));
22+
}
23+
});
24+
});
25+
26+
427
describe('App', function () {
528
// it('should filter the module list when searching', function () {
629
// browser.get();
@@ -67,6 +90,12 @@ describe('docs.angularjs.org', function () {
6790
browser.get('index-debug.html#!error/ng/areq?p0=Missing&p1=not%20a%20function,%20got%20undefined');
6891
expect(element(by.css('.minerr-errmsg')).getText()).toEqual("Argument 'Missing' is not a function, got undefined");
6992
});
93+
94+
95+
it("should display links to code on GitHub", function() {
96+
browser.get('index-debug.html#!/api/does/not/exist');
97+
expect(element(by.css('h1')).getText()).toBe('Oops!');
98+
});
7099
});
71100

72101
describe("templates", function() {

docs/app/src/docs.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ angular.module('DocsController', [])
3333

3434
$scope.navClass = function(navItem) {
3535
return {
36-
active: navItem.href && this.currentPage.path,
36+
active: navItem.href && this.currentPage && this.currentPage.path,
3737
'nav-index-section': navItem.type === 'section'
3838
};
3939
};
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
@ngdoc error
2+
@name $location:nobase
3+
@fullName $location in HTML5 mode requires a <base> tag to be present!
4+
@description
5+
6+
If you configure {@link ng.$location `$location`} to use
7+
{@ng.provider.$locationProvider `html5Mode`} (`history.pushState`), you need to specify the base URL for the application with a [`<base href="">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base) tag.
8+
9+
The base URL is then used to resolve all relative URLs throughout the application regardless of the
10+
entry point into the app.
11+
12+
If you are deploying your app into the root context (e.g. `https://myapp.com/`), set the base URL to `/`:
13+
14+
```html
15+
<head>
16+
<base href="/">
17+
...
18+
</head>
19+
```
20+
21+
If you are deploying your app into a sub-context (e.g. `https://myapp.com/subapp/`), set the base URL to the
22+
URL of the subcontext:
23+
24+
```html
25+
<head>
26+
<base href="/myapp">
27+
...
28+
</head>
29+
```
30+
31+
Before Angular 1.3 we didn't have this hard requirement and it was easy to write apps that worked
32+
when deployed in the root context but were broken when moved to a sub-context because in the
33+
sub-context all absolute urls would resolve to the root context of the app. To prevent this,
34+
use relative URLs throughout your app:
35+
36+
```html
37+
<!-- wrong: -->
38+
<a href="/userProfile">User Profile</a>
39+
40+
41+
<!-- correct: -->
42+
<a href="userProfile">User Profile</a>
43+
44+
```
45+
46+
Additionally, if you want to support [browsers that don't have the `history.pushState`
47+
API](http://caniuse.com/#feat=history), the fallback mechanism provided by `$location`
48+
won't work well without specifying the base url of the application.
49+
50+
In order to make it easier to migrate from hashbang mode to html5 mode, we require that the base
51+
URL is always specified when `$location`'s `html5mode` is enabled.

docs/content/guide/$location.ngdoc

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -325,20 +325,22 @@ to URLs that should be handled with `.`. Now, links to locations, which are not
325325
are not prefixed with `.` and will not be intercepted by the `otherwise` rule in your `$routeProvider`.
326326

327327

328-
### Server side
328+
### Relative links
329329

330-
Using this mode requires URL rewriting on server side, basically you have to rewrite all your links
331-
to entry point of your application (e.g. index.html)
330+
Be sure to check all relative links, images, scripts etc. Angular requires you to specify the url base in
331+
the head of your main html file (`<base href="/my-base">`). With that, relative urls will
332+
always be resolved to this base url, event if the initial url of the document was different.
332333

333-
### Relative links
334+
There is one exception: Links that only contain a hash fragment (e.g. `<a href="#target">`)
335+
will only change `$location.hash()` and not modify the url otherwise. This is useful for scrolling
336+
to anchors on the same page without needing to know on which page the user currently is.
334337

335-
Be sure to check all relative links, images, scripts etc. You must either specify the url base in
336-
the head of your main html file (`<base href="/my-base">`) or you must use absolute urls
337-
(starting with `/`) everywhere because relative urls will be resolved to absolute urls using the
338-
initial absolute url of the document, which is often different from the root of the application.
338+
### Server side
339339

340-
Running Angular apps with the History API enabled from document root is strongly encouraged as it
341-
takes care of all relative link issues.
340+
Using this mode requires URL rewriting on server side, basically you have to rewrite all your links
341+
to entry point of your application (e.g. index.html). Requiring a `<base>` tag is also important for
342+
this case, as it allows Angular to differentiate between the part of the url that is the application
343+
base and the path that should be handeled by the application.
342344

343345
### Sending links among different browsers
344346

src/ng/directive/form.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ SUBMITTED_CLASS = 'ng-submitted';
2121
* @property {boolean} $dirty True if user has already interacted with the form.
2222
* @property {boolean} $valid True if all of the containing forms and controls are valid.
2323
* @property {boolean} $invalid True if at least one containing control or form is invalid.
24+
* @property {boolean} $submitted True if user has submitted the form even if its invalid.
2425
*
2526
* @property {Object} $error Is an object hash, containing references to all invalid controls or
2627
* forms, where:

src/ng/directive/input.js

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -899,7 +899,18 @@ function testFlags(validity, flags) {
899899
return false;
900900
}
901901

902+
function stringBasedInputType(ctrl) {
903+
ctrl.$formatters.push(function(value) {
904+
return ctrl.$isEmpty(value) ? value : value.toString();
905+
});
906+
}
907+
902908
function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
909+
baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
910+
stringBasedInputType(ctrl);
911+
}
912+
913+
function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
903914
var validity = element.prop(VALIDITY_STATE_PROPERTY);
904915
var placeholder = element[0].placeholder, noevent = {};
905916
var type = lowercase(element[0].type);
@@ -1050,7 +1061,7 @@ function createDateParser(regexp, mapping) {
10501061
function createDateInputType(type, regexp, parseDate, format) {
10511062
return function dynamicDateInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter) {
10521063
badInputChecker(scope, element, attr, ctrl);
1053-
textInputType(scope, element, attr, ctrl, $sniffer, $browser);
1064+
baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
10541065
var timezone = ctrl && ctrl.$options && ctrl.$options.timezone;
10551066

10561067
ctrl.$$parserName = type;
@@ -1100,7 +1111,7 @@ function badInputChecker(scope, element, attr, ctrl) {
11001111

11011112
function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
11021113
badInputChecker(scope, element, attr, ctrl);
1103-
textInputType(scope, element, attr, ctrl, $sniffer, $browser);
1114+
baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
11041115

11051116
ctrl.$$parserName = 'number';
11061117
ctrl.$parsers.push(function(value) {
@@ -1134,7 +1145,8 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
11341145

11351146
function urlInputType(scope, element, attr, ctrl, $sniffer, $browser) {
11361147
badInputChecker(scope, element, attr, ctrl);
1137-
textInputType(scope, element, attr, ctrl, $sniffer, $browser);
1148+
baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
1149+
stringBasedInputType(ctrl);
11381150

11391151
ctrl.$$parserName = 'url';
11401152
ctrl.$validators.url = function(modelValue, viewValue) {
@@ -1145,7 +1157,8 @@ function urlInputType(scope, element, attr, ctrl, $sniffer, $browser) {
11451157

11461158
function emailInputType(scope, element, attr, ctrl, $sniffer, $browser) {
11471159
badInputChecker(scope, element, attr, ctrl);
1148-
textInputType(scope, element, attr, ctrl, $sniffer, $browser);
1160+
baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
1161+
stringBasedInputType(ctrl);
11491162

11501163
ctrl.$$parserName = 'email';
11511164
ctrl.$validators.email = function(modelValue, viewValue) {
@@ -2473,8 +2486,8 @@ var maxlengthDirective = function() {
24732486
maxlength = int(value) || 0;
24742487
ctrl.$validate();
24752488
});
2476-
ctrl.$validators.maxlength = function(value) {
2477-
return ctrl.$isEmpty(value) || value.length <= maxlength;
2489+
ctrl.$validators.maxlength = function(modelValue, viewValue) {
2490+
return ctrl.$isEmpty(viewValue) || viewValue.length <= maxlength;
24782491
};
24792492
}
24802493
};
@@ -2492,8 +2505,8 @@ var minlengthDirective = function() {
24922505
minlength = int(value) || 0;
24932506
ctrl.$validate();
24942507
});
2495-
ctrl.$validators.minlength = function(value) {
2496-
return ctrl.$isEmpty(value) || value.length >= minlength;
2508+
ctrl.$validators.minlength = function(modelValue, viewValue) {
2509+
return ctrl.$isEmpty(viewValue) || viewValue.length >= minlength;
24972510
};
24982511
}
24992512
};
@@ -2585,6 +2598,7 @@ var minlengthDirective = function() {
25852598
var ngListDirective = function() {
25862599
return {
25872600
restrict: 'A',
2601+
priority: 100,
25882602
require: 'ngModel',
25892603
link: function(scope, element, attr, ctrl) {
25902604
// We want to control whitespace trimming so we use this convoluted approach

src/ng/directive/ngRepeat.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,9 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
364364
forEach(nextBlockOrder, function (block) {
365365
if (block && block.scope) lastBlockMap[block.id] = block;
366366
});
367-
throw ngRepeatMinErr('dupes', "Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}",
368-
expression, trackById);
367+
throw ngRepeatMinErr('dupes',
368+
"Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}, Duplicate value: {2}",
369+
expression, trackById, toJson(value));
369370
} else {
370371
// new never before seen block
371372
nextBlockOrder[index] = {id: trackById, scope: undefined, clone: undefined};

src/ng/directive/ngSwitch.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -141,23 +141,23 @@ var ngSwitchDirective = ['$animate', function($animate) {
141141
var watchExpr = attr.ngSwitch || attr.on,
142142
selectedTranscludes = [],
143143
selectedElements = [],
144-
previousElements = [],
144+
previousLeaveAnimations = [],
145145
selectedScopes = [];
146146

147147
scope.$watch(watchExpr, function ngSwitchWatchAction(value) {
148148
var i, ii;
149-
for (i = 0, ii = previousElements.length; i < ii; ++i) {
150-
previousElements[i].remove();
149+
for (i = 0, ii = previousLeaveAnimations.length; i < ii; ++i) {
150+
$animate.cancel(previousLeaveAnimations[i]);
151151
}
152-
previousElements.length = 0;
152+
previousLeaveAnimations.length = 0;
153153

154154
for (i = 0, ii = selectedScopes.length; i < ii; ++i) {
155155
var selected = getBlockNodes(selectedElements[i].clone);
156156
selectedScopes[i].$destroy();
157-
previousElements[i] = selected;
158-
$animate.leave(selected).then((function(i) {
157+
var promise = previousLeaveAnimations[i] = $animate.leave(selected);
158+
promise.then((function(i) {
159159
return function(){
160-
previousElements.splice(i, 1).remove();
160+
previousLeaveAnimations.splice(i, 1);
161161
};
162162
}(i)));
163163
}

0 commit comments

Comments
 (0)