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

Commit 56f09f0

Browse files
jbedardjeffbcross
authored andcommitted
perf($compile): move $$isolateBinding creation to directive factory instead of on each link
1 parent 9314719 commit 56f09f0

File tree

3 files changed

+53
-22
lines changed

3 files changed

+53
-22
lines changed

src/ng/compile.js

+33-13
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,31 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
574574
// 'on' and be composed of only English letters.
575575
var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;
576576

577+
function parseIsolateBindings(scope, directiveName) {
578+
var LOCAL_REGEXP = /^\s*([@=&])(\??)\s*(\w*)\s*$/;
579+
580+
var bindings = {};
581+
582+
forEach(scope, function(definition, scopeName) {
583+
var match = definition.match(LOCAL_REGEXP);
584+
585+
if (!match) {
586+
throw $compileMinErr('iscp',
587+
"Invalid isolate scope definition for directive '{0}'." +
588+
" Definition: {... {1}: '{2}' ...}",
589+
directiveName, scopeName, definition);
590+
}
591+
592+
bindings[scopeName] = {
593+
attrName: match[3] || scopeName,
594+
mode: match[1],
595+
optional: match[2] === '?'
596+
};
597+
});
598+
599+
return bindings;
600+
}
601+
577602
/**
578603
* @ngdoc method
579604
* @name $compileProvider#directive
@@ -611,6 +636,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
611636
directive.name = directive.name || name;
612637
directive.require = directive.require || (directive.controller && directive.name);
613638
directive.restrict = directive.restrict || 'EA';
639+
if (isObject(directive.scope)) {
640+
directive.$$isolateBindings = parseIsolateBindings(directive.scope, directive.name);
641+
}
614642
directives.push(directive);
615643
} catch (e) {
616644
$exceptionHandler(e);
@@ -1657,16 +1685,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16571685
newIsolateScopeDirective.bindToController === true) {
16581686
isolateBindingContext = isolateScopeController.instance;
16591687
}
1660-
forEach(newIsolateScopeDirective.scope, function(definition, scopeName) {
1661-
var match = definition.match(LOCAL_REGEXP) || [],
1662-
attrName = match[3] || scopeName,
1663-
optional = (match[2] == '?'),
1664-
mode = match[1], // @, =, or &
1688+
1689+
forEach(isolateScope.$$isolateBindings = newIsolateScopeDirective.$$isolateBindings, function(definition, scopeName) {
1690+
var attrName = definition.attrName,
1691+
optional = definition.optional,
1692+
mode = definition.mode, // @, =, or &
16651693
lastValue,
16661694
parentGet, parentSet, compare;
16671695

1668-
isolateScope.$$isolateBindings[scopeName] = mode + attrName;
1669-
16701696
switch (mode) {
16711697

16721698
case '@':
@@ -1721,12 +1747,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
17211747
return parentGet(scope, locals);
17221748
};
17231749
break;
1724-
1725-
default:
1726-
throw $compileMinErr('iscp',
1727-
"Invalid isolate scope definition for directive '{0}'." +
1728-
" Definition: {... {1}: '{2}' ...}",
1729-
newIsolateScopeDirective.name, scopeName, definition);
17301750
}
17311751
});
17321752
}

src/ng/rootScope.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ function $RootScopeProvider(){
134134
this.$$postDigestQueue = [];
135135
this.$$listeners = {};
136136
this.$$listenerCount = {};
137-
this.$$isolateBindings = {};
137+
this.$$isolateBindings = null;
138138
this.$$applyAsyncQueue = [];
139139
}
140140

test/ng/compileSpec.js

+19-8
Original file line numberDiff line numberDiff line change
@@ -3507,14 +3507,25 @@ describe('$compile', function() {
35073507

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

3510-
expect(componentScope.$$isolateBindings.attr).toBe('@attr');
3511-
expect(componentScope.$$isolateBindings.attrAlias).toBe('@attr');
3512-
expect(componentScope.$$isolateBindings.ref).toBe('=ref');
3513-
expect(componentScope.$$isolateBindings.refAlias).toBe('=ref');
3514-
expect(componentScope.$$isolateBindings.reference).toBe('=reference');
3515-
expect(componentScope.$$isolateBindings.expr).toBe('&expr');
3516-
expect(componentScope.$$isolateBindings.exprAlias).toBe('&expr');
3517-
3510+
expect(componentScope.$$isolateBindings.attr.mode).toBe('@');
3511+
expect(componentScope.$$isolateBindings.attr.attrName).toBe('attr');
3512+
expect(componentScope.$$isolateBindings.attrAlias.attrName).toBe('attr');
3513+
expect(componentScope.$$isolateBindings.ref.mode).toBe('=');
3514+
expect(componentScope.$$isolateBindings.ref.attrName).toBe('ref');
3515+
expect(componentScope.$$isolateBindings.refAlias.attrName).toBe('ref');
3516+
expect(componentScope.$$isolateBindings.reference.mode).toBe('=');
3517+
expect(componentScope.$$isolateBindings.reference.attrName).toBe('reference');
3518+
expect(componentScope.$$isolateBindings.expr.mode).toBe('&');
3519+
expect(componentScope.$$isolateBindings.expr.attrName).toBe('expr');
3520+
expect(componentScope.$$isolateBindings.exprAlias.attrName).toBe('expr');
3521+
3522+
var firstComponentScope = componentScope,
3523+
first$$isolateBindings = componentScope.$$isolateBindings;
3524+
3525+
dealoc(element);
3526+
compile('<div><span my-component>');
3527+
expect(componentScope).not.toBe(firstComponentScope);
3528+
expect(componentScope.$$isolateBindings).toBe(first$$isolateBindings);
35183529
}));
35193530

35203531

0 commit comments

Comments
 (0)