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

Commit

Permalink
perf($compile): move $$isolateBinding creation to directive factory i…
Browse files Browse the repository at this point in the history
…nstead of on each link
  • Loading branch information
jbedard authored and jeffbcross committed Sep 10, 2014
1 parent 9314719 commit 56f09f0
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 22 deletions.
46 changes: 33 additions & 13 deletions src/ng/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,31 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
// 'on' and be composed of only English letters.
var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;

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

var bindings = {};

forEach(scope, function(definition, scopeName) {
var match = definition.match(LOCAL_REGEXP);

if (!match) {
throw $compileMinErr('iscp',
"Invalid isolate scope definition for directive '{0}'." +
" Definition: {... {1}: '{2}' ...}",
directiveName, scopeName, definition);
}

bindings[scopeName] = {
attrName: match[3] || scopeName,
mode: match[1],
optional: match[2] === '?'
};
});

return bindings;
}

/**
* @ngdoc method
* @name $compileProvider#directive
Expand Down Expand Up @@ -611,6 +636,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
directive.name = directive.name || name;
directive.require = directive.require || (directive.controller && directive.name);
directive.restrict = directive.restrict || 'EA';
if (isObject(directive.scope)) {
directive.$$isolateBindings = parseIsolateBindings(directive.scope, directive.name);
}
directives.push(directive);
} catch (e) {
$exceptionHandler(e);
Expand Down Expand Up @@ -1657,16 +1685,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
newIsolateScopeDirective.bindToController === true) {
isolateBindingContext = isolateScopeController.instance;
}
forEach(newIsolateScopeDirective.scope, function(definition, scopeName) {
var match = definition.match(LOCAL_REGEXP) || [],
attrName = match[3] || scopeName,
optional = (match[2] == '?'),
mode = match[1], // @, =, or &

forEach(isolateScope.$$isolateBindings = newIsolateScopeDirective.$$isolateBindings, function(definition, scopeName) {
var attrName = definition.attrName,
optional = definition.optional,
mode = definition.mode, // @, =, or &
lastValue,
parentGet, parentSet, compare;

isolateScope.$$isolateBindings[scopeName] = mode + attrName;

switch (mode) {

case '@':
Expand Down Expand Up @@ -1721,12 +1747,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
return parentGet(scope, locals);
};
break;

default:
throw $compileMinErr('iscp',
"Invalid isolate scope definition for directive '{0}'." +
" Definition: {... {1}: '{2}' ...}",
newIsolateScopeDirective.name, scopeName, definition);
}
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/ng/rootScope.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ function $RootScopeProvider(){
this.$$postDigestQueue = [];
this.$$listeners = {};
this.$$listenerCount = {};
this.$$isolateBindings = {};
this.$$isolateBindings = null;
this.$$applyAsyncQueue = [];
}

Expand Down
27 changes: 19 additions & 8 deletions test/ng/compileSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3507,14 +3507,25 @@ describe('$compile', function() {

expect(typeof componentScope.$$isolateBindings).toBe('object');

expect(componentScope.$$isolateBindings.attr).toBe('@attr');
expect(componentScope.$$isolateBindings.attrAlias).toBe('@attr');
expect(componentScope.$$isolateBindings.ref).toBe('=ref');
expect(componentScope.$$isolateBindings.refAlias).toBe('=ref');
expect(componentScope.$$isolateBindings.reference).toBe('=reference');
expect(componentScope.$$isolateBindings.expr).toBe('&expr');
expect(componentScope.$$isolateBindings.exprAlias).toBe('&expr');

expect(componentScope.$$isolateBindings.attr.mode).toBe('@');
expect(componentScope.$$isolateBindings.attr.attrName).toBe('attr');
expect(componentScope.$$isolateBindings.attrAlias.attrName).toBe('attr');
expect(componentScope.$$isolateBindings.ref.mode).toBe('=');
expect(componentScope.$$isolateBindings.ref.attrName).toBe('ref');
expect(componentScope.$$isolateBindings.refAlias.attrName).toBe('ref');
expect(componentScope.$$isolateBindings.reference.mode).toBe('=');
expect(componentScope.$$isolateBindings.reference.attrName).toBe('reference');
expect(componentScope.$$isolateBindings.expr.mode).toBe('&');
expect(componentScope.$$isolateBindings.expr.attrName).toBe('expr');
expect(componentScope.$$isolateBindings.exprAlias.attrName).toBe('expr');

var firstComponentScope = componentScope,
first$$isolateBindings = componentScope.$$isolateBindings;

dealoc(element);
compile('<div><span my-component>');
expect(componentScope).not.toBe(firstComponentScope);
expect(componentScope.$$isolateBindings).toBe(first$$isolateBindings);
}));


Expand Down

0 comments on commit 56f09f0

Please sign in to comment.