Skip to content

Commit

Permalink
Merge pull request #5952 from Snuffleupagus/api-externalLinkTarget
Browse files Browse the repository at this point in the history
[api-minor] Add an option to PDFJS for specifying the |target| attribute of external links (bug 976541)
  • Loading branch information
brendandahl committed Oct 13, 2015
2 parents d89fde0 + 610df45 commit 2096a2a
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 10 deletions.
7 changes: 4 additions & 3 deletions src/display/annotation_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* limitations under the License.
*/
/* globals PDFJS, Util, AnnotationType, AnnotationBorderStyleType, warn,
CustomStyle */
CustomStyle, isExternalLinkTargetSet, LinkTargetStringMap */

'use strict';

Expand Down Expand Up @@ -261,8 +261,9 @@ var AnnotationUtils = (function AnnotationUtilsClosure() {

var link = document.createElement('a');
link.href = link.title = item.url || '';
if (item.url && PDFJS.openExternalLinksInNewWindow) {
link.target = '_blank';

if (item.url && isExternalLinkTargetSet()) {
link.target = LinkTargetStringMap[PDFJS.externalLinkTarget];
}

container.appendChild(link);
Expand Down
17 changes: 15 additions & 2 deletions src/display/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,14 +169,27 @@ PDFJS.maxCanvasPixels = (PDFJS.maxCanvasPixels === undefined ?
16777216 : PDFJS.maxCanvasPixels);

/**
* Opens external links in a new window if enabled. The default behavior opens
* external links in the PDF.js window.
* (Deprecated) Opens external links in a new window if enabled.
* The default behavior opens external links in the PDF.js window.
* @var {boolean}
*/
PDFJS.openExternalLinksInNewWindow = (
PDFJS.openExternalLinksInNewWindow === undefined ?
false : PDFJS.openExternalLinksInNewWindow);

/**
* Specifies the |target| attribute for external links.
* The constants from PDFJS.LinkTarget should be used:
* - NONE [default]
* - SELF
* - BLANK
* - PARENT
* - TOP
* @var {number}
*/
PDFJS.externalLinkTarget = (PDFJS.externalLinkTarget === undefined ?
PDFJS.LinkTarget.NONE : PDFJS.externalLinkTarget);

/**
* Determines if we can eval strings as JS. Primarily used to improve
* performance for font rendering.
Expand Down
43 changes: 43 additions & 0 deletions src/shared/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,49 @@ function shadow(obj, prop, value) {
}
PDFJS.shadow = shadow;

var LinkTarget = PDFJS.LinkTarget = {
NONE: 0, // Default value.
SELF: 1,
BLANK: 2,
PARENT: 3,
TOP: 4,
};
var LinkTargetStringMap = [
'',
'_self',
'_blank',
'_parent',
'_top'
];

function isExternalLinkTargetSet() {
//#if GENERIC
if (PDFJS.openExternalLinksInNewWindow) {
warn('PDFJS.openExternalLinksInNewWindow is deprecated, ' +
'use PDFJS.externalLinkTarget instead.');
if (PDFJS.externalLinkTarget === LinkTarget.NONE) {
PDFJS.externalLinkTarget = LinkTarget.BLANK;
}
// Reset the deprecated parameter, to suppress further warnings.
PDFJS.openExternalLinksInNewWindow = false;
}
//#endif
switch (PDFJS.externalLinkTarget) {
case LinkTarget.NONE:
return false;
case LinkTarget.SELF:
case LinkTarget.BLANK:
case LinkTarget.PARENT:
case LinkTarget.TOP:
return true;
}
warn('PDFJS.externalLinkTarget is invalid: ' + PDFJS.externalLinkTarget);
// Reset the external link target, to suppress further warnings.
PDFJS.externalLinkTarget = LinkTarget.NONE;
return false;
}
PDFJS.isExternalLinkTargetSet = isExternalLinkTargetSet;

var PasswordResponses = PDFJS.PasswordResponses = {
NEED_PASSWORD: 1,
INCORRECT_PASSWORD: 2
Expand Down
32 changes: 30 additions & 2 deletions test/unit/util_spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* globals expect, it, describe, combineUrl, Dict, isDict, Name,
stringToPDFString */
/* globals expect, it, describe, combineUrl, Dict, isDict, Name, PDFJS,
stringToPDFString, isExternalLinkTargetSet, LinkTarget */

'use strict';

Expand Down Expand Up @@ -99,4 +99,32 @@ describe('util', function() {
expect(stringToPDFString(str2)).toEqual('');
});
});

describe('isExternalLinkTargetSet', function() {
// Save the current state, to avoid interfering with other tests.
var previousExternalLinkTarget = PDFJS.externalLinkTarget;

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);
}
});

// Reset the state.
PDFJS.externalLinkTarget = previousExternalLinkTarget;
});
});
3 changes: 2 additions & 1 deletion web/default_preferences.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ var DEFAULT_PREFERENCES = {
disableAutoFetch: false,
disableFontFace: false,
disableTextLayer: false,
useOnlyCssZoom: false
useOnlyCssZoom: false,
externalLinkTarget: 0,
};
16 changes: 14 additions & 2 deletions web/viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,12 +288,24 @@ var PDFViewerApplication = {
}),
Preferences.get('useOnlyCssZoom').then(function resolved(value) {
PDFJS.useOnlyCssZoom = value;
})
}),
Preferences.get('externalLinkTarget').then(function resolved(value) {
if (PDFJS.isExternalLinkTargetSet()) {
return;
}
PDFJS.externalLinkTarget = value;
}),
// TODO move more preferences and other async stuff here
]).catch(function (reason) { });

return initializedPromise.then(function () {
PDFViewerApplication.initialized = true;
if (self.isViewerEmbedded && !PDFJS.isExternalLinkTargetSet()) {
// Prevent external links from "replacing" the viewer,
// when it's embedded in e.g. an iframe or an object.
PDFJS.externalLinkTarget = PDFJS.LinkTarget.TOP;
}

self.initialized = true;
});
},

Expand Down

0 comments on commit 2096a2a

Please sign in to comment.