blob: f43e56dd8fc220733a1f3f6c2c1c5dfd4e90c68a [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const FilesQuickView = Polymer({
is: 'files-quick-view',
properties: {
// File media type, e.g. image, video.
type: String,
subtype: String,
filePath: String,
// True if there is a file task that can open the file type.
hasTask: Boolean,
// URLs should be accessible from the <webview> since their content is
// rendered inside the <wevbiew>. Hint: use URL.createObjectURL.
contentUrl: String,
videoPoster: String,
audioArtwork: String,
// Autoplay property for audio, video.
autoplay: Boolean,
// True if this file is not image, audio, video nor HTML but is supported
// by Chrome - content that is directly preview-able in Chrome by setting
// the <webview> src attribute. Examples: pdf, text.
browsable: Boolean,
// The metadata-box-active-changed event is fired on attribute change.
metadataBoxActive: {
value: true,
type: Boolean,
notify: true,
},
// Text shown when there is no playback/preview available.
noPlaybackText: String,
noPreviewText: String,
/**
* True if the Files app window is a dialog, e.g. save-as or open-with.
* @type {boolean}
*/
isModal: Boolean,
},
listeners: {
'files-safe-media-tap-outside': 'close',
},
/**
* Apply custom CSS to autogenerated webview content.
*
* @param {!Event} e
*/
applyTextCss: function(e) {
// Don't override the Chrome PDF viewer's CSS: crbug.com/1001034.
if (this.subtype === 'PDF') {
return;
}
const webview = /** @type {WebView} */ (e.target);
webview.insertCSS({
'file': 'foreground/elements/files_safe_text_webview_content.css',
});
},
// Clears fields.
clear: function() {
this.setProperties({
type: '',
subtype: '',
filePath: '',
hasTask: false,
contentUrl: '',
videoPoster: '',
audioArtwork: '',
autoplay: false,
browsable: false,
});
const video = this.$.contentPanel.querySelector('#videoSafeMedia');
if (video) {
video.src = '';
video.fire('src-changed');
}
},
/** @return {boolean} */
isOpened: function() {
return this.$.dialog.open;
},
// Opens the dialog.
open: function() {
if (!this.isOpened()) {
this.$.dialog.showModal();
// Make dialog focusable and set focus to a dialog. This is how we can
// prevent default behaviour of a dialog which by default sets focus to
// the first input inside itself. When a dialog gains focus we remove
// focusability to prevent selecting dialog when moving with a keyboard.
this.$.dialog.setAttribute('tabindex', '0');
this.$.dialog.focus();
this.$.dialog.setAttribute('tabindex', '-1');
}
},
// Closes the dialog.
close: function() {
if (this.isOpened()) {
this.$.dialog.close();
}
},
/**
* @return {!FilesMetadataBox}
*/
getFilesMetadataBox: function() {
return this.$['metadata-box'];
},
/**
* Client should assign the function to open the file.
*
* @param {!Event} event
*/
onOpenInNewButtonTap: function(event) {},
/**
* @param {boolean} hasTask
* @param {boolean} isModal
* @return {boolean}
*
* @private
*/
shouldShowOpenButton_: function(hasTask, isModal) {
return hasTask && !isModal;
},
/**
* @param {!Event} event tap event.
*
* @private
*/
onMetadataButtonTap_: function(event) {
// Set focus back to innerContent panel so that pressing space key next
// closes Quick View.
this.$.innerContentPanel.focus();
},
/**
* Close Quick View unless the clicked target or its ancestor contains
* 'no-close-on-click' class.
*
* @param {!Event} event tap event.
*
* @private
*/
onContentPanelTap_: function(event) {
let target = event.detail.sourceEvent.target;
while (target) {
if (target.classList.contains('no-close-on-click')) {
return;
}
target = target.parentElement;
}
this.close();
},
/**
* @param {string} type
* @param {string} subtype
* @return {boolean}
*
* @private
*/
isHtml_: function(type, subtype) {
return type === 'document' && subtype === 'HTML';
},
/**
* @param {string} type
* @return {boolean}
*
* @private
*/
isImage_: function(type) {
return type === 'image';
},
/**
* @param {string} type
* @return {boolean}
*
* @private
*/
isVideo_: function(type) {
return type === 'video';
},
/**
* @param {string} type
* @return {boolean}
*
* @private
*/
isAudio_: function(type) {
return type === 'audio';
},
/**
* @param {string} contentUrl
* @param {string} type
* @return {string}
*
* @private
*/
audioUrl_: function(contentUrl, type) {
return this.isAudio_(type) ? contentUrl : '';
},
/**
* @param {string} type
* @return {boolean}
*
* @private
*/
isUnsupported_: function(type, subtype, browsable) {
return !this.isImage_(type) && !this.isVideo_(type) &&
!this.isAudio_(type) && !this.isHtml_(type, subtype) && !browsable;
},
/** @private */
onDialogClose_: function(e) {
assert(e.target === this.$.dialog);
this.clear();
// Catch and re-fire the 'close' event such that it bubbles across Shadow
// DOM v1.
this.fire('close');
}
});