puppeteer-ruby 0.0.14 → 0.0.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/puppeteer/dom_world.rb +41 -38
- data/lib/puppeteer/frame.rb +4 -2
- data/lib/puppeteer/page.rb +51 -55
- data/lib/puppeteer/page/pdf_options.rb +166 -0
- data/lib/puppeteer/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9bff69308f1dc62011bd6278beb2883c5f16b42dfae0d138c8a442c0ed78cd93
|
4
|
+
data.tar.gz: f336776cfc903db13391c11110650d8103e0eb291fa9a9d79366c9b0f9544b9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe90923f1c31681ec8bc0c092a9ca59976d18f682a99491de57f764f76b35ce27482f47b08348adc84f0b09e215c8cfe788730cb53d776b4922d1e397509ab23
|
7
|
+
data.tar.gz: ea4cb7f51c4944d082592c2a6fad51c69e8c3e6f356d6c5e6867cf9da3821249e346db7beee103e96a74f517ee929dcc1c865f79a07837a5f8c10efac357f748
|
data/lib/puppeteer/dom_world.rb
CHANGED
@@ -132,45 +132,48 @@ class Puppeteer::DOMWorld
|
|
132
132
|
document.SS(selector)
|
133
133
|
end
|
134
134
|
|
135
|
-
#
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
135
|
+
# @return [String]
|
136
|
+
def content
|
137
|
+
evaluate <<-JAVASCRIPT
|
138
|
+
() => {
|
139
|
+
let retVal = '';
|
140
|
+
if (document.doctype)
|
141
|
+
retVal = new XMLSerializer().serializeToString(document.doctype);
|
142
|
+
if (document.documentElement)
|
143
|
+
retVal += document.documentElement.outerHTML;
|
144
|
+
return retVal;
|
145
|
+
}
|
146
|
+
JAVASCRIPT
|
147
|
+
end
|
148
148
|
|
149
|
-
#
|
150
|
-
#
|
151
|
-
#
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
149
|
+
# @param html [String]
|
150
|
+
# @param timeout [Integer]
|
151
|
+
# @param wait_until [String|Array<String>]
|
152
|
+
def set_content(html, timeout: nil, wait_until: nil)
|
153
|
+
option_wait_until = [wait_until || 'load'].flatten
|
154
|
+
option_timeout = @timeout_settings.navigation_timeout
|
155
|
+
|
156
|
+
# We rely upon the fact that document.open() will reset frame lifecycle with "init"
|
157
|
+
# lifecycle event. @see https://crrev.com/608658
|
158
|
+
js = <<-JAVASCRIPT
|
159
|
+
(html) => {
|
160
|
+
document.open();
|
161
|
+
document.write(html);
|
162
|
+
document.close();
|
163
|
+
}
|
164
|
+
JAVASCRIPT
|
165
|
+
evaluate(js, html)
|
166
|
+
|
167
|
+
watcher = Puppeteer::LifecycleWatcher.new(@frame_manager, @frame, option_wait_until, option_timeout)
|
168
|
+
begin
|
169
|
+
await_any(
|
170
|
+
watcher.timeout_or_termination_promise,
|
171
|
+
watcher.lifecycle_promise,
|
172
|
+
)
|
173
|
+
ensure
|
174
|
+
watcher.dispose
|
175
|
+
end
|
176
|
+
end
|
174
177
|
|
175
178
|
# /**
|
176
179
|
# * @param {!{url?: string, path?: string, content?: string, type?: string}} options
|
data/lib/puppeteer/frame.rb
CHANGED
@@ -110,12 +110,14 @@ class Puppeteer::Frame
|
|
110
110
|
|
111
111
|
define_async_method :async_SS
|
112
112
|
|
113
|
+
# @return [String]
|
113
114
|
def content
|
114
115
|
@secondary_world.content
|
115
116
|
end
|
116
117
|
|
117
|
-
# @param
|
118
|
-
# @param
|
118
|
+
# @param html [String]
|
119
|
+
# @param timeout [Integer]
|
120
|
+
# @param wait_until [String|Array<String>]
|
119
121
|
def set_content(html, timeout: nil, wait_until: nil)
|
120
122
|
@secondary_world.set_content(html, timeout: timeout, wait_until: wait_until)
|
121
123
|
end
|
data/lib/puppeteer/page.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'base64'
|
2
|
+
require "stringio"
|
2
3
|
|
4
|
+
require_relative './page/pdf_options'
|
3
5
|
require_relative './page/screenshot_options'
|
4
6
|
|
5
7
|
class Puppeteer::Page
|
@@ -649,13 +651,14 @@ class Puppeteer::Page
|
|
649
651
|
main_frame.content
|
650
652
|
end
|
651
653
|
|
652
|
-
# @param
|
653
|
-
# @param
|
654
|
+
# @param html [String]
|
655
|
+
# @param timeout [Integer]
|
656
|
+
# @param wait_until [String|Array<String>]
|
654
657
|
def set_content(html, timeout: nil, wait_until: nil)
|
655
658
|
main_frame.set_content(html, timeout: timeout, wait_until: wait_until)
|
656
659
|
end
|
657
660
|
|
658
|
-
# @param
|
661
|
+
# @param html [String]
|
659
662
|
def content=(html)
|
660
663
|
main_frame.set_content(html)
|
661
664
|
end
|
@@ -915,60 +918,53 @@ class Puppeteer::Page
|
|
915
918
|
buffer
|
916
919
|
end
|
917
920
|
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
# scale = 1,
|
925
|
-
# displayHeaderFooter = false,
|
926
|
-
# headerTemplate = '',
|
927
|
-
# footerTemplate = '',
|
928
|
-
# printBackground = false,
|
929
|
-
# landscape = false,
|
930
|
-
# pageRanges = '',
|
931
|
-
# preferCSSPageSize = false,
|
932
|
-
# margin = {},
|
933
|
-
# path = null
|
934
|
-
# } = options;
|
921
|
+
class ProtocolStreamReader
|
922
|
+
def initialize(client:, handle:, path:)
|
923
|
+
@client = client
|
924
|
+
@handle = handle
|
925
|
+
@path = path
|
926
|
+
end
|
935
927
|
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
928
|
+
def read
|
929
|
+
out = StringIO.new
|
930
|
+
File.open(@path, 'w') do |file|
|
931
|
+
eof = false
|
932
|
+
until eof
|
933
|
+
response = @client.send_message('IO.read', handle: @handle)
|
934
|
+
eof = response['eof']
|
935
|
+
data =
|
936
|
+
if response['base64Encoded']
|
937
|
+
Base64.decode64(response['data'])
|
938
|
+
else
|
939
|
+
response['data']
|
940
|
+
end
|
941
|
+
out.write(data)
|
942
|
+
file.write(data)
|
943
|
+
end
|
944
|
+
end
|
945
|
+
@client.send_message('IO.close', handle: @handle)
|
946
|
+
out.read
|
947
|
+
end
|
948
|
+
end
|
947
949
|
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
#
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
# marginRight,
|
967
|
-
# pageRanges,
|
968
|
-
# preferCSSPageSize
|
969
|
-
# });
|
970
|
-
# return await helper.readProtocolStream(this._client, result.stream, path);
|
971
|
-
# }
|
950
|
+
class PrintToPdfIsNotImplementedError < StandardError
|
951
|
+
def initialize
|
952
|
+
super('pdf() is only available in headless mode. See https://github.com/puppeteer/puppeteer/issues/1829')
|
953
|
+
end
|
954
|
+
end
|
955
|
+
|
956
|
+
# @return [String]
|
957
|
+
def pdf(options = {})
|
958
|
+
pdf_options = PDFOptions.new(options)
|
959
|
+
result = @client.send_message('Page.printToPDF', pdf_options.page_print_args)
|
960
|
+
ProtocolStreamReader.new(client: @client, handle: result['stream'], path: pdf_options.path).read
|
961
|
+
rescue => err
|
962
|
+
if err.message.include?('PrintToPDF is not implemented')
|
963
|
+
raise PrintToPdfIsNotImplementedError.new
|
964
|
+
else
|
965
|
+
raise
|
966
|
+
end
|
967
|
+
end
|
972
968
|
|
973
969
|
# @param run_before_unload [Boolean]
|
974
970
|
def close(run_before_unload: false)
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'mime/types'
|
2
|
+
|
3
|
+
class Puppeteer::Page
|
4
|
+
# /**
|
5
|
+
# * @typedef {Object} PDFOptions
|
6
|
+
# * @property {number=} scale
|
7
|
+
# * @property {boolean=} displayHeaderFooter
|
8
|
+
# * @property {string=} headerTemplate
|
9
|
+
# * @property {string=} footerTemplate
|
10
|
+
# * @property {boolean=} printBackground
|
11
|
+
# * @property {boolean=} landscape
|
12
|
+
# * @property {string=} pageRanges
|
13
|
+
# * @property {string=} format
|
14
|
+
# * @property {string|number=} width
|
15
|
+
# * @property {string|number=} height
|
16
|
+
# * @property {boolean=} preferCSSPageSize
|
17
|
+
# * @property {!{top?: string|number, bottom?: string|number, left?: string|number, right?: string|number}=} margin
|
18
|
+
# * @property {string=} path
|
19
|
+
# */
|
20
|
+
class PDFOptions
|
21
|
+
# @params options [Hash]
|
22
|
+
def initialize(options)
|
23
|
+
unless options[:path]
|
24
|
+
# Original puppeteer allows path = nil, however nothing to do without path actually.
|
25
|
+
# Also in most case, users forget to specify path parameter. So let's raise ArgumentError.
|
26
|
+
raise ArgumentError('"path" parameter must be specified.')
|
27
|
+
end
|
28
|
+
|
29
|
+
@scale = options[:scale]
|
30
|
+
@display_header_footer = options[:display_header_footer]
|
31
|
+
@header_template = options[:header_template]
|
32
|
+
@footer_template = options[:footer_template]
|
33
|
+
@print_background = options[:print_background]
|
34
|
+
@landscape = options[:landscape]
|
35
|
+
@page_ranges = options[:page_ranges]
|
36
|
+
@format = options[:format]
|
37
|
+
@width = options[:width]
|
38
|
+
@height = options[:height]
|
39
|
+
@prefer_css_page_size = options[:prefer_css_page_size]
|
40
|
+
@margin = Margin.new(options[:margin] || {})
|
41
|
+
@path = options[:path]
|
42
|
+
end
|
43
|
+
|
44
|
+
attr_reader :path
|
45
|
+
|
46
|
+
class PaperSize
|
47
|
+
def initialize(width:, height:)
|
48
|
+
@width = width
|
49
|
+
@height = height
|
50
|
+
end
|
51
|
+
attr_reader :width, :height
|
52
|
+
end
|
53
|
+
|
54
|
+
PAPER_FORMATS = {
|
55
|
+
letter: PaperSize.new(width: 8.5, height: 11),
|
56
|
+
legal: PaperSize.new(width: 8.5, height: 14),
|
57
|
+
tabloid: PaperSize.new(width: 11, height: 17),
|
58
|
+
ledger: PaperSize.new(width: 17, height: 11),
|
59
|
+
a0: PaperSize.new(width: 33.1, height: 46.8),
|
60
|
+
a1: PaperSize.new(width: 23.4, height: 33.1),
|
61
|
+
a2: PaperSize.new(width: 16.54, height: 23.4),
|
62
|
+
a3: PaperSize.new(width: 11.7, height: 16.54),
|
63
|
+
a4: PaperSize.new(width: 8.27, height: 11.7),
|
64
|
+
a5: PaperSize.new(width: 5.83, height: 8.27),
|
65
|
+
a6: PaperSize.new(width: 4.13, height: 5.83),
|
66
|
+
}
|
67
|
+
|
68
|
+
UNIT_TO_PIXELS = {
|
69
|
+
px: 1,
|
70
|
+
in: 96,
|
71
|
+
cm: 37.8,
|
72
|
+
mm: 3.78,
|
73
|
+
}
|
74
|
+
|
75
|
+
# @param parameter [String|Integer|nil]
|
76
|
+
private def convert_print_parameter_to_inches(parameter)
|
77
|
+
return nil if parameter.nil?
|
78
|
+
|
79
|
+
pixels =
|
80
|
+
if parameter.is_a?(Numeric)
|
81
|
+
parameter.to_i
|
82
|
+
elsif parameter.is_a?(String)
|
83
|
+
unit = parameter[-2..-1].downcase
|
84
|
+
value =
|
85
|
+
if UNIT_TO_PIXELS.has_key?(unit)
|
86
|
+
parameter[0...-2].to_i
|
87
|
+
else
|
88
|
+
unit = 'px'
|
89
|
+
parameter.to_i
|
90
|
+
end
|
91
|
+
|
92
|
+
value * UNIT_TO_PIXELS[unit]
|
93
|
+
else
|
94
|
+
raise ArgumentError.new("page.pdf() Cannot handle parameter type: #{parameter.class}")
|
95
|
+
end
|
96
|
+
|
97
|
+
pixels / 96
|
98
|
+
end
|
99
|
+
|
100
|
+
private def paper_size
|
101
|
+
@paper_size ||= calc_paper_size
|
102
|
+
end
|
103
|
+
|
104
|
+
# @return [PaperSize]
|
105
|
+
private def calc_paper_size
|
106
|
+
if @format
|
107
|
+
PAPER_FORMATS[@format.downcase] or raise ArgumentError.new("Unknown paper format: #{@format}")
|
108
|
+
else
|
109
|
+
PaperSize.new(
|
110
|
+
width: convert_print_parameter_to_inches(@width) || 8.5,
|
111
|
+
height: convert_print_parameter_to_inches(@height) || 11.0,
|
112
|
+
)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
class Margin
|
117
|
+
def initialize(options)
|
118
|
+
@top = options[:top]
|
119
|
+
@bottom = options[:bottom]
|
120
|
+
@left = options[:left]
|
121
|
+
@right = options[:right]
|
122
|
+
end
|
123
|
+
|
124
|
+
def translate(&block)
|
125
|
+
new_margin ={
|
126
|
+
top: block.call(@top),
|
127
|
+
bottom: block.call(@bottom),
|
128
|
+
left: block.call(@left),
|
129
|
+
right: block.call(@right),
|
130
|
+
}
|
131
|
+
Margin.new(new_margin)
|
132
|
+
end
|
133
|
+
attr_reader :top, :bottom, :left, :right
|
134
|
+
end
|
135
|
+
|
136
|
+
private def margin
|
137
|
+
@__margin ||= calc_margin
|
138
|
+
end
|
139
|
+
|
140
|
+
private def calc_margin
|
141
|
+
@margin.translate do |value|
|
142
|
+
convert_print_parameter_to_inches(value) || 0
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def page_print_args
|
147
|
+
{
|
148
|
+
transferMode: 'ReturnAsStream',
|
149
|
+
landscape: @landscape || false,
|
150
|
+
displayHeaderFooter: @display_header_footer || false,
|
151
|
+
headerTemplate: @header_template || '',
|
152
|
+
footerTemplate: @footer_template || '',
|
153
|
+
printBackground: @print_background || false,
|
154
|
+
scale: @scale || 1,
|
155
|
+
paperWidth: paper_size.width,
|
156
|
+
paperHeight: paper_size.height,
|
157
|
+
marginTop: margin.top,
|
158
|
+
marginBottom: margin.bottom,
|
159
|
+
marginLeft: margin.left,
|
160
|
+
marginRight: margin.right,
|
161
|
+
pageRanges: @page_ranges || '',
|
162
|
+
preferCSSPageSize: @prefer_css_page_size || false,
|
163
|
+
}
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
data/lib/puppeteer/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puppeteer-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- YusukeIwaki
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-06-
|
11
|
+
date: 2020-06-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -224,6 +224,7 @@ files:
|
|
224
224
|
- lib/puppeteer/mouse.rb
|
225
225
|
- lib/puppeteer/network_manager.rb
|
226
226
|
- lib/puppeteer/page.rb
|
227
|
+
- lib/puppeteer/page/pdf_options.rb
|
227
228
|
- lib/puppeteer/page/screenshot_options.rb
|
228
229
|
- lib/puppeteer/remote_object.rb
|
229
230
|
- lib/puppeteer/target.rb
|