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

Commit 2918cc9

Browse files
committed
fix(compiler): resolve breaking changes in AngularJS 1.7.1
Fixes #11319
1 parent 0046467 commit 2918cc9

File tree

4 files changed

+83
-61
lines changed

4 files changed

+83
-61
lines changed

package-lock.json

Lines changed: 24 additions & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@
2121
"scss": "./dist/angular-material.scss",
2222
"devDependencies": {
2323
"add-stream": "^1.0.0",
24-
"angular": "^1.5.0",
25-
"angular-animate": "^1.5.0",
26-
"angular-aria": "^1.5.0",
27-
"angular-messages": "^1.5.0",
28-
"angular-mocks": "^1.5.0",
29-
"angular-route": "^1.5.0",
30-
"angular-sanitize": "^1.5.0",
31-
"angular-touch": "^1.5.0",
24+
"angular": "^1.7.0",
25+
"angular-animate": "^1.7.0",
26+
"angular-aria": "^1.7.0",
27+
"angular-messages": "^1.7.0",
28+
"angular-mocks": "^1.7.0",
29+
"angular-route": "^1.7.0",
30+
"angular-sanitize": "^1.7.0",
31+
"angular-touch": "^1.7.0",
3232
"angularytics": "^0.4.0",
3333
"canonical-path": "0.0.2",
3434
"cli-color": "^1.0.0",

src/core/services/compiler/compiler.js

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ function MdCompilerProvider($compileProvider) {
124124
* - `>=1.7` - the compiler calls the constructor first before assigning bindings and
125125
* `$compileProvider.preAssignBindingsEnabled()` no longer exists.
126126
*
127-
* The default value is `false` but will change to `true` in AngularJS Material 1.2.
127+
* The default value is `false` in AngularJS 1.6 and earlier but `true` in AngularJS 1.7.
128128
*
129129
* It is recommended to set this flag to `true` in AngularJS Material 1.1.x. The only reason
130130
* it's not set that way by default is backwards compatibility. Not setting the flag to `true`
@@ -133,10 +133,13 @@ function MdCompilerProvider($compileProvider) {
133133
* Material Dialog/Panel/Toast/BottomSheet controllers using the `$controller` helper
134134
* as it always follows the `$compileProvider.preAssignBindingsEnabled()` value.
135135
*/
136-
// TODO change it to `true` in Material 1.2.
137-
var respectPreAssignBindingsEnabled = false;
136+
var respectPreAssignBindingsEnabled = angular.version.major === 1 && angular.version.minor >= 7;
138137
this.respectPreAssignBindingsEnabled = function(respected) {
139138
if (angular.isDefined(respected)) {
139+
if (!respected && angular.version.major === 1 && angular.version.minor >= 7) {
140+
throw new Error(
141+
'Disabling respectPreAssignBindingsEnabled is not supported in AngularJS 1.7 or later.');
142+
}
140143
respectPreAssignBindingsEnabled = respected;
141144
return this;
142145
}
@@ -444,27 +447,34 @@ function MdCompilerProvider($compileProvider) {
444447

445448
/**
446449
* Creates and instantiates a new controller with the specified options.
447-
* @param {!Object} options Options that include the controller
450+
* @param {!Object} options Options that include the controller function or string
448451
* @param {!Object} injectLocals Locals to to be provided in the controller DI.
449452
* @param {!Object} locals Locals to be injected to the controller.
450453
* @returns {!Object} Created controller instance.
451454
*/
452455
MdCompilerService.prototype._createController = function(options, injectLocals, locals) {
453-
// The third and fourth arguments to $controller are considered private and are undocumented:
454-
// https://github.com/angular/angular.js/blob/master/src/ng/controller.js#L86
455-
// Passing `true` as the third argument causes `$controller` to return a function that
456-
// gets the controller instance instead returning of the instance directly. When the
457-
// controller is defined as a function, `invokeCtrl.instance` is the *same instance* as
458-
// `invokeCtrl()`. However, then the controller is an ES6 class, `invokeCtrl.instance` is a
459-
// *different instance* from `invokeCtrl()`.
460-
var invokeCtrl = this.$controller(options.controller, injectLocals, true, options.controllerAs);
461-
462-
if (getPreAssignBindingsEnabled() && options.bindToController) {
463-
angular.extend(invokeCtrl.instance, locals);
464-
}
456+
var ctrl;
457+
if ((angular.version.major === 1 && angular.version.minor === 7 && angular.version.dot >= 1) ||
458+
(angular.version.major === 1 && angular.version.minor > 7)) {
459+
ctrl = this.$controller(options.controller, injectLocals, options.controllerAs);
460+
} else {
461+
// The third and fourth arguments to $controller are considered private and are undocumented
462+
// in AngularJS prior to 1.7.1:
463+
// https://github.com/angular/angular.js/blob/v1.6.10/src/ng/controller.js#L102-L109
464+
// Passing `true` as the third argument causes `$controller` to return a function that
465+
// gets the controller instance instead of returning the instance directly. When the
466+
// controller is defined as a function, `invokeCtrl.instance` is the *same instance* as
467+
// `invokeCtrl()`. However, when the controller is an ES6 class, `invokeCtrl.instance` is a
468+
// *different instance* from `invokeCtrl()`.
469+
var invokeCtrl = this.$controller(options.controller, injectLocals, true, options.controllerAs);
470+
471+
if (getPreAssignBindingsEnabled() && options.bindToController) {
472+
angular.extend(invokeCtrl.instance, locals);
473+
}
465474

466-
// Instantiate and initialize the specified controller.
467-
var ctrl = invokeCtrl();
475+
// Instantiate and initialize the specified controller.
476+
ctrl = invokeCtrl();
477+
}
468478

469479
if (!getPreAssignBindingsEnabled() && options.bindToController) {
470480
angular.extend(ctrl, locals);

src/core/services/compiler/compiler.spec.js

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ describe('$mdCompiler service', function() {
112112
var data = compile({
113113
template: '<span>hello</span>'
114114
});
115-
var scope = $rootScope.$new();
115+
var scope = $rootScope.$new(false);
116116
data.link(scope);
117117
expect(data.element.scope()).toBe(scope);
118118
}));
@@ -127,7 +127,7 @@ describe('$mdCompiler service', function() {
127127
this.injectedOne = one;
128128
}
129129
});
130-
var scope = $rootScope.$new();
130+
var scope = $rootScope.$new(false);
131131
data.link(scope);
132132
expect(data.element.controller()).toBeTruthy();
133133
expect(data.element.controller().injectedOne).toBe(1);
@@ -143,7 +143,7 @@ describe('$mdCompiler service', function() {
143143
}
144144
});
145145

146-
var scope = $rootScope.$new();
146+
var scope = $rootScope.$new(false);
147147
data.link(scope);
148148

149149
expect(ctrlElement).toBe(data.element);
@@ -155,7 +155,7 @@ describe('$mdCompiler service', function() {
155155
controller: function Ctrl() {},
156156
controllerAs: 'myControllerAs'
157157
});
158-
var scope = $rootScope.$new();
158+
var scope = $rootScope.$new(false);
159159
data.link(scope);
160160
expect(scope.myControllerAs).toBe(data.element.controller());
161161
}));
@@ -164,12 +164,24 @@ describe('$mdCompiler service', function() {
164164

165165
});
166166

167-
[
167+
var bindingStatesToTest;
168+
if (angular.version.major === 1 && angular.version.minor >= 7) {
169+
bindingStatesToTest = [
170+
{respectPreAssignBindingsEnabled: true}
171+
];
172+
} else if (angular.version.major === 1 && angular.version.minor === 6) {
173+
bindingStatesToTest = [
168174
{respectPreAssignBindingsEnabled: true},
169175
{respectPreAssignBindingsEnabled: false},
170-
// TODO change `equivalentTo` to `true` in Material 1.2.
171176
{respectPreAssignBindingsEnabled: '"default"', equivalentTo: false}
172-
].forEach(function(options) {
177+
];
178+
} else if (angular.version.major === 1 && angular.version.minor < 6) {
179+
bindingStatesToTest = [
180+
{respectPreAssignBindingsEnabled: false}
181+
];
182+
}
183+
184+
bindingStatesToTest.forEach(function(options) {
173185
var realRespectPreAssignBindingsEnabled = options.respectPreAssignBindingsEnabled;
174186
var respectPreAssignBindingsEnabled = angular.isDefined(options.equivalentTo) ?
175187
options.equivalentTo :
@@ -224,8 +236,8 @@ describe('$mdCompiler service', function() {
224236
expect(isInstantiated).toBe(true);
225237
});
226238

227-
// Bindings are not preassigned only if we respect the AngularJS config and they're
228-
// disabled there. This logic will change in Material 1.2.0.
239+
// Bindings are not pre-assigned if we respect the AngularJS config and pre-assigning
240+
// them is disabled there.
229241
if (respectPreAssignBindingsEnabled && !preAssignBindingsEnabledInAngularJS) {
230242
it('disabled should assign bindings after constructor', function() {
231243
var isInstantiated = false;
@@ -400,7 +412,7 @@ describe('$mdCompiler service', function() {
400412

401413
it('should preserve a previous linked scope', function() {
402414

403-
var scope = $rootScope.$new();
415+
var scope = $rootScope.$new(false);
404416

405417
var data = compile({
406418
contentElement: $compile('<div>With Scope</div>')(scope)
@@ -445,7 +457,7 @@ describe('$mdCompiler service', function() {
445457
beforeEach(inject(function($injector) {
446458
$mdCompiler = $injector.get('$mdCompiler');
447459
$rootScope = $injector.get('$rootScope');
448-
pageScope = $rootScope.$new();
460+
pageScope = $rootScope.$new(false);
449461
}));
450462

451463
it('should assign bindings by $onInit for ES6 classes', function(done) {

0 commit comments

Comments
 (0)