Merge pull request #12056 from Snuffleupagus/_delayedFallback

Refactor/simplify the "delayedFallback" handling in the default viewer
This commit is contained in:
Tim van der Meij 2020-07-09 00:10:40 +02:00 committed by GitHub
commit 72d71ba6a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -86,6 +86,51 @@ const ViewOnLoad = {
INITIAL: 1, INITIAL: 1,
}; };
// Keep these in sync with mozilla-central's Histograms.json.
const KNOWN_VERSIONS = [
"1.0",
"1.1",
"1.2",
"1.3",
"1.4",
"1.5",
"1.6",
"1.7",
"1.8",
"1.9",
"2.0",
"2.1",
"2.2",
"2.3",
];
// Keep these in sync with mozilla-central's Histograms.json.
const KNOWN_GENERATORS = [
"acrobat distiller",
"acrobat pdfwriter",
"adobe livecycle",
"adobe pdf library",
"adobe photoshop",
"ghostscript",
"tcpdf",
"cairo",
"dvipdfm",
"dvips",
"pdftex",
"pdfkit",
"itext",
"prince",
"quarkxpress",
"mac os x",
"microsoft",
"openoffice",
"oracle",
"luradocument",
"pdf-xchange",
"antenna house",
"aspose.cells",
"fpdf",
];
class DefaultExternalServices { class DefaultExternalServices {
constructor() { constructor() {
throw new Error("Cannot initialize DefaultExternalServices."); throw new Error("Cannot initialize DefaultExternalServices.");
@ -189,8 +234,7 @@ const PDFViewerApplication = {
externalServices: DefaultExternalServices, externalServices: DefaultExternalServices,
_boundEvents: {}, _boundEvents: {},
contentDispositionFilename: null, contentDispositionFilename: null,
_hasInteracted: false, triggerDelayedFallback: null,
_delayedFallbackFeatureIds: [],
// Called once when the document is loaded. // Called once when the document is loaded.
async initialize(appConfig) { async initialize(appConfig) {
@ -690,6 +734,7 @@ const PDFViewerApplication = {
this.url = ""; this.url = "";
this.baseUrl = ""; this.baseUrl = "";
this.contentDispositionFilename = null; this.contentDispositionFilename = null;
this.triggerDelayedFallback = null;
this.pdfSidebar.reset(); this.pdfSidebar.reset();
this.pdfOutlineViewer.reset(); this.pdfOutlineViewer.reset();
@ -864,38 +909,38 @@ const PDFViewerApplication = {
.catch(downloadByUrl); // Error occurred, try downloading with the URL. .catch(downloadByUrl); // Error occurred, try downloading with the URL.
}, },
_recordFallbackErrorTelemetry(featureId) { /**
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("MOZCENTRAL")) { * For PDF documents that contain e.g. forms and javaScript, we should only
* trigger the fallback bar once the user has interacted with the page.
* @private
*/
_delayedFallback(featureId) {
// Ensure that telemetry is always reported, since it's not guaranteed
// that the fallback bar will be shown (depends on user interaction).
this.externalServices.reportTelemetry({ this.externalServices.reportTelemetry({
type: "unsupportedFeature", type: "unsupportedFeature",
featureId, featureId,
}); });
if (!this.triggerDelayedFallback) {
this.triggerDelayedFallback = () => {
this.fallback(featureId);
this.triggerDelayedFallback = null;
};
} }
}, },
fallback(featureId) { fallback(featureId) {
if ( this.externalServices.reportTelemetry({
typeof PDFJSDev === "undefined" || type: "unsupportedFeature",
PDFJSDev.test("MOZCENTRAL || GENERIC") featureId,
) { });
if (featureId) {
this._recordFallbackErrorTelemetry(featureId);
}
// For PDFs that contain script and form errors, we should only trigger
// the fallback once the user has interacted with the page.
if (this._delayedFallbackFeatureIds.length >= 1 && this._hasInteracted) {
featureId = this._delayedFallbackFeatureIds[0];
// Reset to prevent all click events from showing fallback bar.
this._delayedFallbackFeatureIds = [];
}
// Only trigger the fallback once so we don't spam the user with messages // Only trigger the fallback once so we don't spam the user with messages
// for one PDF. // for one PDF.
if (this.fellback) { if (this.fellback) {
return; return;
} }
this.fellback = true; this.fellback = true;
this.externalServices.fallback( this.externalServices.fallback(
{ {
@ -909,7 +954,6 @@ const PDFViewerApplication = {
PDFViewerApplication.download(); PDFViewerApplication.download();
} }
); );
}
}, },
/** /**
@ -1259,8 +1303,7 @@ const PDFViewerApplication = {
return false; return false;
} }
console.warn("Warning: JavaScript is not supported"); console.warn("Warning: JavaScript is not supported");
this._delayedFallbackFeatureIds.push(UNSUPPORTED_FEATURES.javaScript); this._delayedFallback(UNSUPPORTED_FEATURES.javaScript);
this._recordFallbackErrorTelemetry(UNSUPPORTED_FEATURES.javaScript);
return true; return true;
}); });
@ -1311,7 +1354,6 @@ const PDFViewerApplication = {
); );
let pdfTitle; let pdfTitle;
const infoTitle = info && info.Title; const infoTitle = info && info.Title;
if (infoTitle) { if (infoTitle) {
pdfTitle = infoTitle; pdfTitle = infoTitle;
@ -1331,7 +1373,6 @@ const PDFViewerApplication = {
pdfTitle = metadataTitle; pdfTitle = metadataTitle;
} }
} }
if (pdfTitle) { if (pdfTitle) {
this.setTitle( this.setTitle(
`${pdfTitle} - ${contentDispositionFilename || document.title}` `${pdfTitle} - ${contentDispositionFilename || document.title}`
@ -1342,65 +1383,15 @@ const PDFViewerApplication = {
if (info.IsAcroFormPresent) { if (info.IsAcroFormPresent) {
console.warn("Warning: AcroForm/XFA is not supported"); console.warn("Warning: AcroForm/XFA is not supported");
this._delayedFallbackFeatureIds.push(UNSUPPORTED_FEATURES.forms); this._delayedFallback(UNSUPPORTED_FEATURES.forms);
this._recordFallbackErrorTelemetry(UNSUPPORTED_FEATURES.forms);
} }
if (
typeof PDFJSDev === "undefined" ||
PDFJSDev.test("MOZCENTRAL || GENERIC")
) {
// Telemetry labels must be C++ variable friendly. // Telemetry labels must be C++ variable friendly.
let versionId = "other"; let versionId = "other";
// Keep these in sync with mozilla central's Histograms.json.
const KNOWN_VERSIONS = [
"1.0",
"1.1",
"1.2",
"1.3",
"1.4",
"1.5",
"1.6",
"1.7",
"1.8",
"1.9",
"2.0",
"2.1",
"2.2",
"2.3",
];
if (KNOWN_VERSIONS.includes(info.PDFFormatVersion)) { if (KNOWN_VERSIONS.includes(info.PDFFormatVersion)) {
versionId = `v${info.PDFFormatVersion.replace(".", "_")}`; versionId = `v${info.PDFFormatVersion.replace(".", "_")}`;
} }
let generatorId = "other"; let generatorId = "other";
// Keep these in sync with mozilla central's Histograms.json.
const KNOWN_GENERATORS = [
"acrobat distiller",
"acrobat pdfwriter",
"adobe livecycle",
"adobe pdf library",
"adobe photoshop",
"ghostscript",
"tcpdf",
"cairo",
"dvipdfm",
"dvips",
"pdftex",
"pdfkit",
"itext",
"prince",
"quarkxpress",
"mac os x",
"microsoft",
"openoffice",
"oracle",
"luradocument",
"pdf-xchange",
"antenna house",
"aspose.cells",
"fpdf",
];
if (info.Producer) { if (info.Producer) {
const producer = info.Producer.toLowerCase(); const producer = info.Producer.toLowerCase();
KNOWN_GENERATORS.some(function (generator) { KNOWN_GENERATORS.some(function (generator) {
@ -1411,7 +1402,6 @@ const PDFViewerApplication = {
return true; return true;
}); });
} }
let formType = null; let formType = null;
if (info.IsAcroFormPresent) { if (info.IsAcroFormPresent) {
formType = info.IsXFAPresent ? "xfa" : "acroform"; formType = info.IsXFAPresent ? "xfa" : "acroform";
@ -1422,7 +1412,6 @@ const PDFViewerApplication = {
generator: generatorId, generator: generatorId,
formType, formType,
}); });
}
}, },
/** /**
@ -1635,14 +1624,9 @@ const PDFViewerApplication = {
printService.layout(); printService.layout();
if (
typeof PDFJSDev === "undefined" ||
PDFJSDev.test("MOZCENTRAL || GENERIC")
) {
this.externalServices.reportTelemetry({ this.externalServices.reportTelemetry({
type: "print", type: "print",
}); });
}
}, },
afterPrint() { afterPrint() {
@ -2084,10 +2068,6 @@ function webViewerPageRendered(evt) {
}); });
} }
if (
typeof PDFJSDev === "undefined" ||
PDFJSDev.test("MOZCENTRAL || GENERIC")
) {
PDFViewerApplication.externalServices.reportTelemetry({ PDFViewerApplication.externalServices.reportTelemetry({
type: "pageInfo", type: "pageInfo",
timestamp: evt.timestamp, timestamp: evt.timestamp,
@ -2100,7 +2080,6 @@ function webViewerPageRendered(evt) {
}); });
}); });
} }
}
function webViewerPageMode({ mode }) { function webViewerPageMode({ mode }) {
// Handle the 'pagemode' hash parameter, see also `PDFLinkService_setHash`. // Handle the 'pagemode' hash parameter, see also `PDFLinkService_setHash`.
@ -2501,15 +2480,13 @@ function webViewerWheel(evt) {
} }
function webViewerClick(evt) { function webViewerClick(evt) {
PDFViewerApplication._hasInteracted = true;
// Avoid triggering the fallback bar when the user clicks on the // Avoid triggering the fallback bar when the user clicks on the
// toolbar or sidebar. // toolbar or sidebar.
if ( if (
PDFViewerApplication._delayedFallbackFeatureIds.length >= 1 && PDFViewerApplication.triggerDelayedFallback &&
PDFViewerApplication.pdfViewer.containsElement(evt.target) PDFViewerApplication.pdfViewer.containsElement(evt.target)
) { ) {
PDFViewerApplication.fallback(); PDFViewerApplication.triggerDelayedFallback();
} }
if (!PDFViewerApplication.secondaryToolbar.isOpen) { if (!PDFViewerApplication.secondaryToolbar.isOpen) {
@ -2527,12 +2504,10 @@ function webViewerClick(evt) {
function webViewerKeyUp(evt) { function webViewerKeyUp(evt) {
if (evt.keyCode === 9) { if (evt.keyCode === 9) {
// The user is tabbing into the pdf. Display the error message // The user is tabbing into the viewer. Trigger the fallback bar if it has
// if it has not already been displayed. // not already been displayed.
PDFViewerApplication._hasInteracted = true; if (PDFViewerApplication.triggerDelayedFallback) {
PDFViewerApplication.triggerDelayedFallback();
if (PDFViewerApplication._delayedFallbackFeatureIds.length >= 1) {
PDFViewerApplication.fallback();
} }
} }
} }