google-chrome-client 0.1

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