Skip to content

Commit

Permalink
Merge pull request #14092 from Snuffleupagus/xfa-addLinkAttributes
Browse files Browse the repository at this point in the history
[api-minor] Ensure that various URL-related options are applied in the `xfaLayer` too
  • Loading branch information
timvandermeij authored Oct 2, 2021
2 parents 284d259 + 8cb6efe commit 7beb67a
Show file tree
Hide file tree
Showing 13 changed files with 110 additions and 44 deletions.
3 changes: 1 addition & 2 deletions src/core/xfa/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -1094,15 +1094,14 @@ class Button extends XFAObject {
if (!href) {
continue;
}
const target = jsURL.newWindow ? "_blank" : undefined;

// we've an url so generate a <a>
htmlButton.children.push({
name: "a",
attributes: {
id: "link" + this[$uid],
href,
target,
newWindow: jsURL.newWindow,
class: ["xfaLink"],
style: {},
},
Expand Down
29 changes: 14 additions & 15 deletions src/display/annotation_layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,6 @@
* limitations under the License.
*/

import {
addLinkAttributes,
DOMSVGFactory,
getFilenameFromUrl,
LinkTarget,
PDFDateString,
} from "./display_utils.js";
import {
AnnotationBorderStyleType,
AnnotationType,
Expand All @@ -30,6 +23,11 @@ import {
Util,
warn,
} from "../shared/util.js";
import {
DOMSVGFactory,
getFilenameFromUrl,
PDFDateString,
} from "./display_utils.js";
import { AnnotationStorage } from "./annotation_storage.js";
import { ColorConverters } from "../shared/scripting_utils.js";

Expand Down Expand Up @@ -443,14 +441,15 @@ class LinkAnnotationElement extends AnnotationElement {
const link = document.createElement("a");

if (data.url) {
addLinkAttributes(link, {
url: data.url,
target: data.newWindow
? LinkTarget.BLANK
: linkService.externalLinkTarget,
rel: linkService.externalLinkRel,
enabled: linkService.externalLinkEnabled,
});
if (
(typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) &&
!linkService.addLinkAttributes
) {
warn(
"LinkAnnotationElement.render - missing `addLinkAttributes`-method on the `linkService`-instance."
);
}
linkService.addLinkAttributes?.(link, data.url, data.newWindow);
} else if (data.action) {
this._bindNamedAction(link, data.action);
} else if (data.dest) {
Expand Down
3 changes: 1 addition & 2 deletions src/display/display_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ const LinkTarget = {

/**
* Adds various attributes (href, title, target, rel) to hyperlinks.
* @param {HTMLLinkElement} link - The link element.
* @param {HTMLAnchorElement} link - The link element.
* @param {ExternalLinkParameters} params
*/
function addLinkAttributes(link, { url, target, rel, enabled = true } = {}) {
Expand Down Expand Up @@ -633,7 +633,6 @@ function getXfaPageViewport(xfaPage, { scale = 1, rotation = 0 }) {

export {
addLinkAttributes,
DEFAULT_LINK_REL,
deprecated,
DOMCanvasFactory,
DOMCMapReaderFactory,
Expand Down
40 changes: 37 additions & 3 deletions src/display/xfa_layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* limitations under the License.
*/

import { warn } from "../shared/util.js";
import { XfaText } from "./xfa_text.js";

class XfaLayer {
Expand Down Expand Up @@ -84,8 +85,10 @@ class XfaLayer {
}
}

static setAttributes(html, element, storage, intent) {
static setAttributes({ html, element, storage = null, intent, linkService }) {
const { attributes } = element;
const isHTMLAnchorElement = html instanceof HTMLAnchorElement;

if (attributes.type === "radio") {
// Avoid to have a radio group when printing with the same as one
// already displayed.
Expand All @@ -105,13 +108,32 @@ class XfaLayer {
} else if (key === "class") {
html.setAttribute(key, value.join(" "));
} else {
if (isHTMLAnchorElement && (key === "href" || key === "newWindow")) {
continue; // Handled below.
}
html.setAttribute(key, value);
}
} else {
Object.assign(html.style, value);
}
}

if (isHTMLAnchorElement) {
if (
(typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) &&
!linkService.addLinkAttributes
) {
warn(
"XfaLayer.setAttribute - missing `addLinkAttributes`-method on the `linkService`-instance."
);
}
linkService.addLinkAttributes?.(
html,
attributes.href,
attributes.newWindow
);
}

// Set the value after the others to be sure overwrite
// any other values.
if (storage && attributes.dataId) {
Expand All @@ -121,11 +143,17 @@ class XfaLayer {

static render(parameters) {
const storage = parameters.annotationStorage;
const linkService = parameters.linkService;
const root = parameters.xfa;
const intent = parameters.intent || "display";
const rootHtml = document.createElement(root.name);
if (root.attributes) {
this.setAttributes(rootHtml, root);
this.setAttributes({
html: rootHtml,
element: root,
intent,
linkService,
});
}
const stack = [[root, -1, rootHtml]];

Expand Down Expand Up @@ -169,7 +197,13 @@ class XfaLayer {

html.appendChild(childHtml);
if (child.attributes) {
this.setAttributes(childHtml, child, storage, intent);
this.setAttributes({
html: childHtml,
element: child,
storage,
intent,
linkService,
});
}

if (child.children && child.children.length > 0) {
Expand Down
1 change: 1 addition & 0 deletions test/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ var rasterizeXfaLayer = (function rasterizeXfaLayerClosure() {
div,
viewport: viewport.clone({ dontFlip: true }),
annotationStorage,
linkService: new SimpleLinkService(),
intent: isPrint ? "print" : "display",
});

Expand Down
4 changes: 2 additions & 2 deletions test/unit/xfa_tohtml_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -640,10 +640,10 @@ describe("XFAFactory", function () {
const pages = factory.getPages();
let a = searchHtmlNode(pages, "name", "a");
expect(a.attributes.href).toEqual("https://github.com/mozilla/pdf.js");
expect(a.attributes.target).toEqual("_blank");
expect(a.attributes.newWindow).toEqual(true);

a = searchHtmlNode(pages, "name", "a", false, [1]);
expect(a.attributes.href).toEqual("https://github.com/allizom/pdf.js");
expect(a.attributes.target).toBe(undefined);
expect(a.attributes.newWindow).toEqual(false);
});
});
1 change: 1 addition & 0 deletions web/base_viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1366,6 +1366,7 @@ class BaseViewer {
pdfPage,
annotationStorage:
annotationStorage || this.pdfDocument?.annotationStorage,
linkService: this.linkService,
});
}

Expand Down
16 changes: 15 additions & 1 deletion web/interfaces.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ class IPDFLinkService {
*/
goToPage(val) {}

/**
* @param {HTMLAnchorElement} link
* @param {string} url
* @param {boolean} [newWindow]
*/
addLinkAttributes(link, url, newWindow = false) {}

/**
* @param dest - The PDF destination object.
* @returns {string} The hyperlink to the PDF object.
Expand Down Expand Up @@ -191,9 +198,16 @@ class IPDFXfaLayerFactory {
/**
* @param {HTMLDivElement} pageDiv
* @param {PDFPage} pdfPage
* @param {AnnotationStorage} [annotationStorage]
* @param {Object} [xfaHtml]
* @returns {XfaLayerBuilder}
*/
createXfaLayerBuilder(pageDiv, pdfPage) {}
createXfaLayerBuilder(
pageDiv,
pdfPage,
annotationStorage = null,
xfaHtml = null
) {}
}

/**
Expand Down
28 changes: 25 additions & 3 deletions web/pdf_link_service.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

/** @typedef {import("./interfaces").IPDFLinkService} IPDFLinkService */

import { addLinkAttributes, LinkTarget } from "pdfjs-lib";
import { parseQueryString } from "./ui_utils.js";

/**
Expand Down Expand Up @@ -227,6 +228,21 @@ class PDFLinkService {
this.pdfViewer.scrollPageIntoView({ pageNumber });
}

/**
* Wrapper around the `addLinkAttributes`-function in the API.
* @param {HTMLAnchorElement} link
* @param {string} url
* @param {boolean} [newWindow]
*/
addLinkAttributes(link, url, newWindow = false) {
addLinkAttributes(link, {
url,
target: newWindow ? LinkTarget.BLANK : this.externalLinkTarget,
rel: this.externalLinkRel,
enabled: this.externalLinkEnabled,
});
}

/**
* @param {string|Array} dest - The PDF destination object.
* @returns {string} The hyperlink to the PDF object.
Expand Down Expand Up @@ -514,10 +530,7 @@ function isValidExplicitDestination(dest) {
*/
class SimpleLinkService {
constructor() {
this.externalLinkTarget = null;
this.externalLinkRel = null;
this.externalLinkEnabled = true;
this._ignoreDestinationZoom = false;
}

/**
Expand Down Expand Up @@ -561,6 +574,15 @@ class SimpleLinkService {
*/
goToPage(val) {}

/**
* @param {HTMLAnchorElement} link
* @param {string} url
* @param {boolean} [newWindow]
*/
addLinkAttributes(link, url, newWindow = false) {
addLinkAttributes(link, { url, enabled: this.externalLinkEnabled });
}

/**
* @param dest - The PDF destination object.
* @returns {string} The hyperlink to the PDF object.
Expand Down
13 changes: 2 additions & 11 deletions web/pdf_outline_viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,8 @@
* limitations under the License.
*/

import {
addLinkAttributes,
createPromiseCapability,
LinkTarget,
} from "pdfjs-lib";
import { BaseTreeViewer } from "./base_tree_viewer.js";
import { createPromiseCapability } from "pdfjs-lib";
import { SidebarView } from "./ui_utils.js";

/**
Expand Down Expand Up @@ -115,12 +111,7 @@ class PDFOutlineViewer extends BaseTreeViewer {
const { linkService } = this;

if (url) {
addLinkAttributes(element, {
url,
target: newWindow ? LinkTarget.BLANK : linkService.externalLinkTarget,
rel: linkService.externalLinkRel,
enabled: linkService.externalLinkEnabled,
});
linkService.addLinkAttributes(element, url, newWindow);
return;
}

Expand Down
4 changes: 2 additions & 2 deletions web/secondary_toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ import { PDFSinglePageViewer } from "./pdf_single_page_viewer.js";
* @property {HTMLButtonElement} printButton - Button to print the document.
* @property {HTMLButtonElement} downloadButton - Button to download the
* document.
* @property {HTMLLinkElement} viewBookmarkButton - Button to obtain a bookmark
* link to the current location in the document.
* @property {HTMLAnchorElement} viewBookmarkButton - Button to obtain a
* bookmark link to the current location in the document.
* @property {HTMLButtonElement} firstPageButton - Button to go to the first
* page in the document.
* @property {HTMLButtonElement} lastPageButton - Button to go to the last page
Expand Down
4 changes: 2 additions & 2 deletions web/toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ const PAGE_NUMBER_LOADING_INDICATOR = "visiblePageIsLoading";
* @property {HTMLButtonElement} presentationModeButton - Button to switch to
* presentation mode.
* @property {HTMLButtonElement} download - Button to download the document.
* @property {HTMLAElement} viewBookmark - Element to link current url of
* the page view.
* @property {HTMLAnchorElement} viewBookmark - Button to obtain a bookmark link
* to the current location in the document.
*/

class Toolbar {
Expand Down
8 changes: 7 additions & 1 deletion web/xfa_layer_builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,27 @@

/** @typedef {import("./interfaces").IPDFXfaLayerFactory} IPDFXfaLayerFactory */

import { SimpleLinkService } from "./pdf_link_service.js";
import { XfaLayer } from "pdfjs-lib";

/**
* @typedef {Object} XfaLayerBuilderOptions
* @property {HTMLDivElement} pageDiv
* @property {PDFPage} pdfPage
* @property {AnnotationStorage} [annotationStorage]
* @property {IPDFLinkService} linkService
* @property {Object} [xfaHtml]
*/

class XfaLayerBuilder {
/**
* @param {XfaLayerBuilderOptions} options
*/
constructor({ pageDiv, pdfPage, annotationStorage, xfaHtml }) {
constructor({ pageDiv, pdfPage, annotationStorage, linkService, xfaHtml }) {
this.pageDiv = pageDiv;
this.pdfPage = pdfPage;
this.annotationStorage = annotationStorage;
this.linkService = linkService;
this.xfaHtml = xfaHtml;

this.div = null;
Expand All @@ -54,6 +57,7 @@ class XfaLayerBuilder {
xfa: this.xfaHtml,
page: null,
annotationStorage: this.annotationStorage,
linkService: this.linkService,
intent,
};

Expand All @@ -80,6 +84,7 @@ class XfaLayerBuilder {
xfa,
page: this.pdfPage,
annotationStorage: this.annotationStorage,
linkService: this.linkService,
intent,
};

Expand Down Expand Up @@ -129,6 +134,7 @@ class DefaultXfaLayerFactory {
pageDiv,
pdfPage,
annotationStorage,
linkService: new SimpleLinkService(),
xfaHtml,
});
}
Expand Down

0 comments on commit 7beb67a

Please sign in to comment.