Skip to content

Commit 3087beb

Browse files
Merge pull request #41 from angular/master
Update upstream
2 parents c4e4f21 + 7df2952 commit 3087beb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+281
-4896
lines changed

Gruntfile.js

-12
Original file line numberDiff line numberDiff line change
@@ -186,16 +186,6 @@ module.exports = function(grunt) {
186186
},
187187

188188
build: {
189-
scenario: {
190-
dest: 'build/angular-scenario.js',
191-
src: [
192-
'bower_components/jquery/dist/jquery.js',
193-
util.wrap([files['angularSrc'], files['angularScenario']], 'ngScenario/angular')
194-
],
195-
styles: {
196-
css: ['css/angular.css', 'css/angular-scenario.css']
197-
}
198-
},
199189
angular: {
200190
dest: 'build/angular.js',
201191
src: util.wrap([files['angularSrc']], 'angular'),
@@ -281,9 +271,7 @@ module.exports = function(grunt) {
281271
files: [
282272
'src/**/*.js',
283273
'test/**/*.js',
284-
'!test/ngScenario/DescribeSpec.js',
285274
'!src/ng/directive/attrs.js', // legitimate xit here
286-
'!src/ngScenario/**/*.js',
287275
'!test/helpers/privateMocks*.js'
288276
],
289277
options: {

angularFiles.js

-27
Original file line numberDiff line numberDiff line change
@@ -153,26 +153,8 @@ var angularFiles = {
153153
]
154154
},
155155

156-
'angularScenario': [
157-
'src/ngScenario/Scenario.js',
158-
'src/ngScenario/Application.js',
159-
'src/ngScenario/Describe.js',
160-
'src/ngScenario/Future.js',
161-
'src/ngScenario/ObjectModel.js',
162-
'src/ngScenario/Runner.js',
163-
'src/ngScenario/SpecRunner.js',
164-
'src/ngScenario/dsl.js',
165-
'src/ngScenario/matchers.js',
166-
'src/ngScenario/output/Html.js',
167-
'src/ngScenario/output/Json.js',
168-
'src/ngScenario/output/Xml.js',
169-
'src/ngScenario/output/Object.js'
170-
],
171-
172156
'angularTest': [
173157
'test/helpers/*.js',
174-
'test/ngScenario/*.js',
175-
'test/ngScenario/output/*.js',
176158
'test/*.js',
177159
'test/auto/*.js',
178160
'test/ng/**/*.js',
@@ -193,22 +175,15 @@ var angularFiles = {
193175
'test/jquery_remove.js',
194176
'@angularSrc',
195177
'@angularSrcModules',
196-
'@angularScenario',
197178
'@angularTest'
198179
],
199180

200181
'karmaExclude': [
201182
'test/jquery_alias.js',
202183
'src/angular-bootstrap.js',
203-
'src/ngScenario/angular-bootstrap.js',
204184
'src/angular.bind.js'
205185
],
206186

207-
'karmaScenario': [
208-
'build/angular-scenario.js',
209-
'build/docs/docs-scenario.js'
210-
],
211-
212187
'karmaModules': [
213188
'build/angular.js',
214189
'@angularSrcModules',
@@ -231,13 +206,11 @@ var angularFiles = {
231206
'test/jquery_alias.js',
232207
'@angularSrc',
233208
'@angularSrcModules',
234-
'@angularScenario',
235209
'@angularTest'
236210
],
237211

238212
'karmaJqueryExclude': [
239213
'src/angular-bootstrap.js',
240-
'src/ngScenario/angular-bootstrap.js',
241214
'test/jquery_remove.js',
242215
'src/angular.bind.js'
243216
]

docs/content/error/$rootScope/inevt.ngdoc

-22
This file was deleted.

docs/content/guide/e2e-testing.ngdoc

-6
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,6 @@
55

66
# E2E Testing
77

8-
<div class="alert alert-danger">
9-
**Note:** In the past, end-to-end testing could be done with a deprecated tool called
10-
[AngularJS Scenario Runner](http://code.angularjs.org/1.2.16/docs/guide/e2e-testing). That tool
11-
is now in maintenance mode.
12-
</div>
13-
148
As applications grow in size and complexity, it becomes unrealistic to rely on manual testing to
159
verify the correctness of new features, catch bugs and notice regressions. Unit tests
1610
are the first line of defense for catching bugs, but sometimes issues come up with integration

package.json

-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@
6767
"karma-firefox-launcher": "^1.0.1",
6868
"karma-jasmine": "^1.1.0",
6969
"karma-junit-reporter": "^1.2.0",
70-
"karma-ng-scenario": "^1.0.0",
7170
"karma-sauce-launcher": "^1.2.0",
7271
"karma-script-launcher": "^1.0.0",
7372
"karma-spec-reporter": "^0.0.31",

src/ng/browser.js

-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ function Browser(window, document, $log, $sniffer) {
6767

6868
/**
6969
* @private
70-
* Note: this method is used only by scenario runner
7170
* TODO(vojta): prefix this method with $$ ?
7271
* @param {function()} callback Function that will be called when no outstanding request
7372
*/

src/ng/directive/form.js

+32-13
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ var nullFormCtrl = {
99
$setValidity: noop,
1010
$setDirty: noop,
1111
$setPristine: noop,
12-
$setSubmitted: noop
12+
$setSubmitted: noop,
13+
$$setSubmitted: noop
1314
},
1415
PENDING_CLASS = 'ng-pending',
1516
SUBMITTED_CLASS = 'ng-submitted';
@@ -274,12 +275,25 @@ FormController.prototype = {
274275
* @name form.FormController#$setSubmitted
275276
*
276277
* @description
277-
* Sets the form to its submitted state.
278+
* Sets the form to its `$submitted` state. This will also set `$submitted` on all child and
279+
* parent forms of the form.
278280
*/
279281
$setSubmitted: function() {
282+
var rootForm = this;
283+
while (rootForm.$$parentForm && (rootForm.$$parentForm !== nullFormCtrl)) {
284+
rootForm = rootForm.$$parentForm;
285+
}
286+
rootForm.$$setSubmitted();
287+
},
288+
289+
$$setSubmitted: function() {
280290
this.$$animate.addClass(this.$$element, SUBMITTED_CLASS);
281291
this.$submitted = true;
282-
this.$$parentForm.$setSubmitted();
292+
forEach(this.$$controls, function(control) {
293+
if (control.$$setSubmitted) {
294+
control.$$setSubmitted();
295+
}
296+
});
283297
}
284298
};
285299

@@ -338,16 +352,21 @@ addSetValidityMethod({
338352
* @restrict EAC
339353
*
340354
* @description
341-
* Nestable alias of {@link ng.directive:form `form`} directive. HTML
342-
* does not allow nesting of form elements. It is useful to nest forms, for example if the validity of a
343-
* sub-group of controls needs to be determined.
344-
*
345-
* Note: the purpose of `ngForm` is to group controls,
346-
* but not to be a replacement for the `<form>` tag with all of its capabilities
347-
* (e.g. posting to the server, ...).
348-
*
349-
* @param {string=} ngForm|name Name of the form. If specified, the form controller will be published into
350-
* related scope, under this name.
355+
* Helper directive that makes it possible to create control groups inside a
356+
* {@link ng.directive:form `form`} directive.
357+
* These "child forms" can be used, for example, to determine the validity of a sub-group of
358+
* controls.
359+
*
360+
* <div class="alert alert-danger">
361+
* **Note**: `ngForm` cannot be used as a replacement for `<form>`, because it lacks its
362+
* [built-in HTML functionality](https://html.spec.whatwg.org/#the-form-element).
363+
* Specifically, you cannot submit `ngForm` like a `<form>` tag. That means,
364+
* you cannot send data to the server with `ngForm`, or integrate it with
365+
* {@link ng.directive:ngSubmit `ngSubmit`}.
366+
* </div>
367+
*
368+
* @param {string=} ngForm|name Name of the form. If specified, the form controller will
369+
* be published into the related scope, under this name.
351370
*
352371
*/
353372

src/ng/location.js

-2
Original file line numberDiff line numberDiff line change
@@ -938,8 +938,6 @@ function $LocationProvider() {
938938
// update location manually
939939
if ($location.absUrl() !== $browser.url()) {
940940
$rootScope.$apply();
941-
// hack to work around FF6 bug 684208 when scenario runner clicks on links
942-
$window.angular['ff-684208-preventDefault'] = true;
943941
}
944942
}
945943
}

src/ng/rootScope.js

+48-34
Original file line numberDiff line numberDiff line change
@@ -1271,14 +1271,13 @@ function $RootScopeProvider() {
12711271

12721272
var self = this;
12731273
return function() {
1274-
var index = arrayRemove(namedListeners, listener);
1275-
if (index >= 0) {
1274+
var indexOfListener = namedListeners.indexOf(listener);
1275+
if (indexOfListener !== -1) {
1276+
// Use delete in the hope of the browser deallocating the memory for the array entry,
1277+
// while not shifting the array indexes of other listeners.
1278+
// See issue https://github.com/angular/angular.js/issues/16135
1279+
delete namedListeners[indexOfListener];
12761280
decrementListenerCount(self, 1, name);
1277-
// We are removing a listener while iterating over the list of listeners.
1278-
// Update the current $$index if necessary to ensure no listener is skipped.
1279-
if (index <= namedListeners.$$index) {
1280-
namedListeners.$$index--;
1281-
}
12821281
}
12831282
};
12841283
},
@@ -1307,7 +1306,9 @@ function $RootScopeProvider() {
13071306
* @return {Object} Event object (see {@link ng.$rootScope.Scope#$on}).
13081307
*/
13091308
$emit: function(name, args) {
1310-
var scope = this,
1309+
var empty = [],
1310+
namedListeners,
1311+
scope = this,
13111312
stopPropagation = false,
13121313
event = {
13131314
name: name,
@@ -1318,11 +1319,28 @@ function $RootScopeProvider() {
13181319
},
13191320
defaultPrevented: false
13201321
},
1321-
listenerArgs = concat([event], arguments, 1);
1322+
listenerArgs = concat([event], arguments, 1),
1323+
i, length;
13221324

13231325
do {
1324-
invokeListeners(scope, event, listenerArgs, name);
1325-
1326+
namedListeners = scope.$$listeners[name] || empty;
1327+
event.currentScope = scope;
1328+
for (i = 0, length = namedListeners.length; i < length; i++) {
1329+
1330+
// if listeners were deregistered, defragment the array
1331+
if (!namedListeners[i]) {
1332+
namedListeners.splice(i, 1);
1333+
i--;
1334+
length--;
1335+
continue;
1336+
}
1337+
try {
1338+
//allow all listeners attached to the current scope to run
1339+
namedListeners[i].apply(null, listenerArgs);
1340+
} catch (e) {
1341+
$exceptionHandler(e);
1342+
}
1343+
}
13261344
//if any listener on the current scope stops propagation, prevent bubbling
13271345
if (stopPropagation) {
13281346
break;
@@ -1373,11 +1391,28 @@ function $RootScopeProvider() {
13731391

13741392
if (!target.$$listenerCount[name]) return event;
13751393

1376-
var listenerArgs = concat([event], arguments, 1);
1394+
var listenerArgs = concat([event], arguments, 1),
1395+
listeners, i, length;
13771396

13781397
//down while you can, then up and next sibling or up and next sibling until back at root
13791398
while ((current = next)) {
1380-
invokeListeners(current, event, listenerArgs, name);
1399+
event.currentScope = current;
1400+
listeners = current.$$listeners[name] || [];
1401+
for (i = 0, length = listeners.length; i < length; i++) {
1402+
// if listeners were deregistered, defragment the array
1403+
if (!listeners[i]) {
1404+
listeners.splice(i, 1);
1405+
i--;
1406+
length--;
1407+
continue;
1408+
}
1409+
1410+
try {
1411+
listeners[i].apply(null, listenerArgs);
1412+
} catch (e) {
1413+
$exceptionHandler(e);
1414+
}
1415+
}
13811416

13821417
// Insanity Warning: scope depth-first traversal
13831418
// yes, this code is a bit crazy, but it works and we have tests to prove it!
@@ -1408,27 +1443,6 @@ function $RootScopeProvider() {
14081443

14091444
return $rootScope;
14101445

1411-
function invokeListeners(scope, event, listenerArgs, name) {
1412-
var listeners = scope.$$listeners[name];
1413-
if (listeners) {
1414-
if (listeners.$$index !== undefined) {
1415-
throw $rootScopeMinErr('inevt', '{0} already $emit/$broadcast-ing on scope ({1})', name, scope.$id);
1416-
}
1417-
event.currentScope = scope;
1418-
try {
1419-
for (listeners.$$index = 0; listeners.$$index < listeners.length; listeners.$$index++) {
1420-
try {
1421-
//allow all listeners attached to the current scope to run
1422-
listeners[listeners.$$index].apply(null, listenerArgs);
1423-
} catch (e) {
1424-
$exceptionHandler(e);
1425-
}
1426-
}
1427-
} finally {
1428-
listeners.$$index = undefined;
1429-
}
1430-
}
1431-
}
14321446

14331447
function beginPhase(phase) {
14341448
if ($rootScope.$$phase) {

0 commit comments

Comments
 (0)