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
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
addLinkAttributes,
|
addLinkAttributes,
|
||||||
|
ColorConverters,
|
||||||
DOMSVGFactory,
|
DOMSVGFactory,
|
||||||
getFilenameFromUrl,
|
getFilenameFromUrl,
|
||||||
LinkTarget,
|
LinkTarget,
|
||||||
@ -567,6 +568,12 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
event.target.setSelectionRange(selStart, selEnd);
|
event.target.setSelectionRange(selStart, selEnd);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
strokeColor() {
|
||||||
|
const color = detail.strokeColor;
|
||||||
|
event.target.style.color = ColorConverters[`${color[0]}_HTML`](
|
||||||
|
color.slice(1)
|
||||||
|
);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
for (const name of Object.keys(detail)) {
|
for (const name of Object.keys(detail)) {
|
||||||
if (name in actions) {
|
if (name in actions) {
|
||||||
|
@ -635,6 +635,59 @@ class PDFDateString {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function makeColorComp(n) {
|
||||||
|
return Math.floor(Math.max(0, Math.min(1, n)) * 255)
|
||||||
|
.toString(16)
|
||||||
|
.padStart(2, "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
const ColorConverters = {
|
||||||
|
// PDF specifications section 10.3
|
||||||
|
CMYK_G([c, y, m, k]) {
|
||||||
|
return ["G", 1 - Math.min(1, 0.3 * c + 0.59 * m + 0.11 * y + k)];
|
||||||
|
},
|
||||||
|
G_CMYK([g]) {
|
||||||
|
return ["CMYK", 0, 0, 0, 1 - g];
|
||||||
|
},
|
||||||
|
G_RGB([g]) {
|
||||||
|
return ["RGB", g, g, g];
|
||||||
|
},
|
||||||
|
G_HTML([g]) {
|
||||||
|
const G = makeColorComp(g);
|
||||||
|
return `#${G}${G}${G}`;
|
||||||
|
},
|
||||||
|
RGB_G([r, g, b]) {
|
||||||
|
return ["G", 0.3 * r + 0.59 * g + 0.11 * b];
|
||||||
|
},
|
||||||
|
RGB_HTML([r, g, b]) {
|
||||||
|
const R = makeColorComp(r);
|
||||||
|
const G = makeColorComp(g);
|
||||||
|
const B = makeColorComp(b);
|
||||||
|
return `#${R}${G}${B}`;
|
||||||
|
},
|
||||||
|
T_HTML() {
|
||||||
|
return "#00000000";
|
||||||
|
},
|
||||||
|
CMYK_RGB([c, y, m, k]) {
|
||||||
|
return [
|
||||||
|
"RGB",
|
||||||
|
1 - Math.min(1, c + k),
|
||||||
|
1 - Math.min(1, m + k),
|
||||||
|
1 - Math.min(1, y + k),
|
||||||
|
];
|
||||||
|
},
|
||||||
|
CMYK_HTML(components) {
|
||||||
|
return ColorConverters.RGB_HTML(ColorConverters.CMYK_RGB(components));
|
||||||
|
},
|
||||||
|
RGB_CMYK([r, g, b]) {
|
||||||
|
const c = 1 - r;
|
||||||
|
const m = 1 - g;
|
||||||
|
const y = 1 - b;
|
||||||
|
const k = Math.min(c, m, y);
|
||||||
|
return ["CMYK", c, m, y, k];
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
PageViewport,
|
PageViewport,
|
||||||
RenderingCancelledException,
|
RenderingCancelledException,
|
||||||
@ -645,6 +698,7 @@ export {
|
|||||||
BaseCanvasFactory,
|
BaseCanvasFactory,
|
||||||
DOMCanvasFactory,
|
DOMCanvasFactory,
|
||||||
BaseCMapReaderFactory,
|
BaseCMapReaderFactory,
|
||||||
|
ColorConverters,
|
||||||
DOMCMapReaderFactory,
|
DOMCMapReaderFactory,
|
||||||
DOMSVGFactory,
|
DOMSVGFactory,
|
||||||
StatTimer,
|
StatTimer,
|
||||||
|
@ -13,22 +13,50 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { Color } from "./color.js";
|
||||||
import { EventDispatcher } from "./event.js";
|
import { EventDispatcher } from "./event.js";
|
||||||
import { NotSupportedError } from "./error.js";
|
import { FullScreen } from "./fullscreen.js";
|
||||||
import { PDFObject } from "./pdf_object.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 {
|
class App extends PDFObject {
|
||||||
constructor(data) {
|
constructor(data) {
|
||||||
super(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._document = data._document;
|
||||||
|
this._proxyHandler = data.proxyHandler;
|
||||||
this._objects = Object.create(null);
|
this._objects = Object.create(null);
|
||||||
this._eventDispatcher = new EventDispatcher(
|
this._eventDispatcher = new EventDispatcher(
|
||||||
this._document,
|
this._document,
|
||||||
data.calculationOrder,
|
data.calculationOrder,
|
||||||
this._objects
|
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;
|
this._isApp = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,12 +66,339 @@ class App extends PDFObject {
|
|||||||
this._eventDispatcher.dispatch(pdfEvent);
|
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() {
|
get activeDocs() {
|
||||||
return [this._document.wrapped];
|
return [this._document.wrapped];
|
||||||
}
|
}
|
||||||
|
|
||||||
set activeDocs(_) {
|
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(
|
alert(
|
||||||
@ -56,6 +411,160 @@ class App extends PDFObject {
|
|||||||
) {
|
) {
|
||||||
this._send({ command: "alert", value: cMsg });
|
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 };
|
export { App };
|
||||||
|
129
src/scripting_api/color.js
Normal file
129
src/scripting_api/color.js
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/* Copyright 2020 Mozilla Foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ColorConverters } from "../display/display_utils.js";
|
||||||
|
import { PDFObject } from "./pdf_object.js";
|
||||||
|
|
||||||
|
class Color extends PDFObject {
|
||||||
|
constructor() {
|
||||||
|
super({});
|
||||||
|
|
||||||
|
this.transparent = ["T"];
|
||||||
|
this.black = ["G", 0];
|
||||||
|
this.white = ["G", 1];
|
||||||
|
this.red = ["RGB", 1, 0, 0];
|
||||||
|
this.green = ["RGB", 0, 1, 0];
|
||||||
|
this.blue = ["RGB", 0, 0, 1];
|
||||||
|
this.cyan = ["CMYK", 1, 0, 0, 0];
|
||||||
|
this.magenta = ["CMYK", 0, 1, 0, 0];
|
||||||
|
this.yellow = ["CMYK", 0, 0, 1, 0];
|
||||||
|
this.dkGray = ["G", 0.25];
|
||||||
|
this.gray = ["G", 0.5];
|
||||||
|
this.ltGray = ["G", 0.75];
|
||||||
|
}
|
||||||
|
|
||||||
|
static _isValidSpace(cColorSpace) {
|
||||||
|
return (
|
||||||
|
typeof cColorSpace === "string" &&
|
||||||
|
(cColorSpace === "T" ||
|
||||||
|
cColorSpace === "G" ||
|
||||||
|
cColorSpace === "RGB" ||
|
||||||
|
cColorSpace === "CMYK")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static _isValidColor(colorArray) {
|
||||||
|
if (!Array.isArray(colorArray) || colorArray.length === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const space = colorArray[0];
|
||||||
|
if (!Color._isValidSpace(space)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (space) {
|
||||||
|
case "T":
|
||||||
|
if (colorArray.length !== 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "G":
|
||||||
|
if (colorArray.length !== 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "RGB":
|
||||||
|
if (colorArray.length !== 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "CMYK":
|
||||||
|
if (colorArray.length !== 5) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return colorArray
|
||||||
|
.slice(1)
|
||||||
|
.every(c => typeof c === "number" && c >= 0 && c <= 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static _getCorrectColor(colorArray) {
|
||||||
|
return Color._isValidColor(colorArray) ? colorArray : ["G", 0];
|
||||||
|
}
|
||||||
|
|
||||||
|
convert(colorArray, cColorSpace) {
|
||||||
|
if (!Color._isValidSpace(cColorSpace)) {
|
||||||
|
return this.black;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cColorSpace === "T") {
|
||||||
|
return ["T"];
|
||||||
|
}
|
||||||
|
|
||||||
|
colorArray = Color._getCorrectColor(colorArray);
|
||||||
|
if (colorArray[0] === cColorSpace) {
|
||||||
|
return colorArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colorArray[0] === "T") {
|
||||||
|
return this.convert(this.black, cColorSpace);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ColorConverters[`${colorArray[0]}_${cColorSpace}`](
|
||||||
|
colorArray.slice(1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
equal(colorArray1, colorArray2) {
|
||||||
|
colorArray1 = Color._getCorrectColor(colorArray1);
|
||||||
|
colorArray2 = Color._getCorrectColor(colorArray2);
|
||||||
|
|
||||||
|
if (colorArray1[0] === "T" || colorArray2[0] === "T") {
|
||||||
|
return colorArray1[0] === "T" && colorArray2[0] === "T";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colorArray1[0] !== colorArray2[0]) {
|
||||||
|
colorArray2 = this.convert(colorArray2, colorArray1[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return colorArray1.slice(1).every((c, i) => c === colorArray2[i + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Color };
|
@ -13,6 +13,105 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const Border = Object.freeze({
|
||||||
|
s: "solid",
|
||||||
|
d: "dashed",
|
||||||
|
b: "beveled",
|
||||||
|
i: "inset",
|
||||||
|
u: "underline",
|
||||||
|
});
|
||||||
|
|
||||||
|
const Cursor = Object.freeze({
|
||||||
|
visible: 0,
|
||||||
|
hidden: 1,
|
||||||
|
delay: 2,
|
||||||
|
});
|
||||||
|
|
||||||
|
const Display = Object.freeze({
|
||||||
|
visible: 0,
|
||||||
|
hidden: 1,
|
||||||
|
noPrint: 2,
|
||||||
|
noView: 3,
|
||||||
|
});
|
||||||
|
|
||||||
|
const Font = Object.freeze({
|
||||||
|
Times: "Times-Roman",
|
||||||
|
TimesB: "Times-Bold",
|
||||||
|
TimesI: "Times-Italic",
|
||||||
|
TimesBI: "Times-BoldItalic",
|
||||||
|
Helv: "Helvetica",
|
||||||
|
HelvB: "Helvetica-Bold",
|
||||||
|
HelvI: "Helvetica-Oblique",
|
||||||
|
HelvBI: "Helvetica-BoldOblique",
|
||||||
|
Cour: "Courier",
|
||||||
|
CourB: "Courier-Bold",
|
||||||
|
CourI: "Courier-Oblique",
|
||||||
|
CourBI: "Courier-BoldOblique",
|
||||||
|
Symbol: "Symbol",
|
||||||
|
ZapfD: "ZapfDingbats",
|
||||||
|
KaGo: "HeiseiKakuGo-W5-UniJIS-UCS2-H",
|
||||||
|
KaMi: "HeiseiMin-W3-UniJIS-UCS2-H",
|
||||||
|
});
|
||||||
|
|
||||||
|
const Highlight = Object.freeze({
|
||||||
|
n: "none",
|
||||||
|
i: "invert",
|
||||||
|
p: "push",
|
||||||
|
o: "outline",
|
||||||
|
});
|
||||||
|
|
||||||
|
const Position = Object.freeze({
|
||||||
|
textOnly: 0,
|
||||||
|
iconOnly: 1,
|
||||||
|
iconTextV: 2,
|
||||||
|
textIconV: 3,
|
||||||
|
iconTextH: 4,
|
||||||
|
textIconH: 5,
|
||||||
|
overlay: 6,
|
||||||
|
});
|
||||||
|
|
||||||
|
const ScaleHow = Object.freeze({
|
||||||
|
proportional: 0,
|
||||||
|
anamorphic: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
const ScaleWhen = Object.freeze({
|
||||||
|
always: 0,
|
||||||
|
never: 1,
|
||||||
|
tooBig: 2,
|
||||||
|
tooSmall: 3,
|
||||||
|
});
|
||||||
|
|
||||||
|
const Style = Object.freeze({
|
||||||
|
ch: "check",
|
||||||
|
cr: "cross",
|
||||||
|
di: "diamond",
|
||||||
|
ci: "circle",
|
||||||
|
st: "star",
|
||||||
|
sq: "square",
|
||||||
|
});
|
||||||
|
|
||||||
|
const Trans = Object.freeze({
|
||||||
|
blindsH: "BlindsHorizontal",
|
||||||
|
blindsV: "BlindsVertical",
|
||||||
|
boxI: "BoxIn",
|
||||||
|
boxO: "BoxOut",
|
||||||
|
dissolve: "Dissolve",
|
||||||
|
glitterD: "GlitterDown",
|
||||||
|
glitterR: "GlitterRight",
|
||||||
|
glitterRD: "GlitterRightDown",
|
||||||
|
random: "Random",
|
||||||
|
replace: "Replace",
|
||||||
|
splitHI: "SplitHorizontalIn",
|
||||||
|
splitHO: "SplitHorizontalOut",
|
||||||
|
splitVI: "SplitVerticalIn",
|
||||||
|
splitVO: "SplitVerticalOut",
|
||||||
|
wipeD: "WipeDown",
|
||||||
|
wipeL: "WipeLeft",
|
||||||
|
wipeR: "WipeRight",
|
||||||
|
wipeU: "WipeUp",
|
||||||
|
});
|
||||||
|
|
||||||
const ZoomType = Object.freeze({
|
const ZoomType = Object.freeze({
|
||||||
none: "NoVary",
|
none: "NoVary",
|
||||||
fitP: "FitPage",
|
fitP: "FitPage",
|
||||||
@ -23,4 +122,16 @@ const ZoomType = Object.freeze({
|
|||||||
refW: "ReflowWidth",
|
refW: "ReflowWidth",
|
||||||
});
|
});
|
||||||
|
|
||||||
export { ZoomType };
|
export {
|
||||||
|
Border,
|
||||||
|
Cursor,
|
||||||
|
Display,
|
||||||
|
Font,
|
||||||
|
Highlight,
|
||||||
|
Position,
|
||||||
|
ScaleHow,
|
||||||
|
ScaleWhen,
|
||||||
|
Style,
|
||||||
|
Trans,
|
||||||
|
ZoomType,
|
||||||
|
};
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { Color } from "./color.js";
|
||||||
import { PDFObject } from "./pdf_object.js";
|
import { PDFObject } from "./pdf_object.js";
|
||||||
|
|
||||||
class Field extends PDFObject {
|
class Field extends PDFObject {
|
||||||
@ -41,7 +42,6 @@ class Field extends PDFObject {
|
|||||||
this.editable = data.editable;
|
this.editable = data.editable;
|
||||||
this.exportValues = data.exportValues;
|
this.exportValues = data.exportValues;
|
||||||
this.fileSelect = data.fileSelect;
|
this.fileSelect = data.fileSelect;
|
||||||
this.fillColor = data.fillColor;
|
|
||||||
this.hidden = data.hidden;
|
this.hidden = data.hidden;
|
||||||
this.highlight = data.highlight;
|
this.highlight = data.highlight;
|
||||||
this.lineWidth = data.lineWidth;
|
this.lineWidth = data.lineWidth;
|
||||||
@ -59,10 +59,8 @@ class Field extends PDFObject {
|
|||||||
this.richText = data.richText;
|
this.richText = data.richText;
|
||||||
this.richValue = data.richValue;
|
this.richValue = data.richValue;
|
||||||
this.rotation = data.rotation;
|
this.rotation = data.rotation;
|
||||||
this.strokeColor = data.strokeColor;
|
|
||||||
this.style = data.style;
|
this.style = data.style;
|
||||||
this.submitName = data.submitName;
|
this.submitName = data.submitName;
|
||||||
this.textColor = data.textColor;
|
|
||||||
this.textFont = data.textFont;
|
this.textFont = data.textFont;
|
||||||
this.textSize = data.textSize;
|
this.textSize = data.textSize;
|
||||||
this.type = data.type;
|
this.type = data.type;
|
||||||
@ -73,6 +71,40 @@ class Field extends PDFObject {
|
|||||||
// Private
|
// Private
|
||||||
this._document = data.doc;
|
this._document = data.doc;
|
||||||
this._actions = this._createActionsMap(data.actions);
|
this._actions = this._createActionsMap(data.actions);
|
||||||
|
|
||||||
|
this._fillColor = data.fillColor | ["T"];
|
||||||
|
this._strokeColor = data.strokeColor | ["G", 0];
|
||||||
|
this._textColor = data.textColor | ["G", 0];
|
||||||
|
}
|
||||||
|
|
||||||
|
get fillColor() {
|
||||||
|
return this._fillColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
set fillColor(color) {
|
||||||
|
if (Color._isValidColor(color)) {
|
||||||
|
this._fillColor = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get strokeColor() {
|
||||||
|
return this._strokeColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
set strokeColor(color) {
|
||||||
|
if (Color._isValidColor(color)) {
|
||||||
|
this._strokeColor = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get textColor() {
|
||||||
|
return this._textColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
set textColor(color) {
|
||||||
|
if (Color._isValidColor(color)) {
|
||||||
|
this._textColor = color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setAction(cTrigger, cScript) {
|
setAction(cTrigger, cScript) {
|
||||||
@ -131,7 +163,7 @@ class Field extends PDFObject {
|
|||||||
`"${error.toString()}" for event ` +
|
`"${error.toString()}" for event ` +
|
||||||
`"${eventName}" in object ${this._id}.` +
|
`"${eventName}" in object ${this._id}.` +
|
||||||
`\n${error.stack}`;
|
`\n${error.stack}`;
|
||||||
this._send({ id: "error", value });
|
this._send({ command: "error", value });
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
145
src/scripting_api/fullscreen.js
Normal file
145
src/scripting_api/fullscreen.js
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/* Copyright 2020 Mozilla Foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Cursor } from "./constants.js";
|
||||||
|
import { PDFObject } from "./pdf_object.js";
|
||||||
|
|
||||||
|
class FullScreen extends PDFObject {
|
||||||
|
constructor(data) {
|
||||||
|
super(data);
|
||||||
|
|
||||||
|
this._backgroundColor = [];
|
||||||
|
this._clickAdvances = true;
|
||||||
|
this._cursor = Cursor.hidden;
|
||||||
|
this._defaultTransition = "";
|
||||||
|
this._escapeExits = true;
|
||||||
|
this._isFullScreen = true;
|
||||||
|
this._loop = false;
|
||||||
|
this._timeDelay = 3600;
|
||||||
|
this._usePageTiming = false;
|
||||||
|
this._useTimer = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
get backgroundColor() {
|
||||||
|
return this._backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
set backgroundColor(_) {
|
||||||
|
/* TODO or not */
|
||||||
|
}
|
||||||
|
|
||||||
|
get clickAdvances() {
|
||||||
|
return this._clickAdvances;
|
||||||
|
}
|
||||||
|
|
||||||
|
set clickAdvances(_) {
|
||||||
|
/* TODO or not */
|
||||||
|
}
|
||||||
|
|
||||||
|
get cursor() {
|
||||||
|
return this._cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
set cursor(_) {
|
||||||
|
/* TODO or not */
|
||||||
|
}
|
||||||
|
|
||||||
|
get defaultTransition() {
|
||||||
|
return this._defaultTransition;
|
||||||
|
}
|
||||||
|
|
||||||
|
set defaultTransition(_) {
|
||||||
|
/* TODO or not */
|
||||||
|
}
|
||||||
|
|
||||||
|
get escapeExits() {
|
||||||
|
return this._escapeExits;
|
||||||
|
}
|
||||||
|
|
||||||
|
set escapeExits(_) {
|
||||||
|
/* TODO or not */
|
||||||
|
}
|
||||||
|
|
||||||
|
get isFullScreen() {
|
||||||
|
return this._isFullScreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
set isFullScreen(_) {
|
||||||
|
/* TODO or not */
|
||||||
|
}
|
||||||
|
|
||||||
|
get loop() {
|
||||||
|
return this._loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
set loop(_) {
|
||||||
|
/* TODO or not */
|
||||||
|
}
|
||||||
|
|
||||||
|
get timeDelay() {
|
||||||
|
return this._timeDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
set timeDelay(_) {
|
||||||
|
/* TODO or not */
|
||||||
|
}
|
||||||
|
|
||||||
|
get transitions() {
|
||||||
|
// This list of possible value for transition has been found:
|
||||||
|
// https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/5186AcroJS.pdf#page=198
|
||||||
|
return [
|
||||||
|
"Replace",
|
||||||
|
"WipeRight",
|
||||||
|
"WipeLeft",
|
||||||
|
"WipeDown",
|
||||||
|
"WipeUp",
|
||||||
|
"SplitHorizontalIn",
|
||||||
|
"SplitHorizontalOut",
|
||||||
|
"SplitVerticalIn",
|
||||||
|
"SplitVerticalOut",
|
||||||
|
"BlindsHorizontal",
|
||||||
|
"BlindsVertical",
|
||||||
|
"BoxIn",
|
||||||
|
"BoxOut",
|
||||||
|
"GlitterRight",
|
||||||
|
"GlitterDown",
|
||||||
|
"GlitterRightDown",
|
||||||
|
"Dissolve",
|
||||||
|
"Random",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
set transitions(_) {
|
||||||
|
throw new Error("fullscreen.transitions is read-only");
|
||||||
|
}
|
||||||
|
|
||||||
|
get usePageTiming() {
|
||||||
|
return this._usePageTiming;
|
||||||
|
}
|
||||||
|
|
||||||
|
set usePageTiming(_) {
|
||||||
|
/* TODO or not */
|
||||||
|
}
|
||||||
|
|
||||||
|
get useTimer() {
|
||||||
|
return this._useTimer;
|
||||||
|
}
|
||||||
|
|
||||||
|
set useTimer(_) {
|
||||||
|
/* TODO or not */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { FullScreen };
|
@ -13,18 +13,38 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
Border,
|
||||||
|
Cursor,
|
||||||
|
Display,
|
||||||
|
Font,
|
||||||
|
Highlight,
|
||||||
|
Position,
|
||||||
|
ScaleHow,
|
||||||
|
ScaleWhen,
|
||||||
|
Style,
|
||||||
|
Trans,
|
||||||
|
ZoomType,
|
||||||
|
} from "./constants.js";
|
||||||
import { AForm } from "./aform.js";
|
import { AForm } from "./aform.js";
|
||||||
import { App } from "./app.js";
|
import { App } from "./app.js";
|
||||||
|
import { Color } from "./color.js";
|
||||||
import { Console } from "./console.js";
|
import { Console } from "./console.js";
|
||||||
import { Doc } from "./doc.js";
|
import { Doc } from "./doc.js";
|
||||||
import { Field } from "./field.js";
|
import { Field } from "./field.js";
|
||||||
import { ProxyHandler } from "./proxy.js";
|
import { ProxyHandler } from "./proxy.js";
|
||||||
import { Util } from "./util.js";
|
import { Util } from "./util.js";
|
||||||
import { ZoomType } from "./constants.js";
|
|
||||||
|
|
||||||
function initSandbox({ data, extra, out }) {
|
function initSandbox({ data, extra, out }) {
|
||||||
const proxyHandler = new ProxyHandler(data.dispatchEventName);
|
const proxyHandler = new ProxyHandler(data.dispatchEventName);
|
||||||
const { send, crackURL } = extra;
|
const {
|
||||||
|
send,
|
||||||
|
crackURL,
|
||||||
|
setTimeout,
|
||||||
|
clearTimeout,
|
||||||
|
setInterval,
|
||||||
|
clearInterval,
|
||||||
|
} = extra;
|
||||||
const doc = new Doc({
|
const doc = new Doc({
|
||||||
send,
|
send,
|
||||||
...data.docInfo,
|
...data.docInfo,
|
||||||
@ -32,8 +52,14 @@ function initSandbox({ data, extra, out }) {
|
|||||||
const _document = { obj: doc, wrapped: new Proxy(doc, proxyHandler) };
|
const _document = { obj: doc, wrapped: new Proxy(doc, proxyHandler) };
|
||||||
const app = new App({
|
const app = new App({
|
||||||
send,
|
send,
|
||||||
|
setTimeout,
|
||||||
|
clearTimeout,
|
||||||
|
setInterval,
|
||||||
|
clearInterval,
|
||||||
_document,
|
_document,
|
||||||
calculationOrder: data.calculationOrder,
|
calculationOrder: data.calculationOrder,
|
||||||
|
proxyHandler,
|
||||||
|
...data.appInfo,
|
||||||
});
|
});
|
||||||
const util = new Util({ crackURL });
|
const util = new Util({ crackURL });
|
||||||
const aform = new AForm(doc, app, util);
|
const aform = new AForm(doc, app, util);
|
||||||
@ -50,9 +76,21 @@ function initSandbox({ data, extra, out }) {
|
|||||||
|
|
||||||
out.global = Object.create(null);
|
out.global = Object.create(null);
|
||||||
out.app = new Proxy(app, proxyHandler);
|
out.app = new Proxy(app, proxyHandler);
|
||||||
|
out.color = new Proxy(new Color(), proxyHandler);
|
||||||
out.console = new Proxy(new Console({ send }), proxyHandler);
|
out.console = new Proxy(new Console({ send }), proxyHandler);
|
||||||
out.util = new Proxy(util, proxyHandler);
|
out.util = new Proxy(util, proxyHandler);
|
||||||
|
out.border = Border;
|
||||||
|
out.cursor = Cursor;
|
||||||
|
out.display = Display;
|
||||||
|
out.font = Font;
|
||||||
|
out.highlight = Highlight;
|
||||||
|
out.position = Position;
|
||||||
|
out.scaleHow = ScaleHow;
|
||||||
|
out.scaleWhen = ScaleWhen;
|
||||||
|
out.style = Style;
|
||||||
|
out.trans = Trans;
|
||||||
out.zoomtype = ZoomType;
|
out.zoomtype = ZoomType;
|
||||||
|
|
||||||
for (const name of Object.getOwnPropertyNames(AForm.prototype)) {
|
for (const name of Object.getOwnPropertyNames(AForm.prototype)) {
|
||||||
if (name.startsWith("AF")) {
|
if (name.startsWith("AF")) {
|
||||||
out[name] = aform[name].bind(aform);
|
out[name] = aform[name].bind(aform);
|
||||||
|
@ -83,7 +83,11 @@ class Sandbox {
|
|||||||
evalForTesting(code, key) {
|
evalForTesting(code, key) {
|
||||||
if (this._testMode) {
|
if (this._testMode) {
|
||||||
this._evalInSandbox(
|
this._evalInSandbox(
|
||||||
`send({ id: "${key}", result: ${code} });`,
|
`try {
|
||||||
|
send({ id: "${key}", result: ${code} });
|
||||||
|
} catch (error) {
|
||||||
|
send({ id: "${key}", result: error.message });
|
||||||
|
}`,
|
||||||
this._alertOnError
|
this._alertOnError
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
69
src/scripting_api/thermometer.js
Normal file
69
src/scripting_api/thermometer.js
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/* Copyright 2020 Mozilla Foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { PDFObject } from "./pdf_object.js";
|
||||||
|
|
||||||
|
class Thermometer extends PDFObject {
|
||||||
|
constructor(data) {
|
||||||
|
super(data);
|
||||||
|
|
||||||
|
this._cancelled = false;
|
||||||
|
this._duration = 100;
|
||||||
|
this._text = "";
|
||||||
|
this._value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
get cancelled() {
|
||||||
|
return this._cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
set cancelled(_) {
|
||||||
|
throw new Error("thermometer.cancelled is read-only");
|
||||||
|
}
|
||||||
|
|
||||||
|
get duration() {
|
||||||
|
return this._duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
set duration(val) {
|
||||||
|
this._duration = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
get text() {
|
||||||
|
return this._text;
|
||||||
|
}
|
||||||
|
|
||||||
|
set text(val) {
|
||||||
|
this._text = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
get value() {
|
||||||
|
return this._value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set value(val) {
|
||||||
|
this._value = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
begin() {
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
|
||||||
|
end() {
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Thermometer };
|
@ -23,6 +23,15 @@ describe("Scripting", function () {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function myeval(code) {
|
||||||
|
const key = (test_id++).toString();
|
||||||
|
return sandbox.eval(code, key).then(() => {
|
||||||
|
const result = send_queue.get(key).result;
|
||||||
|
send_queue.delete(key);
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
beforeAll(function (done) {
|
beforeAll(function (done) {
|
||||||
test_id = 0;
|
test_id = 0;
|
||||||
ref = 1;
|
ref = 1;
|
||||||
@ -92,6 +101,7 @@ describe("Scripting", function () {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
calculationOrder: [],
|
calculationOrder: [],
|
||||||
|
appInfo: { language: "en-US", platform: "Linux x86_64" },
|
||||||
dispatchEventName: "_dispatchMe",
|
dispatchEventName: "_dispatchMe",
|
||||||
};
|
};
|
||||||
sandbox.createSandbox(data);
|
sandbox.createSandbox(data);
|
||||||
@ -115,15 +125,9 @@ describe("Scripting", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("Util", function () {
|
describe("Util", function () {
|
||||||
function myeval(code) {
|
|
||||||
const key = (test_id++).toString();
|
|
||||||
return sandbox.eval(code, key).then(() => {
|
|
||||||
return send_queue.get(key).result;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
beforeAll(function (done) {
|
beforeAll(function (done) {
|
||||||
sandbox.createSandbox({
|
sandbox.createSandbox({
|
||||||
|
appInfo: { language: "en-US", platform: "Linux x86_64" },
|
||||||
objects: {},
|
objects: {},
|
||||||
calculationOrder: [],
|
calculationOrder: [],
|
||||||
dispatchEventName: "_dispatchMe",
|
dispatchEventName: "_dispatchMe",
|
||||||
@ -214,7 +218,7 @@ describe("Scripting", function () {
|
|||||||
.then(() => done());
|
.then(() => done());
|
||||||
});
|
});
|
||||||
|
|
||||||
it(" print a string with a percent", function (done) {
|
it("print a string with a percent", function (done) {
|
||||||
myeval(`util.printf("%%s")`)
|
myeval(`util.printf("%%s")`)
|
||||||
.then(value => {
|
.then(value => {
|
||||||
expect(value).toEqual("%%s");
|
expect(value).toEqual("%%s");
|
||||||
@ -250,6 +254,7 @@ describe("Scripting", function () {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
appInfo: { language: "en-US", platform: "Linux x86_64" },
|
||||||
calculationOrder: [],
|
calculationOrder: [],
|
||||||
dispatchEventName: "_dispatchMe",
|
dispatchEventName: "_dispatchMe",
|
||||||
};
|
};
|
||||||
@ -287,6 +292,7 @@ describe("Scripting", function () {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
appInfo: { language: "en-US", platform: "Linux x86_64" },
|
||||||
calculationOrder: [],
|
calculationOrder: [],
|
||||||
dispatchEventName: "_dispatchMe",
|
dispatchEventName: "_dispatchMe",
|
||||||
};
|
};
|
||||||
@ -328,6 +334,7 @@ describe("Scripting", function () {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
appInfo: { language: "en-US", platform: "Linux x86_64" },
|
||||||
calculationOrder: [],
|
calculationOrder: [],
|
||||||
dispatchEventName: "_dispatchMe",
|
dispatchEventName: "_dispatchMe",
|
||||||
};
|
};
|
||||||
@ -368,6 +375,7 @@ describe("Scripting", function () {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
appInfo: { language: "en-US", platform: "Linux x86_64" },
|
||||||
calculationOrder: [],
|
calculationOrder: [],
|
||||||
dispatchEventName: "_dispatchMe",
|
dispatchEventName: "_dispatchMe",
|
||||||
};
|
};
|
||||||
@ -412,6 +420,7 @@ describe("Scripting", function () {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
appInfo: { language: "en-US", platform: "Linux x86_64" },
|
||||||
calculationOrder: [refId2],
|
calculationOrder: [refId2],
|
||||||
dispatchEventName: "_dispatchMe",
|
dispatchEventName: "_dispatchMe",
|
||||||
};
|
};
|
||||||
@ -435,4 +444,133 @@ describe("Scripting", function () {
|
|||||||
.catch(done.fail);
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("Color", function () {
|
||||||
|
beforeAll(function (done) {
|
||||||
|
sandbox.createSandbox({
|
||||||
|
appInfo: { language: "en-US", platform: "Linux x86_64" },
|
||||||
|
objects: {},
|
||||||
|
calculationOrder: [],
|
||||||
|
dispatchEventName: "_dispatchMe",
|
||||||
|
});
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
function round(color) {
|
||||||
|
return [
|
||||||
|
color[0],
|
||||||
|
...color.slice(1).map(x => Math.round(x * 1000) / 1000),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
it("should convert RGB color for different color spaces", function (done) {
|
||||||
|
Promise.all([
|
||||||
|
myeval(`color.convert(["RGB", 0.1, 0.2, 0.3], "T")`).then(value => {
|
||||||
|
expect(round(value)).toEqual(["T"]);
|
||||||
|
}),
|
||||||
|
myeval(`color.convert(["RGB", 0.1, 0.2, 0.3], "G")`).then(value => {
|
||||||
|
expect(round(value)).toEqual(["G", 0.181]);
|
||||||
|
}),
|
||||||
|
myeval(`color.convert(["RGB", 0.1, 0.2, 0.3], "RGB")`).then(value => {
|
||||||
|
expect(round(value)).toEqual(["RGB", 0.1, 0.2, 0.3]);
|
||||||
|
}),
|
||||||
|
myeval(`color.convert(["RGB", 0.1, 0.2, 0.3], "CMYK")`).then(value => {
|
||||||
|
expect(round(value)).toEqual(["CMYK", 0.9, 0.8, 0.7, 0.7]);
|
||||||
|
}),
|
||||||
|
]).then(() => done());
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should convert CMYK color for different color spaces", function (done) {
|
||||||
|
Promise.all([
|
||||||
|
myeval(`color.convert(["CMYK", 0.1, 0.2, 0.3, 0.4], "T")`).then(
|
||||||
|
value => {
|
||||||
|
expect(round(value)).toEqual(["T"]);
|
||||||
|
}
|
||||||
|
),
|
||||||
|
myeval(`color.convert(["CMYK", 0.1, 0.2, 0.3, 0.4], "G")`).then(
|
||||||
|
value => {
|
||||||
|
expect(round(value)).toEqual(["G", 0.371]);
|
||||||
|
}
|
||||||
|
),
|
||||||
|
myeval(`color.convert(["CMYK", 0.1, 0.2, 0.3, 0.4], "RGB")`).then(
|
||||||
|
value => {
|
||||||
|
expect(round(value)).toEqual(["RGB", 0.5, 0.3, 0.4]);
|
||||||
|
}
|
||||||
|
),
|
||||||
|
myeval(`color.convert(["CMYK", 0.1, 0.2, 0.3, 0.4], "CMYK")`).then(
|
||||||
|
value => {
|
||||||
|
expect(round(value)).toEqual(["CMYK", 0.1, 0.2, 0.3, 0.4]);
|
||||||
|
}
|
||||||
|
),
|
||||||
|
]).then(() => done());
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should convert Gray color for different color spaces", function (done) {
|
||||||
|
Promise.all([
|
||||||
|
myeval(`color.convert(["G", 0.1], "T")`).then(value => {
|
||||||
|
expect(round(value)).toEqual(["T"]);
|
||||||
|
}),
|
||||||
|
myeval(`color.convert(["G", 0.1], "G")`).then(value => {
|
||||||
|
expect(round(value)).toEqual(["G", 0.1]);
|
||||||
|
}),
|
||||||
|
myeval(`color.convert(["G", 0.1], "RGB")`).then(value => {
|
||||||
|
expect(round(value)).toEqual(["RGB", 0.1, 0.1, 0.1]);
|
||||||
|
}),
|
||||||
|
myeval(`color.convert(["G", 0.1], "CMYK")`).then(value => {
|
||||||
|
expect(round(value)).toEqual(["CMYK", 0, 0, 0, 0.9]);
|
||||||
|
}),
|
||||||
|
]).then(() => done());
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should convert Transparent color for different color spaces", function (done) {
|
||||||
|
Promise.all([
|
||||||
|
myeval(`color.convert(["T"], "T")`).then(value => {
|
||||||
|
expect(round(value)).toEqual(["T"]);
|
||||||
|
}),
|
||||||
|
myeval(`color.convert(["T"], "G")`).then(value => {
|
||||||
|
expect(round(value)).toEqual(["G", 0]);
|
||||||
|
}),
|
||||||
|
myeval(`color.convert(["T"], "RGB")`).then(value => {
|
||||||
|
expect(round(value)).toEqual(["RGB", 0, 0, 0]);
|
||||||
|
}),
|
||||||
|
myeval(`color.convert(["T"], "CMYK")`).then(value => {
|
||||||
|
expect(round(value)).toEqual(["CMYK", 0, 0, 0, 1]);
|
||||||
|
}),
|
||||||
|
]).then(() => done());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("App", function () {
|
||||||
|
beforeAll(function (done) {
|
||||||
|
sandbox.createSandbox({
|
||||||
|
appInfo: { language: "en-US", platform: "Linux x86_64" },
|
||||||
|
objects: {},
|
||||||
|
calculationOrder: [],
|
||||||
|
dispatchEventName: "_dispatchMe",
|
||||||
|
});
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should test language", function (done) {
|
||||||
|
Promise.all([
|
||||||
|
myeval(`app.language`).then(value => {
|
||||||
|
expect(value).toEqual("ENU");
|
||||||
|
}),
|
||||||
|
myeval(`app.language = "hello"`).then(value => {
|
||||||
|
expect(value).toEqual("app.language is read-only");
|
||||||
|
}),
|
||||||
|
]).then(() => done());
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should test platform", function (done) {
|
||||||
|
Promise.all([
|
||||||
|
myeval(`app.platform`).then(value => {
|
||||||
|
expect(value).toEqual("UNIX");
|
||||||
|
}),
|
||||||
|
myeval(`app.platform = "hello"`).then(value => {
|
||||||
|
expect(value).toEqual("app.platform is read-only");
|
||||||
|
}),
|
||||||
|
]).then(() => done());
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -1486,6 +1486,10 @@ const PDFViewerApplication = {
|
|||||||
objects,
|
objects,
|
||||||
dispatchEventName,
|
dispatchEventName,
|
||||||
calculationOrder,
|
calculationOrder,
|
||||||
|
appInfo: {
|
||||||
|
platform: navigator.platform,
|
||||||
|
language: navigator.language,
|
||||||
|
},
|
||||||
docInfo: {
|
docInfo: {
|
||||||
...info,
|
...info,
|
||||||
baseURL: this.baseUrl,
|
baseURL: this.baseUrl,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user