Merge pull request #14092 from Snuffleupagus/xfa-addLinkAttributes
[api-minor] Ensure that various URL-related options are applied in the `xfaLayer` too
This commit is contained in:
commit
7beb67af7b
@ -1094,7 +1094,6 @@ class Button extends XFAObject {
|
|||||||
if (!href) {
|
if (!href) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const target = jsURL.newWindow ? "_blank" : undefined;
|
|
||||||
|
|
||||||
// we've an url so generate a <a>
|
// we've an url so generate a <a>
|
||||||
htmlButton.children.push({
|
htmlButton.children.push({
|
||||||
@ -1102,7 +1101,7 @@ class Button extends XFAObject {
|
|||||||
attributes: {
|
attributes: {
|
||||||
id: "link" + this[$uid],
|
id: "link" + this[$uid],
|
||||||
href,
|
href,
|
||||||
target,
|
newWindow: jsURL.newWindow,
|
||||||
class: ["xfaLink"],
|
class: ["xfaLink"],
|
||||||
style: {},
|
style: {},
|
||||||
},
|
},
|
||||||
|
@ -13,13 +13,6 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
|
||||||
addLinkAttributes,
|
|
||||||
DOMSVGFactory,
|
|
||||||
getFilenameFromUrl,
|
|
||||||
LinkTarget,
|
|
||||||
PDFDateString,
|
|
||||||
} from "./display_utils.js";
|
|
||||||
import {
|
import {
|
||||||
AnnotationBorderStyleType,
|
AnnotationBorderStyleType,
|
||||||
AnnotationType,
|
AnnotationType,
|
||||||
@ -30,6 +23,11 @@ import {
|
|||||||
Util,
|
Util,
|
||||||
warn,
|
warn,
|
||||||
} from "../shared/util.js";
|
} from "../shared/util.js";
|
||||||
|
import {
|
||||||
|
DOMSVGFactory,
|
||||||
|
getFilenameFromUrl,
|
||||||
|
PDFDateString,
|
||||||
|
} from "./display_utils.js";
|
||||||
import { AnnotationStorage } from "./annotation_storage.js";
|
import { AnnotationStorage } from "./annotation_storage.js";
|
||||||
import { ColorConverters } from "../shared/scripting_utils.js";
|
import { ColorConverters } from "../shared/scripting_utils.js";
|
||||||
|
|
||||||
@ -443,14 +441,15 @@ class LinkAnnotationElement extends AnnotationElement {
|
|||||||
const link = document.createElement("a");
|
const link = document.createElement("a");
|
||||||
|
|
||||||
if (data.url) {
|
if (data.url) {
|
||||||
addLinkAttributes(link, {
|
if (
|
||||||
url: data.url,
|
(typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) &&
|
||||||
target: data.newWindow
|
!linkService.addLinkAttributes
|
||||||
? LinkTarget.BLANK
|
) {
|
||||||
: linkService.externalLinkTarget,
|
warn(
|
||||||
rel: linkService.externalLinkRel,
|
"LinkAnnotationElement.render - missing `addLinkAttributes`-method on the `linkService`-instance."
|
||||||
enabled: linkService.externalLinkEnabled,
|
);
|
||||||
});
|
}
|
||||||
|
linkService.addLinkAttributes?.(link, data.url, data.newWindow);
|
||||||
} else if (data.action) {
|
} else if (data.action) {
|
||||||
this._bindNamedAction(link, data.action);
|
this._bindNamedAction(link, data.action);
|
||||||
} else if (data.dest) {
|
} else if (data.dest) {
|
||||||
|
@ -338,7 +338,7 @@ const LinkTarget = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds various attributes (href, title, target, rel) to hyperlinks.
|
* Adds various attributes (href, title, target, rel) to hyperlinks.
|
||||||
* @param {HTMLLinkElement} link - The link element.
|
* @param {HTMLAnchorElement} link - The link element.
|
||||||
* @param {ExternalLinkParameters} params
|
* @param {ExternalLinkParameters} params
|
||||||
*/
|
*/
|
||||||
function addLinkAttributes(link, { url, target, rel, enabled = true } = {}) {
|
function addLinkAttributes(link, { url, target, rel, enabled = true } = {}) {
|
||||||
@ -633,7 +633,6 @@ function getXfaPageViewport(xfaPage, { scale = 1, rotation = 0 }) {
|
|||||||
|
|
||||||
export {
|
export {
|
||||||
addLinkAttributes,
|
addLinkAttributes,
|
||||||
DEFAULT_LINK_REL,
|
|
||||||
deprecated,
|
deprecated,
|
||||||
DOMCanvasFactory,
|
DOMCanvasFactory,
|
||||||
DOMCMapReaderFactory,
|
DOMCMapReaderFactory,
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { warn } from "../shared/util.js";
|
||||||
import { XfaText } from "./xfa_text.js";
|
import { XfaText } from "./xfa_text.js";
|
||||||
|
|
||||||
class XfaLayer {
|
class XfaLayer {
|
||||||
@ -84,8 +85,10 @@ class XfaLayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static setAttributes(html, element, storage, intent) {
|
static setAttributes({ html, element, storage = null, intent, linkService }) {
|
||||||
const { attributes } = element;
|
const { attributes } = element;
|
||||||
|
const isHTMLAnchorElement = html instanceof HTMLAnchorElement;
|
||||||
|
|
||||||
if (attributes.type === "radio") {
|
if (attributes.type === "radio") {
|
||||||
// Avoid to have a radio group when printing with the same as one
|
// Avoid to have a radio group when printing with the same as one
|
||||||
// already displayed.
|
// already displayed.
|
||||||
@ -105,6 +108,9 @@ class XfaLayer {
|
|||||||
} else if (key === "class") {
|
} else if (key === "class") {
|
||||||
html.setAttribute(key, value.join(" "));
|
html.setAttribute(key, value.join(" "));
|
||||||
} else {
|
} else {
|
||||||
|
if (isHTMLAnchorElement && (key === "href" || key === "newWindow")) {
|
||||||
|
continue; // Handled below.
|
||||||
|
}
|
||||||
html.setAttribute(key, value);
|
html.setAttribute(key, value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -112,6 +118,22 @@ class XfaLayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
// Set the value after the others to be sure overwrite
|
||||||
// any other values.
|
// any other values.
|
||||||
if (storage && attributes.dataId) {
|
if (storage && attributes.dataId) {
|
||||||
@ -121,11 +143,17 @@ class XfaLayer {
|
|||||||
|
|
||||||
static render(parameters) {
|
static render(parameters) {
|
||||||
const storage = parameters.annotationStorage;
|
const storage = parameters.annotationStorage;
|
||||||
|
const linkService = parameters.linkService;
|
||||||
const root = parameters.xfa;
|
const root = parameters.xfa;
|
||||||
const intent = parameters.intent || "display";
|
const intent = parameters.intent || "display";
|
||||||
const rootHtml = document.createElement(root.name);
|
const rootHtml = document.createElement(root.name);
|
||||||
if (root.attributes) {
|
if (root.attributes) {
|
||||||
this.setAttributes(rootHtml, root);
|
this.setAttributes({
|
||||||
|
html: rootHtml,
|
||||||
|
element: root,
|
||||||
|
intent,
|
||||||
|
linkService,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const stack = [[root, -1, rootHtml]];
|
const stack = [[root, -1, rootHtml]];
|
||||||
|
|
||||||
@ -169,7 +197,13 @@ class XfaLayer {
|
|||||||
|
|
||||||
html.appendChild(childHtml);
|
html.appendChild(childHtml);
|
||||||
if (child.attributes) {
|
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) {
|
if (child.children && child.children.length > 0) {
|
||||||
|
@ -334,6 +334,7 @@ var rasterizeXfaLayer = (function rasterizeXfaLayerClosure() {
|
|||||||
div,
|
div,
|
||||||
viewport: viewport.clone({ dontFlip: true }),
|
viewport: viewport.clone({ dontFlip: true }),
|
||||||
annotationStorage,
|
annotationStorage,
|
||||||
|
linkService: new SimpleLinkService(),
|
||||||
intent: isPrint ? "print" : "display",
|
intent: isPrint ? "print" : "display",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -640,10 +640,10 @@ describe("XFAFactory", function () {
|
|||||||
const pages = factory.getPages();
|
const pages = factory.getPages();
|
||||||
let a = searchHtmlNode(pages, "name", "a");
|
let a = searchHtmlNode(pages, "name", "a");
|
||||||
expect(a.attributes.href).toEqual("https://github.com/mozilla/pdf.js");
|
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]);
|
a = searchHtmlNode(pages, "name", "a", false, [1]);
|
||||||
expect(a.attributes.href).toEqual("https://github.com/allizom/pdf.js");
|
expect(a.attributes.href).toEqual("https://github.com/allizom/pdf.js");
|
||||||
expect(a.attributes.target).toBe(undefined);
|
expect(a.attributes.newWindow).toEqual(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1366,6 +1366,7 @@ class BaseViewer {
|
|||||||
pdfPage,
|
pdfPage,
|
||||||
annotationStorage:
|
annotationStorage:
|
||||||
annotationStorage || this.pdfDocument?.annotationStorage,
|
annotationStorage || this.pdfDocument?.annotationStorage,
|
||||||
|
linkService: this.linkService,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +63,13 @@ class IPDFLinkService {
|
|||||||
*/
|
*/
|
||||||
goToPage(val) {}
|
goToPage(val) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {HTMLAnchorElement} link
|
||||||
|
* @param {string} url
|
||||||
|
* @param {boolean} [newWindow]
|
||||||
|
*/
|
||||||
|
addLinkAttributes(link, url, newWindow = false) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param dest - The PDF destination object.
|
* @param dest - The PDF destination object.
|
||||||
* @returns {string} The hyperlink to the PDF object.
|
* @returns {string} The hyperlink to the PDF object.
|
||||||
@ -191,9 +198,16 @@ class IPDFXfaLayerFactory {
|
|||||||
/**
|
/**
|
||||||
* @param {HTMLDivElement} pageDiv
|
* @param {HTMLDivElement} pageDiv
|
||||||
* @param {PDFPage} pdfPage
|
* @param {PDFPage} pdfPage
|
||||||
|
* @param {AnnotationStorage} [annotationStorage]
|
||||||
|
* @param {Object} [xfaHtml]
|
||||||
* @returns {XfaLayerBuilder}
|
* @returns {XfaLayerBuilder}
|
||||||
*/
|
*/
|
||||||
createXfaLayerBuilder(pageDiv, pdfPage) {}
|
createXfaLayerBuilder(
|
||||||
|
pageDiv,
|
||||||
|
pdfPage,
|
||||||
|
annotationStorage = null,
|
||||||
|
xfaHtml = null
|
||||||
|
) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
/** @typedef {import("./interfaces").IPDFLinkService} IPDFLinkService */
|
/** @typedef {import("./interfaces").IPDFLinkService} IPDFLinkService */
|
||||||
|
|
||||||
|
import { addLinkAttributes, LinkTarget } from "pdfjs-lib";
|
||||||
import { parseQueryString } from "./ui_utils.js";
|
import { parseQueryString } from "./ui_utils.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -227,6 +228,21 @@ class PDFLinkService {
|
|||||||
this.pdfViewer.scrollPageIntoView({ pageNumber });
|
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.
|
* @param {string|Array} dest - The PDF destination object.
|
||||||
* @returns {string} The hyperlink to the PDF object.
|
* @returns {string} The hyperlink to the PDF object.
|
||||||
@ -514,10 +530,7 @@ function isValidExplicitDestination(dest) {
|
|||||||
*/
|
*/
|
||||||
class SimpleLinkService {
|
class SimpleLinkService {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.externalLinkTarget = null;
|
|
||||||
this.externalLinkRel = null;
|
|
||||||
this.externalLinkEnabled = true;
|
this.externalLinkEnabled = true;
|
||||||
this._ignoreDestinationZoom = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -561,6 +574,15 @@ class SimpleLinkService {
|
|||||||
*/
|
*/
|
||||||
goToPage(val) {}
|
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.
|
* @param dest - The PDF destination object.
|
||||||
* @returns {string} The hyperlink to the PDF object.
|
* @returns {string} The hyperlink to the PDF object.
|
||||||
|
@ -13,12 +13,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
|
||||||
addLinkAttributes,
|
|
||||||
createPromiseCapability,
|
|
||||||
LinkTarget,
|
|
||||||
} from "pdfjs-lib";
|
|
||||||
import { BaseTreeViewer } from "./base_tree_viewer.js";
|
import { BaseTreeViewer } from "./base_tree_viewer.js";
|
||||||
|
import { createPromiseCapability } from "pdfjs-lib";
|
||||||
import { SidebarView } from "./ui_utils.js";
|
import { SidebarView } from "./ui_utils.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -115,12 +111,7 @@ class PDFOutlineViewer extends BaseTreeViewer {
|
|||||||
const { linkService } = this;
|
const { linkService } = this;
|
||||||
|
|
||||||
if (url) {
|
if (url) {
|
||||||
addLinkAttributes(element, {
|
linkService.addLinkAttributes(element, url, newWindow);
|
||||||
url,
|
|
||||||
target: newWindow ? LinkTarget.BLANK : linkService.externalLinkTarget,
|
|
||||||
rel: linkService.externalLinkRel,
|
|
||||||
enabled: linkService.externalLinkEnabled,
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@ import { PDFSinglePageViewer } from "./pdf_single_page_viewer.js";
|
|||||||
* @property {HTMLButtonElement} printButton - Button to print the document.
|
* @property {HTMLButtonElement} printButton - Button to print the document.
|
||||||
* @property {HTMLButtonElement} downloadButton - Button to download the
|
* @property {HTMLButtonElement} downloadButton - Button to download the
|
||||||
* document.
|
* document.
|
||||||
* @property {HTMLLinkElement} viewBookmarkButton - Button to obtain a bookmark
|
* @property {HTMLAnchorElement} viewBookmarkButton - Button to obtain a
|
||||||
* link to the current location in the document.
|
* bookmark link to the current location in the document.
|
||||||
* @property {HTMLButtonElement} firstPageButton - Button to go to the first
|
* @property {HTMLButtonElement} firstPageButton - Button to go to the first
|
||||||
* page in the document.
|
* page in the document.
|
||||||
* @property {HTMLButtonElement} lastPageButton - Button to go to the last page
|
* @property {HTMLButtonElement} lastPageButton - Button to go to the last page
|
||||||
|
@ -43,8 +43,8 @@ const PAGE_NUMBER_LOADING_INDICATOR = "visiblePageIsLoading";
|
|||||||
* @property {HTMLButtonElement} presentationModeButton - Button to switch to
|
* @property {HTMLButtonElement} presentationModeButton - Button to switch to
|
||||||
* presentation mode.
|
* presentation mode.
|
||||||
* @property {HTMLButtonElement} download - Button to download the document.
|
* @property {HTMLButtonElement} download - Button to download the document.
|
||||||
* @property {HTMLAElement} viewBookmark - Element to link current url of
|
* @property {HTMLAnchorElement} viewBookmark - Button to obtain a bookmark link
|
||||||
* the page view.
|
* to the current location in the document.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Toolbar {
|
class Toolbar {
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
/** @typedef {import("./interfaces").IPDFXfaLayerFactory} IPDFXfaLayerFactory */
|
/** @typedef {import("./interfaces").IPDFXfaLayerFactory} IPDFXfaLayerFactory */
|
||||||
|
|
||||||
|
import { SimpleLinkService } from "./pdf_link_service.js";
|
||||||
import { XfaLayer } from "pdfjs-lib";
|
import { XfaLayer } from "pdfjs-lib";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -22,6 +23,7 @@ import { XfaLayer } from "pdfjs-lib";
|
|||||||
* @property {HTMLDivElement} pageDiv
|
* @property {HTMLDivElement} pageDiv
|
||||||
* @property {PDFPage} pdfPage
|
* @property {PDFPage} pdfPage
|
||||||
* @property {AnnotationStorage} [annotationStorage]
|
* @property {AnnotationStorage} [annotationStorage]
|
||||||
|
* @property {IPDFLinkService} linkService
|
||||||
* @property {Object} [xfaHtml]
|
* @property {Object} [xfaHtml]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -29,10 +31,11 @@ class XfaLayerBuilder {
|
|||||||
/**
|
/**
|
||||||
* @param {XfaLayerBuilderOptions} options
|
* @param {XfaLayerBuilderOptions} options
|
||||||
*/
|
*/
|
||||||
constructor({ pageDiv, pdfPage, annotationStorage, xfaHtml }) {
|
constructor({ pageDiv, pdfPage, annotationStorage, linkService, xfaHtml }) {
|
||||||
this.pageDiv = pageDiv;
|
this.pageDiv = pageDiv;
|
||||||
this.pdfPage = pdfPage;
|
this.pdfPage = pdfPage;
|
||||||
this.annotationStorage = annotationStorage;
|
this.annotationStorage = annotationStorage;
|
||||||
|
this.linkService = linkService;
|
||||||
this.xfaHtml = xfaHtml;
|
this.xfaHtml = xfaHtml;
|
||||||
|
|
||||||
this.div = null;
|
this.div = null;
|
||||||
@ -54,6 +57,7 @@ class XfaLayerBuilder {
|
|||||||
xfa: this.xfaHtml,
|
xfa: this.xfaHtml,
|
||||||
page: null,
|
page: null,
|
||||||
annotationStorage: this.annotationStorage,
|
annotationStorage: this.annotationStorage,
|
||||||
|
linkService: this.linkService,
|
||||||
intent,
|
intent,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -80,6 +84,7 @@ class XfaLayerBuilder {
|
|||||||
xfa,
|
xfa,
|
||||||
page: this.pdfPage,
|
page: this.pdfPage,
|
||||||
annotationStorage: this.annotationStorage,
|
annotationStorage: this.annotationStorage,
|
||||||
|
linkService: this.linkService,
|
||||||
intent,
|
intent,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -129,6 +134,7 @@ class DefaultXfaLayerFactory {
|
|||||||
pageDiv,
|
pageDiv,
|
||||||
pdfPage,
|
pdfPage,
|
||||||
annotationStorage,
|
annotationStorage,
|
||||||
|
linkService: new SimpleLinkService(),
|
||||||
xfaHtml,
|
xfaHtml,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user