google-chrome-client 0.1

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.
Files changed (3) hide show
  1. data/bin/chrome-repl +67 -0
  2. data/lib/google/chrome/client.rb +186 -0
  3. metadata +64 -0
data/bin/chrome-repl ADDED
@@ -0,0 +1,67 @@
1
+ #! /usr/bin/env ruby
2
+ require 'google/chrome/client'
3
+ require 'readline'
4
+ require 'pp'
5
+ require 'optparse'
6
+
7
+ def print_log_and_error(data)
8
+ if data['error']
9
+ puts data['error']['stack']
10
+ elsif data['log']
11
+ if data['log'].kind_of?(String)
12
+ puts data['log']
13
+ else
14
+ pp data['log']
15
+ end
16
+ end
17
+ end
18
+
19
+ def print_response(data)
20
+ if data.empty?
21
+ puts 'nil'
22
+ elsif data['success']
23
+ pp data['success']
24
+ else
25
+ print_log_and_error(data)
26
+ end
27
+ end
28
+
29
+ extension_id = 'olppoehbaphcegdobmaipllacoammngl'
30
+ port = 9222
31
+ script = nil
32
+
33
+ parser = OptionParser.new
34
+
35
+ parser.on('--port N', Integer) do |n|
36
+ port = n
37
+ end
38
+
39
+ parser.on('--extension ID') do |s|
40
+ extension_id = s
41
+ end
42
+
43
+ parser.on('-e SCRIPT') do |s|
44
+ script = s
45
+ end
46
+
47
+ parser.parse!(ARGV)
48
+
49
+ client = Google::Chrome::Client.new('localhost', port)
50
+ extension = client.extension(extension_id)
51
+
52
+ extension.connect do |port|
53
+ if script
54
+ extension.post(port, script)
55
+ client.read_all_response.each do |header, resp|
56
+ print_log_and_error(resp['data'])
57
+ end
58
+ else
59
+ puts "Protocol version: %s" % client.server_version
60
+ while ln = Readline.readline('> ', true)
61
+ extension.post(port, ln)
62
+ client.read_all_response.each do |header, resp|
63
+ print_response(resp['data'])
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,186 @@
1
+ #
2
+ # = google/chrome/client.rb
3
+ #
4
+ # "Google Chrome Developer Tools Procotol" client library.
5
+ #
6
+ # Author:: KATO Kazuyoshi
7
+ # License:: X11 License
8
+ #
9
+
10
+ require 'socket'
11
+ require 'json'
12
+
13
+ module Google
14
+ module Chrome
15
+ class Client
16
+ #
17
+ # Create a Client object and establish the debugger connection.
18
+ #
19
+ def initialize(host, port)
20
+ @socket = TCPSocket.open(host, port)
21
+ handshake
22
+ end
23
+
24
+ #
25
+ # Read all responses from the server.
26
+ #
27
+ def read_all_response
28
+ result = []
29
+
30
+ while IO.select([ @socket ], [], [], 0.1)
31
+ result << read_response
32
+ end
33
+
34
+ result
35
+ end
36
+
37
+ #
38
+ # Read one response from the server.
39
+ #
40
+ def read_response
41
+ header = {}
42
+
43
+ while ln = @socket.gets
44
+ case ln
45
+ when "\r\n"
46
+ break
47
+ when /^([A-Za-z-]+):(.*)$/
48
+ header[$1] = $2.chomp
49
+ else
50
+ raise
51
+ end
52
+ end
53
+
54
+ body = JSON.parse(@socket.read(header['Content-Length'].to_i))
55
+ return header, body
56
+ end
57
+
58
+ #
59
+ # Send a request.
60
+ #
61
+ def request(header, body)
62
+ write_request(header, body)
63
+ return read_response
64
+ end
65
+
66
+ def server_version
67
+ header, resp = request({ 'Tool' => 'DevToolsService' },
68
+ { 'command' => 'version' })
69
+ resp['data']
70
+ end
71
+
72
+ def tabs
73
+ header, resp = request({ 'Tool' => 'DevToolsService' },
74
+ { 'command' => 'list_tabs' })
75
+ resp['data'].map do |ary|
76
+ Tab.new(self, ary[0].to_i)
77
+ end
78
+ end
79
+
80
+ def extension(id)
81
+ ExtensionPorts.new(self, id)
82
+ end
83
+
84
+ private
85
+ def handshake
86
+ str = "ChromeDevToolsHandshake\r\n"
87
+ @socket.write(str)
88
+ if @socket.gets == str
89
+ ;
90
+ else
91
+ raise
92
+ end
93
+ end
94
+
95
+ def write_request(header, body)
96
+ str = body.to_json
97
+
98
+ header['Content-Length'] = str.length
99
+ header.each_pair do |k, v|
100
+ @socket.write("#{k}:#{v}\r\n")
101
+ end
102
+ @socket.write("\r\n")
103
+ @socket.write(str)
104
+ end
105
+ end
106
+
107
+ class Tab
108
+ @@seq = 1
109
+
110
+ def initialize(client, number)
111
+ @client = client
112
+ @number = number
113
+ end
114
+
115
+ def request(body)
116
+ @client.request({ 'Tool' => 'V8Debugger', 'Destination' => @number },
117
+ body)
118
+ end
119
+
120
+ def attach
121
+ request({ 'command' => 'attach' })
122
+ return unless block_given?
123
+
124
+ begin
125
+ yield
126
+ ensure
127
+ detach
128
+ end
129
+ end
130
+
131
+ def detach
132
+ request({ 'command' => 'attach' })
133
+ end
134
+
135
+ def debugger_command(command, arguments)
136
+ h, r = request({
137
+ 'command' => 'debugger_command',
138
+ 'data' => {
139
+ 'seq' => @@seq,
140
+ 'type' => 'request',
141
+ 'command' => command,
142
+ 'arguments' => arguments,
143
+ }
144
+ })
145
+ @@seq += 1
146
+
147
+ return h, r
148
+ end
149
+ end
150
+
151
+ class ExtensionPorts
152
+ def initialize(client, id)
153
+ @client = client
154
+ @id = id
155
+ end
156
+
157
+ def connect
158
+ h, r = @client.request({ 'Tool' => 'ExtensionPorts' },
159
+ { 'command' => 'connect',
160
+ 'data' => { 'extensionId' => @id } })
161
+ port = r['data']['portId'].to_i
162
+
163
+ if block_given?
164
+ begin
165
+ yield(port)
166
+ ensure
167
+ disconnect(port)
168
+ end
169
+ else
170
+ return port
171
+ end
172
+ end
173
+
174
+ def disconnect(port)
175
+ @client.request({ 'Tool' => 'ExtensionPorts', 'Destination' => port },
176
+ { 'command' => 'disconnect' })
177
+ end
178
+
179
+ def post(port, data)
180
+ @client.request({ 'Tool' => 'ExtensionPorts', 'Destination' => port },
181
+ { 'command' => 'postMessage',
182
+ 'data' => data })
183
+ end
184
+ end
185
+ end
186
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: google-chrome-client
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - KATO Kazuyoshi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-14 00:00:00 +09:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: json
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description:
26
+ email: kzys@8-p.info
27
+ executables:
28
+ - chrome-repl
29
+ extensions: []
30
+
31
+ extra_rdoc_files: []
32
+
33
+ files:
34
+ - lib/google/chrome/client.rb
35
+ has_rdoc: true
36
+ homepage: http://8-p.info/chrome-repl/
37
+ licenses: []
38
+
39
+ post_install_message:
40
+ rdoc_options: []
41
+
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ requirements: []
57
+
58
+ rubyforge_project:
59
+ rubygems_version: 1.3.5
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: Ruby client of Google Chrome Developer Tools Protocol
63
+ test_files: []
64
+