@@ -8,12 +8,13 @@ import {
8
8
EventEmitter ,
9
9
Injector ,
10
10
Input ,
11
+ NgZone ,
11
12
OnDestroy ,
12
13
Output ,
13
14
ViewContainerRef ,
14
15
} from '@angular/core' ;
15
- import { Router } from '@angular/router' ;
16
16
import { Subscription } from 'rxjs' ;
17
+ import { take } from 'rxjs/operators' ;
17
18
import { ExampleViewer } from '../example-viewer/example-viewer' ;
18
19
import { HeaderLink } from './header-link' ;
19
20
@@ -31,7 +32,7 @@ export class DocViewer implements OnDestroy {
31
32
this . _fetchDocument ( url ) ;
32
33
}
33
34
34
- @Output ( ) contentLoaded = new EventEmitter < void > ( ) ;
35
+ @Output ( ) contentRendered = new EventEmitter < void > ( ) ;
35
36
36
37
/** The document text. It should not be HTML encoded. */
37
38
textContent = '' ;
@@ -42,7 +43,8 @@ export class DocViewer implements OnDestroy {
42
43
private _http : HttpClient ,
43
44
private _injector : Injector ,
44
45
private _viewContainerRef : ViewContainerRef ,
45
- private _router : Router ) { }
46
+ private _ngZone : NgZone ) {
47
+ }
46
48
47
49
/** Fetch a document by URL. */
48
50
private _fetchDocument ( url : string ) {
@@ -66,8 +68,13 @@ export class DocViewer implements OnDestroy {
66
68
this . textContent = this . _elementRef . nativeElement . textContent ;
67
69
this . _loadComponents ( 'material-docs-example' , ExampleViewer ) ;
68
70
this . _loadComponents ( 'header-link' , HeaderLink ) ;
69
- this . _fixFragmentUrls ( ) ;
70
- this . contentLoaded . next ( ) ;
71
+
72
+ // Resolving and creating components dynamically in Angular happens synchronously, but since
73
+ // we want to emit the output if the components are actually rendered completely, we wait
74
+ // until the Angular zone becomes stable.
75
+ this . _ngZone . onStable
76
+ . pipe ( take ( 1 ) )
77
+ . subscribe ( ( ) => this . contentRendered . next ( ) ) ;
71
78
}
72
79
73
80
/** Show an error that occurred when fetching a document. */
@@ -77,15 +84,6 @@ export class DocViewer implements OnDestroy {
77
84
`Failed to load document: ${ url } . Error: ${ error . statusText } ` ;
78
85
}
79
86
80
- releadLiveExamples ( ) {
81
- // When the example viewer is dynamically loaded inside of md-tabs, they somehow end up in
82
- // the wrong place in the DOM after switching tabs. This function is a workaround to
83
- // put the live examples back in the right place.
84
- this . _clearLiveExamples ( ) ;
85
- this . _loadComponents ( 'material-docs-example' , ExampleViewer ) ;
86
- this . _loadComponents ( 'header-link' , HeaderLink ) ;
87
- }
88
-
89
87
/** Instantiate a ExampleViewer for each example. */
90
88
private _loadComponents ( componentName : string , componentClass : any ) {
91
89
let exampleElements =
@@ -108,25 +106,6 @@ export class DocViewer implements OnDestroy {
108
106
this . _portalHosts = [ ] ;
109
107
}
110
108
111
- /**
112
- * A fragment link is a link that references a specific element on the page that should be
113
- * scrolled into the viewport on page load or click.
114
- *
115
- * By default those links refer to the root page of the documentation and the fragment links
116
- * won't work properly. Those links need to be updated to be relative to the current base URL.
117
- */
118
- private _fixFragmentUrls ( ) {
119
- const baseUrl = this . _router . url . split ( '#' ) [ 0 ] ;
120
- const anchorElements =
121
- [ ] . slice . call ( this . _elementRef . nativeElement . querySelectorAll ( 'a' ) ) as HTMLAnchorElement [ ] ;
122
-
123
- // Update hash links that are referring to the same page and host. Links that are referring
124
- // to a different destination shouldn't be updated. For example the Google Fonts URL.
125
- anchorElements
126
- . filter ( anchorEl => anchorEl . hash && anchorEl . host === location . host )
127
- . forEach ( anchorEl => anchorEl . href = `${ baseUrl } ${ anchorEl . hash } ` ) ;
128
- }
129
-
130
109
ngOnDestroy ( ) {
131
110
this . _clearLiveExamples ( ) ;
132
111
0 commit comments