@theia/mini-browser 1.45.1 → 1.46.0-next.72

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.
Files changed (63) hide show
  1. package/README.md +45 -45
  2. package/lib/browser/environment/mini-browser-environment-module.d.ts +3 -3
  3. package/lib/browser/environment/mini-browser-environment-module.js +24 -24
  4. package/lib/browser/environment/mini-browser-environment.d.ts +25 -25
  5. package/lib/browser/environment/mini-browser-environment.js +95 -95
  6. package/lib/browser/environment/mini-browser-environment.js.map +1 -1
  7. package/lib/browser/location-mapper-service.d.ts +58 -58
  8. package/lib/browser/location-mapper-service.js +140 -140
  9. package/lib/browser/mini-browser-content-style.d.ts +17 -17
  10. package/lib/browser/mini-browser-content-style.js +36 -36
  11. package/lib/browser/mini-browser-content.d.ts +177 -177
  12. package/lib/browser/mini-browser-content.js +554 -554
  13. package/lib/browser/mini-browser-frontend-module.d.ts +4 -4
  14. package/lib/browser/mini-browser-frontend-module.js +70 -70
  15. package/lib/browser/mini-browser-frontend-security-warnings.d.ts +11 -11
  16. package/lib/browser/mini-browser-frontend-security-warnings.js +73 -73
  17. package/lib/browser/mini-browser-open-handler.d.ts +76 -76
  18. package/lib/browser/mini-browser-open-handler.js +292 -292
  19. package/lib/browser/mini-browser.d.ts +25 -25
  20. package/lib/browser/mini-browser.js +118 -118
  21. package/lib/common/mini-browser-endpoint.d.ts +12 -12
  22. package/lib/common/mini-browser-endpoint.js +31 -31
  23. package/lib/common/mini-browser-service.d.ts +14 -14
  24. package/lib/common/mini-browser-service.js +20 -20
  25. package/lib/electron-browser/environment/electron-mini-browser-environment-module.d.ts +3 -3
  26. package/lib/electron-browser/environment/electron-mini-browser-environment-module.js +25 -25
  27. package/lib/electron-browser/environment/electron-mini-browser-environment.d.ts +9 -9
  28. package/lib/electron-browser/environment/electron-mini-browser-environment.js +60 -60
  29. package/lib/electron-main/mini-browser-electron-main-contribution.d.ts +12 -12
  30. package/lib/electron-main/mini-browser-electron-main-contribution.js +54 -54
  31. package/lib/node/mini-browser-backend-module.d.ts +3 -3
  32. package/lib/node/mini-browser-backend-module.js +41 -41
  33. package/lib/node/mini-browser-backend-security-warnings.d.ts +5 -5
  34. package/lib/node/mini-browser-backend-security-warnings.js +51 -51
  35. package/lib/node/mini-browser-endpoint.d.ts +97 -97
  36. package/lib/node/mini-browser-endpoint.js +268 -268
  37. package/lib/node/mini-browser-endpoint.js.map +1 -1
  38. package/lib/node/mini-browser-ws-validator.d.ts +12 -12
  39. package/lib/node/mini-browser-ws-validator.js +69 -69
  40. package/lib/package.spec.js +18 -18
  41. package/package.json +5 -6
  42. package/src/browser/environment/mini-browser-environment-module.ts +24 -24
  43. package/src/browser/environment/mini-browser-environment.ts +87 -87
  44. package/src/browser/location-mapper-service.ts +150 -150
  45. package/src/browser/mini-browser-content-style.ts +32 -32
  46. package/src/browser/mini-browser-content.ts +630 -630
  47. package/src/browser/mini-browser-frontend-module.ts +86 -86
  48. package/src/browser/mini-browser-frontend-security-warnings.ts +59 -59
  49. package/src/browser/mini-browser-open-handler.ts +312 -312
  50. package/src/browser/mini-browser.ts +110 -110
  51. package/src/browser/pdfobject.d.ts +99 -99
  52. package/src/browser/style/index.css +157 -157
  53. package/src/browser/style/mini-browser.svg +17 -17
  54. package/src/common/mini-browser-endpoint.ts +28 -28
  55. package/src/common/mini-browser-service.ts +29 -29
  56. package/src/electron-browser/environment/electron-mini-browser-environment-module.ts +25 -25
  57. package/src/electron-browser/environment/electron-mini-browser-environment.ts +53 -53
  58. package/src/electron-main/mini-browser-electron-main-contribution.ts +42 -42
  59. package/src/node/mini-browser-backend-module.ts +41 -41
  60. package/src/node/mini-browser-backend-security-warnings.ts +45 -45
  61. package/src/node/mini-browser-endpoint.ts +315 -315
  62. package/src/node/mini-browser-ws-validator.ts +56 -56
  63. package/src/package.spec.ts +21 -21
