Merge pull request #12525 from brendandahl/mark-info
[api-minor] Implement API to get MarkInfo from the catalog.
This commit is contained in:
commit
e341e6e542
@ -153,6 +153,47 @@ class Catalog {
|
|||||||
return shadow(this, "metadata", metadata);
|
return shadow(this, "metadata", metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get markInfo() {
|
||||||
|
let markInfo = null;
|
||||||
|
try {
|
||||||
|
markInfo = this._readMarkInfo();
|
||||||
|
} catch (ex) {
|
||||||
|
if (ex instanceof MissingDataException) {
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
warn("Unable to read mark info.");
|
||||||
|
}
|
||||||
|
return shadow(this, "markInfo", markInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_readMarkInfo() {
|
||||||
|
const obj = this._catDict.get("MarkInfo");
|
||||||
|
if (!isDict(obj)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const markInfo = Object.assign(Object.create(null), {
|
||||||
|
Marked: false,
|
||||||
|
UserProperties: false,
|
||||||
|
Suspects: false,
|
||||||
|
});
|
||||||
|
for (const key in markInfo) {
|
||||||
|
if (!obj.has(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const value = obj.get(key);
|
||||||
|
if (!isBool(value)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
markInfo[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return markInfo;
|
||||||
|
}
|
||||||
|
|
||||||
get toplevelPagesDict() {
|
get toplevelPagesDict() {
|
||||||
const pagesObj = this._catDict.get("Pages");
|
const pagesObj = this._catDict.get("Pages");
|
||||||
if (!isDict(pagesObj)) {
|
if (!isDict(pagesObj)) {
|
||||||
|
@ -499,6 +499,10 @@ class WorkerMessageHandler {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
handler.on("GetMarkInfo", function wphSetupGetMarkInfo(data) {
|
||||||
|
return pdfManager.ensureCatalog("markInfo");
|
||||||
|
});
|
||||||
|
|
||||||
handler.on("GetData", function wphSetupGetData(data) {
|
handler.on("GetData", function wphSetupGetData(data) {
|
||||||
pdfManager.requestLoadedStream();
|
pdfManager.requestLoadedStream();
|
||||||
return pdfManager.onLoadedStream().then(function (stream) {
|
return pdfManager.onLoadedStream().then(function (stream) {
|
||||||
|
@ -805,6 +805,23 @@ class PDFDocumentProxy {
|
|||||||
return this._transport.getMetadata();
|
return this._transport.getMetadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} MarkInfo
|
||||||
|
* Properties correspond to Table 321 of the PDF 32000-1:2008 spec.
|
||||||
|
* @property {boolean} Marked
|
||||||
|
* @property {boolean} UserProperties
|
||||||
|
* @property {boolean} Suspects
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Promise<MarkInfo | null>} A promise that is resolved with
|
||||||
|
* a {MarkInfo} object that contains the MarkInfo flags for the PDF
|
||||||
|
* document, or `null` when no MarkInfo values are present in the PDF file.
|
||||||
|
*/
|
||||||
|
getMarkInfo() {
|
||||||
|
return this._transport.getMarkInfo();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {Promise<TypedArray>} A promise that is resolved with a
|
* @returns {Promise<TypedArray>} A promise that is resolved with a
|
||||||
* {TypedArray} that has the raw data from the PDF.
|
* {TypedArray} that has the raw data from the PDF.
|
||||||
@ -2639,6 +2656,10 @@ class WorkerTransport {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMarkInfo() {
|
||||||
|
return this.messageHandler.sendWithPromise("GetMarkInfo", null);
|
||||||
|
}
|
||||||
|
|
||||||
getStats() {
|
getStats() {
|
||||||
return this.messageHandler.sendWithPromise("GetStats", null);
|
return this.messageHandler.sendWithPromise("GetStats", null);
|
||||||
}
|
}
|
||||||
|
@ -1209,6 +1209,24 @@ describe("api", function () {
|
|||||||
.catch(done.fail);
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("gets markInfo", function (done) {
|
||||||
|
const loadingTask = getDocument(
|
||||||
|
buildGetDocumentParams("annotation-line.pdf")
|
||||||
|
);
|
||||||
|
|
||||||
|
loadingTask.promise
|
||||||
|
.then(function (pdfDoc) {
|
||||||
|
return pdfDoc.getMarkInfo();
|
||||||
|
})
|
||||||
|
.then(function (info) {
|
||||||
|
expect(info.Marked).toEqual(true);
|
||||||
|
expect(info.UserProperties).toEqual(false);
|
||||||
|
expect(info.Suspects).toEqual(false);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
it("gets data", function (done) {
|
it("gets data", function (done) {
|
||||||
const promise = pdfDocument.getData();
|
const promise = pdfDocument.getData();
|
||||||
promise
|
promise
|
||||||
|
32
web/app.js
32
web/app.js
@ -247,6 +247,7 @@ const PDFViewerApplication = {
|
|||||||
triggerDelayedFallback: null,
|
triggerDelayedFallback: null,
|
||||||
_saveInProgress: false,
|
_saveInProgress: false,
|
||||||
_wheelUnusedTicks: 0,
|
_wheelUnusedTicks: 0,
|
||||||
|
_idleCallbacks: new Set(),
|
||||||
|
|
||||||
// Called once when the document is loaded.
|
// Called once when the document is loaded.
|
||||||
async initialize(appConfig) {
|
async initialize(appConfig) {
|
||||||
@ -743,6 +744,10 @@ const PDFViewerApplication = {
|
|||||||
this.contentDispositionFilename = null;
|
this.contentDispositionFilename = null;
|
||||||
this.triggerDelayedFallback = null;
|
this.triggerDelayedFallback = null;
|
||||||
this._saveInProgress = false;
|
this._saveInProgress = false;
|
||||||
|
for (const callback of this._idleCallbacks) {
|
||||||
|
window.cancelIdleCallback(callback);
|
||||||
|
}
|
||||||
|
this._idleCallbacks.clear();
|
||||||
|
|
||||||
this.pdfSidebar.reset();
|
this.pdfSidebar.reset();
|
||||||
this.pdfOutlineViewer.reset();
|
this.pdfOutlineViewer.reset();
|
||||||
@ -1334,6 +1339,16 @@ const PDFViewerApplication = {
|
|||||||
pdfViewer.optionalContentConfigPromise.then(optionalContentConfig => {
|
pdfViewer.optionalContentConfigPromise.then(optionalContentConfig => {
|
||||||
this.pdfLayerViewer.render({ optionalContentConfig, pdfDocument });
|
this.pdfLayerViewer.render({ optionalContentConfig, pdfDocument });
|
||||||
});
|
});
|
||||||
|
if ("requestIdleCallback" in window) {
|
||||||
|
const callback = window.requestIdleCallback(
|
||||||
|
() => {
|
||||||
|
this._collectTelemetry(pdfDocument);
|
||||||
|
this._idleCallbacks.delete(callback);
|
||||||
|
},
|
||||||
|
{ timeout: 1000 }
|
||||||
|
);
|
||||||
|
this._idleCallbacks.add(callback);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this._initializePageLabels(pdfDocument);
|
this._initializePageLabels(pdfDocument);
|
||||||
@ -1398,6 +1413,23 @@ const PDFViewerApplication = {
|
|||||||
scripting.createSandbox({ objects, dispatchEventName, calculationOrder });
|
scripting.createSandbox({ objects, dispatchEventName, calculationOrder });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A place to fetch data for telemetry after one page is rendered and the
|
||||||
|
* viewer is idle.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
async _collectTelemetry(pdfDocument) {
|
||||||
|
const markInfo = await this.pdfDocument.getMarkInfo();
|
||||||
|
if (pdfDocument !== this.pdfDocument) {
|
||||||
|
return; // Document was closed while waiting for mark info.
|
||||||
|
}
|
||||||
|
const tagged = markInfo?.Marked || false;
|
||||||
|
this.externalServices.reportTelemetry({
|
||||||
|
type: "tagged",
|
||||||
|
tagged,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user