[REF] web,*: hide buttons that doesn't work in webviews

Some features of the PDF.js library doesn't work in the
webview of the mobile apps.

Initially 'window.print' is defined as an empty function in
webviews unlike browsers where it is already ready.
After that, PDF.js needs to monkey patch 'window.print' and
saves a reference to the original definition, which is not
yet fulfilled in by the mobile app (Java part).
So the print of PDF.js doesn't work in webviews and end
users will need to download the file before printing it.

Regarding the Download button, the 'download' attribute is
not supported by the webview as you can see in:
https://bugs.chromium.org/p/chromium/issues/detail?id=432414
As there's many ways to download a file in Odoo it's not
a big deal to simply hide it in PDF.js.

Because it's quite complicated to fix this, we decided
to hide the features that don't work (Download / Print)
or don't make sense (Open file).

Task-id: 2200168
This commit is contained in:
Romeo Fragomeli
2021-05-07 11:01:27 +00:00
parent c1c225eff2
commit 8a755d5833
7 changed files with 92 additions and 10 deletions
@@ -3530,6 +3530,7 @@ odoo.define('im_livechat.legacy.mail.DocumentViewer', function (require) {
var core = require('web.core');
var Widget = require('web.Widget');
var { hidePDFJSButtons } = require('@web/js/libs/pdfjs');
var QWeb = core.qweb;
@@ -3658,6 +3659,9 @@ var DocumentViewer = Widget.extend({
this.$('.o_viewer_content').html(QWeb.render('im_livechat.legacy.mail.DocumentViewer.Content', {
widget: this
}));
if (this.activeAttachment.fileType === 'application/pdf') {
hidePDFJSButtons(this.$('.o_viewer_content')[0]);
}
this.$('.o_viewer_img').on("load", _.bind(this._onImageLoaded, this));
this.$('[data-toggle="tooltip"]').tooltip({ delay: 0 });
this._reset();
@@ -5,6 +5,8 @@ import useShouldUpdateBasedOnProps from '@mail/component_hooks/use_should_update
import useStore from '@mail/component_hooks/use_store/use_store';
import { link } from '@mail/model/model_field_command';
import { hidePDFJSButtons } from '@web/js/libs/pdfjs';
const { Component, QWeb } = owl;
const { useRef } = owl.hooks;
@@ -53,6 +55,10 @@ class AttachmentViewer extends Component {
* transformation on image visualisation.
*/
this._zoomerRef = useRef('zoomer');
/**
* Reference of the IFRAME node when the attachment is a PDF.
*/
this._iframeViewerPdfRef = useRef('iframeViewerPdf');
/**
* Tracked translate transformations on image visualisation. This is
* not observed with `useStore` because they are used to compute zoomer
@@ -67,6 +73,7 @@ class AttachmentViewer extends Component {
mounted() {
this.el.focus();
this._handleImageLoad();
this._hideUnwantedPdfJsButtons();
document.addEventListener('click', this._onClickGlobal);
}
@@ -75,6 +82,7 @@ class AttachmentViewer extends Component {
*/
patched() {
this._handleImageLoad();
this._hideUnwantedPdfJsButtons();
}
willUnmount() {
@@ -169,6 +177,17 @@ class AttachmentViewer extends Component {
}
}
/**
* @see 'hidePDFJSButtons'
*
* @private
*/
_hideUnwantedPdfJsButtons() {
if (this._iframeViewerPdfRef.el) {
hidePDFJSButtons(this._iframeViewerPdfRef.el);
}
}
/**
* Display the previous attachment in the list of attachments.
*
@@ -46,7 +46,7 @@
</div>
</t>
<t t-if="attachmentViewer.attachment.fileType === 'application/pdf'">
<iframe class="o_AttachmentViewer_view o_AttachmentViewer_viewIframe o_AttachmentViewer_viewPdf" t-att-class="{ 'o-isMobile': env.messaging.device.isMobile }" t-att-src="attachmentViewer.attachment.defaultSource"/>
<iframe class="o_AttachmentViewer_view o_AttachmentViewer_viewIframe o_AttachmentViewer_viewPdf" t-ref="iframeViewerPdf" t-att-class="{ 'o-isMobile': env.messaging.device.isMobile }" t-att-src="attachmentViewer.attachment.defaultSource"/>
</t>
<t t-if="attachmentViewer.attachment.isTextFile">
<iframe class="o_AttachmentViewer_view o_AttachmentViewer_viewIframe o_text" t-att-src="attachmentViewer.attachment.defaultSource"/>
@@ -2,6 +2,7 @@
import core from 'web.core';
import Widget from 'web.Widget';
import { hidePDFJSButtons } from '@web/js/libs/pdfjs';
var QWeb = core.qweb;
@@ -74,6 +75,15 @@ var DocumentViewer = Widget.extend({
this.modelName = 'ir.attachment';
this._reset();
},
/**
* Do some actions after the widget is appended to the DOM
* @override
*/
setElement: function () {
const result = this._super(...arguments);
this._hidePdfButtonsIfPresent();
return result;
},
/**
* Open a modal displaying the active attachment
* @override
@@ -101,6 +111,15 @@ var DocumentViewer = Widget.extend({
// Private
//---------------------------------------------------------------------------
/**
* Hide some buttons in PDF.js
* @override
*/
_hidePdfButtonsIfPresent: function () {
if (this.activeAttachment.mimetype === 'application/pdf') {
hidePDFJSButtons(this.el);
}
},
/**
* @private
*/
@@ -137,6 +156,7 @@ var DocumentViewer = Widget.extend({
widget: this
}));
this.$('.o_viewer_img').on("load", _.bind(this._onImageLoaded, this));
this._hidePdfButtonsIfPresent();
this.$('[data-toggle="tooltip"]').tooltip({delay: 0});
this._reset();
},
+1
View File
@@ -388,6 +388,7 @@ This module provides the core of the Odoo Web Client.
'web/static/src/js/libs/fullcalendar.js',
'web/static/src/js/libs/jquery.js',
'web/static/src/js/libs/underscore.js',
'web/static/src/js/libs/pdfjs.js',
'web/static/src/js/libs/popper.js',
'web/static/src/js/libs/zoomodoo.js',
'web/static/src/js/libs/jSignatureCustom.js',
@@ -25,6 +25,7 @@ var view_dialogs = require('web.view_dialogs');
var field_utils = require('web.field_utils');
var time = require('web.time');
const {ColorpickerDialog} = require('web.Colorpicker');
const { hidePDFJSButtons } = require('@web/js/libs/pdfjs');
let FieldBoolean = deprecatedFields.FieldBoolean;
@@ -2253,13 +2254,6 @@ var FieldPdfViewer = FieldBinaryFile.extend({
// Private
//--------------------------------------------------------------------------
/**
* @private
* @param {DOMElement} iframe
*/
_disableButtons: function (iframe) {
$(iframe).contents().find('button#openFile').hide();
},
/**
* @private
* @param {string} [fileURI] file URI if specified
@@ -2292,7 +2286,6 @@ var FieldPdfViewer = FieldBinaryFile.extend({
$iFrame.on('load', function () {
self.PDFViewerApplication = this.contentWindow.window.PDFViewerApplication;
self._disableButtons(this);
});
if (this.mode === "readonly" && this.value) {
$iFrame.attr('src', this._getURI());
@@ -2309,6 +2302,7 @@ var FieldPdfViewer = FieldBinaryFile.extend({
$selectUpload.removeClass('o_hidden');
}
}
hidePDFJSButtons($iFrame[0]);
},
//--------------------------------------------------------------------------
+45 -1
View File
@@ -1,5 +1,49 @@
/** @odoo-module **/
import config from 'web.config';
/**
* Until we have our own implementation of the /web/static/lib/pdfjs/web/viewer.{html,js,css}
* (currently based on Firefox), this method allows us to hide the buttons that we do not want:
* * "Open File"
* * "Print" (Hidden on mobile)
* * "Download"
*
* @link https://mozilla.github.io/pdf.js/getting_started/
*
* @param {Element} rootElement
*/
export function hidePDFJSButtons(rootElement) {
const cssStyle = document.createElement("style");
cssStyle.rel = "stylesheet";
cssStyle.innerHTML = `button#secondaryDownload.secondaryToolbarButton, button#download.toolbarButton,
button#secondaryOpenFile.secondaryToolbarButton, button#openFile.toolbarButton {
display: none !important;
}`;
if (config.device.isMobileDevice) {
cssStyle.innerHTML = `${cssStyle.innerHTML}
button#secondaryPrint.secondaryToolbarButton, button#print.toolbarButton{
display: none !important;
}`;
}
const iframe = rootElement.tagName === 'IFRAME' ? rootElement : rootElement.querySelector('iframe');
if (iframe) {
if (!iframe.dataset.hideButtons) {
iframe.dataset.hideButtons = 'true';
iframe.addEventListener('load', event => {
if (iframe.contentDocument && iframe.contentDocument.head) {
iframe.contentDocument.head.appendChild(cssStyle);
}
});
}
} else {
console.warn('No IFRAME found');
}
}
/*
* There is no changes to pdf.js in this file, but only a note about a change that has been done in it.
* List of changes made in the library
* There is no changes to pdf.js in this section, but only a note about changes that has been done in /web/static/lib/pdfjs/.
*
* In the module account_invoice_extract, the the code need to react to the 'pagerendered' event triggered by
* pdf.js. However in recent version of pdf.js, event are not visible outside of the library, except if the