11import {
22 Inject , Injectable , Optional , NgZone ,
33 RendererV2 , RendererFactoryV2 , RendererTypeV2 ,
4- // ViewEncapsulation
5- // ɵAnimationStyles, ɵAnimationKeyframe,
4+ ViewEncapsulation ,
65} from "@angular/core" ;
76import { APP_ROOT_VIEW , DEVICE } from "./platform-providers" ;
87import { isBlank } from "./lang-facade" ;
@@ -16,8 +15,12 @@ import { escapeRegexSymbols } from "utils/utils";
1615import { Device } from "platform" ;
1716
1817// CONTENT_ATTR not exported from NativeScript_renderer - we need it for styles application.
18+ const COMPONENT_REGEX = / % C O M P % / g;
1919export const COMPONENT_VARIABLE = "%COMP%" ;
20+ export const HOST_ATTR = `_nghost-${ COMPONENT_VARIABLE } ` ;
2021export const CONTENT_ATTR = `_ngcontent-${ COMPONENT_VARIABLE } ` ;
22+ const ATTR_REPLACER = new RegExp ( escapeRegexSymbols ( CONTENT_ATTR ) , "g" ) ;
23+ const ATTR_SANITIZER = / - / g;
2124
2225@Injectable ( )
2326export class NativeScriptRendererFactory implements RendererFactoryV2 {
@@ -29,7 +32,7 @@ export class NativeScriptRendererFactory implements RendererFactoryV2 {
2932 constructor (
3033 @Optional ( ) @Inject ( APP_ROOT_VIEW ) rootView : View ,
3134 @Inject ( DEVICE ) device : Device ,
32- zone : NgZone
35+ private zone : NgZone
3336 ) {
3437 this . viewUtil = new ViewUtil ( device ) ;
3538 this . setRootNgView ( rootView ) ;
@@ -50,30 +53,19 @@ export class NativeScriptRendererFactory implements RendererFactoryV2 {
5053 }
5154
5255 let renderer : NativeScriptRenderer = this . componentRenderers . get ( type . id ) ;
53- if ( isBlank ( renderer ) ) {
54- renderer = this . defaultRenderer ;
55-
56- let stylesLength = type . styles . length ;
57- for ( let i = 0 ; i < stylesLength ; i ++ ) {
58- console . log ( type . styles [ i ] ) ;
59- // this.hasComponentStyles = true;
60- let cssString = type . styles [ i ] + "" ;
61- const realCSS = this . replaceNgAttribute ( cssString , type . id ) ;
62- addCss ( realCSS ) ;
63- }
64- this . componentRenderers . set ( type . id , renderer ) ;
56+ if ( ! isBlank ( renderer ) ) {
57+ return renderer ;
6558 }
6659
67- return renderer ;
68- }
69-
70- private attrReplacer = new RegExp ( escapeRegexSymbols ( CONTENT_ATTR ) , "g" ) ;
71- private attrSanitizer = / - / g ;
72-
60+ if ( type . encapsulation === ViewEncapsulation . Emulated ) {
61+ renderer = new EmulatedRenderer ( type , this . rootNgView , this . zone , this . viewUtil ) ;
62+ ( < EmulatedRenderer > renderer ) . applyToHost ( element ) ;
63+ } else {
64+ renderer = this . defaultRenderer ;
65+ }
7366
74- private replaceNgAttribute ( input : string , componentId : string ) : string {
75- return input . replace ( this . attrReplacer ,
76- "_ng_content_" + componentId . replace ( this . attrSanitizer , "_" ) ) ;
67+ this . componentRenderers . set ( type . id , renderer ) ;
68+ return renderer ;
7769 }
7870}
7971
@@ -89,16 +81,21 @@ export class NativeScriptRenderer extends RendererV2 {
8981 traceLog ( "NativeScriptRenderer created" ) ;
9082 }
9183
92- appendChild ( parent : any , newChild : any ) : void {
84+ appendChild ( parent : any , newChild : NgView ) : void {
9385 traceLog ( `NativeScriptRenderer.appendChild child: ${ newChild } parent: ${ parent } ` ) ;
86+ console . log ( typeof parent )
87+ console . log ( "appending child" )
88+ console . log ( newChild . id )
9489 this . viewUtil . insertChild ( parent , newChild ) ;
9590 }
9691
9792
98- insertBefore ( parent : any , newChild : any , refChild : any ) : void {
93+ insertBefore ( parent : any , newChild : any , _refChild : any ) : void {
9994 traceLog ( `NativeScriptRenderer.insertBefore child: ${ newChild } parent: ${ parent } ` ) ;
10095 if ( parent ) {
101- parent . insertBefore ( newChild , refChild ) ;
96+ // Temporary solution until we implement nextSibling method
97+ this . appendChild ( parent , newChild ) ;
98+ // parent.insertBefore(newChild, refChild);
10299 }
103100 }
104101
@@ -112,24 +109,22 @@ export class NativeScriptRenderer extends RendererV2 {
112109 return this . rootView ;
113110 }
114111
115- parentNode ( node : NgView ) : NgView {
116- return node . templateParent ;
112+ parentNode ( node : NgView ) : any {
113+ return node . parent ;
117114 }
118115
119116 nextSibling ( _node : NgView ) : void {
120117 traceLog ( `NativeScriptRenderer.nextSibling ${ _node } ` ) ;
121118 }
122119
123120 createViewRoot ( hostElement : NgView ) : NgView {
124- traceLog ( "CREATE VIEW ROOT: " + hostElement . nodeName ) ;
121+ traceLog ( `NativeScriptRenderer.createViewRoot ${ hostElement . nodeName } ` )
125122 return hostElement ;
126123 }
127124
128125 projectNodes ( parentElement : NgView , nodes : NgView [ ] ) : void {
129126 traceLog ( "NativeScriptRenderer.projectNodes" ) ;
130- nodes . forEach ( ( node ) => {
131- this . viewUtil . insertChild ( parentElement , node ) ;
132- } ) ;
127+ nodes . forEach ( ( node ) => this . viewUtil . insertChild ( parentElement , node ) ) ;
133128 }
134129
135130 destroy ( ) {
@@ -197,17 +192,7 @@ export class NativeScriptRenderer extends RendererV2 {
197192
198193 createElement ( name : any , _namespace : string ) : NgView {
199194 traceLog ( `NativeScriptRenderer.createElement: ${ name } ` ) ;
200-
201- return this . viewUtil . createView ( name , view => {
202- console . log ( view ) ;
203- // Set an attribute to the view to scope component-specific css.
204- // The property name is pre-generated by Angular.
205-
206- // if (this.hasComponentStyles) {
207- // const cssAttribute = this.replaceNgAttribute(CONTENT_ATTR, this.componentProtoId);
208- // view[cssAttribute] = true;
209- // }
210- } ) ;
195+ return this . viewUtil . createView ( name )
211196 }
212197
213198 createText ( _value : string ) : NgView {
@@ -234,3 +219,63 @@ export class NativeScriptRenderer extends RendererV2 {
234219 }
235220}
236221
222+ class EmulatedRenderer extends NativeScriptRenderer {
223+ private contentAttr : string ;
224+ private hostAttr : string ;
225+
226+ constructor (
227+ private component : RendererTypeV2 ,
228+ rootView : NgView ,
229+ zone : NgZone ,
230+ viewUtil : ViewUtil ,
231+ ) {
232+ super ( rootView , zone , viewUtil ) ;
233+
234+ this . addStyles ( ) ;
235+ this . contentAttr = shimContentAttribute ( component . id ) ;
236+ this . hostAttr = shimHostAttribute ( component . id ) ;
237+ }
238+
239+ applyToHost ( view : NgView ) {
240+ super . setAttribute ( view , this . hostAttr , "" ) ;
241+ }
242+
243+ appendChild ( parent : any , newChild : NgView ) : void {
244+ // Set an attribute to the view to scope component-specific css.
245+ // The property name is pre-generated by Angular.
246+ const cssAttribute = this . replaceNgAttribute ( CONTENT_ATTR ) ;
247+ newChild [ cssAttribute ] = true ;
248+
249+ super . appendChild ( parent , newChild ) ;
250+ }
251+
252+ createElement ( parent : any , name : string ) : NgView {
253+ const view = super . createElement ( parent , name ) ;
254+ super . setAttribute ( view , this . contentAttr , "" ) ;
255+
256+ return view ;
257+ }
258+
259+ private addStyles ( ) {
260+ this . component . styles
261+ . map ( s => s . toString ( ) )
262+ . map ( s => this . replaceNgAttribute ( s ) )
263+ . forEach ( addCss ) ;
264+ }
265+
266+ private replaceNgAttribute ( input : string ) : string {
267+ return input . replace ( ATTR_REPLACER , `_ng_content_${ this . componentId } ` ) ;
268+ }
269+
270+ private get componentId ( ) : string {
271+ return this . component . id . replace ( ATTR_SANITIZER , "_" ) ;
272+ }
273+ }
274+
275+ function shimContentAttribute ( componentShortId : string ) : string {
276+ return CONTENT_ATTR . replace ( COMPONENT_REGEX , componentShortId ) ;
277+ }
278+
279+ function shimHostAttribute ( componentShortId : string ) : string {
280+ return HOST_ATTR . replace ( COMPONENT_REGEX , componentShortId ) ;
281+ }
0 commit comments