11import { View } from "tns-core-modules/ui/core/view" ;
2+ import { LayoutBase } from "tns-core-modules/ui/layouts/layout-base" ;
23
34export type NgView = ( View & ViewExtensions ) ;
4- export type NgElement = NgView | CommentNode ;
5+ export type NgElement = NgView | InvisibleNode ;
56
67export interface ViewExtensions {
78 nodeType : number ;
@@ -15,12 +16,55 @@ export interface ViewClass {
1516 new ( ) : View ;
1617}
1718
18- // used for creating comments and text nodes in the renderer
19- export class CommentNode {
20- meta : { skipAddToDom : true } ;
19+ export abstract class InvisibleNode extends View implements ViewExtensions {
20+ meta : { skipAddToDom : boolean } ;
2121 templateParent : NgView ;
22+ nodeType : number ;
23+ nodeName : string ;
24+ ngCssClasses : Map < string , boolean > ;
25+
26+ constructor ( ) {
27+ super ( ) ;
28+
29+ this . nodeType = 1 ;
30+ this . nodeName = getClassName ( this ) ;
31+ }
32+
33+ toString ( ) {
34+ return `${ this . nodeName } (${ this . id } )` ;
35+ }
36+ }
37+
38+ export class CommentNode extends InvisibleNode {
39+ protected static id = 0 ;
40+
41+ constructor ( ) {
42+ super ( ) ;
43+
44+ this . meta = {
45+ skipAddToDom : false ,
46+ } ;
47+ this . id = CommentNode . id . toString ( ) ;
48+ CommentNode . id += 1 ;
49+ }
50+ }
51+
52+ export class TextNode extends InvisibleNode {
53+ protected static id = 0 ;
54+
55+ constructor ( ) {
56+ super ( ) ;
57+
58+ this . meta = {
59+ skipAddToDom : true ,
60+ } ;
61+ this . id = TextNode . id . toString ( ) ;
62+ TextNode . id += 1 ;
63+ }
2264}
2365
66+ const getClassName = instance => instance . constructor . name ;
67+
2468export interface ViewClassMeta {
2569 skipAddToDom ?: boolean ;
2670 insertChild ?: ( parent : NgView , child : NgView , atIndex : number ) => void ;
@@ -76,6 +120,30 @@ export function isKnownView(elementName: string): boolean {
76120 elementMap . has ( elementName . toLowerCase ( ) ) ;
77121}
78122
123+ export function getSingleViewRecursive ( nodes : Array < any > , nestLevel : number ) : View {
124+ const actualNodes = nodes . filter ( node => ! ( node instanceof InvisibleNode ) ) ;
125+
126+ if ( actualNodes . length === 0 ) {
127+ throw new Error ( `No suitable views found in list template! ` +
128+ `Nesting level: ${ nestLevel } ` ) ;
129+ } else if ( actualNodes . length > 1 ) {
130+ throw new Error ( `More than one view found in list template!` +
131+ `Nesting level: ${ nestLevel } ` ) ;
132+ }
133+
134+ const rootLayout = actualNodes [ 0 ] ;
135+ if ( ! rootLayout ) {
136+ return getSingleViewRecursive ( rootLayout . children , nestLevel + 1 ) ;
137+ }
138+
139+ const parentLayout = rootLayout . parent ;
140+ if ( parentLayout instanceof LayoutBase ) {
141+ parentLayout . removeChild ( rootLayout ) ;
142+ }
143+
144+ return rootLayout ;
145+ }
146+
79147// Register default NativeScript components
80148// Note: ActionBar related components are registerd together with action-bar directives.
81149registerElement ( "AbsoluteLayout" , ( ) => require ( "tns-core-modules/ui/layouts/absolute-layout" ) . AbsoluteLayout ) ;
0 commit comments