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

Commit 351fe4b

Browse files
lugovskylgalfaso
authored andcommitted
feat($compile): show module name during multidir error
Show module name if possible when multidir error happens. Closes #11775
1 parent d19504a commit 351fe4b

File tree

3 files changed

+96
-11
lines changed

3 files changed

+96
-11
lines changed

src/loader.js

+21-8
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ function setupModuleLoader(window) {
146146
* @description
147147
* See {@link auto.$provide#provider $provide.provider()}.
148148
*/
149-
provider: invokeLater('$provide', 'provider'),
149+
provider: invokeLaterAndSetModuleName('$provide', 'provider'),
150150

151151
/**
152152
* @ngdoc method
@@ -157,7 +157,7 @@ function setupModuleLoader(window) {
157157
* @description
158158
* See {@link auto.$provide#factory $provide.factory()}.
159159
*/
160-
factory: invokeLater('$provide', 'factory'),
160+
factory: invokeLaterAndSetModuleName('$provide', 'factory'),
161161

162162
/**
163163
* @ngdoc method
@@ -168,7 +168,7 @@ function setupModuleLoader(window) {
168168
* @description
169169
* See {@link auto.$provide#service $provide.service()}.
170170
*/
171-
service: invokeLater('$provide', 'service'),
171+
service: invokeLaterAndSetModuleName('$provide', 'service'),
172172

173173
/**
174174
* @ngdoc method
@@ -203,7 +203,7 @@ function setupModuleLoader(window) {
203203
* @description
204204
* See {@link auto.$provide#decorator $provide.decorator()}.
205205
*/
206-
decorator: invokeLater('$provide', 'decorator'),
206+
decorator: invokeLaterAndSetModuleName('$provide', 'decorator'),
207207

208208
/**
209209
* @ngdoc method
@@ -237,7 +237,7 @@ function setupModuleLoader(window) {
237237
* See {@link ng.$animateProvider#register $animateProvider.register()} and
238238
* {@link ngAnimate ngAnimate module} for more information.
239239
*/
240-
animation: invokeLater('$animateProvider', 'register'),
240+
animation: invokeLaterAndSetModuleName('$animateProvider', 'register'),
241241

242242
/**
243243
* @ngdoc method
@@ -255,7 +255,7 @@ function setupModuleLoader(window) {
255255
* (`myapp_subsection_filterx`).
256256
* </div>
257257
*/
258-
filter: invokeLater('$filterProvider', 'register'),
258+
filter: invokeLaterAndSetModuleName('$filterProvider', 'register'),
259259

260260
/**
261261
* @ngdoc method
@@ -267,7 +267,7 @@ function setupModuleLoader(window) {
267267
* @description
268268
* See {@link ng.$controllerProvider#register $controllerProvider.register()}.
269269
*/
270-
controller: invokeLater('$controllerProvider', 'register'),
270+
controller: invokeLaterAndSetModuleName('$controllerProvider', 'register'),
271271

272272
/**
273273
* @ngdoc method
@@ -280,7 +280,7 @@ function setupModuleLoader(window) {
280280
* @description
281281
* See {@link ng.$compileProvider#directive $compileProvider.directive()}.
282282
*/
283-
directive: invokeLater('$compileProvider', 'directive'),
283+
directive: invokeLaterAndSetModuleName('$compileProvider', 'directive'),
284284

285285
/**
286286
* @ngdoc method
@@ -330,6 +330,19 @@ function setupModuleLoader(window) {
330330
return moduleInstance;
331331
};
332332
}
333+
334+
/**
335+
* @param {string} provider
336+
* @param {string} method
337+
* @returns {angular.Module}
338+
*/
339+
function invokeLaterAndSetModuleName(provider, method) {
340+
return function(recipeName, factoryFunction) {
341+
if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name;
342+
invokeQueue.push([provider, method, arguments]);
343+
return moduleInstance;
344+
};
345+
}
333346
});
334347
};
335348
});

src/ng/compile.js

