phantompdf 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +19 -33
- data/lib/phantompdf/generator.rb +1 -1
- data/lib/phantompdf/version.rb +1 -1
- data/spec/fixtures/phantompdf.html +3 -1
- data/spec/phantompdf/generator_spec.rb +13 -0
- data/vendor/assets/javascripts/rasterize.js +113 -55
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3b1dce9a0f9ad3bc7f5a86520f0f73f54d7ae377
|
4
|
+
data.tar.gz: a08c72427bfcb0c66897eba3d5a04e60720da311
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 544666b16d0ce3639078ed7bf20945ce722e944633b72babb0e9248e4611f11d7febf5bd8d24af2345fe9f2e4363a102acae256f3e72a1ef104c899aaac519a0
|
7
|
+
data.tar.gz: b1fcf15eeea1eb265080c767377a7e3059cef4e7b20db8f8a88e7aebb4f5b87c29e1137d3223b9f150eb2144e15b2a21dfae76f4f1e73b56985ae47033115f93
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
phantompdf (1.0.
|
4
|
+
phantompdf (1.0.3)
|
5
5
|
json
|
6
6
|
phantomjs
|
7
7
|
|
@@ -10,27 +10,20 @@ GEM
|
|
10
10
|
specs:
|
11
11
|
Ascii85 (1.0.2)
|
12
12
|
afm (0.2.0)
|
13
|
-
byebug (2.
|
13
|
+
byebug (2.2.2)
|
14
14
|
columnize (~> 0.3.6)
|
15
15
|
debugger-linecache (~> 1.2.0)
|
16
|
-
capybara (
|
16
|
+
capybara (2.1.0)
|
17
17
|
mime-types (>= 1.16)
|
18
18
|
nokogiri (>= 1.3.3)
|
19
19
|
rack (>= 1.0.0)
|
20
20
|
rack-test (>= 0.5.4)
|
21
|
-
|
22
|
-
|
23
|
-
childprocess (0.3.9)
|
24
|
-
ffi (~> 1.0, >= 1.0.11)
|
21
|
+
xpath (~> 2.0)
|
22
|
+
cliver (0.2.2)
|
25
23
|
columnize (0.3.6)
|
26
24
|
debugger-linecache (1.2.0)
|
27
25
|
diff-lcs (1.2.4)
|
28
|
-
eventmachine (1.0.3)
|
29
|
-
faye-websocket (0.4.7)
|
30
|
-
eventmachine (>= 0.12.0)
|
31
|
-
ffi (1.9.0)
|
32
26
|
hashery (2.1.1)
|
33
|
-
http_parser.rb (0.5.3)
|
34
27
|
json (1.8.0)
|
35
28
|
mime-types (1.25)
|
36
29
|
mini_portile (0.5.1)
|
@@ -45,34 +38,27 @@ GEM
|
|
45
38
|
ttfunk
|
46
39
|
phantomjs (1.8.1.1)
|
47
40
|
poltergeist
|
48
|
-
poltergeist (1.
|
49
|
-
capybara (~> 1.
|
50
|
-
|
51
|
-
faye-websocket (~> 0.4.4)
|
52
|
-
http_parser.rb (~> 0.5.3)
|
41
|
+
poltergeist (1.4.1)
|
42
|
+
capybara (~> 2.1.0)
|
43
|
+
cliver (~> 0.2.1)
|
53
44
|
multi_json (~> 1.0)
|
54
|
-
|
45
|
+
websocket-driver (>= 0.2.0)
|
46
|
+
rack (1.5.2)
|
55
47
|
rack-test (0.6.2)
|
56
48
|
rack (>= 1.0)
|
57
49
|
rake (10.1.0)
|
58
|
-
rspec (2.
|
59
|
-
rspec-core (~> 2.
|
60
|
-
rspec-expectations (~> 2.
|
61
|
-
rspec-mocks (~> 2.
|
62
|
-
rspec-core (2.
|
63
|
-
rspec-expectations (2.
|
50
|
+
rspec (2.14.1)
|
51
|
+
rspec-core (~> 2.14.0)
|
52
|
+
rspec-expectations (~> 2.14.0)
|
53
|
+
rspec-mocks (~> 2.14.0)
|
54
|
+
rspec-core (2.14.5)
|
55
|
+
rspec-expectations (2.14.3)
|
64
56
|
diff-lcs (>= 1.1.3, < 2.0)
|
65
|
-
rspec-mocks (2.
|
57
|
+
rspec-mocks (2.14.3)
|
66
58
|
ruby-rc4 (0.1.5)
|
67
|
-
rubyzip (0.9.9)
|
68
|
-
selenium-webdriver (2.35.1)
|
69
|
-
childprocess (>= 0.2.5)
|
70
|
-
multi_json (~> 1.0)
|
71
|
-
rubyzip (< 1.0.0)
|
72
|
-
websocket (~> 1.0.4)
|
73
59
|
ttfunk (1.0.3)
|
74
|
-
websocket (
|
75
|
-
xpath (0.
|
60
|
+
websocket-driver (0.3.0)
|
61
|
+
xpath (2.0.0)
|
76
62
|
nokogiri (~> 1.3)
|
77
63
|
|
78
64
|
PLATFORMS
|
data/lib/phantompdf/generator.rb
CHANGED
data/lib/phantompdf/version.rb
CHANGED
@@ -72,6 +72,7 @@ module PhantomPDF
|
|
72
72
|
before :all do
|
73
73
|
@url = 'http://www.google.com'
|
74
74
|
@file = '/tmp/google.pdf'
|
75
|
+
@image = 'http://www.google.com/images/srpr/logo4w.png'
|
75
76
|
end
|
76
77
|
|
77
78
|
after :each do
|
@@ -87,6 +88,12 @@ module PhantomPDF
|
|
87
88
|
pdf_content.should include(header)
|
88
89
|
end
|
89
90
|
|
91
|
+
it "should support images in custom header" do
|
92
|
+
header = "1.8cm*PhantomPDF header!<img src=\"#{@image}\" style=\"float:right;\"/>"
|
93
|
+
|
94
|
+
Generator.new(@url, @file, {header: header}).generate.should be_pdf_file
|
95
|
+
end
|
96
|
+
|
90
97
|
pending "should support custom :footer" do
|
91
98
|
header = 'Hello, PhantomPDF footer!'
|
92
99
|
|
@@ -95,6 +102,12 @@ module PhantomPDF
|
|
95
102
|
pdf_content = PDF::Reader.new(@file).page(1).text
|
96
103
|
pdf_content.should include(header)
|
97
104
|
end
|
105
|
+
|
106
|
+
it "should support images in custom header or footer" do
|
107
|
+
footer = "1.8cm*PhantomPDF footer!<img src=\"#{@image}\" style=\"float:right;\"/>"
|
108
|
+
|
109
|
+
Generator.new(@url, @file, {footer: footer}).generate.should be_pdf_file
|
110
|
+
end
|
98
111
|
end
|
99
112
|
end
|
100
113
|
|
@@ -8,7 +8,94 @@ if (system_args_length < 3 || system_args_length > 12) {
|
|
8
8
|
phantom.exit(1);
|
9
9
|
}
|
10
10
|
|
11
|
-
var
|
11
|
+
var // PhantomJS CAN NOT handle images in custom header/footer,
|
12
|
+
// and this is used to fix the issue.
|
13
|
+
io_images = [],
|
14
|
+
|
15
|
+
is_html = function(s){
|
16
|
+
return /<([a-z]+?\d*?)[^>]*?>[^\0]*?<\/\1>/i.test(s) === true;
|
17
|
+
},
|
18
|
+
|
19
|
+
extract_images = function(html){
|
20
|
+
var image_tags = html.match(/<img[^>]+?src=(["'])https?:\/\/[^>]+?\1[^>]*?\/?>/ig),
|
21
|
+
image_tags_len = image_tags.length,
|
22
|
+
i, image;
|
23
|
+
if (image_tags_len < 1) {
|
24
|
+
return;
|
25
|
+
}
|
26
|
+
|
27
|
+
for (i=0; i<image_tags_len; i++) {
|
28
|
+
image = image_tags[i].match(/src=(["'])(https?:\/\/[^>]+?)\1/i);
|
29
|
+
|
30
|
+
if (image.length == 3 && io_images.indexOf(image[2]) < 0) {
|
31
|
+
io_images[io_images.length] = image[2];
|
32
|
+
}
|
33
|
+
}
|
34
|
+
},
|
35
|
+
inject_images = function(html){
|
36
|
+
var images_num = io_images.length;
|
37
|
+
if (images_num < 1) {
|
38
|
+
return html;
|
39
|
+
}
|
40
|
+
|
41
|
+
var klass, klasses = [],
|
42
|
+
html_injected, html_temp,
|
43
|
+
i, fragments = ['<style type="text/css">'];
|
44
|
+
for (i=0; i<images_num; i++) {
|
45
|
+
klass = 'phantompdf-' + i;
|
46
|
+
|
47
|
+
klasses[klasses.length] = klass;
|
48
|
+
fragments[fragments.length] = '.' + klass + '{background:url(' + io_images[i] + ');}';
|
49
|
+
}
|
50
|
+
fragments[fragments.length] = '</style>';
|
51
|
+
fragments[fragments.length] = '<div class="' + klasses.join(' ') + '" style="display:none;width:0;height:0;font-size:0;"></div>';
|
52
|
+
|
53
|
+
html_injected = fragments.join('');
|
54
|
+
|
55
|
+
html_temp = html.split('</body>');
|
56
|
+
if (html_temp.length > 1) {
|
57
|
+
html_temp[html_temp.length - 1] = html_injected + html_temp.slice(-1)[0];
|
58
|
+
|
59
|
+
html = html_temp.join('</body>');
|
60
|
+
} else {
|
61
|
+
html = html + html_injected;
|
62
|
+
}
|
63
|
+
|
64
|
+
return html;
|
65
|
+
},
|
66
|
+
|
67
|
+
render_pdf = function(html){
|
68
|
+
if (!is_html(html)) {
|
69
|
+
phantom.exit(1);
|
70
|
+
|
71
|
+
throw 'Invalid HTML source!';
|
72
|
+
}
|
73
|
+
|
74
|
+
page.content = inject_images(html);
|
75
|
+
|
76
|
+
window.setTimeout(function(){
|
77
|
+
page.render(output + '_tmp.pdf');
|
78
|
+
|
79
|
+
if (fs.exists(output)) {
|
80
|
+
fs.remove(output);
|
81
|
+
}
|
82
|
+
|
83
|
+
try {
|
84
|
+
fs.move(output + '_tmp.pdf', output);
|
85
|
+
|
86
|
+
// return pdf file path
|
87
|
+
console.log(output);
|
88
|
+
} catch (e) {
|
89
|
+
phantom.exit(1);
|
90
|
+
|
91
|
+
throw e;
|
92
|
+
}
|
93
|
+
|
94
|
+
phantom.exit();
|
95
|
+
}, render_timeout);
|
96
|
+
},
|
97
|
+
|
98
|
+
input = system.args[1],
|
12
99
|
output = system.args[2],
|
13
100
|
|
14
101
|
margin = system.args[6] || '0cm',
|
@@ -21,8 +108,9 @@ var input = system.args[1],
|
|
21
108
|
render_timeout = system.args[10] || 10000,
|
22
109
|
timeout = system.args[11] || 90000;
|
23
110
|
|
24
|
-
window.setTimeout(function
|
111
|
+
window.setTimeout(function(){
|
25
112
|
console.log("Shit's being weird no result within " + timeout + "ms");
|
113
|
+
|
26
114
|
phantom.exit(1);
|
27
115
|
}, timeout);
|
28
116
|
|
@@ -38,6 +126,8 @@ if (output.substr(-4) === '.pdf') {
|
|
38
126
|
if (system_args_length > 4) {
|
39
127
|
header = system.args[4].split('*');
|
40
128
|
if (header.length >= 2) {
|
129
|
+
extract_images(header.join('*'));
|
130
|
+
|
41
131
|
paper_size_options['header'] = {
|
42
132
|
height: header.shift(),
|
43
133
|
contents: phantom.callback(function(pageNum, pageTotal){
|
@@ -50,6 +140,8 @@ if (output.substr(-4) === '.pdf') {
|
|
50
140
|
if (system_args_length > 5) {
|
51
141
|
footer = system.args[5].split('*');
|
52
142
|
if (footer.length >= 2) {
|
143
|
+
extract_images(footer.join('*'));
|
144
|
+
|
53
145
|
paper_size_options['footer'] = {
|
54
146
|
height: footer.shift(),
|
55
147
|
contents: phantom.callback(function(pageNum, pageTotal){
|
@@ -63,52 +155,34 @@ if (output.substr(-4) === '.pdf') {
|
|
63
155
|
}
|
64
156
|
page.zoomFactor = zoom;
|
65
157
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
if (fs.exists(output)) {
|
73
|
-
fs.remove(output);
|
74
|
-
}
|
158
|
+
// cookies injection
|
159
|
+
if (cookie_file) {
|
160
|
+
try {
|
161
|
+
fd = fs.open(cookie_file, 'r');
|
162
|
+
cookies = JSON.parse(fd.read());
|
163
|
+
fs.remove(cookie_file);
|
75
164
|
|
76
|
-
try {
|
77
|
-
fs.move(output + '_tmp.pdf', output);
|
78
165
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
166
|
+
phantom.cookiesEnabled = true;
|
167
|
+
phantom.cookies = cookies;
|
168
|
+
} catch (e) {
|
169
|
+
// ignore
|
170
|
+
}
|
171
|
+
}
|
84
172
|
|
85
|
-
|
86
|
-
|
87
|
-
} else {
|
173
|
+
if (is_html(input)) { // for html string
|
174
|
+
render_pdf(input);
|
175
|
+
} else { // for url resource
|
88
176
|
var statusCode = null;
|
89
177
|
|
90
|
-
if (cookie_file) {
|
91
|
-
try {
|
92
|
-
fd = fs.open(cookie_file, 'r');
|
93
|
-
cookies = JSON.parse(fd.read());
|
94
|
-
fs.remove(cookie_file);
|
95
|
-
|
96
|
-
|
97
|
-
phantom.cookiesEnabled = true;
|
98
|
-
phantom.cookies = cookies;
|
99
|
-
} catch (e) {
|
100
|
-
// console.log(e);
|
101
|
-
}
|
102
|
-
}
|
103
|
-
|
104
178
|
// determine the statusCode
|
105
|
-
page.onResourceReceived = function
|
179
|
+
page.onResourceReceived = function(resource){
|
106
180
|
if (new RegExp('^'+input).test(resource.url)) {
|
107
181
|
statusCode = resource.status;
|
108
182
|
}
|
109
183
|
};
|
110
184
|
|
111
|
-
page.open(input, function
|
185
|
+
page.open(input, function(status){
|
112
186
|
if (status !== 'success' || (statusCode !== null && statusCode != 200)) {
|
113
187
|
console.log(statusCode, 'Failed to load the input!');
|
114
188
|
|
@@ -120,29 +194,13 @@ if (/<([a-z]+?\d*?).*?>[^\0]*?<\/\1>/i.test(input) === true) {
|
|
120
194
|
fs.touch(output);
|
121
195
|
} catch (e) {
|
122
196
|
phantom.exit(1);
|
197
|
+
|
123
198
|
throw e;
|
124
199
|
}
|
125
200
|
|
126
201
|
phantom.exit(1);
|
127
202
|
} else {
|
128
|
-
|
129
|
-
page.render(output + '_tmp.pdf');
|
130
|
-
|
131
|
-
if (fs.exists(output)) {
|
132
|
-
fs.remove(output);
|
133
|
-
}
|
134
|
-
|
135
|
-
try {
|
136
|
-
fs.move(output + '_tmp.pdf', output);
|
137
|
-
|
138
|
-
console.log(output);
|
139
|
-
} catch (e) {
|
140
|
-
phantom.exit(1);
|
141
|
-
throw e;
|
142
|
-
}
|
143
|
-
|
144
|
-
phantom.exit();
|
145
|
-
}, render_timeout);
|
203
|
+
render_pdf(page.content);
|
146
204
|
}
|
147
205
|
});
|
148
206
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: phantompdf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Spring MC
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-09-
|
11
|
+
date: 2013-09-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: phantomjs
|