// 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