Move the externalLinkTarget
and externalLinkRel
options to PDFLinkService
options
This removes the `PDFJS.externalLinkTarget`/`PDFJS.externalLinkRel` dependency from the viewer components, but please note that as a *temporary* solution the default viewer still uses it.
This commit is contained in:
parent
c45c394364
commit
3a6f6d23d6
@ -281,17 +281,21 @@ class LinkAnnotationElement extends AnnotationElement {
|
|||||||
render() {
|
render() {
|
||||||
this.container.className = 'linkAnnotation';
|
this.container.className = 'linkAnnotation';
|
||||||
|
|
||||||
|
let { data, linkService, } = this;
|
||||||
let link = document.createElement('a');
|
let link = document.createElement('a');
|
||||||
|
|
||||||
addLinkAttributes(link, {
|
addLinkAttributes(link, {
|
||||||
url: this.data.url,
|
url: data.url,
|
||||||
target: (this.data.newWindow ? LinkTarget.BLANK : undefined),
|
target: (data.newWindow ?
|
||||||
|
LinkTarget.BLANK : linkService.externalLinkTarget),
|
||||||
|
rel: linkService.externalLinkRel,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!this.data.url) {
|
if (!data.url) {
|
||||||
if (this.data.action) {
|
if (data.action) {
|
||||||
this._bindNamedAction(link, this.data.action);
|
this._bindNamedAction(link, data.action);
|
||||||
} else {
|
} else {
|
||||||
this._bindLink(link, this.data.dest);
|
this._bindLink(link, data.dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,7 +274,7 @@ var RenderingCancelledException = (function RenderingCancelledException() {
|
|||||||
return RenderingCancelledException;
|
return RenderingCancelledException;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
var LinkTarget = {
|
const LinkTarget = {
|
||||||
NONE: 0, // Default value.
|
NONE: 0, // Default value.
|
||||||
SELF: 1,
|
SELF: 1,
|
||||||
BLANK: 2,
|
BLANK: 2,
|
||||||
@ -282,7 +282,7 @@ var LinkTarget = {
|
|||||||
TOP: 4,
|
TOP: 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
var LinkTargetStringMap = [
|
const LinkTargetStringMap = [
|
||||||
'',
|
'',
|
||||||
'_self',
|
'_self',
|
||||||
'_blank',
|
'_blank',
|
||||||
@ -294,8 +294,10 @@ var LinkTargetStringMap = [
|
|||||||
* @typedef ExternalLinkParameters
|
* @typedef ExternalLinkParameters
|
||||||
* @typedef {Object} ExternalLinkParameters
|
* @typedef {Object} ExternalLinkParameters
|
||||||
* @property {string} url - An absolute URL.
|
* @property {string} url - An absolute URL.
|
||||||
* @property {LinkTarget} target - The link target.
|
* @property {LinkTarget} target - (optional) The link target.
|
||||||
* @property {string} rel - The link relationship.
|
* The default value is `LinkTarget.NONE`.
|
||||||
|
* @property {string} rel - (optional) The link relationship.
|
||||||
|
* The default value is `DEFAULT_LINK_REL`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -303,22 +305,16 @@ var LinkTargetStringMap = [
|
|||||||
* @param {HTMLLinkElement} link - The link element.
|
* @param {HTMLLinkElement} link - The link element.
|
||||||
* @param {ExternalLinkParameters} params
|
* @param {ExternalLinkParameters} params
|
||||||
*/
|
*/
|
||||||
function addLinkAttributes(link, params) {
|
function addLinkAttributes(link, { url, target, rel, } = {}) {
|
||||||
var url = params && params.url;
|
|
||||||
link.href = link.title = (url ? removeNullCharacters(url) : '');
|
link.href = link.title = (url ? removeNullCharacters(url) : '');
|
||||||
|
|
||||||
if (url) {
|
if (url) {
|
||||||
var target = params.target;
|
const LinkTargetValues = Object.values(LinkTarget);
|
||||||
if (typeof target === 'undefined') {
|
let targetIndex =
|
||||||
target = getDefaultSetting('externalLinkTarget');
|
LinkTargetValues.includes(target) ? target : LinkTarget.NONE;
|
||||||
}
|
link.target = LinkTargetStringMap[targetIndex];
|
||||||
link.target = LinkTargetStringMap[target];
|
|
||||||
|
|
||||||
var rel = params.rel;
|
link.rel = (typeof rel === 'string' ? rel : DEFAULT_LINK_REL);
|
||||||
if (typeof rel === 'undefined') {
|
|
||||||
rel = getDefaultSetting('externalLinkRel');
|
|
||||||
}
|
|
||||||
link.rel = rel;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,25 +361,6 @@ function getDefaultSetting(id) {
|
|||||||
return globalSettings ? globalSettings.maxImageSize : -1;
|
return globalSettings ? globalSettings.maxImageSize : -1;
|
||||||
case 'isEvalSupported':
|
case 'isEvalSupported':
|
||||||
return globalSettings ? globalSettings.isEvalSupported : true;
|
return globalSettings ? globalSettings.isEvalSupported : true;
|
||||||
case 'externalLinkTarget':
|
|
||||||
if (!globalSettings) {
|
|
||||||
return LinkTarget.NONE;
|
|
||||||
}
|
|
||||||
switch (globalSettings.externalLinkTarget) {
|
|
||||||
case LinkTarget.NONE:
|
|
||||||
case LinkTarget.SELF:
|
|
||||||
case LinkTarget.BLANK:
|
|
||||||
case LinkTarget.PARENT:
|
|
||||||
case LinkTarget.TOP:
|
|
||||||
return globalSettings.externalLinkTarget;
|
|
||||||
}
|
|
||||||
warn('PDFJS.externalLinkTarget is invalid: ' +
|
|
||||||
globalSettings.externalLinkTarget);
|
|
||||||
// Reset the external link target, to suppress further warnings.
|
|
||||||
globalSettings.externalLinkTarget = LinkTarget.NONE;
|
|
||||||
return LinkTarget.NONE;
|
|
||||||
case 'externalLinkRel':
|
|
||||||
return globalSettings ? globalSettings.externalLinkRel : DEFAULT_LINK_REL;
|
|
||||||
case 'enableStats':
|
case 'enableStats':
|
||||||
return !!(globalSettings && globalSettings.enableStats);
|
return !!(globalSettings && globalSettings.enableStats);
|
||||||
default:
|
default:
|
||||||
@ -391,19 +368,6 @@ function getDefaultSetting(id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isExternalLinkTargetSet() {
|
|
||||||
var externalLinkTarget = getDefaultSetting('externalLinkTarget');
|
|
||||||
switch (externalLinkTarget) {
|
|
||||||
case LinkTarget.NONE:
|
|
||||||
return false;
|
|
||||||
case LinkTarget.SELF:
|
|
||||||
case LinkTarget.BLANK:
|
|
||||||
case LinkTarget.PARENT:
|
|
||||||
case LinkTarget.TOP:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class StatTimer {
|
class StatTimer {
|
||||||
constructor(enable = true) {
|
constructor(enable = true) {
|
||||||
this.enabled = !!enable;
|
this.enabled = !!enable;
|
||||||
@ -481,7 +445,6 @@ class DummyStatTimer {
|
|||||||
export {
|
export {
|
||||||
RenderingCancelledException,
|
RenderingCancelledException,
|
||||||
addLinkAttributes,
|
addLinkAttributes,
|
||||||
isExternalLinkTargetSet,
|
|
||||||
getFilenameFromUrl,
|
getFilenameFromUrl,
|
||||||
LinkTarget,
|
LinkTarget,
|
||||||
getDefaultSetting,
|
getDefaultSetting,
|
||||||
|
@ -13,10 +13,6 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
|
||||||
addLinkAttributes, DEFAULT_LINK_REL, getFilenameFromUrl,
|
|
||||||
isExternalLinkTargetSet, isValidUrl, LinkTarget
|
|
||||||
} from './dom_utils';
|
|
||||||
import {
|
import {
|
||||||
createBlob, createObjectURL, createPromiseCapability, getVerbosityLevel,
|
createBlob, createObjectURL, createPromiseCapability, getVerbosityLevel,
|
||||||
InvalidPDFException, isLittleEndian, MissingPDFException, OPS, PageViewport,
|
InvalidPDFException, isLittleEndian, MissingPDFException, OPS, PageViewport,
|
||||||
@ -24,6 +20,7 @@ import {
|
|||||||
shadow, UnexpectedResponseException, UnknownErrorException,
|
shadow, UnexpectedResponseException, UnknownErrorException,
|
||||||
UNSUPPORTED_FEATURES, Util, VERBOSITY_LEVELS
|
UNSUPPORTED_FEATURES, Util, VERBOSITY_LEVELS
|
||||||
} from '../shared/util';
|
} from '../shared/util';
|
||||||
|
import { DEFAULT_LINK_REL, getFilenameFromUrl, LinkTarget } from './dom_utils';
|
||||||
import {
|
import {
|
||||||
getDocument, LoopbackPort, PDFDataRangeTransport, PDFWorker
|
getDocument, LoopbackPort, PDFDataRangeTransport, PDFWorker
|
||||||
} from './api';
|
} from './api';
|
||||||
@ -67,7 +64,6 @@ Object.defineProperty(PDFJS, 'verbosity', {
|
|||||||
PDFJS.VERBOSITY_LEVELS = VERBOSITY_LEVELS;
|
PDFJS.VERBOSITY_LEVELS = VERBOSITY_LEVELS;
|
||||||
PDFJS.OPS = OPS;
|
PDFJS.OPS = OPS;
|
||||||
PDFJS.UNSUPPORTED_FEATURES = UNSUPPORTED_FEATURES;
|
PDFJS.UNSUPPORTED_FEATURES = UNSUPPORTED_FEATURES;
|
||||||
PDFJS.isValidUrl = isValidUrl;
|
|
||||||
PDFJS.shadow = shadow;
|
PDFJS.shadow = shadow;
|
||||||
PDFJS.createBlob = createBlob;
|
PDFJS.createBlob = createBlob;
|
||||||
PDFJS.createObjectURL = function PDFJS_createObjectURL(data, contentType) {
|
PDFJS.createObjectURL = function PDFJS_createObjectURL(data, contentType) {
|
||||||
@ -193,7 +189,7 @@ PDFJS.disableWebGL = (PDFJS.disableWebGL === undefined ?
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies the |target| attribute for external links.
|
* Specifies the |target| attribute for external links.
|
||||||
* The constants from PDFJS.LinkTarget should be used:
|
* The constants from {LinkTarget} should be used:
|
||||||
* - NONE [default]
|
* - NONE [default]
|
||||||
* - SELF
|
* - SELF
|
||||||
* - BLANK
|
* - BLANK
|
||||||
@ -225,10 +221,7 @@ PDFJS.LoopbackPort = LoopbackPort;
|
|||||||
PDFJS.PDFDataRangeTransport = PDFDataRangeTransport;
|
PDFJS.PDFDataRangeTransport = PDFDataRangeTransport;
|
||||||
PDFJS.PDFWorker = PDFWorker;
|
PDFJS.PDFWorker = PDFWorker;
|
||||||
|
|
||||||
PDFJS.LinkTarget = LinkTarget;
|
|
||||||
PDFJS.addLinkAttributes = addLinkAttributes;
|
|
||||||
PDFJS.getFilenameFromUrl = getFilenameFromUrl;
|
PDFJS.getFilenameFromUrl = getFilenameFromUrl;
|
||||||
PDFJS.isExternalLinkTargetSet = isExternalLinkTargetSet;
|
|
||||||
|
|
||||||
PDFJS.AnnotationLayer = AnnotationLayer;
|
PDFJS.AnnotationLayer = AnnotationLayer;
|
||||||
|
|
||||||
|
@ -91,4 +91,5 @@ exports.createBlob = pdfjsSharedUtil.createBlob;
|
|||||||
exports.RenderingCancelledException =
|
exports.RenderingCancelledException =
|
||||||
pdfjsDisplayDOMUtils.RenderingCancelledException;
|
pdfjsDisplayDOMUtils.RenderingCancelledException;
|
||||||
exports.getFilenameFromUrl = pdfjsDisplayDOMUtils.getFilenameFromUrl;
|
exports.getFilenameFromUrl = pdfjsDisplayDOMUtils.getFilenameFromUrl;
|
||||||
|
exports.LinkTarget = pdfjsDisplayDOMUtils.LinkTarget;
|
||||||
exports.addLinkAttributes = pdfjsDisplayDOMUtils.addLinkAttributes;
|
exports.addLinkAttributes = pdfjsDisplayDOMUtils.addLinkAttributes;
|
||||||
|
@ -13,11 +13,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import { DOMSVGFactory, getFilenameFromUrl } from '../../src/display/dom_utils';
|
||||||
DOMSVGFactory, getFilenameFromUrl, isExternalLinkTargetSet, LinkTarget
|
|
||||||
} from '../../src/display/dom_utils';
|
|
||||||
import isNodeJS from '../../src/shared/is_node';
|
import isNodeJS from '../../src/shared/is_node';
|
||||||
import { PDFJS } from '../../src/display/global';
|
|
||||||
|
|
||||||
describe('dom_utils', function() {
|
describe('dom_utils', function() {
|
||||||
describe('DOMSVGFactory', function() {
|
describe('DOMSVGFactory', function() {
|
||||||
@ -95,37 +92,4 @@ describe('dom_utils', function() {
|
|||||||
expect(result).toEqual(expected);
|
expect(result).toEqual(expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('isExternalLinkTargetSet', function() {
|
|
||||||
var savedExternalLinkTarget;
|
|
||||||
|
|
||||||
beforeAll(function (done) {
|
|
||||||
savedExternalLinkTarget = PDFJS.externalLinkTarget;
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(function () {
|
|
||||||
PDFJS.externalLinkTarget = savedExternalLinkTarget;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('handles the predefined LinkTargets', function() {
|
|
||||||
for (var key in LinkTarget) {
|
|
||||||
var linkTarget = LinkTarget[key];
|
|
||||||
PDFJS.externalLinkTarget = linkTarget;
|
|
||||||
|
|
||||||
expect(isExternalLinkTargetSet()).toEqual(!!linkTarget);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('handles incorrect LinkTargets', function() {
|
|
||||||
var targets = [true, '', false, -1, '_blank', null];
|
|
||||||
|
|
||||||
for (var i = 0, ii = targets.length; i < ii; i++) {
|
|
||||||
var linkTarget = targets[i];
|
|
||||||
PDFJS.externalLinkTarget = linkTarget;
|
|
||||||
|
|
||||||
expect(isExternalLinkTargetSet()).toEqual(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
11
web/app.js
11
web/app.js
@ -22,7 +22,7 @@ import {
|
|||||||
} from './ui_utils';
|
} from './ui_utils';
|
||||||
import {
|
import {
|
||||||
build, createBlob, getDocument, getFilenameFromUrl, InvalidPDFException,
|
build, createBlob, getDocument, getFilenameFromUrl, InvalidPDFException,
|
||||||
MissingPDFException, OPS, PDFJS, PDFWorker, shadow,
|
LinkTarget, MissingPDFException, OPS, PDFJS, PDFWorker, shadow,
|
||||||
UnexpectedResponseException, UNSUPPORTED_FEATURES, version
|
UnexpectedResponseException, UNSUPPORTED_FEATURES, version
|
||||||
} from 'pdfjs-lib';
|
} from 'pdfjs-lib';
|
||||||
import { CursorTool, PDFCursorTools } from './pdf_cursor_tools';
|
import { CursorTool, PDFCursorTools } from './pdf_cursor_tools';
|
||||||
@ -184,10 +184,11 @@ let PDFViewerApplication = {
|
|||||||
this.eventBus.dispatch('localized');
|
this.eventBus.dispatch('localized');
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.isViewerEmbedded && !PDFJS.isExternalLinkTargetSet()) {
|
if (this.isViewerEmbedded &&
|
||||||
|
PDFJS.externalLinkTarget === LinkTarget.NONE) {
|
||||||
// Prevent external links from "replacing" the viewer,
|
// Prevent external links from "replacing" the viewer,
|
||||||
// when it's embedded in e.g. an iframe or an object.
|
// when it's embedded in e.g. an iframe or an object.
|
||||||
PDFJS.externalLinkTarget = PDFJS.LinkTarget.TOP;
|
PDFJS.externalLinkTarget = LinkTarget.TOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
@ -250,7 +251,7 @@ let PDFViewerApplication = {
|
|||||||
PDFJS.useOnlyCssZoom = value;
|
PDFJS.useOnlyCssZoom = value;
|
||||||
}),
|
}),
|
||||||
preferences.get('externalLinkTarget').then(function resolved(value) {
|
preferences.get('externalLinkTarget').then(function resolved(value) {
|
||||||
if (PDFJS.isExternalLinkTargetSet()) {
|
if (PDFJS.externalLinkTarget !== LinkTarget.NONE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PDFJS.externalLinkTarget = value;
|
PDFJS.externalLinkTarget = value;
|
||||||
@ -378,6 +379,8 @@ let PDFViewerApplication = {
|
|||||||
|
|
||||||
let pdfLinkService = new PDFLinkService({
|
let pdfLinkService = new PDFLinkService({
|
||||||
eventBus,
|
eventBus,
|
||||||
|
externalLinkTarget: PDFJS.externalLinkTarget,
|
||||||
|
externalLinkRel: PDFJS.externalLinkRel,
|
||||||
});
|
});
|
||||||
this.pdfLinkService = pdfLinkService;
|
this.pdfLinkService = pdfLinkService;
|
||||||
|
|
||||||
|
@ -19,6 +19,11 @@ import { parseQueryString } from './ui_utils';
|
|||||||
/**
|
/**
|
||||||
* @typedef {Object} PDFLinkServiceOptions
|
* @typedef {Object} PDFLinkServiceOptions
|
||||||
* @property {EventBus} eventBus - The application event bus.
|
* @property {EventBus} eventBus - The application event bus.
|
||||||
|
* @property {number} externalLinkTarget - (optional) Specifies the `target`
|
||||||
|
* attribute for external links. Must use one of the values from {LinkTarget}.
|
||||||
|
* Defaults to using no target.
|
||||||
|
* @property {string} externalLinkRel - (optional) Specifies the `rel` attribute
|
||||||
|
* for external links. Defaults to stripping the referrer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,8 +35,12 @@ class PDFLinkService {
|
|||||||
/**
|
/**
|
||||||
* @param {PDFLinkServiceOptions} options
|
* @param {PDFLinkServiceOptions} options
|
||||||
*/
|
*/
|
||||||
constructor({ eventBus, } = {}) {
|
constructor({ eventBus, externalLinkTarget = null,
|
||||||
|
externalLinkRel = null, } = {}) {
|
||||||
this.eventBus = eventBus || getGlobalEventBus();
|
this.eventBus = eventBus || getGlobalEventBus();
|
||||||
|
this.externalLinkTarget = externalLinkTarget;
|
||||||
|
this.externalLinkRel = externalLinkRel;
|
||||||
|
|
||||||
this.baseUrl = null;
|
this.baseUrl = null;
|
||||||
this.pdfDocument = null;
|
this.pdfDocument = null;
|
||||||
this.pdfViewer = null;
|
this.pdfViewer = null;
|
||||||
@ -409,6 +418,11 @@ function isValidExplicitDestination(dest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class SimpleLinkService {
|
class SimpleLinkService {
|
||||||
|
constructor() {
|
||||||
|
this.externalLinkTarget = null;
|
||||||
|
this.externalLinkRel = null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {number}
|
* @returns {number}
|
||||||
*/
|
*/
|
||||||
|
@ -13,9 +13,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import { addLinkAttributes, LinkTarget, removeNullCharacters } from 'pdfjs-lib';
|
||||||
addLinkAttributes, PDFJS, removeNullCharacters
|
|
||||||
} from 'pdfjs-lib';
|
|
||||||
|
|
||||||
const DEFAULT_TITLE = '\u2013';
|
const DEFAULT_TITLE = '\u2013';
|
||||||
|
|
||||||
@ -68,20 +66,22 @@ class PDFOutlineViewer {
|
|||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_bindLink(element, item) {
|
_bindLink(element, { url, newWindow, dest, }) {
|
||||||
if (item.url) {
|
let { linkService, } = this;
|
||||||
|
|
||||||
|
if (url) {
|
||||||
addLinkAttributes(element, {
|
addLinkAttributes(element, {
|
||||||
url: item.url,
|
url,
|
||||||
target: (item.newWindow ? PDFJS.LinkTarget.BLANK : undefined),
|
target: (newWindow ? LinkTarget.BLANK : linkService.externalLinkTarget),
|
||||||
|
rel: linkService.externalLinkRel,
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let destination = item.dest;
|
|
||||||
|
|
||||||
element.href = this.linkService.getDestinationHash(destination);
|
element.href = this.linkService.getDestinationHash(dest);
|
||||||
element.onclick = () => {
|
element.onclick = () => {
|
||||||
if (destination) {
|
if (dest) {
|
||||||
this.linkService.navigateTo(destination);
|
this.linkService.navigateTo(dest);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
@ -90,12 +90,12 @@ class PDFOutlineViewer {
|
|||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_setStyles(element, item) {
|
_setStyles(element, { bold, italic, }) {
|
||||||
let styleStr = '';
|
let styleStr = '';
|
||||||
if (item.bold) {
|
if (bold) {
|
||||||
styleStr += 'font-weight: bold;';
|
styleStr += 'font-weight: bold;';
|
||||||
}
|
}
|
||||||
if (item.italic) {
|
if (italic) {
|
||||||
styleStr += 'font-style: italic;';
|
styleStr += 'font-style: italic;';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user