From 35f3c98b7b64ba9988f2fb76ed6232d0edba1eb6 Mon Sep 17 00:00:00 2001 From: Buu Nguyen Date: Mon, 14 Oct 2013 22:34:16 -0500 Subject: [PATCH] fix($compile): fix missing error handling when new-scope directive is applied before isolated-scope directive Given dirA, which requests new scope, and dirB, which requests new & isolated scope. If dirA is applied *after* dirB, $compile reports an error ('Multiple directives [dirB, dirA] asking for new/isolated scope'), which is expected. However, if dirA is applied *before* dirB, e.g. because dirA has high priority, then no error is thrown. This is the inconsistency. Plus, dirA ends up sharing the isolated scope created for dirB, which may break dirA because it might need to access to parent scope's members. This fix addresses this situation by throwing error regardless of order of directive application. Closes #4402 --- src/ng/compile.js | 7 ++++--- test/ng/compileSpec.js | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/ng/compile.js b/src/ng/compile.js index c44985fdee26..f587d0bdbe4c 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -794,18 +794,19 @@ function $CompileProvider($provide) { } if (directiveValue = directive.scope) { - newScopeDirective = newScopeDirective || directive; - // skip the check for directives with async templates, we'll check the derived sync directive when // the template arrives if (!directive.templateUrl) { - assertNoDuplicate('new/isolated scope', newIsolateScopeDirective, directive, $compileNode); if (isObject(directiveValue)) { + assertNoDuplicate('new/isolated scope', newIsolateScopeDirective || newScopeDirective, directive, $compileNode); safeAddClass($compileNode, 'ng-isolate-scope'); newIsolateScopeDirective = directive; + } else { + assertNoDuplicate('new/isolated scope', newIsolateScopeDirective, directive, $compileNode); } safeAddClass($compileNode, 'ng-scope'); } + newScopeDirective = newScopeDirective || directive; } directiveName = directive.name; diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index 9a69824aaca3..f093deae937f 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -1539,6 +1539,25 @@ describe('$compile', function() { }) ); + it('should not allow more than one isolate scope creation per element regardless of directive priority', function() { + module(function($compileProvider) { + $compileProvider.directive('highPriorityScope', function() { + return { + restrict: 'C', + priority: 1, + scope: true, + link: function() {} + } + }); + }); + inject(function($compile) { + expect(function(){ + $compile('
'); + }).toThrowMinErr('$compile', 'multidir', 'Multiple directives [highPriorityScope, iscopeA] asking for new/isolated scope on: ' + + '
'); + }); + }); + it('should create new scope even at the root of the template', inject( function($rootScope, $compile, log) {