Skip to content
This repository has been archived by the owner on Feb 22, 2018. It is now read-only.

Commit

Permalink
feat(block): Chain ElementProbe parents; add to shadowRoot
Browse files Browse the repository at this point in the history
This allows one to retrieve ElementProbe from any element including
a shadowRoot. The ElementProbe contains element, injector, and scope. 
The added benefit is that by waling the ElementProbe parent one can 
get the parent element of a shadow DOM.

Closes #625
  • Loading branch information
mhevery committed Feb 26, 2014
1 parent 5b21520 commit b307c82
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 9 deletions.
28 changes: 20 additions & 8 deletions lib/core_dom/block_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,9 @@ class BlockFactory {
TemplateCache templateCache = injector.get(TemplateCache);
DirectiveMap directives = injector.get(DirectiveMap);
// This is a bit of a hack since we are returning different type then we are.
var componentFactory = new _ComponentFactory(node, ref.type, ref.annotation as NgComponent, injector.get(dom.NodeTreeSanitizer));
var componentFactory = new _ComponentFactory(node, ref.type,
ref.annotation as NgComponent,
injector.get(dom.NodeTreeSanitizer), _expando);
if (fctrs == null) fctrs = new Map<Type, _ComponentFactory>();
fctrs[ref.type] = componentFactory;
return componentFactory.call(injector, compiler, scope, blockCache, http, templateCache, directives);
Expand All @@ -177,11 +179,14 @@ class BlockFactory {
boundBlockFactory = (Injector injector) => ref.blockFactory.bind(injector);
}
});
nodeModule.factory(BlockHole, blockHoleFactory);
nodeModule.factory(BlockFactory, blockFactory);
nodeModule.factory(BoundBlockFactory, boundBlockFactory);
nodeModule
..factory(BlockHole, blockHoleFactory)
..factory(BlockFactory, blockFactory)
..factory(BoundBlockFactory, boundBlockFactory)
..factory(ElementProbe, (_) => probe);
nodeInjector = parentInjector.createChild([nodeModule]);
probe = _expando[node] = new ElementProbe(node, nodeInjector, scope);
probe = _expando[node] = new ElementProbe(
parentInjector.get(ElementProbe), node, nodeInjector, scope);
} finally {
assert(_perf.stopTimer(timerId) != false);
}
Expand Down Expand Up @@ -314,14 +319,16 @@ class _ComponentFactory {
final Type type;
final NgComponent component;
final dom.NodeTreeSanitizer treeSanitizer;
final Expando _expando;

dom.ShadowRoot shadowDom;
Scope shadowScope;
Injector shadowInjector;
Compiler compiler;
var controller;

_ComponentFactory(this.element, this.type, this.component, this.treeSanitizer);
_ComponentFactory(this.element, this.type, this.component, this.treeSanitizer,
this._expando);

dynamic call(Injector injector, Compiler compiler, Scope scope, BlockCache $blockCache, Http $http, TemplateCache $templateCache, DirectiveMap directives) {
this.compiler = compiler;
Expand Down Expand Up @@ -380,12 +387,16 @@ class _ComponentFactory {
}

createShadowInjector(injector, TemplateLoader templateLoader) {
var probe;
var shadowModule = new Module()
..type(type)
..value(Scope, shadowScope)
..value(TemplateLoader, templateLoader)
..value(dom.ShadowRoot, shadowDom);
..value(dom.ShadowRoot, shadowDom)
..factory(ElementProbe, (_) => probe);
shadowInjector = injector.createChild([shadowModule], name: _SHADOW);
probe = _expando[shadowDom] = new ElementProbe(
injector.get(ElementProbe), shadowDom, shadowInjector, shadowScope);
return shadowInjector;
}
}
Expand Down Expand Up @@ -429,10 +440,11 @@ String _html(obj) {
* SEE: [ngInjector], [ngScope], [ngDirectives]
*/
class ElementProbe {
final ElementProbe parent;
final dom.Node element;
final Injector injector;
final Scope scope;
final directives = [];

ElementProbe(this.element, this.injector, this.scope);
ElementProbe(this.parent, this.element, this.injector, this.scope);
}
1 change: 1 addition & 0 deletions lib/core_dom/module.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ part 'tree_sanitizer.dart';
class NgCoreDomModule extends Module {
NgCoreDomModule() {
value(dom.Window, dom.window);
value(ElementProbe, null);

factory(TemplateCache, (_) => new TemplateCache(capacity: 0));
type(dom.NodeTreeSanitizer, implementedBy: NullTreeSanitizer);
Expand Down
18 changes: 17 additions & 1 deletion test/core_dom/compiler_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,21 @@ main() => describe('dte.compiler', () {
expect(element.textWithShadow()).toEqual('INNER()');
})));

it('should store ElementProbe with Elements', async(inject((TestBed tb) {
tb.compile('<div><simple>innerText</simple></div>');
microLeap();
var simpleElement = tb.rootElement.querySelector('simple');
expect(simpleElement.text).toEqual('innerText');
var simpleProbe = ngProbe(simpleElement);
var simpleComponent = simpleProbe.injector.get(SimpleComponent);
expect(simpleComponent.scope.context['name']).toEqual('INNER');
var shadowRoot = simpleElement.shadowRoot;
var shadowProbe = ngProbe(shadowRoot);
expect(shadowProbe).toBeNotNull();
expect(shadowProbe.element).toEqual(shadowRoot);
expect(shadowProbe.parent.element).toEqual(simpleElement);
})));

it('should create a simple component', async(inject((NgZone zone) {
rootScope.context['name'] = 'OUTTER';
var element = $(r'<div>{{name}}:<simple>{{name}}</simple></div>');
Expand Down Expand Up @@ -674,7 +689,8 @@ class PublishTypesAttrDirective implements PublishTypesDirectiveSuperType {
template: r'{{name}}(<content>SHADOW-CONTENT</content>)'
)
class SimpleComponent {
SimpleComponent(Scope scope) {
Scope scope;
SimpleComponent(Scope this.scope) {
scope.context['name'] = 'INNER';
}
}
Expand Down

0 comments on commit b307c82

Please sign in to comment.