Introduction
The main aim of this blog is to show the content of an .rtf file on the browser window. Usually, when trying to open an .rtf file in the browser, it is downloaded instead of being displayed. This is because the browsers cannot reliably display RTF content. In order to overcome this problem, we came up with a solution which involves converting the contents of an .rtf file into
HTML and then rendering it on the browser window.
This solution has no bearing on the server side programming language that is used. It is handled completely on the browser side.
Implementation
Assume that the file is hosted on a server which can be then retrieved via an AJAX call.
Step – 1
Upon making an ajax call to the server to retrieve the .rtf file, a blob will be received as shown in the image below –
The in-built JavaScript FileReader
object helps in reading the content of a blob. Below is the code snippet explaining how the content of the file is handled.
|
var reader = new FileReader();
reader.readAsArrayBuffer(result);
reader.onload = function (evt) {
displayRtfFile(evt.target.result);
};
|
The
FileReader
object lets web applications asynchronously read the contents of the files. It provides various event handlers and methods. One of them is
FileReader.onload
.
In order to manipulate the content of the RTF file, the external library that we’re going to use requires the content to be an
ArrayBuffer
. This can be done by calling the
FileReader
‘s
reader.readAsArrayBuffer()
method.
So, after manipulating the file content using FileReader
, the value that gets returned is as shown below –
Take a look at the code snippet which does the above-explained work.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
function (file) {
$.ajax({
url: file,
dataType: "binary",
processData: false,
beforesend: function () {
return true;
},
success: function (result) {
// On success, we are getting the content of .rtf file as an ArrayBuffer using FileReader() function.
var reader = new FileReader();
reader.onload = function (evt) {
// TODO: will be called after step #2
// displayRtfFile(evt.target.result);
};
reader.readAsArrayBuffer(result);
},
error: function (jqXHR, textStatus, errorThrown) {
$("#content").text("Error: " + errorThrown);
}
});
}
loadRtfFile(FILE_LOCATION)
|
Step – 2Upon receiving the
ArrayBuffer
, a library called
RTF.js is used that converts the buffered content into the
HTML content that we want.
For proper handling of the content in the .rtf rile, settings can be provided as well. To customize the way images are shown in the rendered HTML file, we can provide these options in callbacks provided by the library.
Picture related settings
|
onPicture: function (create) {
var elem = create().attr("class", "rtfpict");
return elem.css("border", show ? "1px dotted red" : "none");
}
|
For example, using the onPicture
property, a border can be added to the images that are present in the .rtf file and display them on the browser window.
Hyperlink related settings
We have the onHyperlink
property to add custom styles/events to hyperlinks in the PDF.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
onHyperlink:function (create, hyperlink) {
var url = hyperlink.url();
var lnk = create();
if (url.substr(0, 7) == "http://") {
var span = setUnsafeLink($("<span>").addClass("unsafelink").append(lnk), warnHttpLinks);
span.click(function (evt) {
if ($("#warnhttplink").prop("checked")) {
evt.preventDefault();
alert("Unsafe link: " + url);
return false;
}
});
return {
content: lnk,
element: span
};
} else {
return {
content: lnk,
element: lnk
};
}
}
|
Below is the code snippet that takes an ArrayBuffer
as input and returns an object comprising of meta data and the actual .rtf content.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
function displayRtfFile(arrayBuffer) {
var settings = {
onPicture: function (create) {
var elem = create().attr("class", "rtfpict");
return elem.css("border", showPicBorder ? "1px dotted red" : "none");
},
onHyperlink: function (create, hyperlink) {
var url = hyperlink.url();
var lnk = create();
if (url.substr(0, 7) == "http://") {
var span = setUnsafeLink($("<span>").addClass("unsafelink").append(lnk), warnHttpLinks);
span.click(function (evt) {
if ($("#warnhttplink").prop("checked")) {
evt.preventDefault();
alert("Unsafe link: " + url);
return false;
}
});
return {
content: lnk,
element: span
};
} else {
return {
content: lnk,
element: lnk
};
}
}
};
var doc = new RTFJS.Document(arrayBuffer, settings);
var meta = doc.metadata();
// Appending the meta information like - author of the document,
// title of the of the document- into meta tag of html.
for (var prop in meta) {
$("meta").append($("<div>").append($("<span>").text(prop + ": "))
.append($("<span>").text(meta[prop].toString())));
haveMeta = true;
}
// Appending the content to html page.
$("#content").empty().append(doc.render());
}
// Helper function to set border for unsafe links.
function setUnsafeLink(elem, warn) {
return elem.css("border", warn ? "1px dashed red" : "none");
}
|
Metadata comprises of author name, file name, and description. This can be appended to the
<meta></meta>
tags of the
HTML content.
Likewise, the actual content of the file is obtained by using the render()
method of the included library.
Then, the rendered HTML content can be shown on the browser window by appending it to any element.