Skip to content

Commit a315a4d

Browse files
committed
Added a plugin manager.
Fire a plugin event on the static PubSub before the first page is added.
1 parent a6d7af4 commit a315a4d

5 files changed

Lines changed: 179 additions & 134 deletions

File tree

jspdf.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1768,6 +1768,7 @@ var jsPDF = (function(global) {
17681768
// Add the first page automatically
17691769
addFonts();
17701770
activeFontKey = 'F1';
1771+
jsPDF.plugins.internal.onInitialize(API);
17711772
_addPage(format, orientation);
17721773

17731774
events.publish('initialized');
@@ -1802,13 +1803,28 @@ var jsPDF = (function(global) {
18021803
*/
18031804
jsPDF.API = {events:[]};
18041805
jsPDF.version = "1.0.0-trunk";
1805-
18061806
if (typeof define === 'function' && define.amd) {
18071807
define('jsPDF', function() {
18081808
return jsPDF;
18091809
});
18101810
} else {
18111811
global.jsPDF = jsPDF;
18121812
}
1813+
jsPDF.plugins = {
1814+
register:function(plugin){
1815+
this.internal.plugins.push(plugin);
1816+
},
1817+
internal:{
1818+
plugins:[],
1819+
onInitialize: function(pdf){
1820+
for (var i = 0; i < this.plugins.length; i++) {
1821+
var plugin = this.plugins[i];
1822+
if (typeof plugin.onInitialize === 'function'){
1823+
plugin.onInitialize.call(plugin, pdf);
1824+
}
1825+
}
1826+
},
1827+
}
1828+
};
18131829
return jsPDF;
18141830
}(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this));

jspdf.plugin.annotations.js

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
/**
1010
* There are many types of annotations in a PDF document. Annotations are placed
11-
* on a page at a particular location. They are not 'attached' to an object'
11+
* on a page at a particular location. They are not 'attached' to an object.
1212
* <br />
1313
* This plugin current supports <br />
1414
* <li> Goto Page (set pageNumber in options)
@@ -36,23 +36,31 @@ function notEmpty(obj) {
3636
(function(jsPDFAPI) {
3737
'use strict';
3838

39-
jsPDFAPI.initAnnotationPlugin = function() {
40-
this.annotationPlugin = {};
39+
var annotationPlugin = {
40+
onInitialize : function(pdf) {
41+
this.installAnnotationPlugin(pdf);
42+
}
43+
};
44+
jsPDF.API.annotationPlugin = annotationPlugin;
45+
jsPDF.plugins.register(annotationPlugin);
46+
47+
annotationPlugin.installAnnotationPlugin = function(pdf) {
4148

42-
this.annotationPlugin.annotations = [];
49+
this.annotations = [];
50+
4351
// TODO remove this after we find a way to subscribe before the
4452
// first page is created.
45-
this.annotationPlugin.annotations[1] = [];
53+
//this.annotations[1] = [];
4654

47-
this.annotationPlugin.f2 = function(number) {
55+
this.f2 = function(number) {
4856
return number.toFixed(2);
4957
};
5058

51-
this.internal.events.subscribe('addPage', function(info) {
59+
pdf.internal.events.subscribe('addPage', function(info) {
5260
this.annotationPlugin.annotations[info.pageNumber] = [];
5361
});
5462

55-
this.internal.events.subscribe('render/page', function(info) {
63+
pdf.internal.events.subscribe('render/page', function(info) {
5664
var pageAnnos = this.annotationPlugin.annotations[info.pageNumber];
5765

5866
var found = false;
@@ -70,11 +78,12 @@ function notEmpty(obj) {
7078
}
7179

7280
this.internal.write("/Annots [");
81+
var f2 = this.annotationPlugin.f2;
7382
for (var a = 0; a < pageAnnos.length; a++) {
7483
var anno = pageAnnos[a];
7584
var k = this.internal.scaleFactor;
7685
var pageHeight = this.internal.pageSize.height;
77-
var rect = "/Rect [" + this.annotationPlugin.f2(anno.x * k) + " " + this.annotationPlugin.f2((pageHeight - anno.y) * k) + " " + this.annotationPlugin.f2(anno.x + anno.w * k) + " " + this.annotationPlugin.f2(pageHeight - (anno.y + anno.h) * k) + "] ";
86+
var rect = "/Rect [" + f2(anno.x * k) + " " + f2((pageHeight - anno.y) * k) + " " + f2(anno.x + anno.w * k) + " " + f2(pageHeight - (anno.y + anno.h) * k) + "] ";
7887
if (anno.options.url) {
7988
this.internal.write('<</Type /Annot /Subtype /Link ' + rect + '/Border [0 0 0] /A <</S /URI /URI (' + anno.options.url + ') >> >>')
8089
} else if (anno.options.pageNumber) {

jspdf.plugin.outline.js

Lines changed: 134 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -12,151 +12,165 @@
1212
;
1313
(function(jsPDFAPI) {
1414
'use strict';
15-
16-
jsPDFAPI.initOutlinePlugin = function() {
17-
18-
this.outline = {};
19-
this.outline.root = {
20-
children : []
21-
};
22-
23-
this.internal.events.subscribe('postPutResources', function() {
24-
if (this.outline.root.children.length > 0) {
25-
var lines = this.outline.render().split(/\r\n/);
26-
for (var int = 0; int < lines.length; int++) {
27-
var line = lines[int];
28-
if (line.endsWith('obj')){
29-
var oid = line.split(' ')[0];
30-
this.internal.newObjectDeferredBegin(oid);
15+
var outline = {
16+
17+
onInitialize : function(pdf) {
18+
19+
this.installOutlinePlugin(pdf);
20+
21+
pdf.internal.events.subscribe('postPutResources', function() {
22+
23+
var rx = /^(\d+) 0 obj$/;
24+
25+
if (this.outline.root.children.length > 0) {
26+
var lines = pdf.outline.render().split(/\r\n/);
27+
for (var i = 0; i < lines.length; i++) {
28+
var line = lines[i];
29+
var m = rx.exec(line);
30+
if (m != null) {
31+
var oid = m[1];
32+
pdf.internal.newObjectDeferredBegin(oid);
33+
}
34+
pdf.internal.write(line);
3135
}
32-
this.internal.write(line);
3336
}
34-
}
35-
});
37+
});
38+
39+
pdf.internal.events.subscribe('putCatalog', function() {
40+
if (pdf.outline.root.children.length > 0) {
41+
pdf.internal.write("/Outlines", this.outline.makeRef(this.outline.root));
42+
}
43+
});
44+
},
45+
46+
installOutlinePlugin : function(pdf) {
3647

37-
this.internal.events.subscribe('putCatalog', function() {
38-
if (this.outline.root.children.length > 0) {
39-
this.internal.write("/Outlines", this.outline.makeRef(this.outline.root));
40-
}
41-
});
42-
43-
/**
44-
* Options: pageNumber
45-
*/
46-
this.outline.add = function(parent,title,options) {
47-
var item = {
48-
title : title,
49-
options : options,
48+
pdf.outline = {};
49+
pdf.outline.root = {
5050
children : []
5151
};
52-
if (parent == null) {
53-
parent = this.root;
52+
53+
/**
54+
* Options: pageNumber
55+
*/
56+
pdf.outline.add = function(parent,title,options) {
57+
var item = {
58+
title : title,
59+
options : options,
60+
children : []
61+
};
62+
if (parent == null) {
63+
parent = this.root;
64+
}
65+
parent.children.push(item);
66+
return item;
5467
}
55-
parent.children.push(item);
56-
return item;
57-
}
5868

59-
this.outline.render = function() {
60-
this.outline.ctx = {};
61-
this.outline.nextId = 1000;
62-
this.outline.ctx.val = '';
63-
this.outline.ctx.pdf = this;
69+
pdf.outline.render = function() {
70+
this.ctx = {};
71+
this.ctx.val = '';
72+
this.ctx.pdf = pdf;
6473

65-
this.outline.genIds_r(this.outline.root);
66-
this.outline.renderRoot(this.outline.root);
67-
this.outline.renderItems(this.outline.root);
74+
this.genIds_r(this.root);
75+
this.renderRoot(this.root);
76+
this.renderItems(this.root);
6877

69-
return this.outline.ctx.val;
70-
}.bind(this);
78+
return this.ctx.val;
79+
};
7180

72-
this.outline.genIds_r = function(node) {
73-
node.id = this.internal.newObjectDeferred();
74-
for (var i = 0; i < node.children.length; i++) {
75-
this.outline.genIds_r(node.children[i]);
76-
}
77-
}.bind(this);
78-
79-
this.outline.renderRoot = function(node) {
80-
this.objStart(node);
81-
this.line('/Type /Outlines');
82-
if (node.children.length > 0) {
83-
this.line('/First ' + this.makeRef(node.children[0]));
84-
this.line('/Last ' + this.makeRef(node.children[node.children.length - 1]));
85-
}
86-
this.line('/Count ' + this.count_r({
87-
count : 0
88-
}, node));
89-
this.objEnd();
90-
}
81+
pdf.outline.genIds_r = function(node) {
82+
node.id = pdf.internal.newObjectDeferred();
83+
for (var i = 0; i < node.children.length; i++) {
84+
this.genIds_r(node.children[i]);
85+
}
86+
};
9187

92-
this.outline.renderItems = function(node) {
93-
for (var i = 0; i < node.children.length; i++) {
94-
var item = node.children[i];
95-
this.objStart(item);
88+
pdf.outline.renderRoot = function(node) {
89+
this.objStart(node);
90+
this.line('/Type /Outlines');
91+
if (node.children.length > 0) {
92+
this.line('/First ' + this.makeRef(node.children[0]));
93+
this.line('/Last ' + this.makeRef(node.children[node.children.length - 1]));
94+
}
95+
this.line('/Count ' + this.count_r({
96+
count : 0
97+
}, node));
98+
this.objEnd();
99+
};
96100

97-
this.line('/Title ' + this.makeString(item.title));
101+
pdf.outline.renderItems = function(node) {
102+
for (var i = 0; i < node.children.length; i++) {
103+
var item = node.children[i];
104+
this.objStart(item);
98105

99-
this.line('/Parent ' + this.makeRef(node));
100-
if (i > 0) {
101-
this.line('/Prev ' + this.makeRef(node.children[i - 1]));
102-
}
103-
if (i < node.children.length - 1) {
104-
this.line('/Next ' + this.makeRef(node.children[i + 1]));
105-
}
106-
if (item.children.length > 0) {
107-
this.line('/First ' + this.makeRef(item.children[0]));
108-
this.line('/Last ' + this.makeRef(item.children[item.children.length - 1]));
109-
}
106+
this.line('/Title ' + this.makeString(item.title));
110107

111-
var count = this.count = this.count_r({
112-
count : 0
113-
}, item);
114-
if (count > 0) {
115-
this.line('/Count ' + count);
116-
}
108+
this.line('/Parent ' + this.makeRef(node));
109+
if (i > 0) {
110+
this.line('/Prev ' + this.makeRef(node.children[i - 1]));
111+
}
112+
if (i < node.children.length - 1) {
113+
this.line('/Next ' + this.makeRef(node.children[i + 1]));
114+
}
115+
if (item.children.length > 0) {
116+
this.line('/First ' + this.makeRef(item.children[0]));
117+
this.line('/Last ' + this.makeRef(item.children[item.children.length - 1]));
118+
}
119+
120+
var count = this.count = this.count_r({
121+
count : 0
122+
}, item);
123+
if (count > 0) {
124+
this.line('/Count ' + count);
125+
}
117126

118-
if (item.options) {
119-
if (item.options.pageNumber) {
120-
this.line('/Dest ' + '[' + (item.options.pageNumber - 1) + ' /XYZ 0 ' + this.ctx.pdf.internal.pageSize.height + ' 0]');
121-
//this.line('/Dest ' + '[' + (item.options.pageNumber - 1) + ' /Fit]');
127+
if (item.options) {
128+
if (item.options.pageNumber) {
129+
this.line('/Dest ' + '[' + (item.options.pageNumber - 1) + ' /XYZ 0 ' + this.ctx.pdf.internal.pageSize.height + ' 0]');
130+
// this.line('/Dest ' + '[' +
131+
// (item.options.pageNumber -
132+
// 1) + ' /Fit]');
133+
}
122134
}
135+
this.objEnd();
123136
}
124-
this.objEnd();
125-
}
126-
for (var i = 0; i < node.children.length; i++) {
127-
var item = node.children[i];
128-
this.renderItems(item);
129-
}
130-
}
137+
for (var i = 0; i < node.children.length; i++) {
138+
var item = node.children[i];
139+
this.renderItems(item);
140+
}
141+
};
131142

132-
this.outline.line = function(text) {
133-
this.ctx.val += text + '\r\n';
134-
}
143+
pdf.outline.line = function(text) {
144+
this.ctx.val += text + '\r\n';
145+
};
135146

136-
this.outline.makeRef = function(node) {
137-
return node.id + ' 0 R';
138-
}
147+
pdf.outline.makeRef = function(node) {
148+
return node.id + ' 0 R';
149+
};
139150

140-
this.outline.makeString = function(val) {
141-
return '(' + this.internal.pdfEscape(val) + ')';
142-
}.bind(this);
151+
pdf.outline.makeString = function(val) {
152+
return '(' + pdf.internal.pdfEscape(val) + ')';
153+
};
143154

144-
this.outline.objStart = function(node) {
145-
this.ctx.val += '\r\n' + node.id + ' 0 obj' + '\r\n<<\r\n';
146-
}
155+
pdf.outline.objStart = function(node) {
156+
this.ctx.val += '\r\n' + node.id + ' 0 obj' + '\r\n<<\r\n';
157+
};
147158

148-
this.outline.objEnd = function(node) {
149-
this.ctx.val += '>> \r\n' + 'endobj' + '\r\n';
150-
}
159+
pdf.outline.objEnd = function(node) {
160+
this.ctx.val += '>> \r\n' + 'endobj' + '\r\n';
161+
};
151162

152-
this.outline.count_r = function(ctx,node) {
153-
for (var i = 0; i < node.children.length; i++) {
154-
ctx.count++;
155-
this.count_r(ctx, node.children[i]);
156-
}
157-
return ctx.count;
163+
pdf.outline.count_r = function(ctx,node) {
164+
for (var i = 0; i < node.children.length; i++) {
165+
ctx.count++;
166+
this.count_r(ctx, node.children[i]);
167+
}
168+
return ctx.count;
169+
};
158170
}
159171
}
172+
jsPDF.API.outline = outline;
173+
jsPDF.plugins.register(outline);
160174

161175
return this;
162176
})(jsPDF.API);

0 commit comments

Comments
 (0)