+11-3
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
852852
if (isObject(bindings.isolateScope)) {
853853
directive.$$isolateBindings = bindings.isolateScope;
854854
}
855+
directive.$$moduleName = directiveFactory.$$moduleName;
855856
directives.push(directive);
856857
} catch (e) {
857858
$exceptionHandler(e);
@@ -2298,11 +2299,18 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
22982299
return a.index - b.index;
22992300
}
23002301

2301-
23022302
function assertNoDuplicate(what, previousDirective, directive, element) {
2303+
2304+
function wrapModuleNameIfDefined(moduleName) {
2305+
return moduleName ?
2306+
(' (module: ' + moduleName + ')') :
2307+
'';
2308+
}
2309+
23032310
if (previousDirective) {
2304-
throw $compileMinErr('multidir', 'Multiple directives [{0}, {1}] asking for {2} on: {3}',
2305-
previousDirective.name, directive.name, what, startingTag(element));
2311+
throw $compileMinErr('multidir', 'Multiple directives [{0}{1}, {2}{3}] asking for {4} on: {5}',
2312+
previousDirective.name, wrapModuleNameIfDefined(previousDirective.$$moduleName),
2313+
directive.name, wrapModuleNameIfDefined(directive.$$moduleName), what, startingTag(element));
23062314
}
23072315
}
23082316

test/ng/compileSpec.js

+64
Original file line numberDiff line numberDiff line change
@@ -2514,6 +2514,70 @@ describe('$compile', function() {
25142514
);
25152515
});
25162516
});
2517+
2518+
describe('multidir isolated scope error messages', function() {
2519+
angular.module('fakeIsoledScopeModule', [])
2520+
.directive('fakeScope', function(log) {
2521+
return {
2522+
scope: true,
2523+
restrict: 'CA',
2524+
compile: function() {
2525+
return {pre: function(scope, element) {
2526+
log(scope.$id);
2527+
expect(element.data('$scope')).toBe(scope);
2528+
}};
2529+
}
2530+
};
2531+
})
2532+
.directive('fakeIScope', function(log) {
2533+
return {
2534+
scope: {},
2535+
restrict: 'CA',
2536+
compile: function() {
2537+
return function(scope, element) {
2538+
iscope = scope;
2539+
log(scope.$id);
2540+
expect(element.data('$isolateScopeNoTemplate')).toBe(scope);
2541+
};
2542+
}
2543+
};
2544+
});
2545+
2546+
beforeEach(module('fakeIsoledScopeModule', function() {
2547+
directive('anonymModuleScopeDirective', function(log) {
2548+
return {
2549+
scope: true,
2550+
restrict: 'CA',
2551+
compile: function() {
2552+
return {pre: function(scope, element) {
2553+
log(scope.$id);
2554+
expect(element.data('$scope')).toBe(scope);
2555+
}};
2556+
}
2557+
};
2558+
});
2559+
}));
2560+
2561+
it('should add module name to multidir isolated scope message if directive defined through module', inject(
2562+
function($rootScope, $compile) {
2563+
expect(function() {
2564+
$compile('<div class="fake-scope; fake-i-scope"></div>');
2565+
}).toThrowMinErr('$compile', 'multidir',
2566+
'Multiple directives [fakeIScope (module: fakeIsoledScopeModule), fakeScope (module: fakeIsoledScopeModule)] ' +
2567+
'asking for new/isolated scope on: <div class="fake-scope; fake-i-scope">');
2568+
})
2569+
);
2570+
2571+
it('sholdn\'t add module name to multidir isolated scope message if directive is defined directly with $compileProvider', inject(
2572+
function($rootScope, $compile) {
2573+
expect(function() {
2574+
$compile('<div class="anonym-module-scope-directive; fake-i-scope"></div>');
2575+
}).toThrowMinErr('$compile', 'multidir',
2576+
'Multiple directives [anonymModuleScopeDirective, fakeIScope (module: fakeIsoledScopeModule)] ' +
2577+
'asking for new/isolated scope on: <div class="anonym-module-scope-directive; fake-i-scope">');
2578+
})
2579+
);
2580+
});
25172581
});
25182582
});
25192583
});

0 commit comments

Comments
 (0)