phantompdf 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|