playwright-ruby-client 0.2.1 → 0.3.0
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/docs/api_coverage.md +102 -49
- data/lib/playwright.rb +1 -0
- data/lib/playwright/channel.rb +10 -10
- data/lib/playwright/channel_owners/binding_call.rb +3 -0
- data/lib/playwright/channel_owners/browser_context.rb +149 -3
- data/lib/playwright/channel_owners/dialog.rb +28 -0
- data/lib/playwright/channel_owners/page.rb +47 -10
- data/lib/playwright/channel_owners/playwright.rb +4 -0
- data/lib/playwright/channel_owners/request.rb +26 -2
- data/lib/playwright/channel_owners/response.rb +60 -0
- data/lib/playwright/channel_owners/route.rb +78 -0
- data/lib/playwright/channel_owners/selectors.rb +19 -1
- data/lib/playwright/route_handler_entry.rb +36 -0
- data/lib/playwright/utils.rb +1 -0
- data/lib/playwright/version.rb +1 -1
- data/lib/playwright_api/android.rb +80 -8
- data/lib/playwright_api/android_device.rb +145 -28
- data/lib/playwright_api/android_input.rb +17 -13
- data/lib/playwright_api/android_socket.rb +16 -0
- data/lib/playwright_api/android_web_view.rb +21 -0
- data/lib/playwright_api/binding_call.rb +11 -6
- data/lib/playwright_api/browser.rb +6 -6
- data/lib/playwright_api/browser_context.rb +33 -28
- data/lib/playwright_api/browser_type.rb +14 -14
- data/lib/playwright_api/chromium_browser_context.rb +6 -6
- data/lib/playwright_api/console_message.rb +6 -6
- data/lib/playwright_api/dialog.rb +32 -5
- data/lib/playwright_api/download.rb +6 -6
- data/lib/playwright_api/element_handle.rb +6 -6
- data/lib/playwright_api/file_chooser.rb +1 -1
- data/lib/playwright_api/frame.rb +13 -11
- data/lib/playwright_api/js_handle.rb +6 -6
- data/lib/playwright_api/page.rb +48 -46
- data/lib/playwright_api/playwright.rb +7 -7
- data/lib/playwright_api/request.rb +8 -8
- data/lib/playwright_api/response.rb +27 -17
- data/lib/playwright_api/route.rb +27 -5
- data/lib/playwright_api/selectors.rb +7 -7
- metadata +7 -2
@@ -0,0 +1,28 @@
|
|
1
|
+
module Playwright
|
2
|
+
define_channel_owner :Dialog do
|
3
|
+
def type
|
4
|
+
@initializer['type']
|
5
|
+
end
|
6
|
+
|
7
|
+
def message
|
8
|
+
@initializer['message']
|
9
|
+
end
|
10
|
+
|
11
|
+
def default_value
|
12
|
+
@initializer['defaultValue']
|
13
|
+
end
|
14
|
+
|
15
|
+
def accept(promptText: nil)
|
16
|
+
accept_async(prompt_text: promptText).value!
|
17
|
+
end
|
18
|
+
|
19
|
+
def accept_async(promptText: nil)
|
20
|
+
params = { promptText: promptText }.compact
|
21
|
+
@channel.async_send_message_to_server('accept', params)
|
22
|
+
end
|
23
|
+
|
24
|
+
def dismiss
|
25
|
+
@channel.async_send_message_to_server('dismiss')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -14,8 +14,16 @@ module Playwright
|
|
14
14
|
@mouse = MouseImpl.new(@channel)
|
15
15
|
@touchscreen = TouchscreenImpl.new(@channel)
|
16
16
|
|
17
|
-
|
17
|
+
if @initializer['viewportSize']
|
18
|
+
@viewport_size = {
|
19
|
+
width: @initializer['viewportSize']['width'],
|
20
|
+
height: @initializer['viewportSize']['height'],
|
21
|
+
}
|
22
|
+
end
|
18
23
|
@closed = false
|
24
|
+
@bindings = {}
|
25
|
+
@routes = Set.new
|
26
|
+
|
19
27
|
@main_frame = ChannelOwners::Frame.from(@initializer['mainFrame'])
|
20
28
|
@main_frame.send(:update_page_from_page, self)
|
21
29
|
@frames = Set.new
|
@@ -96,12 +104,12 @@ module Playwright
|
|
96
104
|
private def on_request_failed(request, response_end_timing, failure_text)
|
97
105
|
request.send(:update_failure_text, failure_text)
|
98
106
|
request.send(:update_response_end_timing, response_end_timing)
|
99
|
-
emit(Events::Page::RequestFailed)
|
107
|
+
emit(Events::Page::RequestFailed, request)
|
100
108
|
end
|
101
109
|
|
102
110
|
private def on_request_finished(request, response_end_timing)
|
103
111
|
request.send(:update_response_end_timing, response_end_timing)
|
104
|
-
emit(Events::Page::RequestFinished)
|
112
|
+
emit(Events::Page::RequestFinished, request)
|
105
113
|
end
|
106
114
|
|
107
115
|
private def on_frame_attached(frame)
|
@@ -117,8 +125,15 @@ module Playwright
|
|
117
125
|
end
|
118
126
|
|
119
127
|
private def on_route(route, request)
|
120
|
-
#
|
121
|
-
|
128
|
+
# It is not desired to use PlaywrightApi.wrap directly.
|
129
|
+
# However it is a little difficult to define wrapper for `handler` parameter in generate_api.
|
130
|
+
# Just a workaround...
|
131
|
+
wrapped_route = PlaywrightApi.wrap(route)
|
132
|
+
wrapped_request = PlaywrightApi.wrap(request)
|
133
|
+
|
134
|
+
if @routes.none? { |handler_entry| handler_entry.handle(wrapped_route, wrapped_request) }
|
135
|
+
@browser_context.send(:on_route, route, request)
|
136
|
+
end
|
122
137
|
end
|
123
138
|
|
124
139
|
private def on_close
|
@@ -130,14 +145,14 @@ module Playwright
|
|
130
145
|
private def on_dialog(params)
|
131
146
|
dialog = ChannelOwners::Dialog.from(params['dialog'])
|
132
147
|
unless emit(Events::Page::Dialog, dialog)
|
133
|
-
dialog.dismiss
|
148
|
+
dialog.dismiss
|
134
149
|
end
|
135
150
|
end
|
136
151
|
|
137
152
|
# @override
|
138
153
|
def on(event, callback)
|
139
154
|
if event == Events::Page::FileChooser && listener_count(event) == 0
|
140
|
-
@channel.
|
155
|
+
@channel.async_send_message_to_server('setFileChooserInterceptedNoReply', intercepted: true)
|
141
156
|
end
|
142
157
|
super
|
143
158
|
end
|
@@ -145,7 +160,7 @@ module Playwright
|
|
145
160
|
# @override
|
146
161
|
def once(event, callback)
|
147
162
|
if event == Events::Page::FileChooser && listener_count(event) == 0
|
148
|
-
@channel.
|
163
|
+
@channel.async_send_message_to_server('setFileChooserInterceptedNoReply', intercepted: true)
|
149
164
|
end
|
150
165
|
super
|
151
166
|
end
|
@@ -154,7 +169,7 @@ module Playwright
|
|
154
169
|
def off(event, callback)
|
155
170
|
super
|
156
171
|
if event == Events::Page::FileChooser && listener_count(event) == 0
|
157
|
-
@channel.
|
172
|
+
@channel.async_send_message_to_server('setFileChooserInterceptedNoReply', intercepted: false)
|
158
173
|
end
|
159
174
|
end
|
160
175
|
|
@@ -347,7 +362,7 @@ module Playwright
|
|
347
362
|
def add_init_script(path: nil, script: nil)
|
348
363
|
source =
|
349
364
|
if path
|
350
|
-
File.read(path
|
365
|
+
File.read(path)
|
351
366
|
elsif script
|
352
367
|
script
|
353
368
|
else
|
@@ -358,6 +373,23 @@ module Playwright
|
|
358
373
|
nil
|
359
374
|
end
|
360
375
|
|
376
|
+
def route(url, handler)
|
377
|
+
entry = RouteHandlerEntry.new(url, handler)
|
378
|
+
@routes << entry
|
379
|
+
if @routes.count >= 1
|
380
|
+
@channel.send_message_to_server('setNetworkInterceptionEnabled', enabled: true)
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
def unroute(url, handler: nil)
|
385
|
+
@routes.reject! do |handler_entry|
|
386
|
+
handler_entry.same_value?(url: url, handler: handler)
|
387
|
+
end
|
388
|
+
if @routes.count == 0
|
389
|
+
@channel.send_message_to_server('setNetworkInterceptionEnabled', enabled: false)
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
361
393
|
def screenshot(
|
362
394
|
path: nil,
|
363
395
|
type: nil,
|
@@ -698,5 +730,10 @@ module Playwright
|
|
698
730
|
private def timeout_settings
|
699
731
|
@timeout_settings
|
700
732
|
end
|
733
|
+
|
734
|
+
# called from BrowserContext#expose_binding
|
735
|
+
private def has_bindings?(name)
|
736
|
+
@bindings.key?(name)
|
737
|
+
end
|
701
738
|
end
|
702
739
|
end
|
@@ -20,6 +20,10 @@ module Playwright
|
|
20
20
|
@electron ||= ::Playwright::ChannelOwners::Electron.from(@initializer['electron'])
|
21
21
|
end
|
22
22
|
|
23
|
+
def selectors
|
24
|
+
@selectors ||= ::Playwright::ChannelOwners::Selectors.from(@initializer['selectors'])
|
25
|
+
end
|
26
|
+
|
23
27
|
class DeviceDescriptor
|
24
28
|
class Viewport
|
25
29
|
def initialize(hash)
|
@@ -29,7 +29,7 @@ module Playwright
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def method
|
32
|
-
@
|
32
|
+
@initializer['method']
|
33
33
|
end
|
34
34
|
|
35
35
|
def post_data
|
@@ -69,7 +69,7 @@ module Playwright
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def frame
|
72
|
-
@initializer['frame']
|
72
|
+
ChannelOwners::Frame.from(@initializer['frame'])
|
73
73
|
end
|
74
74
|
|
75
75
|
def navigation_request?
|
@@ -90,6 +90,30 @@ module Playwright
|
|
90
90
|
@failure_text = failure_text
|
91
91
|
end
|
92
92
|
|
93
|
+
private def update_timings(
|
94
|
+
start_time:,
|
95
|
+
domain_lookup_start:,
|
96
|
+
domain_lookup_end:,
|
97
|
+
connect_start:,
|
98
|
+
secure_connection_start:,
|
99
|
+
connect_end:,
|
100
|
+
request_start:,
|
101
|
+
response_start:)
|
102
|
+
|
103
|
+
@timing["startTime"] = start_time
|
104
|
+
@timing["domainLookupStart"] = domain_lookup_start
|
105
|
+
@timing["domainLookupEnd"] = domain_lookup_end
|
106
|
+
@timing["connectStart"] = connect_start
|
107
|
+
@timing["secureConnectionStart"] = secure_connection_start
|
108
|
+
@timing["connectEnd"] = connect_end
|
109
|
+
@timing["requestStart"] = request_start
|
110
|
+
@timing["responseStart"] = response_start
|
111
|
+
end
|
112
|
+
|
113
|
+
private def update_headers(headers)
|
114
|
+
@headers = parse_headers(headers)
|
115
|
+
end
|
116
|
+
|
93
117
|
private def update_response_end_timing(response_end_timing)
|
94
118
|
@timing[:responseEnd] = response_end_timing
|
95
119
|
end
|
@@ -1,5 +1,65 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'json'
|
3
|
+
|
1
4
|
module Playwright
|
2
5
|
# @ref https://github.com/microsoft/playwright-python/blob/master/playwright/_impl/_network.py
|
3
6
|
define_channel_owner :Response do
|
7
|
+
def after_initialize
|
8
|
+
@request = ChannelOwners::Request.from(@initializer['request'])
|
9
|
+
timing = @initializer['timing']
|
10
|
+
@request.send(:update_timings,
|
11
|
+
start_time: timing["startTime"],
|
12
|
+
domain_lookup_start: timing["domainLookupStart"],
|
13
|
+
domain_lookup_end: timing["domainLookupEnd"],
|
14
|
+
connect_start: timing["connectStart"],
|
15
|
+
secure_connection_start: timing["secureConnectionStart"],
|
16
|
+
connect_end: timing["connectEnd"],
|
17
|
+
request_start: timing["requestStart"],
|
18
|
+
response_start: timing["responseStart"],
|
19
|
+
)
|
20
|
+
@request.send(:update_headers, @initializer['requestHeaders'])
|
21
|
+
end
|
22
|
+
attr_reader :request
|
23
|
+
|
24
|
+
def url
|
25
|
+
@initializer['url']
|
26
|
+
end
|
27
|
+
|
28
|
+
def ok
|
29
|
+
status == 0 || (200...300).include?(status)
|
30
|
+
end
|
31
|
+
alias_method :ok?, :ok
|
32
|
+
|
33
|
+
def status
|
34
|
+
@initializer['status']
|
35
|
+
end
|
36
|
+
|
37
|
+
def status_text
|
38
|
+
@initializer['statusText']
|
39
|
+
end
|
40
|
+
|
41
|
+
def headers
|
42
|
+
@initializer['headers'].map do |header|
|
43
|
+
[header['name'].downcase, header['value']]
|
44
|
+
end.to_h
|
45
|
+
end
|
46
|
+
|
47
|
+
def finished
|
48
|
+
@channel.send_message_to_server('finished')
|
49
|
+
end
|
50
|
+
|
51
|
+
def body
|
52
|
+
binary = @channel.send_message_to_server("body")
|
53
|
+
Base64.strict_decode64(binary)
|
54
|
+
end
|
55
|
+
alias_method :text, :body
|
56
|
+
|
57
|
+
def json
|
58
|
+
JSON.parse(text)
|
59
|
+
end
|
60
|
+
|
61
|
+
def frame
|
62
|
+
@request.frame
|
63
|
+
end
|
4
64
|
end
|
5
65
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'mime/types'
|
3
|
+
|
4
|
+
module Playwright
|
5
|
+
define_channel_owner :Route do
|
6
|
+
def request
|
7
|
+
ChannelOwners::Request.from(@initializer['request'])
|
8
|
+
end
|
9
|
+
|
10
|
+
def abort(errorCode: nil)
|
11
|
+
params = { errorCode: errorCode }.compact
|
12
|
+
@channel.async_send_message_to_server('abort', params)
|
13
|
+
end
|
14
|
+
|
15
|
+
def fulfill(
|
16
|
+
body: nil,
|
17
|
+
contentType: nil,
|
18
|
+
headers: nil,
|
19
|
+
path: nil,
|
20
|
+
status: nil)
|
21
|
+
params = {
|
22
|
+
contentType: contentType,
|
23
|
+
status: status,
|
24
|
+
}.compact
|
25
|
+
|
26
|
+
length = 0
|
27
|
+
content =
|
28
|
+
if body
|
29
|
+
body
|
30
|
+
elsif path
|
31
|
+
File.read(path)
|
32
|
+
else
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
|
36
|
+
param_headers = headers || {}
|
37
|
+
if contentType
|
38
|
+
param_headers['content-type'] = contentType
|
39
|
+
elsif path
|
40
|
+
param_headers['content-type'] = mime_type_for(path)
|
41
|
+
end
|
42
|
+
|
43
|
+
if content
|
44
|
+
if content.is_a?(String)
|
45
|
+
params[:body] = content
|
46
|
+
params[:isBase64] = false
|
47
|
+
else
|
48
|
+
params[:body] = Base64.strict_encode64(content)
|
49
|
+
params[:isBase64] = true
|
50
|
+
end
|
51
|
+
param_headers['content-length'] ||= content.length.to_s
|
52
|
+
end
|
53
|
+
|
54
|
+
params[:headers] = HttpHeaders.new(param_headers).as_serialized
|
55
|
+
|
56
|
+
@channel.async_send_message_to_server('fulfill', params)
|
57
|
+
end
|
58
|
+
|
59
|
+
def continue(headers: nil, method: nil, postData: nil, url: nil)
|
60
|
+
overrides = { url: url, method: method }.compact
|
61
|
+
|
62
|
+
if headers
|
63
|
+
overrides[:headers] = HttpHeaders.new(headers).as_serialized
|
64
|
+
end
|
65
|
+
|
66
|
+
if postData
|
67
|
+
overrides[:postData] = Base64.strict_encode64(postData)
|
68
|
+
end
|
69
|
+
|
70
|
+
@channel.async_send_message_to_server('continue', overrides)
|
71
|
+
end
|
72
|
+
|
73
|
+
private def mime_type_for(filepath)
|
74
|
+
mime_types = MIME::Types.type_for(filepath)
|
75
|
+
mime_types.first.to_s || 'application/octet-stream'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -1,4 +1,22 @@
|
|
1
1
|
module Playwright
|
2
2
|
# https://github.com/microsoft/playwright-python/blob/master/playwright/_impl/_selectors.py
|
3
|
-
define_channel_owner :Selectors
|
3
|
+
define_channel_owner :Selectors do
|
4
|
+
def register(name, contentScript: nil, path: nil, script: nil)
|
5
|
+
source =
|
6
|
+
if path
|
7
|
+
File.read(path)
|
8
|
+
elsif script
|
9
|
+
script
|
10
|
+
else
|
11
|
+
raise ArgumentError.new('Either path or script parameter must be specified')
|
12
|
+
end
|
13
|
+
params = { name: name, source: source }
|
14
|
+
if contentScript
|
15
|
+
params[:contentScript] = true
|
16
|
+
end
|
17
|
+
@channel.send_message_to_server('register', params)
|
18
|
+
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
end
|
4
22
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Playwright
|
2
|
+
class RouteHandlerEntry
|
3
|
+
# @param url [String]
|
4
|
+
# @param handler [Proc]
|
5
|
+
def initialize(url, handler)
|
6
|
+
@url_value = url
|
7
|
+
@url_matcher = UrlMatcher.new(url)
|
8
|
+
@handler = handler
|
9
|
+
end
|
10
|
+
|
11
|
+
def handle(route, request)
|
12
|
+
if url_match?(request.url)
|
13
|
+
@handler.call(route, request)
|
14
|
+
true
|
15
|
+
else
|
16
|
+
false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def same_value?(url:, handler: nil)
|
21
|
+
if handler
|
22
|
+
@url_value == url && @handler == handler
|
23
|
+
else
|
24
|
+
@url_value == url
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private def url_match?(request_url)
|
29
|
+
if @url_value.is_a?(Regexp)
|
30
|
+
@url_matcher.match?(request_url)
|
31
|
+
else
|
32
|
+
@url_matcher.match?(request_url) || File.fnmatch?(@url_value, request_url)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/playwright/utils.rb
CHANGED
@@ -3,6 +3,7 @@ module Playwright
|
|
3
3
|
module PrepareBrowserContextOptions
|
4
4
|
# @see https://github.com/microsoft/playwright/blob/5a2cfdbd47ed3c3deff77bb73e5fac34241f649d/src/client/browserContext.ts#L265
|
5
5
|
private def prepare_browser_context_options(params)
|
6
|
+
params[:sdkLanguage] = 'ruby'
|
6
7
|
if params[:noViewport] == 0
|
7
8
|
params.delete(:noViewport)
|
8
9
|
params[:noDefaultViewport] = true
|
data/lib/playwright/version.rb
CHANGED
@@ -1,28 +1,100 @@
|
|
1
1
|
module Playwright
|
2
|
-
#
|
2
|
+
# Playwright has **experimental** support for Android automation. You can access android namespace via:
|
3
|
+
#
|
4
|
+
#
|
5
|
+
# ```js
|
6
|
+
# const { _android } = require('playwright');
|
7
|
+
# ```
|
8
|
+
#
|
9
|
+
# An example of the Android automation script would be:
|
10
|
+
#
|
11
|
+
#
|
12
|
+
# ```js
|
13
|
+
# const { _android } = require('playwright');
|
14
|
+
#
|
15
|
+
# (async () => {
|
16
|
+
# // Connect to the device.
|
17
|
+
# const [device] = await playwright._android.devices();
|
18
|
+
# console.log(`Model: ${device.model()}`);
|
19
|
+
# console.log(`Serial: ${device.serial()}`);
|
20
|
+
# // Take screenshot of the whole device.
|
21
|
+
# await device.screenshot({ path: 'device.png' });
|
22
|
+
#
|
23
|
+
# {
|
24
|
+
# // --------------------- WebView -----------------------
|
25
|
+
#
|
26
|
+
# // Launch an application with WebView.
|
27
|
+
# await device.shell('am force-stop org.chromium.webview_shell');
|
28
|
+
# await device.shell('am start org.chromium.webview_shell/.WebViewBrowserActivity');
|
29
|
+
# // Get the WebView.
|
30
|
+
# const webview = await device.webView({ pkg: 'org.chromium.webview_shell' });
|
31
|
+
#
|
32
|
+
# // Fill the input box.
|
33
|
+
# await device.fill({ res: 'org.chromium.webview_shell:id/url_field' }, 'github.com/microsoft/playwright');
|
34
|
+
# await device.press({ res: 'org.chromium.webview_shell:id/url_field' }, 'Enter');
|
35
|
+
#
|
36
|
+
# // Work with WebView's page as usual.
|
37
|
+
# const page = await webview.page();
|
38
|
+
# await page.page.waitForNavigation({ url: /.*microsoft\/playwright.*/ });
|
39
|
+
# console.log(await page.title());
|
40
|
+
# }
|
41
|
+
#
|
42
|
+
# {
|
43
|
+
# // --------------------- Browser -----------------------
|
44
|
+
#
|
45
|
+
# // Launch Chrome browser.
|
46
|
+
# await device.shell('am force-stop com.android.chrome');
|
47
|
+
# const context = await device.launchBrowser();
|
48
|
+
#
|
49
|
+
# // Use BrowserContext as usual.
|
50
|
+
# const page = await context.newPage();
|
51
|
+
# await page.goto('https://webkit.org/');
|
52
|
+
# console.log(await page.evaluate(() => window.location.href));
|
53
|
+
# await page.screenshot({ path: 'page.png' });
|
54
|
+
#
|
55
|
+
# await context.close();
|
56
|
+
# }
|
57
|
+
#
|
58
|
+
# // Close the device.
|
59
|
+
# await device.close();
|
60
|
+
# })();
|
61
|
+
# ```
|
62
|
+
#
|
63
|
+
# Note that since you don't need Playwright to install web browsers when testing Android, you can omit browser download
|
64
|
+
# via setting the following environment variable when installing Playwright:
|
65
|
+
#
|
66
|
+
# ```sh js
|
67
|
+
# $ PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm i -D playwright
|
68
|
+
# ```
|
3
69
|
class Android < PlaywrightApi
|
4
70
|
|
5
|
-
#
|
71
|
+
# Returns the list of detected Android devices.
|
6
72
|
def devices
|
7
73
|
wrap_impl(@impl.devices)
|
8
74
|
end
|
9
75
|
|
76
|
+
# This setting will change the default maximum time for all the methods accepting `timeout` option.
|
77
|
+
def set_default_timeout(timeout)
|
78
|
+
raise NotImplementedError.new('set_default_timeout is not implemented yet.')
|
79
|
+
end
|
80
|
+
alias_method :default_timeout=, :set_default_timeout
|
81
|
+
|
10
82
|
# -- inherited from EventEmitter --
|
11
83
|
# @nodoc
|
12
|
-
def
|
13
|
-
event_emitter_proxy.
|
84
|
+
def off(event, callback)
|
85
|
+
event_emitter_proxy.off(event, callback)
|
14
86
|
end
|
15
87
|
|
16
88
|
# -- inherited from EventEmitter --
|
17
89
|
# @nodoc
|
18
|
-
def
|
19
|
-
event_emitter_proxy.
|
90
|
+
def once(event, callback)
|
91
|
+
event_emitter_proxy.once(event, callback)
|
20
92
|
end
|
21
93
|
|
22
94
|
# -- inherited from EventEmitter --
|
23
95
|
# @nodoc
|
24
|
-
def
|
25
|
-
event_emitter_proxy.
|
96
|
+
def on(event, callback)
|
97
|
+
event_emitter_proxy.on(event, callback)
|
26
98
|
end
|
27
99
|
|
28
100
|
private def event_emitter_proxy
|