@@ -2,18 +2,26 @@ import {
2
2
ChangeDetectionStrategy ,
3
3
Component ,
4
4
ElementRef ,
5
- Input ,
6
5
OnDestroy ,
7
6
OnInit ,
8
7
ViewEncapsulation ,
9
8
} from '@angular/core' ;
10
9
import { Router } from '@angular/router' ;
11
- import { Observable , Subscription } from 'rxjs' ;
12
10
import { take } from 'rxjs/operators' ;
13
11
import { IdleMonitorService } from '../idleMonitor/idle-monitor.service' ;
14
12
import { ScullyRoutesService } from '../route-service/scully-routes.service' ;
15
13
import { fetchHttp } from '../utils/fetchHttp' ;
14
+ import { findComments } from '../utils/findComments' ;
16
15
16
+ interface ScullyContent {
17
+ html : string ;
18
+ cssId : string ;
19
+ }
20
+ declare global {
21
+ interface Window {
22
+ scullyContent : ScullyContent ;
23
+ }
24
+ }
17
25
/** this is needed, because otherwise the CLI borks while building */
18
26
const scullyBegin = '<!--scullyContent-begin-->' ;
19
27
const scullyEnd = '<!--scullyContent-end-->' ;
@@ -36,22 +44,15 @@ const scullyEnd = '<!--scullyContent-end-->';
36
44
preserveWhitespaces : true ,
37
45
} )
38
46
export class ScullyContentComponent implements OnInit , OnDestroy {
39
- @Input ( ) type = 'MD' ;
40
-
41
47
elm = this . elmRef . nativeElement as HTMLElement ;
42
- // mutationSubscription: Subscription;
48
+ /** pull in all available routes into an eager promise */
43
49
routes = this . srs . available$ . pipe ( take ( 1 ) ) . toPromise ( ) ;
44
50
45
- constructor (
46
- private elmRef : ElementRef ,
47
- private srs : ScullyRoutesService ,
48
- private router : Router ,
49
- private idle : IdleMonitorService
50
- ) { }
51
+ constructor ( private elmRef : ElementRef , private srs : ScullyRoutesService , private router : Router ) { }
51
52
52
53
ngOnInit ( ) {
53
- /** make sure the idle-check is loaded. */
54
- this . idle . init ( ) ;
54
+ // / ** make sure the idle-check is loaded. */
55
+ // this.idle.init();
55
56
if ( this . elm ) {
56
57
/** this will only fire in a browser environment */
57
58
this . handlePage ( ) ;
@@ -64,11 +65,16 @@ export class ScullyContentComponent implements OnInit, OnDestroy {
64
65
*/
65
66
private async handlePage ( ) {
66
67
const template = document . createElement ( 'template' ) ;
67
- // tslint:disable-next-line: no-string-literal
68
- if ( window [ ' scullyContent' ] ) {
68
+ const currentCssId = this . getCSSId ( this . elm ) ;
69
+ if ( window . scullyContent ) {
69
70
/** upgrade existing static content */
70
- // tslint:disable-next-line: no-string-literal
71
- template . innerHTML = window [ 'scullyContent' ] ;
71
+ const htmlString = window . scullyContent . html ;
72
+ if ( currentCssId !== window . scullyContent . cssId ) {
73
+ /** replace the angular cssId */
74
+ template . innerHTML = htmlString . split ( window . scullyContent . cssId ) . join ( currentCssId ) ;
75
+ } else {
76
+ template . innerHTML = htmlString ;
77
+ }
72
78
} else {
73
79
const curPage = location . href ;
74
80
/**
@@ -81,7 +87,12 @@ export class ScullyContentComponent implements OnInit, OnDestroy {
81
87
await fetchHttp ( curPage , 'text' )
82
88
. then ( ( html : string ) => {
83
89
try {
84
- template . innerHTML = html . split ( scullyBegin ) [ 1 ] . split ( scullyEnd ) [ 0 ] ;
90
+ const htmlString = html . split ( scullyBegin ) [ 1 ] . split ( scullyEnd ) [ 0 ] ;
91
+ if ( htmlString . includes ( '_ngcontent' ) ) {
92
+ /** update the angular cssId */
93
+ const atr = '_ngcontent' + htmlString . split ( '_ngcontent' ) [ 1 ] . split ( '=' ) [ 0 ] ;
94
+ template . innerHTML = htmlString . split ( atr ) . join ( currentCssId ) ;
95
+ }
85
96
} catch ( e ) {
86
97
template . innerHTML = `<h2 id="___scully-parsing-error___">Sorry, could not parse static page content</h2>
87
98
<p>This might happen if you are not using the static generated pages.</p>` ;
@@ -93,6 +104,7 @@ export class ScullyContentComponent implements OnInit, OnDestroy {
93
104
console . error ( 'problem during loading static scully content' , e ) ;
94
105
} ) ;
95
106
}
107
+ /** insert the whole thing just before the `<scully-content>` element */
96
108
const parent = this . elm . parentElement || document . body ;
97
109
const begin = document . createComment ( 'scullyContent-begin' ) ;
98
110
const end = document . createComment ( 'scullyContent-end' ) ;
@@ -130,7 +142,7 @@ export class ScullyContentComponent implements OnInit, OnDestroy {
130
142
return ;
131
143
}
132
144
/** delete the content, as it is now out of date! */
133
- window [ ' scullyContent' ] = undefined ;
145
+ window . scullyContent = undefined ;
134
146
/** check for the same route with different "data", and NOT a level higher (length) */
135
147
if ( curSplit . every ( ( part , i ) => splitRoute [ i ] === part ) && splitRoute . length > curSplit . length ) {
136
148
/**
@@ -155,59 +167,9 @@ export class ScullyContentComponent implements OnInit, OnDestroy {
155
167
}
156
168
}
157
169
158
- ngOnDestroy ( ) {
159
- // if (this.mutationSubscription) {
160
- // this.mutationSubscription.unsubscribe();
161
- // }
170
+ getCSSId ( elm : HTMLElement ) {
171
+ return elm . getAttributeNames ( ) . find ( a => a . startsWith ( '_ngcontent' ) ) || 'none_found' ;
162
172
}
163
- }
164
173
165
- /**
166
- * Returns an observable that fires a mutation when the domMutationObserves does that.
167
- * if flattens the mutations to make handling easier, so you only get 1 mutationRecord at a time.
168
- * @param elm the elm to obse with a mutationObserver
169
- * @param config the config for the mutationobserver
170
- */
171
- export function fromMutationObserver (
172
- elm : HTMLElement ,
173
- config : MutationObserverInit
174
- ) : Observable < MutationRecord > {
175
- return new Observable ( obs => {
176
- const observer = new MutationObserver ( mutations => mutations . forEach ( mutation => obs . next ( mutation ) ) ) ;
177
- observer . observe ( elm , config ) ;
178
- return ( ) => observer . disconnect ( ) ;
179
- } ) ;
180
- }
181
-
182
- /**
183
- * Returns an array of nodes coninting all the html comments in the element.
184
- * When a searchText is given this is narrowed down to only comments that contian this text
185
- * @param rootElem Element to search nto
186
- * @param searchText optional string that needs to be in a HTML comment
187
- */
188
- function findComments ( rootElem : HTMLElement , searchText ?: string ) {
189
- const comments = [ ] ;
190
- // Fourth argument, which is actually obsolete according to the DOM4 standard, seems required in IE 11
191
- const iterator = document . createNodeIterator (
192
- rootElem ,
193
- NodeFilter . SHOW_COMMENT ,
194
- {
195
- acceptNode : node => {
196
- // Logic to determine whether to accept, reject or skip node
197
- // In this case, only accept nodes that have content
198
- // that is containing our searchText, by rejecting any other nodes.
199
- if ( searchText && node . nodeValue && ! node . nodeValue . includes ( searchText ) ) {
200
- return NodeFilter . FILTER_REJECT ;
201
- }
202
- return NodeFilter . FILTER_ACCEPT ;
203
- } ,
204
- }
205
- // , false // IE-11 support requires this parameter.
206
- ) ;
207
- let curNode ;
208
- // tslint:disable-next-line: no-conditional-assignment
209
- while ( ( curNode = iterator . nextNode ( ) ) ) {
210
- comments . push ( curNode ) ;
211
- }
212
- return comments ;
174
+ ngOnDestroy ( ) { }
213
175
}
0 commit comments