1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
ash / webui / file_manager / untrusted_resources / files_media_content.js [blame]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
window.onload = () => {
let messageSource;
let filesAppOrigin;
const content = document.querySelector('#content');
let contentUrl;
/**
* Identifies every message to load an content. Used to check if the current
* load is still valid after an async operation.
*
* @type {number}
*/
let loadId = 0;
window.addEventListener('message', event => {
if (event.origin !== FILES_APP_SWA_ORIGIN) {
console.error('Unknown origin: ' + event.origin);
return;
}
const currentLoadId = ++loadId;
function isValidLoad() {
return currentLoadId === loadId;
}
// Release Object URLs generated with URL.createObjectURL.
URL.revokeObjectURL(contentUrl);
contentUrl = '';
filesAppOrigin = event.origin;
messageSource = event.source;
/** @type {!UntrustedPreviewData} */
const data = event.data;
const sourceContent = data.sourceContent;
switch (sourceContent.dataType) {
case 'url':
contentUrl = /** @type {string} */ (sourceContent.data);
break;
case 'blob':
contentUrl =
URL.createObjectURL(/** @type {!Blob} */ (sourceContent.data));
break;
default:
contentUrl = '';
}
switch (data.type) {
case 'html':
content.textContent = '';
contentChanged(null);
fetch(contentUrl)
.then((response) => {
if (!isValidLoad()) {
return;
}
return response.text();
})
.then((text) => {
if (!isValidLoad()) {
return;
}
content.textContent = text;
contentChanged(text);
});
break;
case 'audio':
case 'video':
content.onloadeddata = (e) => {
if (!isValidLoad()) {
return;
}
contentChanged(e.target.src);
};
content.src = contentUrl;
break;
case 'image':
content.remove();
content.src = '';
const image = new Image();
image.onload = (e) => {
document.body.appendChild(content);
if (!isValidLoad()) {
return;
}
contentChanged(e.target.src);
content.src = e.target.src;
};
image.onerror = (e) => {
contentDecodeFailed();
};
image.src = contentUrl;
break;
default:
content.onload = (e) => isValidLoad() && contentChanged(e.target.src);
content.src = contentUrl;
break;
}
});
document.addEventListener('contextmenu', e => {
e.preventDefault();
return false;
});
document.addEventListener('click', e => {
sendMessage((e.target === content) ? 'tap-inside' : 'tap-outside');
});
function contentChanged(src) {
sendMessage(src ? 'webview-loaded' : 'webview-cleared');
}
function contentDecodeFailed() {
sendMessage('content-decode-failed');
}
function sendMessage(message) {
if (messageSource) {
messageSource.postMessage(message, filesAppOrigin);
}
}
// TODO(oka): This is a workaround to fix FOUC problem, where sometimes
// immature view with smaller window size than outer window is rendered for a
// moment. Remove this after the root cause is fixed. http://crbug.com/640525
window.addEventListener('resize', () => {
// Remove hidden attribute on event of resize to avoid FOUC. The window's
// initial size is 100 x 100 and it's fit into the outer window size after a
// moment. Due to Files App's window size constraint, resized window must be
// larger than 100 x 100. So this event is always invoked.
content.removeAttribute('hidden');
});
// Fallback for the case of webview bug is fixed and above code is not
// executed.
setTimeout(() => {
content.removeAttribute('hidden');
}, 500);
};
// clang-format off
//# sourceURL=//ash/webui/file_manager/untrusted_resources/files_media_content.js