How to disable hyperlinks within a PDF rendered by PDF.js - javascript

I'm looking into PDF.js for use in a web app. So far, it's meeting all of our business requirements. However, management has requested that we have the ability to disable hyperlinks within the PDF. We don't necessarily have to get rid of the blue text and underline, but if the user clicks on the hyperlink, it shouldn't go anywhere.
I've looked carefully through what API there is and couldn't find anything for it. I also looked through the source code, but nothing jumped out at me as something I could comment out in order to disable hyperlinks. Is there any way to disable hyperlinks contained within a PDF?

After a great deal of experimentation, I found out how to do this by modifying the source. There is a block of code that begins with the following:
document.addEventListener('pagerendered', function (e) {
At the end of the function before the close bracket, add the following code:
var allowInternalLinks = true;
var page = document.getElementById('pageContainer' + pageNumber);
var hyperlinks = page.getElementsByTagName('a');
for (var i=0; i<hyperlinks.length; i++){
if (!allowInternalLinks || hyperlinks[i].className != 'internalLink'){
hyperlinks[i].onclick = function(e) {
e.preventDefault();
}
}
};
What this does is take the rendered page, iterate through all of the hyperlinks on that page, and disable them. I have also added a boolean variable that allows you to optionally allow or disallow internal links (i.e. links that take the user to another location within the document).

Related

Using digital signature and image input button in one file

I need to create PDF forms using Antenna House Formatter.
The forms need to have both digital-signature and image-input fields.
The digital signature with AHF-CSS works on its own:
input.signature{
display: -ah-form-field;
-ah-field-type: signature;
}
As does the image-input HTML/JavaScript:
<meta name="openaction"
content="#JavaScript=
var f = this.getField('imageInput');
f.setAction('MouseUp', 'event.target.buttonImportIcon();');
"/>
But if I use both together and try to enter a digital signature I get the message:
The document cannot be signed in its current state. Please save the
document, close it, reopen it, and then attempt to sign again.
Saving and reopening does not fix the problem. Is there a way to resolve this?
I had to ask Antenna House Support about this. (You could do it if your maintenance is current.) Their answer:
I don't think it will be possible with Formatter and CSS. The 'OpenAction' script modifies the document with this code:
f.setAction('MouseUp', 'event.target.buttonImportIcon();');
Even if you save the document the 'OpenAction' script will run again and modify it.
With XSL-FO you could avoid an OpenAction script by just setting the 'MouseUp' value directly:
<axf:form-field-event name="MouseUp" action-type="javascript">
event.target.buttonImportIcon();
</axf:form-field-event>
'form-field-event' isn't available with CSS.
One horrible work around is to add a check in the 'OpenAction' script to see if the button was already modified. Ex:
var f = this.getField('imageInput');
if (color.equal(f.fillColor, color.red)) {
/* do nothing, this will happen after document is saved */
} else {
f.fillColor = color.red;
f.setAction('MouseUp', 'event.target.buttonImportIcon();');
}
You could 'save' the Formatter generated PDF in Acrobat and then the saved result could get the signature.
There might also or instead be a place to set this.dirty = false; so that the document isn't seen as modified. (I've previously used this.dirty = false; in a JavaScript function that toggles layers off and on: I didn't want to be prompted to save the document on closing just because some layers had changed visibility.)

jQuery Replace Breaking Links in Site

So, I'm experiencing an issue when using jQuery to replace phone numbers and certain texts in paragraphs. What's happening is when I use the bit of jQuery below, it either hides or diables links in in my pages. In most of the sites we build, all we want is to replace phone numbers sitewide and not regular text. In the code below, I'm only trying to exclude the site-title because it get wrapped automatically in a <p> tag and if I don't exclude it, it kills the website's main logo.
Help!
jQuery(function($) {
// NUM SWAP
$('p').not('.site-title').each(function() {
var num1 = $(this).text().replace(/800-218-4243/g, "844-853-7373");
$(this).text(num1);
});
$('p').not('.site-title').each(function() {
var num2 = $(this).text().replace(/330-836-0210/g, "844-853-7373");
$(this).text(num2);
});
});
EDIT/UPDATE WITH SOME MORE INFO:
Replacing of the number in the browser is for call tracking for our clients and to preserve the SEO strength of the original phone number. Below is a page link to look at. I'd like you to check the page with javascript enabled and then disabled. For example, have a look at the author name link and comment link just below the title of the blog post and you'll see that with javascript enabled, the links disappear Then, when you disable javascript, the links return as well as a couple of blue buttons 'See Tetimonials' & 'See Case Results' in the sidebar return too.
http://1ohio.us/worst-vehicle-models-for-personal-injury-insurance-claims

How can I make a "reverse preventDefault" in jQuery?

In Private Logistics: Privacy-Sensitive Calendar, Todo, and Personal Information Management, data that is entered can be edited with a click, and there is support for either entering a link as <a href="... or entering a URL, which will be linkified.
This works great but it presents a problem when someone clicks on a link. The desired behavior is for the link to open and not to put the snippet of text into edit mode, which is the reverse of the usual pattern implemented by event.preventDefault()' or '...return false;}. (Clicks outside the link on the element should put the containing element in edit mode, same as a container that doesn't happen to have a link.)
How can I reverse the more common pattern using jQuery? My best guess now is to attempt introspection on the event target and see if it is an anchor. But that's just a best guess; I have seen plenty of examples of the pattern that would cancel the link loading another page but performing the added Ajax functionality of putting the container into edit mode; I'm not sure I've seen the reverse of that pattern which would follow the link and not put the container into edit mode.
I also see a way to dodge the matter by having links load in the same page, but that's the sort of solution I'd prefer to only adopt if there are intractable issues with implementation or the like.
Generally, you don't want to clean up your broad strokes, instead, don't make such broad strokes. Use an if statement prior to running e.preventDefault().
Something like:
var preventedLinks = $('a.preventthislink');
$('a').click(function(e){
if ($(this).index(preventedLinks) != -1) {
e.preventDefault();
}
});
you could alternatively just change the class of whatever you are preventing default on:
$(document).ready(function(){
$('.blue').removeClass('blue').addClass('green');
});

Detecting & displaying links in a form's text area

When I enter a link (video, image, URL, etc.) in Facebook's "What's on your mind?" form, it auto-detects the link and converts it to a thumbnail with a brief description below the text-area. Can anyone provide me with insight or a link to get me going on how to achieve this?
There's a javascript attached to the textarea change event. The javascript detects if the content of the textarea is a url, if it is, the javascript call a webservice that visit the url looking for the page title, the page description, etc, (or the open graph protocol meta tags), if it find each one of the tags they are returned to the javascript who proper organize then.
Facebook also cache this content, and if the same url is posted by another user, he uses the cache values instead of revisiting the page.
The open graph protocol meta tags:
http://developers.facebook.com/docs/opengraphprotocol/
using something like
var input = document.getElementById("textarea");
input.addEventListener("change", checkLink(e));
input.addEventListener("blur", checkLink(e));
function checkText(text){
var exp = "((ht|f)tp(s?))(:((\/\/)(?!\/)))(((w){3}\.)?)([a-zA-Z0-9\-_]+(\.(com|edu|gov|int|mil|net|org|biz|info|name|pro|museum|co\.uk)))(\/(?!\/))(([a-zA-Z0-9\-_\/]*)?)([a-zA-Z0-9])+\.((jpg|jpeg|gif|png)(?!(\w|\W)))";
return text.match(exp);
}
function checkLink(e){
//here you would want to use a regular expression and check for http:
var regularExpression = !!checkText(e.target.innerHTML); // returns true or false
if(regularExpression){
e.target.innerHTML += "<a href='#'><img src="" alt="" /></a>";
}
}
good resource for regular expressions - http://regexlib.com/Search.aspx?k=image&c=-1&m=-1&ps=20
Warning -- have to leave for work so regular expressions are not checked.
Take the link value and run it through a regular expression that looks for ^http:...[^\s] or ^https:...[^\s] and returns those.
Then, pass those URLs to your server and have your server retrieve the document and return a snippit for you to then put in your document. You must have your own server to help because Javascript, by itself, has security restrictions. Google same origin policy for more info.

Deeplinking div blocks

I am looking for a way to deep link div blocks. On a particular page I might have several div blocks each with its own contents. One of this blocks is visible, others are hidden. Once a link or a button is pressed the corresponding div is shown and others are hidden. Here is the HTML for the divs:
<div id="6ba28aae2dae153a1686cfee276632d8" class="page-block" style="display: block;">
<p>
1st block.
</p>
</div>
<div id="55cead0effa915778913d8667d0ae3a9" class="page-block" style="display: none;">
<p>
2nd block.
</p>
</div>
And here is the JavaScript used to switch the blocks.
/* Hide and show necessary blocks. */
function switchBlocks(UID)
{
var blocks = $('div.page-block');
for (i=0; i<blocks.length; i++)
{
if (blocks[i].id == UID)
{
blocks[i].style.display= 'block';
// Get the current URL and split it at the # mark
urlArray = window.location.href.split("#");
// Select the part before #
subURL = urlArray[0];
// Create a fake URL by adding UID to subURL
history.pushState(null, null, subURL + '#' + UID);
}
else
{
blocks[i].style.display= 'none';
}
}
}
What I am trying to do now is assign each block its unique URL by using the blocks ID. I am able to update the URL with the relevant ID yet can't figure out how to link the particular URL to a specific block so that the corresponding block is shown when accessing its URL.
I have studying the tutorial on the HTML5 History API but can't quite figure out how to apply it to my case.
if(window.location.hash == "#55cead0effa915778913d8667d0ae3a9")
{
$("div.page-block").hide();
$("div#55cead0effa915778913d8667d0ae3a9").show();
}
or
hash_id = window.location.hash;
if(hash_id.length > 0)
{
$("div.page-block").hide();
$(hash_id).show();
}
I think it is better to add and remove classes then having the desired css effect. I believe this is more efficient but I could be wrong.
You could also store a reference to the old div that is being shown so that you could just hide that one and show the other rather then iterating over an entire list of divs. In reality you only need to show one div and hide one div.
As far as browser history support. Do you need this to be cross browser supported? html5 history API is not supported in all browsers. This may not be a problem or concern for you.
List of supported browsers
http://caniuse.com/#search=history
I have used jquery bbq to add history support to a web application. It works well in older browsers.
http://benalman.com/projects/jquery-bbq-plugin/
For big javascript projects Backbone.js is the way to go it has browser history support as well as many other helpful built in functions that make it easy to manage your code base.

Categories

Resources