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

Commit

Permalink
fix($compile): allow directives to have decorators
Browse files Browse the repository at this point in the history
Allow directives to have decorators that modify the directive `scope` property

Close: #10149
  • Loading branch information
lgalfaso committed Feb 12, 2016
1 parent ece293a commit 0728cc2
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 5 deletions.
20 changes: 15 additions & 5 deletions src/ng/compile.js
Expand Up @@ -851,13 +851,18 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
// The assumption is that future DOM event attribute names will begin with
// 'on' and be composed of only English letters.
var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;
var bindingCache = createMap();

function parseIsolateBindings(scope, directiveName, isController) {
var LOCAL_REGEXP = /^\s*([@&<]|=(\*?))(\??)\s*(\w*)\s*$/;

var bindings = {};

forEach(scope, function(definition, scopeName) {
if (definition in bindingCache) {
bindings[scopeName] = bindingCache[definition];
return;
}
var match = definition.match(LOCAL_REGEXP);

if (!match) {
Expand All @@ -875,6 +880,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
optional: match[3] === '?',
attrName: match[4] || scopeName
};
if (match[4]) {
bindingCache[definition] = bindings[scopeName];
}
});

return bindings;
Expand Down Expand Up @@ -967,11 +975,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
directive.name = directive.name || name;
directive.require = directive.require || (directive.controller && directive.name);
directive.restrict = directive.restrict || 'EA';
var bindings = directive.$$bindings =
parseDirectiveBindings(directive, directive.name);
if (isObject(bindings.isolateScope)) {
directive.$$isolateBindings = bindings.isolateScope;
}
directive.$$moduleName = directiveFactory.$$moduleName;
directives.push(directive);
} catch (e) {
Expand Down Expand Up @@ -2545,6 +2548,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
if (startAttrName) {
directive = inherit(directive, {$$start: startAttrName, $$end: endAttrName});
}
if (!directive.$$bindings) {
var bindings = directive.$$bindings =
parseDirectiveBindings(directive, directive.name);
if (isObject(bindings.isolateScope)) {
directive.$$isolateBindings = bindings.isolateScope;
}
}
tDirectives.push(directive);
match = directive;
}
Expand Down
45 changes: 45 additions & 0 deletions test/ng/compileSpec.js
Expand Up @@ -8112,6 +8112,51 @@ describe('$compile', function() {
});
});


it('should be possible to change the scope of a directive using $provide', function() {
module(function($provide) {
directive('foo', function() {
return {
scope: {},
template: '<div></div>'
};
});
$provide.decorator('fooDirective', function($delegate) {
var directive = $delegate[0];
directive.scope.something = '=';
directive.template = '<span>{{something}}</span>';
return $delegate;
});
});
inject(function($compile, $rootScope) {
element = $compile('<div><div foo something="bar"></div></div>')($rootScope);
$rootScope.bar = 'bar';
$rootScope.$digest();
expect(element.text()).toBe('bar');
});
});


it('should distinguish different bindings with the same binding name', function() {
module(function() {
directive('foo', function() {
return {
scope: {
foo: '=',
bar: '='
},
template: '<div><div>{{foo}}</div><div>{{bar}}</div></div>'
};
});
});
inject(function($compile, $rootScope) {
element = $compile('<div><div foo="\'foo\'" bar="\'bar\'"></div></div>')($rootScope);
$rootScope.$digest();
expect(element.text()).toBe('foobar');
});
});


it('should safely create transclude comment node and not break with "-->"',
inject(function($rootScope) {
// see: https://github.com/angular/angular.js/issues/1740
Expand Down

0 comments on commit 0728cc2

Please sign in to comment.