@@ -1,555 +1,555 @@
1
- "use strict";
2
- // *****************************************************************************
3
- // Copyright (C) 2018 TypeFox and others.
4
- //
5
- // This program and the accompanying materials are made available under the
6
- // terms of the Eclipse Public License v. 2.0 which is available at
7
- // http://www.eclipse.org/legal/epl-2.0.
8
- //
9
- // This Source Code may also be made available under the following Secondary
10
- // Licenses when the conditions for such availability set forth in the Eclipse
11
- // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
- // with the GNU Classpath Exception which is available at
13
- // https://www.gnu.org/software/classpath/license.html.
14
- //
15
- // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
- // *****************************************************************************
17
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
18
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
19
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
20
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
21
- return c > 3 && r && Object.defineProperty(target, key, r), r;
22
- };
23
- var __metadata = (this && this.__metadata) || function (k, v) {
24
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
25
- };
26
- var __param = (this && this.__param) || function (paramIndex, decorator) {
27
- return function (target, key) { decorator(target, key, paramIndex); }
28
- };
29
- Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.MiniBrowserContent = exports.MiniBrowserContentFactory = exports.MiniBrowserProps = void 0;
31
- const PDFObject = require("pdfobject");
32
- const inversify_1 = require("@theia/core/shared/inversify");
33
- const uri_1 = require("@theia/core/lib/common/uri");
34
- const logger_1 = require("@theia/core/lib/common/logger");
35
- const event_1 = require("@theia/core/lib/common/event");
36
- const keybinding_1 = require("@theia/core/lib/browser/keybinding");
37
- const window_service_1 = require("@theia/core/lib/browser/window/window-service");
38
- const browser_1 = require("@theia/core/lib/browser");
39
- const disposable_1 = require("@theia/core/lib/common/disposable");
40
- const widget_1 = require("@theia/core/lib/browser/widgets/widget");
41
- const location_mapper_service_1 = require("./location-mapper-service");
42
- const application_shell_mouse_tracker_1 = require("@theia/core/lib/browser/shell/application-shell-mouse-tracker");
43
- const debounce = require("@theia/core/shared/lodash.debounce");
44
- const mini_browser_content_style_1 = require("./mini-browser-content-style");
45
- const file_service_1 = require("@theia/filesystem/lib/browser/file-service");
46
- /**
47
- * Initializer properties for the embedded browser widget.
48
- */
49
- let MiniBrowserProps = class MiniBrowserProps {
50
- };
51
- MiniBrowserProps = __decorate([
52
- (0, inversify_1.injectable)()
53
- ], MiniBrowserProps);
54
- exports.MiniBrowserProps = MiniBrowserProps;
55
- (function (MiniBrowserProps) {
56
- /**
57
- * Enumeration of the supported `sandbox` options for the `iframe`.
58
- */
59
- let SandboxOptions;
60
- (function (SandboxOptions) {
61
- /**
62
- * Allows form submissions.
63
- */
64
- SandboxOptions[SandboxOptions["allow-forms"] = 0] = "allow-forms";
65
- /**
66
- * Allows popups, such as `window.open()`, `showModalDialog()`, `target=”_blank”`, etc.
67
- */
68
- SandboxOptions[SandboxOptions["allow-popups"] = 1] = "allow-popups";
69
- /**
70
- * Allows pointer lock.
71
- */
72
- SandboxOptions[SandboxOptions["allow-pointer-lock"] = 2] = "allow-pointer-lock";
73
- /**
74
- * Allows the document to maintain its origin. Pages loaded from https://example.com/ will retain access to that origin’s data.
75
- */
76
- SandboxOptions[SandboxOptions["allow-same-origin"] = 3] = "allow-same-origin";
77
- /**
78
- * Allows JavaScript execution. Also allows features to trigger automatically (as they’d be trivial to implement via JavaScript).
79
- */
80
- SandboxOptions[SandboxOptions["allow-scripts"] = 4] = "allow-scripts";
81
- /**
82
- * Allows the document to break out of the frame by navigating the top-level `window`.
83
- */
84
- SandboxOptions[SandboxOptions["allow-top-navigation"] = 5] = "allow-top-navigation";
85
- /**
86
- * Allows the embedded browsing context to open modal windows.
87
- */
88
- SandboxOptions[SandboxOptions["allow-modals"] = 6] = "allow-modals";
89
- /**
90
- * Allows the embedded browsing context to disable the ability to lock the screen orientation.
91
- */
92
- SandboxOptions[SandboxOptions["allow-orientation-lock"] = 7] = "allow-orientation-lock";
93
- /**
94
- * Allows a sandboxed document to open new windows without forcing the sandboxing flags upon them.
95
- * This will allow, for example, a third-party advertisement to be safely sandboxed without forcing the same restrictions upon a landing page.
96
- */
97
- SandboxOptions[SandboxOptions["allow-popups-to-escape-sandbox"] = 8] = "allow-popups-to-escape-sandbox";
98
- /**
99
- * Allows embedders to have control over whether an iframe can start a presentation session.
100
- */
101
- SandboxOptions[SandboxOptions["allow-presentation"] = 9] = "allow-presentation";
102
- /**
103
- * Allows the embedded browsing context to navigate (load) content to the top-level browsing context only when initiated by a user gesture.
104
- * If this keyword is not used, this operation is not allowed.
105
- */
106
- SandboxOptions[SandboxOptions["allow-top-navigation-by-user-activation"] = 10] = "allow-top-navigation-by-user-activation";
107
- })(SandboxOptions = MiniBrowserProps.SandboxOptions || (MiniBrowserProps.SandboxOptions = {}));
108
- (function (SandboxOptions) {
109
- /**
110
- * The default `sandbox` options, if other is not provided.
111
- *
112
- * See: https://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/
113
- */
114
- SandboxOptions.DEFAULT = [
115
- SandboxOptions['allow-same-origin'],
116
- SandboxOptions['allow-scripts'],
117
- SandboxOptions['allow-popups'],
118
- SandboxOptions['allow-forms'],
119
- SandboxOptions['allow-modals']
120
- ];
121
- })(SandboxOptions = MiniBrowserProps.SandboxOptions || (MiniBrowserProps.SandboxOptions = {}));
122
- })(MiniBrowserProps = exports.MiniBrowserProps || (exports.MiniBrowserProps = {}));
123
- exports.MiniBrowserProps = MiniBrowserProps;
124
- exports.MiniBrowserContentFactory = Symbol('MiniBrowserContentFactory');
125
- let MiniBrowserContent = class MiniBrowserContent extends widget_1.BaseWidget {
126
- constructor(props) {
127
- super();
128
- this.props = props;
129
- this.submitInputEmitter = new event_1.Emitter();
130
- this.navigateBackEmitter = new event_1.Emitter();
131
- this.navigateForwardEmitter = new event_1.Emitter();
132
- this.refreshEmitter = new event_1.Emitter();
133
- this.openEmitter = new event_1.Emitter();
134
- this.toDisposeOnGo = new disposable_1.DisposableCollection();
135
- this.node.tabIndex = 0;
136
- this.addClass(mini_browser_content_style_1.MiniBrowserContentStyle.MINI_BROWSER);
137
- this.input = this.createToolbar(this.node).input;
138
- const contentArea = this.createContentArea(this.node);
139
- this.frame = contentArea.frame;
140
- this.transparentOverlay = contentArea.transparentOverlay;
141
- this.loadIndicator = contentArea.loadIndicator;
142
- this.errorBar = contentArea.errorBar;
143
- this.pdfContainer = contentArea.pdfContainer;
144
- this.initialHistoryLength = history.length;
145
- this.toDispose.pushAll([
146
- this.submitInputEmitter,
147
- this.navigateBackEmitter,
148
- this.navigateForwardEmitter,
149
- this.refreshEmitter,
150
- this.openEmitter
151
- ]);
152
- }
153
- init() {
154
- this.toDispose.push(this.mouseTracker.onMousedown(e => {
155
- if (this.frame.style.display !== 'none') {
156
- this.transparentOverlay.style.display = 'block';
157
- }
158
- }));
159
- this.toDispose.push(this.mouseTracker.onMouseup(e => {
160
- if (this.frame.style.display !== 'none') {
161
- this.transparentOverlay.style.display = 'none';
162
- }
163
- }));
164
- const { startPage } = this.props;
165
- if (startPage) {
166
- setTimeout(() => this.go(startPage), 500);
167
- this.listenOnContentChange(startPage);
168
- }
169
- }
170
- onActivateRequest(msg) {
171
- super.onActivateRequest(msg);
172
- if (this.getToolbarProps() !== 'hide') {
173
- this.input.focus();
174
- }
175
- else {
176
- this.node.focus();
177
- }
178
- }
179
- async listenOnContentChange(location) {
180
- if (await this.fileService.exists(new uri_1.default(location))) {
181
- const fileUri = new uri_1.default(location);
182
- const watcher = this.fileService.watch(fileUri);
183
- this.toDispose.push(watcher);
184
- const onFileChange = (event) => {
185
- if (event.contains(fileUri, 1 /* ADDED */) || event.contains(fileUri, 0 /* UPDATED */)) {
186
- this.go(location, {
187
- showLoadIndicator: false
188
- });
189
- }
190
- };
191
- this.toDispose.push(this.fileService.onDidFilesChange(debounce(onFileChange, 500)));
192
- }
193
- }
194
- createToolbar(parent) {
195
- const toolbar = document.createElement('div');
196
- toolbar.classList.add(this.getToolbarProps() === 'read-only' ? mini_browser_content_style_1.MiniBrowserContentStyle.TOOLBAR_READ_ONLY : mini_browser_content_style_1.MiniBrowserContentStyle.TOOLBAR);
197
- parent.appendChild(toolbar);
198
- this.createPrevious(toolbar);
199
- this.createNext(toolbar);
200
- this.createRefresh(toolbar);
201
- const input = this.createInput(toolbar);
202
- input.readOnly = this.getToolbarProps() === 'read-only';
203
- this.createOpen(toolbar);
204
- if (this.getToolbarProps() === 'hide') {
205
- toolbar.style.display = 'none';
206
- }
207
- return Object.assign(toolbar, { input });
208
- }
209
- getToolbarProps() {
210
- return !this.props.startPage ? 'show' : this.props.toolbar || 'show';
211
- }
212
- // eslint-disable-next-line max-len
213
- createContentArea(parent) {
214
- const contentArea = document.createElement('div');
215
- contentArea.classList.add(mini_browser_content_style_1.MiniBrowserContentStyle.CONTENT_AREA);
216
- const loadIndicator = document.createElement('div');
217
- loadIndicator.classList.add(mini_browser_content_style_1.MiniBrowserContentStyle.PRE_LOAD);
218
- loadIndicator.style.display = 'none';
219
- const errorBar = this.createErrorBar();
220
- const frame = this.createIFrame();
221
- this.submitInputEmitter.event(input => this.go(input, {
222
- preserveFocus: false
223
- }));
224
- this.navigateBackEmitter.event(this.handleBack.bind(this));
225
- this.navigateForwardEmitter.event(this.handleForward.bind(this));
226
- this.refreshEmitter.event(this.handleRefresh.bind(this));
227
- this.openEmitter.event(this.handleOpen.bind(this));
228
- const transparentOverlay = document.createElement('div');
229
- transparentOverlay.classList.add(mini_browser_content_style_1.MiniBrowserContentStyle.TRANSPARENT_OVERLAY);
230
- transparentOverlay.style.display = 'none';
231
- const pdfContainer = document.createElement('div');
232
- pdfContainer.classList.add(mini_browser_content_style_1.MiniBrowserContentStyle.PDF_CONTAINER);
233
- pdfContainer.id = `${this.id}-pdf-container`;
234
- pdfContainer.style.display = 'none';
235
- contentArea.appendChild(errorBar);
236
- contentArea.appendChild(transparentOverlay);
237
- contentArea.appendChild(pdfContainer);
238
- contentArea.appendChild(loadIndicator);
239
- contentArea.appendChild(frame);
240
- parent.appendChild(contentArea);
241
- return Object.assign(contentArea, { frame, loadIndicator, errorBar, pdfContainer, transparentOverlay });
242
- }
243
- createIFrame() {
244
- const frame = document.createElement('iframe');
245
- const sandbox = (this.props.sandbox || MiniBrowserProps.SandboxOptions.DEFAULT).map(name => MiniBrowserProps.SandboxOptions[name]);
246
- frame.sandbox.add(...sandbox);
247
- this.toDispose.push((0, widget_1.addEventListener)(frame, 'load', this.onFrameLoad.bind(this)));
248
- this.toDispose.push((0, widget_1.addEventListener)(frame, 'error', this.onFrameError.bind(this)));
249
- return frame;
250
- }
251
- createErrorBar() {
252
- const errorBar = document.createElement('div');
253
- errorBar.classList.add(mini_browser_content_style_1.MiniBrowserContentStyle.ERROR_BAR);
254
- errorBar.style.display = 'none';
255
- const icon = document.createElement('span');
256
- icon.classList.add(...(0, widget_1.codiconArray)('info'));
257
- errorBar.appendChild(icon);
258
- const message = document.createElement('span');
259
- errorBar.appendChild(message);
260
- return Object.assign(errorBar, { message });
261
- }
262
- onFrameLoad() {
263
- clearTimeout(this.frameLoadTimeout);
264
- this.maybeResetBackground();
265
- this.hideLoadIndicator();
266
- this.hideErrorBar();
267
- }
268
- onFrameError() {
269
- clearTimeout(this.frameLoadTimeout);
270
- this.maybeResetBackground();
271
- this.hideLoadIndicator();
272
- this.showErrorBar('An error occurred while loading this page');
273
- }
274
- onFrameTimeout() {
275
- clearTimeout(this.frameLoadTimeout);
276
- this.maybeResetBackground();
277
- this.hideLoadIndicator();
278
- this.showErrorBar('Still loading...');
279
- }
280
- showLoadIndicator() {
281
- this.loadIndicator.classList.remove(mini_browser_content_style_1.MiniBrowserContentStyle.FADE_OUT);
282
- this.loadIndicator.style.display = 'block';
283
- }
284
- hideLoadIndicator() {
285
- // Start the fade-out transition.
286
- this.loadIndicator.classList.add(mini_browser_content_style_1.MiniBrowserContentStyle.FADE_OUT);
287
- // Actually hide the load indicator after the transition is finished.
288
- const preloadStyle = window.getComputedStyle(this.loadIndicator);
289
- const transitionDuration = (0, browser_1.parseCssTime)(preloadStyle.transitionDuration, 0);
290
- setTimeout(() => {
291
- // But don't hide it if it was shown again since the transition started.
292
- if (this.loadIndicator.classList.contains(mini_browser_content_style_1.MiniBrowserContentStyle.FADE_OUT)) {
293
- this.loadIndicator.style.display = 'none';
294
- this.loadIndicator.classList.remove(mini_browser_content_style_1.MiniBrowserContentStyle.FADE_OUT);
295
- }
296
- }, transitionDuration);
297
- }
298
- showErrorBar(message) {
299
- this.errorBar.message.textContent = message;
300
- this.errorBar.style.display = 'block';
301
- }
302
- hideErrorBar() {
303
- this.errorBar.message.textContent = '';
304
- this.errorBar.style.display = 'none';
305
- }
306
- maybeResetBackground() {
307
- if (this.props.resetBackground === true) {
308
- this.frame.style.backgroundColor = 'white';
309
- }
310
- }
311
- handleBack() {
312
- if (history.length - this.initialHistoryLength > 0) {
313
- history.back();
314
- }
315
- }
316
- handleForward() {
317
- if (history.length > this.initialHistoryLength) {
318
- history.forward();
319
- }
320
- }
321
- handleRefresh() {
322
- // Initial pessimism; use the location of the input.
323
- let location = this.props.startPage;
324
- // Use the the location from the `input`.
325
- if (this.input && this.input.value) {
326
- location = this.input.value;
327
- }
328
- try {
329
- const { contentDocument } = this.frame;
330
- if (contentDocument && contentDocument.location) {
331
- location = contentDocument.location.href;
332
- }
333
- }
334
- catch {
335
- // Security exception due to CORS when trying to access the `location.href` of the content document.
336
- }
337
- if (location) {
338
- this.go(location, {
339
- preserveFocus: false
340
- });
341
- }
342
- }
343
- handleOpen() {
344
- const location = this.frameSrc() || this.input.value;
345
- if (location) {
346
- this.windowService.openNewWindow(location);
347
- }
348
- }
349
- createInput(parent) {
350
- const input = document.createElement('input');
351
- input.type = 'text';
352
- input.spellcheck = false;
353
- input.classList.add('theia-input');
354
- this.toDispose.pushAll([
355
- (0, widget_1.addEventListener)(input, 'keydown', this.handleInputChange.bind(this)),
356
- (0, widget_1.addEventListener)(input, 'click', () => {
357
- if (this.getToolbarProps() === 'read-only') {
358
- this.handleOpen();
359
- }
360
- else {
361
- if (input.value) {
362
- input.select();
363
- }
364
- }
365
- })
366
- ]);
367
- parent.appendChild(input);
368
- return input;
369
- }
370
- handleInputChange(e) {
371
- const { key } = browser_1.KeyCode.createKeyCode(e);
372
- if (key && browser_1.Key.ENTER.keyCode === key.keyCode && this.getToolbarProps() === 'show') {
373
- const { target } = e;
374
- if (target instanceof HTMLInputElement) {
375
- this.mapLocation(target.value).then(location => this.submitInputEmitter.fire(location));
376
- }
377
- }
378
- }
379
- createPrevious(parent) {
380
- return this.onClick(this.createButton(parent, 'Show The Previous Page', mini_browser_content_style_1.MiniBrowserContentStyle.PREVIOUS), this.navigateBackEmitter);
381
- }
382
- createNext(parent) {
383
- return this.onClick(this.createButton(parent, 'Show The Next Page', mini_browser_content_style_1.MiniBrowserContentStyle.NEXT), this.navigateForwardEmitter);
384
- }
385
- createRefresh(parent) {
386
- return this.onClick(this.createButton(parent, 'Reload This Page', mini_browser_content_style_1.MiniBrowserContentStyle.REFRESH), this.refreshEmitter);
387
- }
388
- createOpen(parent) {
389
- const button = this.onClick(this.createButton(parent, 'Open In A New Window', mini_browser_content_style_1.MiniBrowserContentStyle.OPEN), this.openEmitter);
390
- return button;
391
- }
392
- createButton(parent, title, ...className) {
393
- const button = document.createElement('div');
394
- button.title = title;
395
- button.classList.add(...className, mini_browser_content_style_1.MiniBrowserContentStyle.BUTTON);
396
- parent.appendChild(button);
397
- return button;
398
- }
399
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
400
- onClick(element, emitter) {
401
- this.toDispose.push((0, widget_1.addEventListener)(element, 'click', () => {
402
- if (!element.classList.contains(mini_browser_content_style_1.MiniBrowserContentStyle.DISABLED)) {
403
- emitter.fire(undefined);
404
- }
405
- }));
406
- return element;
407
- }
408
- mapLocation(location) {
409
- return this.locationMapper.map(location);
410
- }
411
- setInput(value) {
412
- if (this.input.value !== value) {
413
- this.input.value = value;
414
- }
415
- }
416
- frameSrc() {
417
- let src = this.frame.src;
418
- try {
419
- const { contentWindow } = this.frame;
420
- if (contentWindow) {
421
- src = contentWindow.location.href;
422
- }
423
- }
424
- catch {
425
- // CORS issue. Ignored.
426
- }
427
- if (src === 'about:blank') {
428
- src = '';
429
- }
430
- return src;
431
- }
432
- contentDocument() {
433
- try {
434
- let { contentDocument } = this.frame;
435
- // eslint-disable-next-line no-null/no-null
436
- if (contentDocument === null) {
437
- const { contentWindow } = this.frame;
438
- if (contentWindow) {
439
- contentDocument = contentWindow.document;
440
- }
441
- }
442
- return contentDocument;
443
- }
444
- catch {
445
- // eslint-disable-next-line no-null/no-null
446
- return null;
447
- }
448
- }
449
- async go(location, options) {
450
- const { showLoadIndicator, preserveFocus } = {
451
- showLoadIndicator: true,
452
- preserveFocus: true,
453
- ...options
454
- };
455
- if (location) {
456
- try {
457
- this.toDisposeOnGo.dispose();
458
- const url = await this.mapLocation(location);
459
- this.setInput(url);
460
- if (this.getToolbarProps() === 'read-only') {
461
- this.input.title = `Open ${url} In A New Window`;
462
- }
463
- clearTimeout(this.frameLoadTimeout);
464
- this.frameLoadTimeout = window.setTimeout(this.onFrameTimeout.bind(this), 4000);
465
- if (showLoadIndicator) {
466
- this.showLoadIndicator();
467
- }
468
- if (url.endsWith('.pdf')) {
469
- this.pdfContainer.style.display = 'block';
470
- this.frame.style.display = 'none';
471
- PDFObject.embed(url, this.pdfContainer, {
472
- // eslint-disable-next-line max-len, @typescript-eslint/quotes
473
- fallbackLink: `<p style="padding: 0px 15px 0px 15px">Your browser does not support inline PDFs. Click on this <a href='[url]' target="_blank">link</a> to open the PDF in a new tab.</p>`
474
- });
475
- clearTimeout(this.frameLoadTimeout);
476
- this.hideLoadIndicator();
477
- if (!preserveFocus) {
478
- this.pdfContainer.focus();
479
- }
480
- }
481
- else {
482
- this.pdfContainer.style.display = 'none';
483
- this.frame.style.display = 'block';
484
- this.frame.src = url;
485
- // The load indicator will hide itself if the content of the iframe was loaded.
486
- if (!preserveFocus) {
487
- this.frame.addEventListener('load', () => {
488
- const window = this.frame.contentWindow;
489
- if (window) {
490
- window.focus();
491
- }
492
- }, { once: true });
493
- }
494
- }
495
- // Delegate all the `keypress` events from the `iframe` to the application.
496
- this.toDisposeOnGo.push((0, widget_1.addEventListener)(this.frame, 'load', () => {
497
- try {
498
- const { contentDocument } = this.frame;
499
- if (contentDocument) {
500
- const keypressHandler = (e) => this.keybindings.run(e);
501
- contentDocument.addEventListener('keypress', keypressHandler, true);
502
- this.toDisposeOnDetach.push(disposable_1.Disposable.create(() => contentDocument.removeEventListener('keypress', keypressHandler)));
503
- }
504
- }
505
- catch {
506
- // There is not much we could do with the security exceptions due to CORS.
507
- }
508
- }));
509
- }
510
- catch (e) {
511
- clearTimeout(this.frameLoadTimeout);
512
- this.hideLoadIndicator();
513
- this.showErrorBar(String(e));
514
- console.log(e);
515
- }
516
- }
517
- }
518
- };
519
- __decorate([
520
- (0, inversify_1.inject)(logger_1.ILogger),
521
- __metadata("design:type", Object)
522
- ], MiniBrowserContent.prototype, "logger", void 0);
523
- __decorate([
524
- (0, inversify_1.inject)(window_service_1.WindowService),
525
- __metadata("design:type", Object)
526
- ], MiniBrowserContent.prototype, "windowService", void 0);
527
- __decorate([
528
- (0, inversify_1.inject)(location_mapper_service_1.LocationMapperService),
529
- __metadata("design:type", location_mapper_service_1.LocationMapperService)
530
- ], MiniBrowserContent.prototype, "locationMapper", void 0);
531
- __decorate([
532
- (0, inversify_1.inject)(keybinding_1.KeybindingRegistry),
533
- __metadata("design:type", keybinding_1.KeybindingRegistry)
534
- ], MiniBrowserContent.prototype, "keybindings", void 0);
535
- __decorate([
536
- (0, inversify_1.inject)(application_shell_mouse_tracker_1.ApplicationShellMouseTracker),
537
- __metadata("design:type", application_shell_mouse_tracker_1.ApplicationShellMouseTracker)
538
- ], MiniBrowserContent.prototype, "mouseTracker", void 0);
539
- __decorate([
540
- (0, inversify_1.inject)(file_service_1.FileService),
541
- __metadata("design:type", file_service_1.FileService)
542
- ], MiniBrowserContent.prototype, "fileService", void 0);
543
- __decorate([
544
- (0, inversify_1.postConstruct)(),
545
- __metadata("design:type", Function),
546
- __metadata("design:paramtypes", []),
547
- __metadata("design:returntype", void 0)
548
- ], MiniBrowserContent.prototype, "init", null);
549
- MiniBrowserContent = __decorate([
550
- (0, inversify_1.injectable)(),
551
- __param(0, (0, inversify_1.inject)(MiniBrowserProps)),
552
- __metadata("design:paramtypes", [MiniBrowserProps])
553
- ], MiniBrowserContent);
554
- exports.MiniBrowserContent = MiniBrowserContent;
1
+ "use strict";
2
+ // *****************************************************************************
3
+ // Copyright (C) 2018 TypeFox and others.
4
+ //
5
+ // This program and the accompanying materials are made available under the
6
+ // terms of the Eclipse Public License v. 2.0 which is available at
7
+ // http://www.eclipse.org/legal/epl-2.0.
8
+ //
9
+ // This Source Code may also be made available under the following Secondary
10
+ // Licenses when the conditions for such availability set forth in the Eclipse
11
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
+ // with the GNU Classpath Exception which is available at
13
+ // https://www.gnu.org/software/classpath/license.html.
14
+ //
15
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
+ // *****************************************************************************
17
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
18
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
19
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
20
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
21
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
22
+ };
23
+ var __metadata = (this && this.__metadata) || function (k, v) {
24
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
25
+ };
26
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
27
+ return function (target, key) { decorator(target, key, paramIndex); }
28
+ };
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.MiniBrowserContent = exports.MiniBrowserContentFactory = exports.MiniBrowserProps = void 0;
31
+ const PDFObject = require("pdfobject");
32
+ const inversify_1 = require("@theia/core/shared/inversify");
33
+ const uri_1 = require("@theia/core/lib/common/uri");
34
+ const logger_1 = require("@theia/core/lib/common/logger");
35
+ const event_1 = require("@theia/core/lib/common/event");
36
+ const keybinding_1 = require("@theia/core/lib/browser/keybinding");
37
+ const window_service_1 = require("@theia/core/lib/browser/window/window-service");
38
+ const browser_1 = require("@theia/core/lib/browser");
39
+ const disposable_1 = require("@theia/core/lib/common/disposable");
40
+ const widget_1 = require("@theia/core/lib/browser/widgets/widget");
41
+ const location_mapper_service_1 = require("./location-mapper-service");
42
+ const application_shell_mouse_tracker_1 = require("@theia/core/lib/browser/shell/application-shell-mouse-tracker");
43
+ const debounce = require("@theia/core/shared/lodash.debounce");
44
+ const mini_browser_content_style_1 = require("./mini-browser-content-style");
45
+ const file_service_1 = require("@theia/filesystem/lib/browser/file-service");
46
+ /**
47
+ * Initializer properties for the embedded browser widget.
48
+ */
49
+ let MiniBrowserProps = class MiniBrowserProps {
50
+ };
51
+ MiniBrowserProps = __decorate([
52
+ (0, inversify_1.injectable)()
53
+ ], MiniBrowserProps);
54
+ exports.MiniBrowserProps = MiniBrowserProps;
55
+ (function (MiniBrowserProps) {
56
+ /**
57
+ * Enumeration of the supported `sandbox` options for the `iframe`.
58
+ */
59
+ let SandboxOptions;
60
+ (function (SandboxOptions) {
61
+ /**
62
+ * Allows form submissions.
63
+ */
64
+ SandboxOptions[SandboxOptions["allow-forms"] = 0] = "allow-forms";
65
+ /**
66
+ * Allows popups, such as `window.open()`, `showModalDialog()`, `target=”_blank”`, etc.
67
+ */
68
+ SandboxOptions[SandboxOptions["allow-popups"] = 1] = "allow-popups";
69
+ /**
70
+ * Allows pointer lock.
71
+ */
72
+ SandboxOptions[SandboxOptions["allow-pointer-lock"] = 2] = "allow-pointer-lock";
73
+ /**
74
+ * Allows the document to maintain its origin. Pages loaded from https://example.com/ will retain access to that origin’s data.
75
+ */
76
+ SandboxOptions[SandboxOptions["allow-same-origin"] = 3] = "allow-same-origin";
77
+ /**
78
+ * Allows JavaScript execution. Also allows features to trigger automatically (as they’d be trivial to implement via JavaScript).
79
+ */
80
+ SandboxOptions[SandboxOptions["allow-scripts"] = 4] = "allow-scripts";
81
+ /**
82
+ * Allows the document to break out of the frame by navigating the top-level `window`.
83
+ */
84
+ SandboxOptions[SandboxOptions["allow-top-navigation"] = 5] = "allow-top-navigation";
85
+ /**
86
+ * Allows the embedded browsing context to open modal windows.
87
+ */
88
+ SandboxOptions[SandboxOptions["allow-modals"] = 6] = "allow-modals";
89
+ /**
90
+ * Allows the embedded browsing context to disable the ability to lock the screen orientation.
91
+ */
92
+ SandboxOptions[SandboxOptions["allow-orientation-lock"] = 7] = "allow-orientation-lock";
93
+ /**
94
+ * Allows a sandboxed document to open new windows without forcing the sandboxing flags upon them.
95
+ * This will allow, for example, a third-party advertisement to be safely sandboxed without forcing the same restrictions upon a landing page.
96
+ */
97
+ SandboxOptions[SandboxOptions["allow-popups-to-escape-sandbox"] = 8] = "allow-popups-to-escape-sandbox";
98
+ /**
99
+ * Allows embedders to have control over whether an iframe can start a presentation session.
100
+ */
101
+ SandboxOptions[SandboxOptions["allow-presentation"] = 9] = "allow-presentation";
102
+ /**
103
+ * Allows the embedded browsing context to navigate (load) content to the top-level browsing context only when initiated by a user gesture.
104
+ * If this keyword is not used, this operation is not allowed.
105
+ */
106
+ SandboxOptions[SandboxOptions["allow-top-navigation-by-user-activation"] = 10] = "allow-top-navigation-by-user-activation";
107
+ })(SandboxOptions = MiniBrowserProps.SandboxOptions || (MiniBrowserProps.SandboxOptions = {}));
108
+ (function (SandboxOptions) {
109
+ /**
110
+ * The default `sandbox` options, if other is not provided.
111
+ *
112
+ * See: https://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/
113
+ */
114
+ SandboxOptions.DEFAULT = [
115
+ SandboxOptions['allow-same-origin'],
116
+ SandboxOptions['allow-scripts'],
117
+ SandboxOptions['allow-popups'],
118
+ SandboxOptions['allow-forms'],
119
+ SandboxOptions['allow-modals']
120
+ ];
121
+ })(SandboxOptions = MiniBrowserProps.SandboxOptions || (MiniBrowserProps.SandboxOptions = {}));
122
+ })(MiniBrowserProps = exports.MiniBrowserProps || (exports.MiniBrowserProps = {}));
123
+ exports.MiniBrowserProps = MiniBrowserProps;
124
+ exports.MiniBrowserContentFactory = Symbol('MiniBrowserContentFactory');
125
+ let MiniBrowserContent = class MiniBrowserContent extends widget_1.BaseWidget {
126
+ constructor(props) {
127
+ super();
128
+ this.props = props;
129
+ this.submitInputEmitter = new event_1.Emitter();
130
+ this.navigateBackEmitter = new event_1.Emitter();
131
+ this.navigateForwardEmitter = new event_1.Emitter();
132
+ this.refreshEmitter = new event_1.Emitter();
133
+ this.openEmitter = new event_1.Emitter();
134
+ this.toDisposeOnGo = new disposable_1.DisposableCollection();
135
+ this.node.tabIndex = 0;
136
+ this.addClass(mini_browser_content_style_1.MiniBrowserContentStyle.MINI_BROWSER);
137
+ this.input = this.createToolbar(this.node).input;
138
+ const contentArea = this.createContentArea(this.node);
139
+ this.frame = contentArea.frame;
140
+ this.transparentOverlay = contentArea.transparentOverlay;
141
+ this.loadIndicator = contentArea.loadIndicator;
142
+ this.errorBar = contentArea.errorBar;
143
+ this.pdfContainer = contentArea.pdfContainer;
144
+ this.initialHistoryLength = history.length;
145
+ this.toDispose.pushAll([
146
+ this.submitInputEmitter,
147
+ this.navigateBackEmitter,
148
+ this.navigateForwardEmitter,
149
+ this.refreshEmitter,
150
+ this.openEmitter
151
+ ]);
152
+ }
153
+ init() {
154
+ this.toDispose.push(this.mouseTracker.onMousedown(e => {
155
+ if (this.frame.style.display !== 'none') {
156
+ this.transparentOverlay.style.display = 'block';
157
+ }
158
+ }));
159
+ this.toDispose.push(this.mouseTracker.onMouseup(e => {
160
+ if (this.frame.style.display !== 'none') {
161
+ this.transparentOverlay.style.display = 'none';
162
+ }
163
+ }));
164
+ const { startPage } = this.props;
165
+ if (startPage) {
166
+ setTimeout(() => this.go(startPage), 500);
167
+ this.listenOnContentChange(startPage);
168
+ }
169
+ }
170
+ onActivateRequest(msg) {
171
+ super.onActivateRequest(msg);
172
+ if (this.getToolbarProps() !== 'hide') {
173
+ this.input.focus();
174
+ }
175
+ else {
176
+ this.node.focus();
177
+ }
178
+ }
179
+ async listenOnContentChange(location) {
180
+ if (await this.fileService.exists(new uri_1.default(location))) {
181
+ const fileUri = new uri_1.default(location);
182
+ const watcher = this.fileService.watch(fileUri);
183
+ this.toDispose.push(watcher);
184
+ const onFileChange = (event) => {
185
+ if (event.contains(fileUri, 1 /* ADDED */) || event.contains(fileUri, 0 /* UPDATED */)) {
186
+ this.go(location, {
187
+ showLoadIndicator: false
188
+ });
189
+ }
190
+ };
191
+ this.toDispose.push(this.fileService.onDidFilesChange(debounce(onFileChange, 500)));
192
+ }
193
+ }
194
+ createToolbar(parent) {
195
+ const toolbar = document.createElement('div');
196
+ toolbar.classList.add(this.getToolbarProps() === 'read-only' ? mini_browser_content_style_1.MiniBrowserContentStyle.TOOLBAR_READ_ONLY : mini_browser_content_style_1.MiniBrowserContentStyle.TOOLBAR);
197
+ parent.appendChild(toolbar);
198
+ this.createPrevious(toolbar);
199
+ this.createNext(toolbar);
200
+ this.createRefresh(toolbar);
201
+ const input = this.createInput(toolbar);
202
+ input.readOnly = this.getToolbarProps() === 'read-only';
203
+ this.createOpen(toolbar);
204
+ if (this.getToolbarProps() === 'hide') {
205
+ toolbar.style.display = 'none';
206
+ }
207
+ return Object.assign(toolbar, { input });
208
+ }
209
+ getToolbarProps() {
210
+ return !this.props.startPage ? 'show' : this.props.toolbar || 'show';
211
+ }
212
+ // eslint-disable-next-line max-len
213
+ createContentArea(parent) {
214
+ const contentArea = document.createElement('div');
215
+ contentArea.classList.add(mini_browser_content_style_1.MiniBrowserContentStyle.CONTENT_AREA);
216
+ const loadIndicator = document.createElement('div');
217
+ loadIndicator.classList.add(mini_browser_content_style_1.MiniBrowserContentStyle.PRE_LOAD);
218
+ loadIndicator.style.display = 'none';
219
+ const errorBar = this.createErrorBar();
220
+ const frame = this.createIFrame();
221
+ this.submitInputEmitter.event(input => this.go(input, {
222
+ preserveFocus: false
223
+ }));
224
+ this.navigateBackEmitter.event(this.handleBack.bind(this));
225
+ this.navigateForwardEmitter.event(this.handleForward.bind(this));
226
+ this.refreshEmitter.event(this.handleRefresh.bind(this));
227
+ this.openEmitter.event(this.handleOpen.bind(this));
228
+ const transparentOverlay = document.createElement('div');
229
+ transparentOverlay.classList.add(mini_browser_content_style_1.MiniBrowserContentStyle.TRANSPARENT_OVERLAY);
230
+ transparentOverlay.style.display = 'none';
231
+ const pdfContainer = document.createElement('div');
232
+ pdfContainer.classList.add(mini_browser_content_style_1.MiniBrowserContentStyle.PDF_CONTAINER);
233
+ pdfContainer.id = `${this.id}-pdf-container`;
234
+ pdfContainer.style.display = 'none';
235
+ contentArea.appendChild(errorBar);
236
+ contentArea.appendChild(transparentOverlay);
237
+ contentArea.appendChild(pdfContainer);
238
+ contentArea.appendChild(loadIndicator);
239
+ contentArea.appendChild(frame);
240
+ parent.appendChild(contentArea);
241
+ return Object.assign(contentArea, { frame, loadIndicator, errorBar, pdfContainer, transparentOverlay });
242
+ }
243
+ createIFrame() {
244
+ const frame = document.createElement('iframe');
245
+ const sandbox = (this.props.sandbox || MiniBrowserProps.SandboxOptions.DEFAULT).map(name => MiniBrowserProps.SandboxOptions[name]);
246
+ frame.sandbox.add(...sandbox);
247
+ this.toDispose.push((0, widget_1.addEventListener)(frame, 'load', this.onFrameLoad.bind(this)));
248
+ this.toDispose.push((0, widget_1.addEventListener)(frame, 'error', this.onFrameError.bind(this)));
249
+ return frame;
250
+ }
251
+ createErrorBar() {
252
+ const errorBar = document.createElement('div');
253
+ errorBar.classList.add(mini_browser_content_style_1.MiniBrowserContentStyle.ERROR_BAR);
254
+ errorBar.style.display = 'none';
255
+ const icon = document.createElement('span');
256
+ icon.classList.add(...(0, widget_1.codiconArray)('info'));
257
+ errorBar.appendChild(icon);
258
+ const message = document.createElement('span');
259
+ errorBar.appendChild(message);
260
+ return Object.assign(errorBar, { message });
261
+ }
262
+ onFrameLoad() {
263
+ clearTimeout(this.frameLoadTimeout);
264
+ this.maybeResetBackground();
265
+ this.hideLoadIndicator();
266
+ this.hideErrorBar();
267
+ }
268
+ onFrameError() {
269
+ clearTimeout(this.frameLoadTimeout);
270
+ this.maybeResetBackground();
271
+ this.hideLoadIndicator();
272
+ this.showErrorBar('An error occurred while loading this page');
273
+ }
274
+ onFrameTimeout() {
275
+ clearTimeout(this.frameLoadTimeout);
276
+ this.maybeResetBackground();
277
+ this.hideLoadIndicator();
278
+ this.showErrorBar('Still loading...');
279
+ }
280
+ showLoadIndicator() {
281
+ this.loadIndicator.classList.remove(mini_browser_content_style_1.MiniBrowserContentStyle.FADE_OUT);
282
+ this.loadIndicator.style.display = 'block';
283
+ }
284
+ hideLoadIndicator() {
285
+ // Start the fade-out transition.
286
+ this.loadIndicator.classList.add(mini_browser_content_style_1.MiniBrowserContentStyle.FADE_OUT);
287
+ // Actually hide the load indicator after the transition is finished.
288
+ const preloadStyle = window.getComputedStyle(this.loadIndicator);
289
+ const transitionDuration = (0, browser_1.parseCssTime)(preloadStyle.transitionDuration, 0);
290
+ setTimeout(() => {
291
+ // But don't hide it if it was shown again since the transition started.
292
+ if (this.loadIndicator.classList.contains(mini_browser_content_style_1.MiniBrowserContentStyle.FADE_OUT)) {
293
+ this.loadIndicator.style.display = 'none';
294
+ this.loadIndicator.classList.remove(mini_browser_content_style_1.MiniBrowserContentStyle.FADE_OUT);
295
+ }
296
+ }, transitionDuration);
297
+ }
298
+ showErrorBar(message) {
299
+ this.errorBar.message.textContent = message;
300
+ this.errorBar.style.display = 'block';
301
+ }
302
+ hideErrorBar() {
303
+ this.errorBar.message.textContent = '';
304
+ this.errorBar.style.display = 'none';
305
+ }
306
+ maybeResetBackground() {
307
+ if (this.props.resetBackground === true) {
308
+ this.frame.style.backgroundColor = 'white';
309
+ }
310
+ }
311
+ handleBack() {
312
+ if (history.length - this.initialHistoryLength > 0) {
313
+ history.back();
314
+ }
315
+ }
316
+ handleForward() {
317
+ if (history.length > this.initialHistoryLength) {
318
+ history.forward();
319
+ }
320
+ }
321
+ handleRefresh() {
322
+ // Initial pessimism; use the location of the input.
323
+ let location = this.props.startPage;
324
+ // Use the the location from the `input`.
325
+ if (this.input && this.input.value) {
326
+ location = this.input.value;
327
+ }
328
+ try {
329
+ const { contentDocument } = this.frame;
330
+ if (contentDocument && contentDocument.location) {
331
+ location = contentDocument.location.href;
332
+ }
333
+ }
334
+ catch {
335
+ // Security exception due to CORS when trying to access the `location.href` of the content document.
336
+ }
337
+ if (location) {
338
+ this.go(location, {
339
+ preserveFocus: false
340
+ });
341
+ }
342
+ }
343
+ handleOpen() {
344
+ const location = this.frameSrc() || this.input.value;
345
+ if (location) {
346
+ this.windowService.openNewWindow(location);
347
+ }
348
+ }
349
+ createInput(parent) {
350
+ const input = document.createElement('input');
351
+ input.type = 'text';
352
+ input.spellcheck = false;
353
+ input.classList.add('theia-input');
354
+ this.toDispose.pushAll([
355
+ (0, widget_1.addEventListener)(input, 'keydown', this.handleInputChange.bind(this)),
356
+ (0, widget_1.addEventListener)(input, 'click', () => {
357
+ if (this.getToolbarProps() === 'read-only') {
358
+ this.handleOpen();
359
+ }
360
+ else {
361
+ if (input.value) {
362
+ input.select();
363
+ }
364
+ }
365
+ })
366
+ ]);
367
+ parent.appendChild(input);
368
+ return input;
369
+ }
370
+ handleInputChange(e) {
371
+ const { key } = browser_1.KeyCode.createKeyCode(e);
372
+ if (key && browser_1.Key.ENTER.keyCode === key.keyCode && this.getToolbarProps() === 'show') {
373
+ const { target } = e;
374
+ if (target instanceof HTMLInputElement) {
375
+ this.mapLocation(target.value).then(location => this.submitInputEmitter.fire(location));
376
+ }
377
+ }
378
+ }
379
+ createPrevious(parent) {
380
+ return this.onClick(this.createButton(parent, 'Show The Previous Page', mini_browser_content_style_1.MiniBrowserContentStyle.PREVIOUS), this.navigateBackEmitter);
381
+ }
382
+ createNext(parent) {
383
+ return this.onClick(this.createButton(parent, 'Show The Next Page', mini_browser_content_style_1.MiniBrowserContentStyle.NEXT), this.navigateForwardEmitter);
384
+ }
385
+ createRefresh(parent) {
386
+ return this.onClick(this.createButton(parent, 'Reload This Page', mini_browser_content_style_1.MiniBrowserContentStyle.REFRESH), this.refreshEmitter);
387
+ }
388
+ createOpen(parent) {
389
+ const button = this.onClick(this.createButton(parent, 'Open In A New Window', mini_browser_content_style_1.MiniBrowserContentStyle.OPEN), this.openEmitter);
390
+ return button;
391
+ }
392
+ createButton(parent, title, ...className) {
393
+ const button = document.createElement('div');
394
+ button.title = title;
395
+ button.classList.add(...className, mini_browser_content_style_1.MiniBrowserContentStyle.BUTTON);
396
+ parent.appendChild(button);
397
+ return button;
398
+ }
399
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
400
+ onClick(element, emitter) {
401
+ this.toDispose.push((0, widget_1.addEventListener)(element, 'click', () => {
402
+ if (!element.classList.contains(mini_browser_content_style_1.MiniBrowserContentStyle.DISABLED)) {
403
+ emitter.fire(undefined);
404
+ }
405
+ }));
406
+ return element;
407
+ }
408
+ mapLocation(location) {
409
+ return this.locationMapper.map(location);
410
+ }
411
+ setInput(value) {
412
+ if (this.input.value !== value) {
413
+ this.input.value = value;
414
+ }
415
+ }
416
+ frameSrc() {
417
+ let src = this.frame.src;
418
+ try {
419
+ const { contentWindow } = this.frame;
420
+ if (contentWindow) {
421
+ src = contentWindow.location.href;
422
+ }
423
+ }
424
+ catch {
425
+ // CORS issue. Ignored.
426
+ }
427
+ if (src === 'about:blank') {
428
+ src = '';
429
+ }
430
+ return src;
431
+ }
432
+ contentDocument() {
433
+ try {
434
+ let { contentDocument } = this.frame;
435
+ // eslint-disable-next-line no-null/no-null
436
+ if (contentDocument === null) {
437
+ const { contentWindow } = this.frame;
438
+ if (contentWindow) {
439
+ contentDocument = contentWindow.document;
440
+ }
441
+ }
442
+ return contentDocument;
443
+ }
444
+ catch {
445
+ // eslint-disable-next-line no-null/no-null
446
+ return null;
447
+ }
448
+ }
449
+ async go(location, options) {
450
+ const { showLoadIndicator, preserveFocus } = {
451
+ showLoadIndicator: true,
452
+ preserveFocus: true,
453
+ ...options
454
+ };
455
+ if (location) {
456
+ try {
457
+ this.toDisposeOnGo.dispose();
458
+ const url = await this.mapLocation(location);
459
+ this.setInput(url);
460
+ if (this.getToolbarProps() === 'read-only') {
461
+ this.input.title = `Open ${url} In A New Window`;
462
+ }
463
+ clearTimeout(this.frameLoadTimeout);
464
+ this.frameLoadTimeout = window.setTimeout(this.onFrameTimeout.bind(this), 4000);
465
+ if (showLoadIndicator) {
466
+ this.showLoadIndicator();
467
+ }
468
+ if (url.endsWith('.pdf')) {
469
+ this.pdfContainer.style.display = 'block';
470
+ this.frame.style.display = 'none';
471
+ PDFObject.embed(url, this.pdfContainer, {
472
+ // eslint-disable-next-line max-len, @typescript-eslint/quotes
473
+ fallbackLink: `<p style="padding: 0px 15px 0px 15px">Your browser does not support inline PDFs. Click on this <a href='[url]' target="_blank">link</a> to open the PDF in a new tab.</p>`
474
+ });
475
+ clearTimeout(this.frameLoadTimeout);
476
+ this.hideLoadIndicator();
477
+ if (!preserveFocus) {
478
+ this.pdfContainer.focus();
479
+ }
480
+ }
481
+ else {
482
+ this.pdfContainer.style.display = 'none';
483
+ this.frame.style.display = 'block';
484
+ this.frame.src = url;
485
+ // The load indicator will hide itself if the content of the iframe was loaded.
486
+ if (!preserveFocus) {
487
+ this.frame.addEventListener('load', () => {
488
+ const window = this.frame.contentWindow;
489
+ if (window) {
490
+ window.focus();
491
+ }
492
+ }, { once: true });
493
+ }
494
+ }
495
+ // Delegate all the `keypress` events from the `iframe` to the application.
496
+ this.toDisposeOnGo.push((0, widget_1.addEventListener)(this.frame, 'load', () => {
497
+ try {
498
+ const { contentDocument } = this.frame;
499
+ if (contentDocument) {
500
+ const keypressHandler = (e) => this.keybindings.run(e);
501
+ contentDocument.addEventListener('keypress', keypressHandler, true);
502
+ this.toDisposeOnDetach.push(disposable_1.Disposable.create(() => contentDocument.removeEventListener('keypress', keypressHandler)));
503
+ }
504
+ }
505
+ catch {
506
+ // There is not much we could do with the security exceptions due to CORS.
507
+ }
508
+ }));
509
+ }
510
+ catch (e) {
511
+ clearTimeout(this.frameLoadTimeout);
512
+ this.hideLoadIndicator();
513
+ this.showErrorBar(String(e));
514
+ console.log(e);
515
+ }
516
+ }
517
+ }
518
+ };
519
+ __decorate([
520
+ (0, inversify_1.inject)(logger_1.ILogger),
521
+ __metadata("design:type", Object)
522
+ ], MiniBrowserContent.prototype, "logger", void 0);
523
+ __decorate([
524
+ (0, inversify_1.inject)(window_service_1.WindowService),
525
+ __metadata("design:type", Object)
526
+ ], MiniBrowserContent.prototype, "windowService", void 0);
527
+ __decorate([
528
+ (0, inversify_1.inject)(location_mapper_service_1.LocationMapperService),
529
+ __metadata("design:type", location_mapper_service_1.LocationMapperService)
530
+ ], MiniBrowserContent.prototype, "locationMapper", void 0);
531
+ __decorate([
532
+ (0, inversify_1.inject)(keybinding_1.KeybindingRegistry),
533
+ __metadata("design:type", keybinding_1.KeybindingRegistry)
534
+ ], MiniBrowserContent.prototype, "keybindings", void 0);
535
+ __decorate([
536
+ (0, inversify_1.inject)(application_shell_mouse_tracker_1.ApplicationShellMouseTracker),
537
+ __metadata("design:type", application_shell_mouse_tracker_1.ApplicationShellMouseTracker)
538
+ ], MiniBrowserContent.prototype, "mouseTracker", void 0);
539
+ __decorate([
540
+ (0, inversify_1.inject)(file_service_1.FileService),
541
+ __metadata("design:type", file_service_1.FileService)
542
+ ], MiniBrowserContent.prototype, "fileService", void 0);
543
+ __decorate([
544
+ (0, inversify_1.postConstruct)(),
545
+ __metadata("design:type", Function),
546
+ __metadata("design:paramtypes", []),
547
+ __metadata("design:returntype", void 0)
548
+ ], MiniBrowserContent.prototype, "init", null);
549
+ MiniBrowserContent = __decorate([
550
+ (0, inversify_1.injectable)(),
551
+ __param(0, (0, inversify_1.inject)(MiniBrowserProps)),
552
+ __metadata("design:paramtypes", [MiniBrowserProps])
553
+ ], MiniBrowserContent);
554
+ exports.MiniBrowserContent = MiniBrowserContent;
555
555
  //# sourceMappingURL=mini-browser-content.js.map