Index: third_party/pkg/angular/lib/core_dom/transcluding_component_factory.dart |
diff --git a/third_party/pkg/angular/lib/core_dom/transcluding_component_factory.dart b/third_party/pkg/angular/lib/core_dom/transcluding_component_factory.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..baba003f88f12ae0291f236b1a54c26ef67e22cf |
--- /dev/null |
+++ b/third_party/pkg/angular/lib/core_dom/transcluding_component_factory.dart |
@@ -0,0 +1,121 @@ |
+part of angular.core.dom_internal; |
+ |
+@Decorator( |
+ selector: 'content') |
+class Content implements AttachAware, DetachAware { |
+ final ContentPort _port; |
+ final dom.Element _element; |
+ dom.Comment _beginComment; |
+ Content(this._port, this._element); |
+ |
+ void attach() { |
+ if (_port == null) return; |
+ _beginComment = _port.content(_element); |
+ } |
+ |
+ void detach() { |
+ if (_port == null) return; |
+ _port.detachContent(_beginComment); |
+ } |
+} |
+ |
+class ContentPort { |
+ dom.Element _element; |
+ var _childNodes = []; |
+ |
+ ContentPort(this._element); |
+ |
+ void pullNodes() { |
+ _childNodes.addAll(_element.nodes); |
+ _element.nodes = []; |
+ } |
+ |
+ content(dom.Element elt) { |
+ var hash = elt.hashCode; |
+ var beginComment = new dom.Comment("content $hash"); |
+ |
+ if (_childNodes.isNotEmpty) { |
+ elt.parent.insertBefore(beginComment, elt); |
+ elt.parent.insertAllBefore(_childNodes, elt); |
+ elt.parent.insertBefore(new dom.Comment("end-content $hash"), elt); |
+ _childNodes = []; |
+ } |
+ elt.remove(); |
+ return beginComment; |
+ } |
+ |
+ void detachContent(dom.Comment _beginComment) { |
+ // Search for endComment and extract everything in between. |
+ // TODO optimize -- there may be a better way of pulling out nodes. |
+ |
+ var endCommentText = "end-${_beginComment.text}"; |
+ |
+ var next; |
+ for (next = _beginComment.nextNode; |
+ next.nodeType != dom.Node.COMMENT_NODE && next.text != endCommentText; |
+ next = _beginComment.nextNode) { |
+ _childNodes.add(next); |
+ next.remove(); |
+ } |
+ assert(next.nodeType == dom.Node.COMMENT_NODE && next.text == endCommentText); |
+ next.remove(); |
+ } |
+} |
+ |
+class TranscludingComponentFactory implements ComponentFactory { |
+ final Expando _expando; |
+ |
+ TranscludingComponentFactory(this._expando); |
+ |
+ FactoryFn call(dom.Node node, DirectiveRef ref) { |
+ // CSS is not supported. |
+ assert((ref.annotation as Component).cssUrls == null || |
+ (ref.annotation as Component).cssUrls.isEmpty); |
+ |
+ var element = node as dom.Element; |
+ return (Injector injector) { |
+ var childInjector; |
+ var component = ref.annotation as Component; |
+ Scope scope = injector.get(Scope); |
+ ViewCache viewCache = injector.get(ViewCache); |
+ Http http = injector.get(Http); |
+ TemplateCache templateCache = injector.get(TemplateCache); |
+ DirectiveMap directives = injector.get(DirectiveMap); |
+ NgBaseCss baseCss = injector.get(NgBaseCss); |
+ |
+ var contentPort = new ContentPort(element); |
+ |
+ // Append the component's template as children |
+ var viewFuture = ComponentFactory._viewFuture(component, viewCache, directives); |
+ |
+ if (viewFuture != null) { |
+ viewFuture = viewFuture.then((ViewFactory viewFactory) { |
+ contentPort.pullNodes(); |
+ element.nodes.addAll(viewFactory(childInjector).nodes); |
+ return element; |
+ }); |
+ } else { |
+ viewFuture = new async.Future.microtask(() => contentPort.pullNodes()); |
+ } |
+ TemplateLoader templateLoader = new TemplateLoader(viewFuture); |
+ |
+ Scope shadowScope = scope.createChild({}); |
+ |
+ var probe; |
+ var childModule = new Module() |
+ ..type(ref.type) |
+ ..type(NgElement) |
+ ..value(ContentPort, contentPort) |
+ ..value(Scope, shadowScope) |
+ ..value(TemplateLoader, templateLoader) |
+ ..value(dom.ShadowRoot, new ShadowlessShadowRoot(element)) |
+ ..factory(ElementProbe, (_) => probe); |
+ childInjector = injector.createChild([childModule], name: SHADOW_DOM_INJECTOR_NAME); |
+ |
+ var controller = childInjector.get(ref.type); |
+ shadowScope.context[component.publishAs] = controller; |
+ ComponentFactory._setupOnShadowDomAttach(controller, templateLoader, shadowScope); |
+ return controller; |
+ }; |
+ } |
+} |