Skip to content

Commit 7beb67a

Browse files
Merge pull request #14092 from Snuffleupagus/xfa-addLinkAttributes
[api-minor] Ensure that various URL-related options are applied in the `xfaLayer` too
2 parents 284d259 + 8cb6efe commit 7beb67a

File tree

13 files changed

+110
-44
lines changed

13 files changed

+110
-44
lines changed

src/core/xfa/template.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,15 +1094,14 @@ class Button extends XFAObject {
10941094
if (!href) {
10951095
continue;
10961096
}
1097-
const target = jsURL.newWindow ? "_blank" : undefined;
10981097

10991098
// we've an url so generate a <a>
11001099
htmlButton.children.push({
11011100
name: "a",
11021101
attributes: {
11031102
id: "link" + this[$uid],
11041103
href,
1105-
target,
1104+
newWindow: jsURL.newWindow,
11061105
class: ["xfaLink"],
11071106
style: {},
11081107
},

src/display/annotation_layer.js

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,6 @@
1313
* limitations under the License.
1414
*/
1515

16-
import {
17-
addLinkAttributes,
18-
DOMSVGFactory,
19-
getFilenameFromUrl,
20-
LinkTarget,
21-
PDFDateString,
22-
} from "./display_utils.js";
2316
import {
2417
AnnotationBorderStyleType,
2518
AnnotationType,
@@ -30,6 +23,11 @@ import {
3023
Util,
3124
warn,
3225
} from "../shared/util.js";
26+
import {
27+
DOMSVGFactory,
28+
getFilenameFromUrl,
29+
PDFDateString,
30+
} from "./display_utils.js";
3331
import { AnnotationStorage } from "./annotation_storage.js";
3432
import { ColorConverters } from "../shared/scripting_utils.js";
3533

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

445443
if (data.url) {
446-
addLinkAttributes(link, {
447-
url: data.url,
448-
target: data.newWindow
449-
? LinkTarget.BLANK
450-
: linkService.externalLinkTarget,
451-
rel: linkService.externalLinkRel,
452-
enabled: linkService.externalLinkEnabled,
453-
});
444+
if (
445+
(typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) &&
446+
!linkService.addLinkAttributes
447+
) {
448+
warn(
449+
"LinkAnnotationElement.render - missing `addLinkAttributes`-method on the `linkService`-instance."
450+
);
451+
}
452+
linkService.addLinkAttributes?.(link, data.url, data.newWindow);
454453
} else if (data.action) {
455454
this._bindNamedAction(link, data.action);
456455
} else if (data.dest) {

src/display/display_utils.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ const LinkTarget = {
338338

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

634634
export {
635635
addLinkAttributes,
636-
DEFAULT_LINK_REL,
637636
deprecated,
638637
DOMCanvasFactory,
639638
DOMCMapReaderFactory,

src/display/xfa_layer.js

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* limitations under the License.
1414
*/
1515

16+
import { warn } from "../shared/util.js";
1617
import { XfaText } from "./xfa_text.js";
1718

1819
class XfaLayer {
@@ -84,8 +85,10 @@ class XfaLayer {
8485
}
8586
}
8687

87-
static setAttributes(html, element, storage, intent) {
88+
static setAttributes({ html, element, storage = null, intent, linkService }) {
8889
const { attributes } = element;
90+
const isHTMLAnchorElement = html instanceof HTMLAnchorElement;
91+
8992
if (attributes.type === "radio") {
9093
// Avoid to have a radio group when printing with the same as one
9194
// already displayed.
@@ -105,13 +108,32 @@ class XfaLayer {
105108
} else if (key === "class") {
106109
html.setAttribute(key, value.join(" "));
107110
} else {
111+
if (isHTMLAnchorElement && (key === "href" || key === "newWindow")) {
112+
continue; // Handled below.
113+
}
108114
html.setAttribute(key, value);
109115
}
110116
} else {
111117
Object.assign(html.style, value);
112118
}
113119
}
114120

121+
if (isHTMLAnchorElement) {
122+
if (
123+
(typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) &&
124+
!linkService.addLinkAttributes
125+
) {
126+
warn(
127+
"XfaLayer.setAttribute - missing `addLinkAttributes`-method on the `linkService`-instance."
128+
);
129+
}
130+
linkService.addLinkAttributes?.(
131+
html,
132+
attributes.href,
133+
attributes.newWindow
134+
);
135+
}
136+
115137
// Set the value after the others to be sure overwrite
116138
// any other values.
117139
if (storage && attributes.dataId) {
@@ -121,11 +143,17 @@ class XfaLayer {
121143

122144
static render(parameters) {
123145
const storage = parameters.annotationStorage;
146+
const linkService = parameters.linkService;
124147
const root = parameters.xfa;
125148
const intent = parameters.intent || "display";
126149
const rootHtml = document.createElement(root.name);
127150
if (root.attributes) {
128-
this.setAttributes(rootHtml, root);
151+
this.setAttributes({
152+
html: rootHtml,
153+
element: root,
154+
intent,
155+
linkService,
156+
});
129157
}
130158
const stack = [[root, -1, rootHtml]];
131159

@@ -169,7 +197,13 @@ class XfaLayer {
169197

170198
html.appendChild(childHtml);
171199
if (child.attributes) {
172-
this.setAttributes(childHtml, child, storage, intent);
200+
this.setAttributes({
201+
html: childHtml,
202+
element: child,
203+
storage,
204+
intent,
205+
linkService,
206+
});
173207
}
174208

175209
if (child.children && child.children.length > 0) {

test/driver.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ var rasterizeXfaLayer = (function rasterizeXfaLayerClosure() {
334334
div,
335335
viewport: viewport.clone({ dontFlip: true }),
336336
annotationStorage,
337+
linkService: new SimpleLinkService(),
337338
intent: isPrint ? "print" : "display",
338339
});
339340

test/unit/xfa_tohtml_spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -640,10 +640,10 @@ describe("XFAFactory", function () {
640640
const pages = factory.getPages();
641641
let a = searchHtmlNode(pages, "name", "a");
642642
expect(a.attributes.href).toEqual("https://github.com/mozilla/pdf.js");
643-
expect(a.attributes.target).toEqual("_blank");
643+
expect(a.attributes.newWindow).toEqual(true);
644644

645645
a = searchHtmlNode(pages, "name", "a", false, [1]);
646646
expect(a.attributes.href).toEqual("https://github.com/allizom/pdf.js");
647-
expect(a.attributes.target).toBe(undefined);
647+
expect(a.attributes.newWindow).toEqual(false);
648648
});
649649
});

web/base_viewer.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,6 +1366,7 @@ class BaseViewer {
13661366
pdfPage,
13671367
annotationStorage:
13681368
annotationStorage || this.pdfDocument?.annotationStorage,
1369+
linkService: this.linkService,
13691370
});
13701371
}
13711372

web/interfaces.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ class IPDFLinkService {
6363
*/
6464
goToPage(val) {}
6565

66+
/**
67+
* @param {HTMLAnchorElement} link
68+
* @param {string} url
69+
* @param {boolean} [newWindow]
70+
*/
71+
addLinkAttributes(link, url, newWindow = false) {}
72+
6673
/**
6774
* @param dest - The PDF destination object.
6875
* @returns {string} The hyperlink to the PDF object.
@@ -191,9 +198,16 @@ class IPDFXfaLayerFactory {
191198
/**
192199
* @param {HTMLDivElement} pageDiv
193200
* @param {PDFPage} pdfPage
201+
* @param {AnnotationStorage} [annotationStorage]
202+
* @param {Object} [xfaHtml]
194203
* @returns {XfaLayerBuilder}
195204
*/
196-
createXfaLayerBuilder(pageDiv, pdfPage) {}
205+
createXfaLayerBuilder(
206+
pageDiv,
207+
pdfPage,
208+
annotationStorage = null,
209+
xfaHtml = null
210+
) {}
197211
}
198212

199213
/**

web/pdf_link_service.js

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

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

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

2021
/**
@@ -227,6 +228,21 @@ class PDFLinkService {
227228
this.pdfViewer.scrollPageIntoView({ pageNumber });
228229
}
229230

231+
/**
232+
* Wrapper around the `addLinkAttributes`-function in the API.
233+
* @param {HTMLAnchorElement} link
234+
* @param {string} url
235+
* @param {boolean} [newWindow]
236+
*/
237+
addLinkAttributes(link, url, newWindow = false) {
238+
addLinkAttributes(link, {
239+
url,
240+
target: newWindow ? LinkTarget.BLANK : this.externalLinkTarget,
241+
rel: this.externalLinkRel,
242+
enabled: this.externalLinkEnabled,
243+
});
244+
}
245+
230246
/**
231247
* @param {string|Array} dest - The PDF destination object.
232248
* @returns {string} The hyperlink to the PDF object.
@@ -514,10 +530,7 @@ function isValidExplicitDestination(dest) {
514530
*/
515531
class SimpleLinkService {
516532
constructor() {
517-
this.externalLinkTarget = null;
518-
this.externalLinkRel = null;
519533
this.externalLinkEnabled = true;
520-
this._ignoreDestinationZoom = false;
521534
}
522535

523536
/**
@@ -561,6 +574,15 @@ class SimpleLinkService {
561574
*/
562575
goToPage(val) {}
563576

577+
/**
578+
* @param {HTMLAnchorElement} link
579+
* @param {string} url
580+
* @param {boolean} [newWindow]
581+
*/
582+
addLinkAttributes(link, url, newWindow = false) {
583+
addLinkAttributes(link, { url, enabled: this.externalLinkEnabled });
584+
}
585+
564586
/**
565587
* @param dest - The PDF destination object.
566588
* @returns {string} The hyperlink to the PDF object.

web/pdf_outline_viewer.js

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,8 @@
1313
* limitations under the License.
1414
*/
1515

16-
import {
17-
addLinkAttributes,
18-
createPromiseCapability,
19-
LinkTarget,
20-
} from "pdfjs-lib";
2116
import { BaseTreeViewer } from "./base_tree_viewer.js";
17+
import { createPromiseCapability } from "pdfjs-lib";
2218
import { SidebarView } from "./ui_utils.js";
2319

2420
/**
@@ -115,12 +111,7 @@ class PDFOutlineViewer extends BaseTreeViewer {
115111
const { linkService } = this;
116112

117113
if (url) {
118-
addLinkAttributes(element, {
119-
url,
120-
target: newWindow ? LinkTarget.BLANK : linkService.externalLinkTarget,
121-
rel: linkService.externalLinkRel,
122-
enabled: linkService.externalLinkEnabled,
123-
});
114+
linkService.addLinkAttributes(element, url, newWindow);
124115
return;
125116
}
126117

0 commit comments

Comments
 (0)