ngx-doc-viewer 15.0.0 → 21.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -1
- package/fesm2022/ngx-doc-viewer.mjs +517 -0
- package/fesm2022/ngx-doc-viewer.mjs.map +1 -0
- package/package.json +7 -28
- package/types/ngx-doc-viewer.d.ts +107 -0
- package/esm2020/index.mjs +0 -4
- package/esm2020/lib/document-viewer.component.mjs +0 -152
- package/esm2020/lib/document-viewer.module.mjs +0 -18
- package/esm2020/ngx-doc-viewer.mjs +0 -5
- package/fesm2015/ngx-doc-viewer.mjs +0 -177
- package/fesm2015/ngx-doc-viewer.mjs.map +0 -1
- package/fesm2020/ngx-doc-viewer.mjs +0 -172
- package/fesm2020/ngx-doc-viewer.mjs.map +0 -1
- package/index.d.ts +0 -3
- package/lib/document-viewer.component.d.ts +0 -34
- package/lib/document-viewer.module.d.ts +0 -8
package/README.md
CHANGED
|
@@ -37,6 +37,8 @@ export class AppModule {}
|
|
|
37
37
|
></ngx-doc-viewer>
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
The component now shows an internal loading overlay while external viewers such as Google Docs Viewer and Office Online are initializing, so viewer switches do not appear as a blank panel.
|
|
41
|
+
|
|
40
42
|
To
|
|
41
43
|
|
|
42
44
|
#### API:
|
|
@@ -53,6 +55,75 @@ Input:
|
|
|
53
55
|
- popout: adds an overlay over googles popout button or office popout and menu which disables just this button/menu but keeps giving the possibility to select text. The popout button is still visible (for google during a few seconds) but not clickable.
|
|
54
56
|
- popout-hide: see popup, instead of an transparent overlay a white one. This really hides the button but you'll see a white block while loading for the google viewer.
|
|
55
57
|
- overrideLocalhost: documents from the assets folder are not publicly available and therefor won't show in an external viewer (google, office). If the site is already published to public server, then pass that url and if will replace localhost by the other url. Like: overrideLocalhost="https://angular-doc-viewer.firebaseapp.com/"
|
|
58
|
+
- loadingText: fallback text shown in the built-in loading overlay. Defaults to `Loading document...`
|
|
59
|
+
- errorTextOverride: fallback text shown in the built-in error overlay. Defaults to the runtime error message.
|
|
60
|
+
- retryButtonText: text used by the built-in retry button in the default error overlay. Defaults to `Retry`
|
|
61
|
+
- googleFinalRetryDelay: waits this many milliseconds and retries Google once more before showing the error overlay. Defaults to `0`
|
|
62
|
+
- officeAutoRetry: automatically retries the Office viewer once after `officeRetryDelay`. Defaults to `false`
|
|
63
|
+
- officeRetryDelay: delay in milliseconds before the one-time Office auto retry. Defaults to `3000`
|
|
64
|
+
- officeReloadButtonText: text shown in the persistent Office reload button. Defaults to `↻`
|
|
65
|
+
- officeReloadButtonTitle: tooltip/title for the persistent Office reload button. Defaults to `Reload document`
|
|
66
|
+
- secondaryActionText: optional text for a built-in secondary error action button, for example `Open source` or `Download`
|
|
67
|
+
- secondaryActionMode: controls the built-in secondary action behavior. Supported values: `open` or `download`. Defaults to `open`
|
|
68
|
+
|
|
69
|
+
For custom loading markup in Angular, project an `ng-template` named `loadingContent`.
|
|
70
|
+
The template receives `$implicit` and `state` with:
|
|
71
|
+
- `viewer`
|
|
72
|
+
- `url`
|
|
73
|
+
- `phase`
|
|
74
|
+
- `errorText`
|
|
75
|
+
- `retry()`
|
|
76
|
+
- `actionUrl`
|
|
77
|
+
|
|
78
|
+
```html
|
|
79
|
+
<ngx-doc-viewer [url]="doc" viewer="office">
|
|
80
|
+
<ng-template #loadingContent let-state>
|
|
81
|
+
<div style="display:flex;gap:8px;align-items:center;">
|
|
82
|
+
<span class="spinner"></span>
|
|
83
|
+
<span>Preparing {{ state.viewer }} preview...</span>
|
|
84
|
+
</div>
|
|
85
|
+
</ng-template>
|
|
86
|
+
</ngx-doc-viewer>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
To replace the persistent Office reload control, project an `ng-template` named `officeReloadContent`:
|
|
90
|
+
|
|
91
|
+
```html
|
|
92
|
+
<ngx-doc-viewer [url]="doc" viewer="office">
|
|
93
|
+
<ng-template #officeReloadContent let-state>
|
|
94
|
+
<span>Reload</span>
|
|
95
|
+
</ng-template>
|
|
96
|
+
</ngx-doc-viewer>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
For custom error markup in Angular, project an `ng-template` named `errorContent`.
|
|
100
|
+
It receives the same context and can call `retry()` directly:
|
|
101
|
+
|
|
102
|
+
```html
|
|
103
|
+
<ngx-doc-viewer [url]="doc" viewer="office">
|
|
104
|
+
<ng-template #errorContent let-state>
|
|
105
|
+
<div style="text-align:center;">
|
|
106
|
+
<div>Preview unavailable for {{ state.viewer }}.</div>
|
|
107
|
+
<div>{{ state.actionUrl }}</div>
|
|
108
|
+
<button type="button" (click)="state.retry()">Retry</button>
|
|
109
|
+
<a [href]="state.actionUrl" target="_blank" rel="noreferrer">Open source</a>
|
|
110
|
+
</div>
|
|
111
|
+
</ng-template>
|
|
112
|
+
</ngx-doc-viewer>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
If you want to keep the default error layout but replace just the actions area, project an `ng-template` named `errorActions`:
|
|
116
|
+
|
|
117
|
+
```html
|
|
118
|
+
<ngx-doc-viewer [url]="doc" viewer="office" retryButtonText="Try again">
|
|
119
|
+
<ng-template #errorActions let-state>
|
|
120
|
+
<div style="margin-top: 14px; display: flex; gap: 8px; justify-content: center;">
|
|
121
|
+
<button type="button" (click)="state.retry()">Try again</button>
|
|
122
|
+
<a [href]="state.actionUrl" target="_blank" rel="noreferrer">Open source</a>
|
|
123
|
+
</div>
|
|
124
|
+
</ng-template>
|
|
125
|
+
</ngx-doc-viewer>
|
|
126
|
+
```
|
|
56
127
|
|
|
57
128
|
There are some issues loading document in the google viewer. See: https://stackoverflow.com/questions/40414039/google-docs-viewer-returning-204-responses-no-longer-working-alternatives. If loading pdf's and Word documents, seems to work now with this hack let me know via a Github issue.
|
|
58
129
|
|
|
@@ -61,7 +132,16 @@ There are some issues loading document in the google viewer. See: https://stacko
|
|
|
61
132
|
- googleMaxChecks = 5 | max number of retries
|
|
62
133
|
Output:
|
|
63
134
|
|
|
64
|
-
- loaded:
|
|
135
|
+
- loaded: emitted when the current iframe is ready. Can be used to hook into custom loading or telemetry flows.
|
|
136
|
+
- loading: emitted when the viewer enters the `loading` phase. Payload includes `viewer`, `url`, `phase`, `errorText`, `retry()`, and `actionUrl`.
|
|
137
|
+
- error: emitted when the viewer enters the `error` phase. Payload includes `viewer`, `url`, `phase`, `errorText`, `retry()`, and `actionUrl`.
|
|
138
|
+
- phaseChange: emitted whenever the internal phase changes to `idle`, `loading`, `ready`, or `error`.
|
|
139
|
+
|
|
140
|
+
### Recent behavior improvements
|
|
141
|
+
|
|
142
|
+
- External viewer switches now remount the iframe cleanly when changing between viewers such as Google and Office.
|
|
143
|
+
- A built-in loading overlay is shown while remote viewers are loading.
|
|
144
|
+
- Mammoth rendering now refreshes correctly when switching from an iframe-based viewer back to inline document rendering.
|
|
65
145
|
|
|
66
146
|
### File type support
|
|
67
147
|
|
|
@@ -0,0 +1,517 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { EventEmitter, TemplateRef, ViewChildren, ContentChild, Input, Output, Component, NgModule } from '@angular/core';
|
|
3
|
+
import * as i2 from '@angular/common';
|
|
4
|
+
import { CommonModule } from '@angular/common';
|
|
5
|
+
import { getViewerDetails, isLocalFile, replaceLocalUrl, getDocxToHtml, googleCheckSubscription, getViewerRecoveryPlan, iframeIsLoaded } from 'docviewhelper';
|
|
6
|
+
export * from 'docviewhelper';
|
|
7
|
+
import * as i1 from '@angular/platform-browser';
|
|
8
|
+
|
|
9
|
+
class NgxDocViewerComponent {
|
|
10
|
+
domSanitizer;
|
|
11
|
+
ngZone;
|
|
12
|
+
cdr;
|
|
13
|
+
loaded = new EventEmitter();
|
|
14
|
+
loading = new EventEmitter();
|
|
15
|
+
error = new EventEmitter();
|
|
16
|
+
phaseChange = new EventEmitter();
|
|
17
|
+
url = '';
|
|
18
|
+
queryParams = '';
|
|
19
|
+
viewerUrl = '';
|
|
20
|
+
googleCheckInterval = 3000;
|
|
21
|
+
googleMaxChecks = 5;
|
|
22
|
+
googleFinalRetryDelay = 0;
|
|
23
|
+
disableContent = 'none';
|
|
24
|
+
googleCheckContentLoaded = true;
|
|
25
|
+
viewer = 'google';
|
|
26
|
+
overrideLocalhost = '';
|
|
27
|
+
loadingText = 'Loading document...';
|
|
28
|
+
errorTextOverride = '';
|
|
29
|
+
retryButtonText = 'Retry';
|
|
30
|
+
officeAutoRetry = false;
|
|
31
|
+
officeRetryDelay = 3000;
|
|
32
|
+
officeReloadButtonText = '↻';
|
|
33
|
+
officeReloadButtonTitle = 'Reload document';
|
|
34
|
+
secondaryActionText = '';
|
|
35
|
+
secondaryActionMode = 'open';
|
|
36
|
+
loadingTemplate;
|
|
37
|
+
errorTemplate;
|
|
38
|
+
errorActionsTemplate;
|
|
39
|
+
officeReloadTemplate;
|
|
40
|
+
iframes = undefined;
|
|
41
|
+
fullUrl = undefined;
|
|
42
|
+
externalViewer = false;
|
|
43
|
+
docHtml = '';
|
|
44
|
+
configuredViewer = 'google';
|
|
45
|
+
showIframe = true;
|
|
46
|
+
renderPhase = 'idle';
|
|
47
|
+
errorText = '';
|
|
48
|
+
failedUrl = '';
|
|
49
|
+
retryNonce = 0;
|
|
50
|
+
loadingTemplateContext = this.createTemplateContext();
|
|
51
|
+
errorTemplateContext = this.createTemplateContext();
|
|
52
|
+
checkIFrameSubscription = undefined;
|
|
53
|
+
loadVersion = 0;
|
|
54
|
+
externalLoadTimeoutId = undefined;
|
|
55
|
+
googleFinalRetryTimeoutId = undefined;
|
|
56
|
+
googleFinalRetriedSourceKey = undefined;
|
|
57
|
+
currentGoogleSourceKey = undefined;
|
|
58
|
+
officeRetryTimeoutId = undefined;
|
|
59
|
+
officeAutoRetriedSourceKey = undefined;
|
|
60
|
+
currentOfficeSourceKey = undefined;
|
|
61
|
+
lastEmittedPhase = undefined;
|
|
62
|
+
constructor(domSanitizer, ngZone, cdr) {
|
|
63
|
+
this.domSanitizer = domSanitizer;
|
|
64
|
+
this.ngZone = ngZone;
|
|
65
|
+
this.cdr = cdr;
|
|
66
|
+
}
|
|
67
|
+
ngOnDestroy() {
|
|
68
|
+
this.clearExternalLoadTimeout();
|
|
69
|
+
this.clearGoogleFinalRetry();
|
|
70
|
+
this.clearOfficeRetry();
|
|
71
|
+
if (this.checkIFrameSubscription) {
|
|
72
|
+
this.checkIFrameSubscription.unsubscribe();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async ngOnChanges(changes) {
|
|
76
|
+
if (changes &&
|
|
77
|
+
changes['retryNonce'] &&
|
|
78
|
+
changes['retryNonce'].firstChange) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (changes &&
|
|
82
|
+
changes['viewer'] &&
|
|
83
|
+
(changes['viewer'].firstChange ||
|
|
84
|
+
changes['viewer'].currentValue !== changes['viewer'].previousValue)) {
|
|
85
|
+
if (this.viewer !== 'google' &&
|
|
86
|
+
this.viewer !== 'office' &&
|
|
87
|
+
this.viewer !== 'mammoth' &&
|
|
88
|
+
this.viewer !== 'pdf' &&
|
|
89
|
+
this.viewer !== 'url') {
|
|
90
|
+
console.error(`Unsupported viewer: '${this.viewer}'. Supported viewers: google, office, mammoth and pdf`);
|
|
91
|
+
}
|
|
92
|
+
this.configuredViewer = this.viewer;
|
|
93
|
+
this.updateTemplateContexts();
|
|
94
|
+
}
|
|
95
|
+
if ((changes['url'] &&
|
|
96
|
+
changes['url'].currentValue !== changes['url'].previousValue) ||
|
|
97
|
+
(changes['viewer'] &&
|
|
98
|
+
changes['viewer'].currentValue !== changes['viewer'].previousValue) ||
|
|
99
|
+
(changes['viewerUrl'] &&
|
|
100
|
+
changes['viewerUrl'].currentValue !==
|
|
101
|
+
changes['viewerUrl'].previousValue)) {
|
|
102
|
+
let viewerDetails = getViewerDetails(this.url, this.configuredViewer, this.queryParams, this.viewerUrl);
|
|
103
|
+
const loadVersion = ++this.loadVersion;
|
|
104
|
+
this.clearExternalLoadTimeout();
|
|
105
|
+
this.externalViewer = viewerDetails.externalViewer;
|
|
106
|
+
if (viewerDetails.externalViewer &&
|
|
107
|
+
this.overrideLocalhost &&
|
|
108
|
+
isLocalFile(this.url)) {
|
|
109
|
+
const newUrl = replaceLocalUrl(this.url, this.overrideLocalhost);
|
|
110
|
+
viewerDetails = getViewerDetails(newUrl, this.configuredViewer, this.queryParams, this.viewerUrl);
|
|
111
|
+
}
|
|
112
|
+
const officeSourceKey = this.configuredViewer === 'office' ? viewerDetails.url : undefined;
|
|
113
|
+
if (officeSourceKey !== this.currentOfficeSourceKey) {
|
|
114
|
+
this.officeAutoRetriedSourceKey = undefined;
|
|
115
|
+
}
|
|
116
|
+
this.currentOfficeSourceKey = officeSourceKey;
|
|
117
|
+
const googleSourceKey = this.configuredViewer === 'google' ? viewerDetails.url : undefined;
|
|
118
|
+
if (googleSourceKey !== this.currentGoogleSourceKey) {
|
|
119
|
+
this.googleFinalRetriedSourceKey = undefined;
|
|
120
|
+
}
|
|
121
|
+
this.currentGoogleSourceKey = googleSourceKey;
|
|
122
|
+
this.docHtml = '';
|
|
123
|
+
this.errorText = '';
|
|
124
|
+
this.failedUrl = this.url;
|
|
125
|
+
this.clearGoogleFinalRetry();
|
|
126
|
+
this.clearOfficeRetry();
|
|
127
|
+
this.updateTemplateContexts();
|
|
128
|
+
if (this.checkIFrameSubscription) {
|
|
129
|
+
this.checkIFrameSubscription.unsubscribe();
|
|
130
|
+
}
|
|
131
|
+
if (!this.url) {
|
|
132
|
+
this.fullUrl = undefined;
|
|
133
|
+
this.showIframe = false;
|
|
134
|
+
this.externalViewer = false;
|
|
135
|
+
this.setRenderPhase('idle');
|
|
136
|
+
this.updateTemplateContexts();
|
|
137
|
+
}
|
|
138
|
+
else if (viewerDetails.externalViewer ||
|
|
139
|
+
this.configuredViewer === 'url' ||
|
|
140
|
+
this.configuredViewer === 'pdf') {
|
|
141
|
+
this.setRenderPhase('loading');
|
|
142
|
+
const iframeUrl = this.domSanitizer.bypassSecurityTrustResourceUrl(viewerDetails.url);
|
|
143
|
+
this.fullUrl = undefined;
|
|
144
|
+
this.showIframe = false;
|
|
145
|
+
this.cdr.detectChanges();
|
|
146
|
+
this.fullUrl = iframeUrl;
|
|
147
|
+
this.showIframe = true;
|
|
148
|
+
this.updateTemplateContexts();
|
|
149
|
+
this.scheduleExternalLoadTimeout(loadVersion);
|
|
150
|
+
this.cdr.detectChanges();
|
|
151
|
+
this.scheduleViewerRecovery();
|
|
152
|
+
}
|
|
153
|
+
else if (this.configuredViewer === 'mammoth') {
|
|
154
|
+
this.setRenderPhase('loading');
|
|
155
|
+
this.externalViewer = false;
|
|
156
|
+
this.fullUrl = undefined;
|
|
157
|
+
this.showIframe = false;
|
|
158
|
+
try {
|
|
159
|
+
const docHtml = await getDocxToHtml(this.url);
|
|
160
|
+
if (loadVersion !== this.loadVersion) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
this.ngZone.run(() => {
|
|
164
|
+
this.docHtml = docHtml;
|
|
165
|
+
this.setRenderPhase('ready');
|
|
166
|
+
this.updateTemplateContexts();
|
|
167
|
+
this.cdr.detectChanges();
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
if (loadVersion !== this.loadVersion) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
this.ngZone.run(() => {
|
|
175
|
+
this.errorText =
|
|
176
|
+
error instanceof Error ? error.message : 'Unable to load document.';
|
|
177
|
+
this.setRenderPhase('error');
|
|
178
|
+
this.updateTemplateContexts();
|
|
179
|
+
this.cdr.detectChanges();
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
retryLoad() {
|
|
186
|
+
this.retryNonce += 1;
|
|
187
|
+
const retryVersion = ++this.loadVersion;
|
|
188
|
+
this.clearExternalLoadTimeout();
|
|
189
|
+
this.clearGoogleFinalRetry();
|
|
190
|
+
this.clearOfficeRetry();
|
|
191
|
+
this.errorText = '';
|
|
192
|
+
this.setRenderPhase(this.url ? 'loading' : 'idle');
|
|
193
|
+
this.updateTemplateContexts();
|
|
194
|
+
if (!this.url) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
if (this.configuredViewer === 'mammoth') {
|
|
198
|
+
this.docHtml = '';
|
|
199
|
+
void this.reloadMammoth(retryVersion);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (this.configuredViewer === 'google' ||
|
|
203
|
+
this.configuredViewer === 'office' ||
|
|
204
|
+
this.configuredViewer === 'url' ||
|
|
205
|
+
this.configuredViewer === 'pdf') {
|
|
206
|
+
const details = getViewerDetails(this.url, this.configuredViewer, this.queryParams, this.viewerUrl);
|
|
207
|
+
const finalUrl = details.externalViewer && this.overrideLocalhost && isLocalFile(this.url)
|
|
208
|
+
? getViewerDetails(replaceLocalUrl(this.url, this.overrideLocalhost), this.configuredViewer, this.queryParams, this.viewerUrl).url
|
|
209
|
+
: details.url;
|
|
210
|
+
this.fullUrl = undefined;
|
|
211
|
+
this.showIframe = false;
|
|
212
|
+
this.cdr.detectChanges();
|
|
213
|
+
this.fullUrl =
|
|
214
|
+
this.domSanitizer.bypassSecurityTrustResourceUrl(finalUrl);
|
|
215
|
+
this.showIframe = true;
|
|
216
|
+
this.scheduleExternalLoadTimeout(retryVersion);
|
|
217
|
+
this.scheduleViewerRecovery();
|
|
218
|
+
this.updateTemplateContexts();
|
|
219
|
+
this.cdr.detectChanges();
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
reloadIframe(iframe) {
|
|
223
|
+
this.checkIFrameSubscription = googleCheckSubscription();
|
|
224
|
+
this.checkIFrameSubscription.subscribe(iframe, this.googleCheckInterval, this.googleMaxChecks);
|
|
225
|
+
}
|
|
226
|
+
scheduleViewerRecovery() {
|
|
227
|
+
const recoveryPlan = getViewerRecoveryPlan({
|
|
228
|
+
viewer: this.configuredViewer,
|
|
229
|
+
googleCheckContentLoaded: this.googleCheckContentLoaded,
|
|
230
|
+
googleFinalRetryDelay: this.googleFinalRetryDelay,
|
|
231
|
+
officeAutoRetry: this.officeAutoRetry,
|
|
232
|
+
});
|
|
233
|
+
for (const mode of recoveryPlan.modes) {
|
|
234
|
+
if (mode === 'google-probe') {
|
|
235
|
+
this.scheduleGoogleRecovery();
|
|
236
|
+
}
|
|
237
|
+
if (mode === 'google-final-retry') {
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
if (mode === 'office-auto-retry') {
|
|
241
|
+
this.scheduleOfficeRetry();
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
scheduleGoogleRecovery() {
|
|
246
|
+
if (this.configuredViewer !== 'google' ||
|
|
247
|
+
!this.googleCheckContentLoaded) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
// see:
|
|
251
|
+
// https://stackoverflow.com/questions/40414039/google-docs-viewer-returning-204-responses-no-longer-working-alternatives
|
|
252
|
+
// hack to reload iframe if it's not loaded.
|
|
253
|
+
this.ngZone.runOutsideAngular(() => {
|
|
254
|
+
window.setTimeout(() => {
|
|
255
|
+
const iframe = this.iframes?.first?.nativeElement;
|
|
256
|
+
if (iframe) {
|
|
257
|
+
this.reloadIframe(iframe);
|
|
258
|
+
}
|
|
259
|
+
}, 0);
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
iframeLoaded() {
|
|
263
|
+
const iframe = this.iframes?.first?.nativeElement;
|
|
264
|
+
if (iframe && iframeIsLoaded(iframe)) {
|
|
265
|
+
this.clearExternalLoadTimeout();
|
|
266
|
+
this.clearGoogleFinalRetry();
|
|
267
|
+
this.clearOfficeRetry();
|
|
268
|
+
this.setRenderPhase('ready');
|
|
269
|
+
this.updateTemplateContexts();
|
|
270
|
+
this.loaded.emit(undefined);
|
|
271
|
+
if (this.checkIFrameSubscription) {
|
|
272
|
+
this.checkIFrameSubscription.unsubscribe();
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
objectLoaded() {
|
|
277
|
+
this.clearExternalLoadTimeout();
|
|
278
|
+
this.clearGoogleFinalRetry();
|
|
279
|
+
this.clearOfficeRetry();
|
|
280
|
+
this.setRenderPhase('ready');
|
|
281
|
+
this.updateTemplateContexts();
|
|
282
|
+
}
|
|
283
|
+
async reloadMammoth(loadVersion) {
|
|
284
|
+
this.externalViewer = false;
|
|
285
|
+
this.fullUrl = undefined;
|
|
286
|
+
this.showIframe = false;
|
|
287
|
+
try {
|
|
288
|
+
const docHtml = await getDocxToHtml(this.url);
|
|
289
|
+
if (loadVersion !== this.loadVersion) {
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
this.ngZone.run(() => {
|
|
293
|
+
this.docHtml = docHtml;
|
|
294
|
+
this.setRenderPhase('ready');
|
|
295
|
+
this.updateTemplateContexts();
|
|
296
|
+
this.cdr.detectChanges();
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
if (loadVersion !== this.loadVersion) {
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
this.ngZone.run(() => {
|
|
304
|
+
this.errorText =
|
|
305
|
+
error instanceof Error ? error.message : 'Unable to load document.';
|
|
306
|
+
this.setRenderPhase('error');
|
|
307
|
+
this.updateTemplateContexts();
|
|
308
|
+
this.cdr.detectChanges();
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
scheduleExternalLoadTimeout(loadVersion) {
|
|
313
|
+
this.clearExternalLoadTimeout();
|
|
314
|
+
const timeoutMs = this.configuredViewer === 'google'
|
|
315
|
+
? Math.max(this.googleCheckInterval * this.googleMaxChecks + 2000, 15000)
|
|
316
|
+
: 15000;
|
|
317
|
+
this.externalLoadTimeoutId = window.setTimeout(() => {
|
|
318
|
+
if (loadVersion !== this.loadVersion || this.renderPhase !== 'loading') {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
if (this.scheduleGoogleFinalRetry()) {
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
this.ngZone.run(() => {
|
|
325
|
+
this.errorText = `The ${this.configuredViewer} viewer did not finish loading in time.`;
|
|
326
|
+
this.setRenderPhase('error');
|
|
327
|
+
this.updateTemplateContexts();
|
|
328
|
+
this.cdr.detectChanges();
|
|
329
|
+
});
|
|
330
|
+
}, timeoutMs);
|
|
331
|
+
}
|
|
332
|
+
clearExternalLoadTimeout() {
|
|
333
|
+
if (this.externalLoadTimeoutId) {
|
|
334
|
+
window.clearTimeout(this.externalLoadTimeoutId);
|
|
335
|
+
this.externalLoadTimeoutId = undefined;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
clearGoogleFinalRetry() {
|
|
339
|
+
if (this.googleFinalRetryTimeoutId) {
|
|
340
|
+
window.clearTimeout(this.googleFinalRetryTimeoutId);
|
|
341
|
+
this.googleFinalRetryTimeoutId = undefined;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
clearOfficeRetry() {
|
|
345
|
+
if (this.officeRetryTimeoutId) {
|
|
346
|
+
window.clearTimeout(this.officeRetryTimeoutId);
|
|
347
|
+
this.officeRetryTimeoutId = undefined;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
scheduleOfficeRetry() {
|
|
351
|
+
if (this.configuredViewer !== 'office' ||
|
|
352
|
+
!this.officeAutoRetry ||
|
|
353
|
+
!this.currentOfficeSourceKey ||
|
|
354
|
+
this.officeAutoRetriedSourceKey === this.currentOfficeSourceKey) {
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
this.clearOfficeRetry();
|
|
358
|
+
this.officeRetryTimeoutId = window.setTimeout(() => {
|
|
359
|
+
if (!this.currentOfficeSourceKey ||
|
|
360
|
+
this.officeAutoRetriedSourceKey === this.currentOfficeSourceKey) {
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
this.officeAutoRetriedSourceKey = this.currentOfficeSourceKey;
|
|
364
|
+
this.ngZone.run(() => this.retryLoad());
|
|
365
|
+
}, this.officeRetryDelay);
|
|
366
|
+
}
|
|
367
|
+
scheduleGoogleFinalRetry() {
|
|
368
|
+
const recoveryPlan = getViewerRecoveryPlan({
|
|
369
|
+
viewer: this.configuredViewer,
|
|
370
|
+
googleCheckContentLoaded: this.googleCheckContentLoaded,
|
|
371
|
+
googleFinalRetryDelay: this.googleFinalRetryDelay,
|
|
372
|
+
officeAutoRetry: this.officeAutoRetry,
|
|
373
|
+
});
|
|
374
|
+
if (!recoveryPlan.modes.includes('google-final-retry') ||
|
|
375
|
+
!this.currentGoogleSourceKey ||
|
|
376
|
+
this.googleFinalRetriedSourceKey === this.currentGoogleSourceKey) {
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
379
|
+
this.clearGoogleFinalRetry();
|
|
380
|
+
this.googleFinalRetryTimeoutId = window.setTimeout(() => {
|
|
381
|
+
if (!this.currentGoogleSourceKey ||
|
|
382
|
+
this.googleFinalRetriedSourceKey === this.currentGoogleSourceKey) {
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
this.googleFinalRetriedSourceKey = this.currentGoogleSourceKey;
|
|
386
|
+
this.ngZone.run(() => this.retryLoad());
|
|
387
|
+
}, this.googleFinalRetryDelay);
|
|
388
|
+
return true;
|
|
389
|
+
}
|
|
390
|
+
get displayedErrorText() {
|
|
391
|
+
return this.errorTextOverride || this.errorText || 'Unable to load document.';
|
|
392
|
+
}
|
|
393
|
+
updateTemplateContexts() {
|
|
394
|
+
const state = this.createStateContext();
|
|
395
|
+
this.loadingTemplateContext = { $implicit: state, state };
|
|
396
|
+
this.errorTemplateContext = { $implicit: state, state };
|
|
397
|
+
}
|
|
398
|
+
createTemplateContext() {
|
|
399
|
+
const state = this.createStateContext();
|
|
400
|
+
return { $implicit: state, state };
|
|
401
|
+
}
|
|
402
|
+
createStateContext() {
|
|
403
|
+
return {
|
|
404
|
+
viewer: this.configuredViewer,
|
|
405
|
+
url: this.failedUrl || this.url,
|
|
406
|
+
phase: this.renderPhase,
|
|
407
|
+
errorText: this.displayedErrorText,
|
|
408
|
+
retry: () => this.retryLoad(),
|
|
409
|
+
actionUrl: this.failedUrl || this.url,
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
setRenderPhase(phase) {
|
|
413
|
+
this.renderPhase = phase;
|
|
414
|
+
this.emitLifecycleIfNeeded();
|
|
415
|
+
}
|
|
416
|
+
emitLifecycleIfNeeded() {
|
|
417
|
+
if (this.lastEmittedPhase === this.renderPhase) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
this.lastEmittedPhase = this.renderPhase;
|
|
421
|
+
const state = this.createStateContext();
|
|
422
|
+
this.phaseChange.emit(state);
|
|
423
|
+
if (this.renderPhase === 'loading') {
|
|
424
|
+
this.loading.emit(state);
|
|
425
|
+
}
|
|
426
|
+
if (this.renderPhase === 'error') {
|
|
427
|
+
this.error.emit(state);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: NgxDocViewerComponent, deps: [{ token: i1.DomSanitizer }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
431
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.4", type: NgxDocViewerComponent, isStandalone: true, selector: "ngx-doc-viewer", inputs: { url: "url", queryParams: "queryParams", viewerUrl: "viewerUrl", googleCheckInterval: "googleCheckInterval", googleMaxChecks: "googleMaxChecks", googleFinalRetryDelay: "googleFinalRetryDelay", disableContent: "disableContent", googleCheckContentLoaded: "googleCheckContentLoaded", viewer: "viewer", overrideLocalhost: "overrideLocalhost", loadingText: "loadingText", errorTextOverride: "errorTextOverride", retryButtonText: "retryButtonText", officeAutoRetry: "officeAutoRetry", officeRetryDelay: "officeRetryDelay", officeReloadButtonText: "officeReloadButtonText", officeReloadButtonTitle: "officeReloadButtonTitle", secondaryActionText: "secondaryActionText", secondaryActionMode: "secondaryActionMode" }, outputs: { loaded: "loaded", loading: "loading", error: "error", phaseChange: "phaseChange" }, queries: [{ propertyName: "loadingTemplate", first: true, predicate: ["loadingContent"], descendants: true, read: TemplateRef }, { propertyName: "errorTemplate", first: true, predicate: ["errorContent"], descendants: true, read: TemplateRef }, { propertyName: "errorActionsTemplate", first: true, predicate: ["errorActions"], descendants: true, read: TemplateRef }, { propertyName: "officeReloadTemplate", first: true, predicate: ["officeReloadContent"], descendants: true, read: TemplateRef }], viewQueries: [{ propertyName: "iframes", predicate: ["iframe"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"container\">\n <div *ngIf=\"renderPhase === 'loading'\" class=\"loading-overlay\">\n <ng-container *ngIf=\"loadingTemplate; else defaultLoadingTemplate\">\n <ng-container *ngTemplateOutlet=\"loadingTemplate; context: loadingTemplateContext\"></ng-container>\n </ng-container>\n <ng-template #defaultLoadingTemplate>{{ loadingText }}</ng-template>\n </div>\n <div *ngIf=\"renderPhase === 'error'\" class=\"error-overlay\">\n <ng-container *ngIf=\"errorTemplate; else defaultErrorTemplate\">\n <ng-container *ngTemplateOutlet=\"errorTemplate; context: errorTemplateContext\"></ng-container>\n </ng-container>\n <ng-template #defaultErrorTemplate>\n <div>\n <div>{{ displayedErrorText }}</div>\n <div *ngIf=\"configuredViewer\" style=\"margin-top: 8px; color: #475569;\">\n Viewer: {{ configuredViewer }}\n </div>\n <div *ngIf=\"failedUrl\" style=\"margin-top: 4px; color: #64748b; font-size: 12px; word-break: break-word;\">\n {{ failedUrl }}\n </div>\n <ng-container *ngIf=\"errorActionsTemplate; else defaultErrorActions\">\n <ng-container *ngTemplateOutlet=\"errorActionsTemplate; context: errorTemplateContext\"></ng-container>\n </ng-container>\n <ng-template #defaultErrorActions>\n <div style=\"margin-top: 14px; display: flex; gap: 8px; justify-content: center; flex-wrap: wrap;\">\n <button\n type=\"button\"\n (click)=\"retryLoad()\"\n style=\"border: 1px solid #fecaca; background: #fff; color: #991b1b; border-radius: 999px; padding: 8px 14px; font: inherit; cursor: pointer;\"\n >\n {{ retryButtonText }}\n </button>\n <a\n *ngIf=\"secondaryActionText && failedUrl\"\n [href]=\"failedUrl\"\n [attr.target]=\"secondaryActionMode === 'open' ? '_blank' : null\"\n [attr.rel]=\"secondaryActionMode === 'open' ? 'noreferrer' : null\"\n [attr.download]=\"secondaryActionMode === 'download' ? '' : null\"\n style=\"border: 1px solid #cbd5e1; background: #fff; color: #334155; border-radius: 999px; padding: 8px 14px; text-decoration: none; font: inherit;\"\n >\n {{ secondaryActionText }}\n </a>\n </div>\n </ng-template>\n </div>\n </ng-template>\n </div>\n\n <ng-container *ngIf=\"!externalViewer\">\n <div *ngIf=\"configuredViewer !== 'pdf'\" class=\"inline-document-shell\">\n <div class=\"inline-document-page\" [innerHTML]=\"docHtml\"></div>\n </div>\n <object\n (load)=\"objectLoaded()\"\n *ngIf=\"fullUrl && configuredViewer === 'pdf'\"\n [data]=\"fullUrl\"\n type=\"application/pdf\"\n width=\"100%\"\n height=\"100%\"\n >\n <p>\n Your browser does not support PDFs.\n <a [href]=\"fullUrl\">Download the PDF</a>.\n </p>\n </object>\n </ng-container>\n\n <button\n *ngIf=\"configuredViewer === 'office' && renderPhase === 'ready'\"\n class=\"office-reload-btn\"\n type=\"button\"\n [attr.title]=\"officeReloadButtonTitle\"\n (click)=\"retryLoad()\"\n >\n <ng-container *ngIf=\"officeReloadTemplate; else defaultOfficeReloadTemplate\">\n <ng-container *ngTemplateOutlet=\"officeReloadTemplate; context: errorTemplateContext\"></ng-container>\n </ng-container>\n <ng-template #defaultOfficeReloadTemplate>{{ officeReloadButtonText }}</ng-template>\n </button>\n\n <ng-container *ngIf=\"externalViewer\">\n <iframe\n (load)=\"iframeLoaded()\"\n *ngIf=\"fullUrl && showIframe && disableContent === 'none'\"\n #iframe\n id=\"iframe-doc-viewer\"\n frameBorder=\"0\"\n [src]=\"fullUrl\"\n ></iframe>\n <div class=\"container\" *ngIf=\"disableContent !== 'none'\">\n <div\n [class.overlay-full]=\"disableContent === 'all'\"\n [class.overlay-popout-google]=\"\n configuredViewer === 'google' &&\n (disableContent === 'popout' || disableContent === 'popout-hide')\n \"\n [class.overlay-popout-office]=\"\n configuredViewer === 'office' &&\n (disableContent === 'popout' || disableContent === 'popout-hide')\n \"\n [style.background-color]=\"\n disableContent === 'popout-hide' ? '#fff' : 'transparent'\n \"\n ></div>\n <iframe\n (load)=\"iframeLoaded()\"\n *ngIf=\"fullUrl && showIframe\"\n #iframe\n id=\"iframe\"\n frameBorder=\"0\"\n [src]=\"fullUrl\"\n ></iframe>\n </div>\n </ng-container>\n</div>\n", styles: [":host{display:block}.container{width:100%;height:100%;position:relative}.inline-document-shell{width:100%;height:100%;overflow:auto;background:linear-gradient(180deg,#eef2f7,#f8fafc);padding:24px}.inline-document-page{max-width:900px;min-height:100%;margin:0 auto;background:#fff;border:1px solid #dbe4f0;border-radius:18px;box-shadow:0 18px 40px -24px #0f172a4d,0 6px 18px -10px #0f172a2e;padding:40px 48px}.inline-document-page,.inline-document-page *{box-sizing:border-box}.inline-document-page{color:#1e293b;font-family:Georgia,Cambria,Times New Roman,Times,serif;font-size:18px;line-height:1.7}.inline-document-page p,.inline-document-page ul,.inline-document-page ol,.inline-document-page blockquote,.inline-document-page table{margin:0 0 1.1em}.inline-document-page h1,.inline-document-page h2,.inline-document-page h3,.inline-document-page h4,.inline-document-page h5,.inline-document-page h6{margin:1.4em 0 .65em;color:#0f172a;line-height:1.25}.inline-document-page h1:first-child,.inline-document-page h2:first-child,.inline-document-page h3:first-child,.inline-document-page p:first-child{margin-top:0}.inline-document-page table{width:100%;border-collapse:collapse}.inline-document-page td,.inline-document-page th{padding:6px 10px;vertical-align:top}.inline-document-page img{max-width:100%;height:auto}.inline-document-page hr{border:0;border-top:1px solid #dbe4f0;margin:1.5em 0}.loading-overlay{position:absolute;inset:0;z-index:1001;display:flex;align-items:center;justify-content:center;background:#ffffffe0;color:#475569;font-size:14px;font-weight:600;letter-spacing:.02em;text-align:center;padding:16px}.error-overlay{position:absolute;inset:0;z-index:1001;display:flex;align-items:center;justify-content:center;background:#fffffff0;color:#991b1b;font-size:14px;font-weight:600;letter-spacing:.02em;text-align:center;padding:16px}.overlay-popout-google{width:40px;height:40px;right:26px;top:11.5px;position:absolute;z-index:1000}.overlay-popout-office{width:100px;height:20px;right:0;bottom:0;position:absolute;z-index:1000}.office-reload-btn{position:absolute;top:8px;right:8px;z-index:1001;width:32px;height:32px;border-radius:50%;border:1px solid rgba(0,0,0,.12);background:#ffffffd9;color:#475569;font-size:16px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;opacity:.5;transition:opacity .15s;padding:0}.office-reload-btn:hover{opacity:1}.overlay-full{width:100%;height:100%;right:0;top:0;position:absolute;z-index:1000}iframe{width:100%;height:100%}@media(max-width:768px){.inline-document-shell{padding:12px}.inline-document-page{border-radius:12px;padding:22px 18px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
432
|
+
}
|
|
433
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: NgxDocViewerComponent, decorators: [{
|
|
434
|
+
type: Component,
|
|
435
|
+
args: [{ selector: 'ngx-doc-viewer', standalone: true, imports: [CommonModule], template: "<div class=\"container\">\n <div *ngIf=\"renderPhase === 'loading'\" class=\"loading-overlay\">\n <ng-container *ngIf=\"loadingTemplate; else defaultLoadingTemplate\">\n <ng-container *ngTemplateOutlet=\"loadingTemplate; context: loadingTemplateContext\"></ng-container>\n </ng-container>\n <ng-template #defaultLoadingTemplate>{{ loadingText }}</ng-template>\n </div>\n <div *ngIf=\"renderPhase === 'error'\" class=\"error-overlay\">\n <ng-container *ngIf=\"errorTemplate; else defaultErrorTemplate\">\n <ng-container *ngTemplateOutlet=\"errorTemplate; context: errorTemplateContext\"></ng-container>\n </ng-container>\n <ng-template #defaultErrorTemplate>\n <div>\n <div>{{ displayedErrorText }}</div>\n <div *ngIf=\"configuredViewer\" style=\"margin-top: 8px; color: #475569;\">\n Viewer: {{ configuredViewer }}\n </div>\n <div *ngIf=\"failedUrl\" style=\"margin-top: 4px; color: #64748b; font-size: 12px; word-break: break-word;\">\n {{ failedUrl }}\n </div>\n <ng-container *ngIf=\"errorActionsTemplate; else defaultErrorActions\">\n <ng-container *ngTemplateOutlet=\"errorActionsTemplate; context: errorTemplateContext\"></ng-container>\n </ng-container>\n <ng-template #defaultErrorActions>\n <div style=\"margin-top: 14px; display: flex; gap: 8px; justify-content: center; flex-wrap: wrap;\">\n <button\n type=\"button\"\n (click)=\"retryLoad()\"\n style=\"border: 1px solid #fecaca; background: #fff; color: #991b1b; border-radius: 999px; padding: 8px 14px; font: inherit; cursor: pointer;\"\n >\n {{ retryButtonText }}\n </button>\n <a\n *ngIf=\"secondaryActionText && failedUrl\"\n [href]=\"failedUrl\"\n [attr.target]=\"secondaryActionMode === 'open' ? '_blank' : null\"\n [attr.rel]=\"secondaryActionMode === 'open' ? 'noreferrer' : null\"\n [attr.download]=\"secondaryActionMode === 'download' ? '' : null\"\n style=\"border: 1px solid #cbd5e1; background: #fff; color: #334155; border-radius: 999px; padding: 8px 14px; text-decoration: none; font: inherit;\"\n >\n {{ secondaryActionText }}\n </a>\n </div>\n </ng-template>\n </div>\n </ng-template>\n </div>\n\n <ng-container *ngIf=\"!externalViewer\">\n <div *ngIf=\"configuredViewer !== 'pdf'\" class=\"inline-document-shell\">\n <div class=\"inline-document-page\" [innerHTML]=\"docHtml\"></div>\n </div>\n <object\n (load)=\"objectLoaded()\"\n *ngIf=\"fullUrl && configuredViewer === 'pdf'\"\n [data]=\"fullUrl\"\n type=\"application/pdf\"\n width=\"100%\"\n height=\"100%\"\n >\n <p>\n Your browser does not support PDFs.\n <a [href]=\"fullUrl\">Download the PDF</a>.\n </p>\n </object>\n </ng-container>\n\n <button\n *ngIf=\"configuredViewer === 'office' && renderPhase === 'ready'\"\n class=\"office-reload-btn\"\n type=\"button\"\n [attr.title]=\"officeReloadButtonTitle\"\n (click)=\"retryLoad()\"\n >\n <ng-container *ngIf=\"officeReloadTemplate; else defaultOfficeReloadTemplate\">\n <ng-container *ngTemplateOutlet=\"officeReloadTemplate; context: errorTemplateContext\"></ng-container>\n </ng-container>\n <ng-template #defaultOfficeReloadTemplate>{{ officeReloadButtonText }}</ng-template>\n </button>\n\n <ng-container *ngIf=\"externalViewer\">\n <iframe\n (load)=\"iframeLoaded()\"\n *ngIf=\"fullUrl && showIframe && disableContent === 'none'\"\n #iframe\n id=\"iframe-doc-viewer\"\n frameBorder=\"0\"\n [src]=\"fullUrl\"\n ></iframe>\n <div class=\"container\" *ngIf=\"disableContent !== 'none'\">\n <div\n [class.overlay-full]=\"disableContent === 'all'\"\n [class.overlay-popout-google]=\"\n configuredViewer === 'google' &&\n (disableContent === 'popout' || disableContent === 'popout-hide')\n \"\n [class.overlay-popout-office]=\"\n configuredViewer === 'office' &&\n (disableContent === 'popout' || disableContent === 'popout-hide')\n \"\n [style.background-color]=\"\n disableContent === 'popout-hide' ? '#fff' : 'transparent'\n \"\n ></div>\n <iframe\n (load)=\"iframeLoaded()\"\n *ngIf=\"fullUrl && showIframe\"\n #iframe\n id=\"iframe\"\n frameBorder=\"0\"\n [src]=\"fullUrl\"\n ></iframe>\n </div>\n </ng-container>\n</div>\n", styles: [":host{display:block}.container{width:100%;height:100%;position:relative}.inline-document-shell{width:100%;height:100%;overflow:auto;background:linear-gradient(180deg,#eef2f7,#f8fafc);padding:24px}.inline-document-page{max-width:900px;min-height:100%;margin:0 auto;background:#fff;border:1px solid #dbe4f0;border-radius:18px;box-shadow:0 18px 40px -24px #0f172a4d,0 6px 18px -10px #0f172a2e;padding:40px 48px}.inline-document-page,.inline-document-page *{box-sizing:border-box}.inline-document-page{color:#1e293b;font-family:Georgia,Cambria,Times New Roman,Times,serif;font-size:18px;line-height:1.7}.inline-document-page p,.inline-document-page ul,.inline-document-page ol,.inline-document-page blockquote,.inline-document-page table{margin:0 0 1.1em}.inline-document-page h1,.inline-document-page h2,.inline-document-page h3,.inline-document-page h4,.inline-document-page h5,.inline-document-page h6{margin:1.4em 0 .65em;color:#0f172a;line-height:1.25}.inline-document-page h1:first-child,.inline-document-page h2:first-child,.inline-document-page h3:first-child,.inline-document-page p:first-child{margin-top:0}.inline-document-page table{width:100%;border-collapse:collapse}.inline-document-page td,.inline-document-page th{padding:6px 10px;vertical-align:top}.inline-document-page img{max-width:100%;height:auto}.inline-document-page hr{border:0;border-top:1px solid #dbe4f0;margin:1.5em 0}.loading-overlay{position:absolute;inset:0;z-index:1001;display:flex;align-items:center;justify-content:center;background:#ffffffe0;color:#475569;font-size:14px;font-weight:600;letter-spacing:.02em;text-align:center;padding:16px}.error-overlay{position:absolute;inset:0;z-index:1001;display:flex;align-items:center;justify-content:center;background:#fffffff0;color:#991b1b;font-size:14px;font-weight:600;letter-spacing:.02em;text-align:center;padding:16px}.overlay-popout-google{width:40px;height:40px;right:26px;top:11.5px;position:absolute;z-index:1000}.overlay-popout-office{width:100px;height:20px;right:0;bottom:0;position:absolute;z-index:1000}.office-reload-btn{position:absolute;top:8px;right:8px;z-index:1001;width:32px;height:32px;border-radius:50%;border:1px solid rgba(0,0,0,.12);background:#ffffffd9;color:#475569;font-size:16px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;opacity:.5;transition:opacity .15s;padding:0}.office-reload-btn:hover{opacity:1}.overlay-full{width:100%;height:100%;right:0;top:0;position:absolute;z-index:1000}iframe{width:100%;height:100%}@media(max-width:768px){.inline-document-shell{padding:12px}.inline-document-page{border-radius:12px;padding:22px 18px}}\n"] }]
|
|
436
|
+
}], ctorParameters: () => [{ type: i1.DomSanitizer }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }], propDecorators: { loaded: [{
|
|
437
|
+
type: Output
|
|
438
|
+
}], loading: [{
|
|
439
|
+
type: Output
|
|
440
|
+
}], error: [{
|
|
441
|
+
type: Output
|
|
442
|
+
}], phaseChange: [{
|
|
443
|
+
type: Output
|
|
444
|
+
}], url: [{
|
|
445
|
+
type: Input
|
|
446
|
+
}], queryParams: [{
|
|
447
|
+
type: Input
|
|
448
|
+
}], viewerUrl: [{
|
|
449
|
+
type: Input
|
|
450
|
+
}], googleCheckInterval: [{
|
|
451
|
+
type: Input
|
|
452
|
+
}], googleMaxChecks: [{
|
|
453
|
+
type: Input
|
|
454
|
+
}], googleFinalRetryDelay: [{
|
|
455
|
+
type: Input
|
|
456
|
+
}], disableContent: [{
|
|
457
|
+
type: Input
|
|
458
|
+
}], googleCheckContentLoaded: [{
|
|
459
|
+
type: Input
|
|
460
|
+
}], viewer: [{
|
|
461
|
+
type: Input
|
|
462
|
+
}], overrideLocalhost: [{
|
|
463
|
+
type: Input
|
|
464
|
+
}], loadingText: [{
|
|
465
|
+
type: Input
|
|
466
|
+
}], errorTextOverride: [{
|
|
467
|
+
type: Input
|
|
468
|
+
}], retryButtonText: [{
|
|
469
|
+
type: Input
|
|
470
|
+
}], officeAutoRetry: [{
|
|
471
|
+
type: Input
|
|
472
|
+
}], officeRetryDelay: [{
|
|
473
|
+
type: Input
|
|
474
|
+
}], officeReloadButtonText: [{
|
|
475
|
+
type: Input
|
|
476
|
+
}], officeReloadButtonTitle: [{
|
|
477
|
+
type: Input
|
|
478
|
+
}], secondaryActionText: [{
|
|
479
|
+
type: Input
|
|
480
|
+
}], secondaryActionMode: [{
|
|
481
|
+
type: Input
|
|
482
|
+
}], loadingTemplate: [{
|
|
483
|
+
type: ContentChild,
|
|
484
|
+
args: ['loadingContent', { read: TemplateRef }]
|
|
485
|
+
}], errorTemplate: [{
|
|
486
|
+
type: ContentChild,
|
|
487
|
+
args: ['errorContent', { read: TemplateRef }]
|
|
488
|
+
}], errorActionsTemplate: [{
|
|
489
|
+
type: ContentChild,
|
|
490
|
+
args: ['errorActions', { read: TemplateRef }]
|
|
491
|
+
}], officeReloadTemplate: [{
|
|
492
|
+
type: ContentChild,
|
|
493
|
+
args: ['officeReloadContent', { read: TemplateRef }]
|
|
494
|
+
}], iframes: [{
|
|
495
|
+
type: ViewChildren,
|
|
496
|
+
args: ['iframe']
|
|
497
|
+
}] } });
|
|
498
|
+
|
|
499
|
+
class NgxDocViewerModule {
|
|
500
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: NgxDocViewerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
501
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.4", ngImport: i0, type: NgxDocViewerModule, imports: [CommonModule, NgxDocViewerComponent], exports: [NgxDocViewerComponent] });
|
|
502
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: NgxDocViewerModule, imports: [CommonModule, NgxDocViewerComponent] });
|
|
503
|
+
}
|
|
504
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: NgxDocViewerModule, decorators: [{
|
|
505
|
+
type: NgModule,
|
|
506
|
+
args: [{
|
|
507
|
+
imports: [CommonModule, NgxDocViewerComponent],
|
|
508
|
+
exports: [NgxDocViewerComponent],
|
|
509
|
+
}]
|
|
510
|
+
}] });
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Generated bundle index. Do not edit.
|
|
514
|
+
*/
|
|
515
|
+
|
|
516
|
+
export { NgxDocViewerComponent, NgxDocViewerModule };
|
|
517
|
+
//# sourceMappingURL=ngx-doc-viewer.mjs.map
|