Merge pull request #12056 from Snuffleupagus/_delayedFallback
Refactor/simplify the "delayedFallback" handling in the default viewer
This commit is contained in:
commit
72d71ba6a5
285
web/app.js
285
web/app.js
@ -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,52 +909,51 @@ 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
|
||||||
this.externalServices.reportTelemetry({
|
* trigger the fallback bar once the user has interacted with the page.
|
||||||
type: "unsupportedFeature",
|
* @private
|
||||||
featureId,
|
*/
|
||||||
});
|
_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({
|
||||||
|
type: "unsupportedFeature",
|
||||||
|
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
|
// Only trigger the fallback once so we don't spam the user with messages
|
||||||
// the fallback once the user has interacted with the page.
|
// for one PDF.
|
||||||
if (this._delayedFallbackFeatureIds.length >= 1 && this._hasInteracted) {
|
if (this.fellback) {
|
||||||
featureId = this._delayedFallbackFeatureIds[0];
|
return;
|
||||||
// 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
|
|
||||||
// for one PDF.
|
|
||||||
if (this.fellback) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.fellback = true;
|
|
||||||
this.externalServices.fallback(
|
|
||||||
{
|
|
||||||
featureId,
|
|
||||||
url: this.baseUrl,
|
|
||||||
},
|
|
||||||
function response(download) {
|
|
||||||
if (!download) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
PDFViewerApplication.download();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
this.fellback = true;
|
||||||
|
this.externalServices.fallback(
|
||||||
|
{
|
||||||
|
featureId,
|
||||||
|
url: this.baseUrl,
|
||||||
|
},
|
||||||
|
function response(download) {
|
||||||
|
if (!download) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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,87 +1383,35 @@ 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 (
|
// Telemetry labels must be C++ variable friendly.
|
||||||
typeof PDFJSDev === "undefined" ||
|
let versionId = "other";
|
||||||
PDFJSDev.test("MOZCENTRAL || GENERIC")
|
if (KNOWN_VERSIONS.includes(info.PDFFormatVersion)) {
|
||||||
) {
|
versionId = `v${info.PDFFormatVersion.replace(".", "_")}`;
|
||||||
// Telemetry labels must be C++ variable friendly.
|
}
|
||||||
let versionId = "other";
|
let generatorId = "other";
|
||||||
// Keep these in sync with mozilla central's Histograms.json.
|
if (info.Producer) {
|
||||||
const KNOWN_VERSIONS = [
|
const producer = info.Producer.toLowerCase();
|
||||||
"1.0",
|
KNOWN_GENERATORS.some(function (generator) {
|
||||||
"1.1",
|
if (!producer.includes(generator)) {
|
||||||
"1.2",
|
return false;
|
||||||
"1.3",
|
}
|
||||||
"1.4",
|
generatorId = generator.replace(/[ .\-]/g, "_");
|
||||||
"1.5",
|
return true;
|
||||||
"1.6",
|
|
||||||
"1.7",
|
|
||||||
"1.8",
|
|
||||||
"1.9",
|
|
||||||
"2.0",
|
|
||||||
"2.1",
|
|
||||||
"2.2",
|
|
||||||
"2.3",
|
|
||||||
];
|
|
||||||
if (KNOWN_VERSIONS.includes(info.PDFFormatVersion)) {
|
|
||||||
versionId = `v${info.PDFFormatVersion.replace(".", "_")}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
const producer = info.Producer.toLowerCase();
|
|
||||||
KNOWN_GENERATORS.some(function (generator) {
|
|
||||||
if (!producer.includes(generator)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
generatorId = generator.replace(/[ .\-]/g, "_");
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let formType = null;
|
|
||||||
if (info.IsAcroFormPresent) {
|
|
||||||
formType = info.IsXFAPresent ? "xfa" : "acroform";
|
|
||||||
}
|
|
||||||
this.externalServices.reportTelemetry({
|
|
||||||
type: "documentInfo",
|
|
||||||
version: versionId,
|
|
||||||
generator: generatorId,
|
|
||||||
formType,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
let formType = null;
|
||||||
|
if (info.IsAcroFormPresent) {
|
||||||
|
formType = info.IsXFAPresent ? "xfa" : "acroform";
|
||||||
|
}
|
||||||
|
this.externalServices.reportTelemetry({
|
||||||
|
type: "documentInfo",
|
||||||
|
version: versionId,
|
||||||
|
generator: generatorId,
|
||||||
|
formType,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1635,14 +1624,9 @@ const PDFViewerApplication = {
|
|||||||
|
|
||||||
printService.layout();
|
printService.layout();
|
||||||
|
|
||||||
if (
|
this.externalServices.reportTelemetry({
|
||||||
typeof PDFJSDev === "undefined" ||
|
type: "print",
|
||||||
PDFJSDev.test("MOZCENTRAL || GENERIC")
|
});
|
||||||
) {
|
|
||||||
this.externalServices.reportTelemetry({
|
|
||||||
type: "print",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
afterPrint() {
|
afterPrint() {
|
||||||
@ -2084,22 +2068,17 @@ function webViewerPageRendered(evt) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
PDFViewerApplication.externalServices.reportTelemetry({
|
||||||
typeof PDFJSDev === "undefined" ||
|
type: "pageInfo",
|
||||||
PDFJSDev.test("MOZCENTRAL || GENERIC")
|
timestamp: evt.timestamp,
|
||||||
) {
|
});
|
||||||
|
// It is a good time to report stream and font types.
|
||||||
|
PDFViewerApplication.pdfDocument.getStats().then(function (stats) {
|
||||||
PDFViewerApplication.externalServices.reportTelemetry({
|
PDFViewerApplication.externalServices.reportTelemetry({
|
||||||
type: "pageInfo",
|
type: "documentStats",
|
||||||
timestamp: evt.timestamp,
|
stats,
|
||||||
});
|
});
|
||||||
// It is a good time to report stream and font types.
|
});
|
||||||
PDFViewerApplication.pdfDocument.getStats().then(function (stats) {
|
|
||||||
PDFViewerApplication.externalServices.reportTelemetry({
|
|
||||||
type: "documentStats",
|
|
||||||
stats,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function webViewerPageMode({ mode }) {
|
function webViewerPageMode({ mode }) {
|
||||||
@ -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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user