mirror of
https://github.com/zen-browser/pdf.js.git
synced 2025-07-10 02:05:37 +02:00
JS -- Implement app object
* https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/AcrobatDC_js_api_reference.pdf * Add color, fullscreen objects + few constants.
This commit is contained in:
parent
c88e805870
commit
283aac4c53
12 changed files with 1259 additions and 19 deletions
|
@ -13,22 +13,50 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Color } from "./color.js";
|
||||
import { EventDispatcher } from "./event.js";
|
||||
import { NotSupportedError } from "./error.js";
|
||||
import { FullScreen } from "./fullscreen.js";
|
||||
import { PDFObject } from "./pdf_object.js";
|
||||
import { Thermometer } from "./thermometer.js";
|
||||
|
||||
const VIEWER_TYPE = "PDF.js";
|
||||
const VIEWER_VARIATION = "Full";
|
||||
const VIEWER_VERSION = "10.0";
|
||||
const FORMS_VERSION = undefined;
|
||||
|
||||
class App extends PDFObject {
|
||||
constructor(data) {
|
||||
super(data);
|
||||
|
||||
this.calculate = true;
|
||||
|
||||
this._constants = null;
|
||||
this._focusRect = true;
|
||||
this._fs = null;
|
||||
this._language = App._getLanguage(data.language);
|
||||
this._openInPlace = false;
|
||||
this._platform = App._getPlatform(data.platform);
|
||||
this._runtimeHighlight = false;
|
||||
this._runtimeHighlightColor = ["T"];
|
||||
this._thermometer = null;
|
||||
this._toolbar = false;
|
||||
|
||||
this._document = data._document;
|
||||
this._proxyHandler = data.proxyHandler;
|
||||
this._objects = Object.create(null);
|
||||
this._eventDispatcher = new EventDispatcher(
|
||||
this._document,
|
||||
data.calculationOrder,
|
||||
this._objects
|
||||
);
|
||||
this._setTimeout = data.setTimeout;
|
||||
this._clearTimeout = data.clearTimeout;
|
||||
this._setInterval = data.setInterval;
|
||||
this._clearInterval = data.clearInterval;
|
||||
this._timeoutIds = null;
|
||||
this._timeoutIdsRegistry = null;
|
||||
|
||||
// used in proxy.js to check that this the object with the backdoor
|
||||
// used in proxy.js to check that this is the object with the backdoor
|
||||
this._isApp = true;
|
||||
}
|
||||
|
||||
|
@ -38,12 +66,339 @@ class App extends PDFObject {
|
|||
this._eventDispatcher.dispatch(pdfEvent);
|
||||
}
|
||||
|
||||
_registerTimeout(timeout, id, interval) {
|
||||
if (!this._timeoutIds) {
|
||||
this._timeoutIds = new WeakMap();
|
||||
// FinalizationRegistry isn't implemented in QuickJS
|
||||
// eslint-disable-next-line no-undef
|
||||
if (typeof FinalizationRegistry !== "undefined") {
|
||||
// About setTimeOut/setInterval return values (specs):
|
||||
// The return value of this method must be held in a
|
||||
// JavaScript variable.
|
||||
// Otherwise, the timeout object is subject to garbage-collection,
|
||||
// which would cause the clock to stop.
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
this._timeoutIdsRegistry = new FinalizationRegistry(
|
||||
([timeoutId, isInterval]) => {
|
||||
if (isInterval) {
|
||||
this._clearInterval(timeoutId);
|
||||
} else {
|
||||
this._clearTimeout(timeoutId);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
this._timeoutIds.set(timeout, [id, interval]);
|
||||
if (this._timeoutIdsRegistry) {
|
||||
this._timeoutIdsRegistry.register(timeout, [id, interval]);
|
||||
}
|
||||
}
|
||||
|
||||
_unregisterTimeout(timeout) {
|
||||
if (!this._timeoutIds || !this._timeoutIds.has(timeout)) {
|
||||
return;
|
||||
}
|
||||
const [id, interval] = this._timeoutIds.get(timeout);
|
||||
if (this._timeoutIdsRegistry) {
|
||||
this._timeoutIdsRegistry.unregister(timeout);
|
||||
}
|
||||
this._timeoutIds.delete(timeout);
|
||||
|
||||
if (interval) {
|
||||
this._clearInterval(id);
|
||||
} else {
|
||||
this._clearTimeout(id);
|
||||
}
|
||||
}
|
||||
|
||||
static _getPlatform(platform) {
|
||||
if (typeof platform === "string") {
|
||||
platform = platform.toLowerCase();
|
||||
if (platform.includes("win")) {
|
||||
return "WIN";
|
||||
} else if (platform.includes("mac")) {
|
||||
return "MAC";
|
||||
}
|
||||
}
|
||||
return "UNIX";
|
||||
}
|
||||
|
||||
static _getLanguage(language) {
|
||||
const [main, sub] = language.toLowerCase().split(/[-_]/);
|
||||
switch (main) {
|
||||
case "zh":
|
||||
if (sub === "cn" || sub === "sg") {
|
||||
return "CHS";
|
||||
}
|
||||
return "CHT";
|
||||
case "da":
|
||||
return "DAN";
|
||||
case "de":
|
||||
return "DEU";
|
||||
case "es":
|
||||
return "ESP";
|
||||
case "fr":
|
||||
return "FRA";
|
||||
case "it":
|
||||
return "ITA";
|
||||
case "ko":
|
||||
return "KOR";
|
||||
case "ja":
|
||||
return "JPN";
|
||||
case "nl":
|
||||
return "NLD";
|
||||
case "no":
|
||||
return "NOR";
|
||||
case "pt":
|
||||
if (sub === "br") {
|
||||
return "PTB";
|
||||
}
|
||||
return "ENU";
|
||||
case "fi":
|
||||
return "SUO";
|
||||
case "SV":
|
||||
return "SVE";
|
||||
default:
|
||||
return "ENU";
|
||||
}
|
||||
}
|
||||
|
||||
get activeDocs() {
|
||||
return [this._document.wrapped];
|
||||
}
|
||||
|
||||
set activeDocs(_) {
|
||||
throw new NotSupportedError("app.activeDocs");
|
||||
throw new Error("app.activeDocs is read-only");
|
||||
}
|
||||
|
||||
get constants() {
|
||||
if (!this._constants) {
|
||||
this._constants = Object.freeze({
|
||||
align: Object.freeze({
|
||||
left: 0,
|
||||
center: 1,
|
||||
right: 2,
|
||||
top: 3,
|
||||
bottom: 4,
|
||||
}),
|
||||
});
|
||||
}
|
||||
return this._constants;
|
||||
}
|
||||
|
||||
set constants(_) {
|
||||
throw new Error("app.constants is read-only");
|
||||
}
|
||||
|
||||
get focusRect() {
|
||||
return this._focusRect;
|
||||
}
|
||||
|
||||
set focusRect(val) {
|
||||
/* TODO or not */
|
||||
this._focusRect = val;
|
||||
}
|
||||
|
||||
get formsVersion() {
|
||||
return FORMS_VERSION;
|
||||
}
|
||||
|
||||
set formsVersion(_) {
|
||||
throw new Error("app.formsVersion is read-only");
|
||||
}
|
||||
|
||||
get fromPDFConverters() {
|
||||
return [];
|
||||
}
|
||||
|
||||
set fromPDFConverters(_) {
|
||||
throw new Error("app.fromPDFConverters is read-only");
|
||||
}
|
||||
|
||||
get fs() {
|
||||
if (this._fs === null) {
|
||||
this._fs = new Proxy(
|
||||
new FullScreen({ send: this._send }),
|
||||
this._proxyHandler
|
||||
);
|
||||
}
|
||||
return this._fs;
|
||||
}
|
||||
|
||||
set fs(_) {
|
||||
throw new Error("app.fs is read-only");
|
||||
}
|
||||
|
||||
get language() {
|
||||
return this._language;
|
||||
}
|
||||
|
||||
set language(_) {
|
||||
throw new Error("app.language is read-only");
|
||||
}
|
||||
|
||||
get media() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
set media(_) {
|
||||
throw new Error("app.media is read-only");
|
||||
}
|
||||
|
||||
get monitors() {
|
||||
return [];
|
||||
}
|
||||
|
||||
set monitors(_) {
|
||||
throw new Error("app.monitors is read-only");
|
||||
}
|
||||
|
||||
get numPlugins() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
set numPlugins(_) {
|
||||
throw new Error("app.numPlugins is read-only");
|
||||
}
|
||||
|
||||
get openInPlace() {
|
||||
return this._openInPlace;
|
||||
}
|
||||
|
||||
set openInPlace(val) {
|
||||
this._openInPlace = val;
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
get platform() {
|
||||
return this._platform;
|
||||
}
|
||||
|
||||
set platform(_) {
|
||||
throw new Error("app.platform is read-only");
|
||||
}
|
||||
|
||||
get plugins() {
|
||||
return [];
|
||||
}
|
||||
|
||||
set plugins(_) {
|
||||
throw new Error("app.plugins is read-only");
|
||||
}
|
||||
|
||||
get printColorProfiles() {
|
||||
return [];
|
||||
}
|
||||
|
||||
set printColorProfiles(_) {
|
||||
throw new Error("app.printColorProfiles is read-only");
|
||||
}
|
||||
|
||||
get printerNames() {
|
||||
return [];
|
||||
}
|
||||
|
||||
set printerNames(_) {
|
||||
throw new Error("app.printerNames is read-only");
|
||||
}
|
||||
|
||||
get runtimeHighlight() {
|
||||
return this._runtimeHighlight;
|
||||
}
|
||||
|
||||
set runtimeHighlight(val) {
|
||||
this._runtimeHighlight = val;
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
get runtimeHighlightColor() {
|
||||
return this._runtimeHighlightColor;
|
||||
}
|
||||
|
||||
set runtimeHighlightColor(val) {
|
||||
if (Color._isValidColor(val)) {
|
||||
this._runtimeHighlightColor = val;
|
||||
/* TODO */
|
||||
}
|
||||
}
|
||||
|
||||
get thermometer() {
|
||||
if (this._thermometer === null) {
|
||||
this._thermometer = new Proxy(
|
||||
new Thermometer({ send: this._send }),
|
||||
this._proxyHandler
|
||||
);
|
||||
}
|
||||
return this._thermometer;
|
||||
}
|
||||
|
||||
set thermometer(_) {
|
||||
throw new Error("app.thermometer is read-only");
|
||||
}
|
||||
|
||||
get toolbar() {
|
||||
return this._toolbar;
|
||||
}
|
||||
|
||||
set toolbar(val) {
|
||||
this._toolbar = val;
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
get toolbarHorizontal() {
|
||||
return this.toolbar;
|
||||
}
|
||||
|
||||
set toolbarHorizontal(value) {
|
||||
/* has been deprecated and it's now equivalent to toolbar */
|
||||
this.toolbar = value;
|
||||
}
|
||||
|
||||
get toolbarVertical() {
|
||||
return this.toolbar;
|
||||
}
|
||||
|
||||
set toolbarVertical(value) {
|
||||
/* has been deprecated and it's now equivalent to toolbar */
|
||||
this.toolbar = value;
|
||||
}
|
||||
|
||||
get viewerType() {
|
||||
return VIEWER_TYPE;
|
||||
}
|
||||
|
||||
set viewerType(_) {
|
||||
throw new Error("app.viewerType is read-only");
|
||||
}
|
||||
|
||||
get viewerVariation() {
|
||||
return VIEWER_VARIATION;
|
||||
}
|
||||
|
||||
set viewerVariation(_) {
|
||||
throw new Error("app.viewerVariation is read-only");
|
||||
}
|
||||
|
||||
get viewerVersion() {
|
||||
return VIEWER_VERSION;
|
||||
}
|
||||
|
||||
set viewerVersion(_) {
|
||||
throw new Error("app.viewerVersion is read-only");
|
||||
}
|
||||
|
||||
addMenuItem() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
addSubMenu() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
addToolButton() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
alert(
|
||||
|
@ -56,6 +411,160 @@ class App extends PDFObject {
|
|||
) {
|
||||
this._send({ command: "alert", value: cMsg });
|
||||
}
|
||||
|
||||
beep() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
beginPriv() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
browseForDoc() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
clearInterval(oInterval) {
|
||||
this.unregisterTimeout(oInterval);
|
||||
}
|
||||
|
||||
clearTimeOut(oTime) {
|
||||
this.unregisterTimeout(oTime);
|
||||
}
|
||||
|
||||
endPriv() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
execDialog() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
execMenuItem() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
getNthPlugInName() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
getPath() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
goBack() {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
goForward() {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
hideMenuItem() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
hideToolbarButton() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
launchURL() {
|
||||
/* Unsafe */
|
||||
}
|
||||
|
||||
listMenuItems() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
listToolbarButtons() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
loadPolicyFile() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
mailGetAddrs() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
mailMsg() {
|
||||
/* TODO or not ? */
|
||||
}
|
||||
|
||||
newDoc() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
newCollection() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
newFDF() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
openDoc() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
openFDF() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
popUpMenu() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
popUpMenuEx() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
removeToolButton() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
response() {
|
||||
/* TODO or not */
|
||||
}
|
||||
|
||||
setInterval(cExpr, nMilliseconds) {
|
||||
if (typeof cExpr !== "string") {
|
||||
throw new TypeError("First argument of app.setInterval must be a string");
|
||||
}
|
||||
if (typeof nMilliseconds !== "number") {
|
||||
throw new TypeError(
|
||||
"Second argument of app.setInterval must be a number"
|
||||
);
|
||||
}
|
||||
|
||||
const id = this._setInterval(cExpr, nMilliseconds);
|
||||
const timeout = Object.create(null);
|
||||
this._registerTimeout(timeout, id, true);
|
||||
return timeout;
|
||||
}
|
||||
|
||||
setTimeOut(cExpr, nMilliseconds) {
|
||||
if (typeof cExpr !== "string") {
|
||||
throw new TypeError("First argument of app.setTimeOut must be a string");
|
||||
}
|
||||
if (typeof nMilliseconds !== "number") {
|
||||
throw new TypeError("Second argument of app.setTimeOut must be a number");
|
||||
}
|
||||
|
||||
const id = this._setTimeout(cExpr, nMilliseconds);
|
||||
const timeout = Object.create(null);
|
||||
this._registerTimeout(timeout, id, false);
|
||||
return timeout;
|
||||
}
|
||||
|
||||
trustedFunction() {
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
trustPropagatorFunction() {
|
||||
/* Not implemented */
|
||||
}
|
||||
}
|
||||
|
||||
export { App };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue