playwright-ruby-client 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/playwright.rb +2 -0
- data/lib/playwright/channel_owners/element_handle.rb +75 -0
- data/lib/playwright/channel_owners/frame.rb +117 -0
- data/lib/playwright/channel_owners/page.rb +68 -11
- data/lib/playwright/channel_owners/request.rb +90 -0
- data/lib/playwright/input_type.rb +19 -0
- data/lib/playwright/input_types/keyboard.rb +32 -0
- data/lib/playwright/input_types/mouse.rb +4 -0
- data/lib/playwright/input_types/touchscreen.rb +4 -0
- data/lib/playwright/javascript/expression.rb +22 -0
- data/lib/playwright/javascript/function.rb +22 -0
- data/lib/playwright/playwright_api.rb +31 -23
- data/lib/playwright/timeout_settings.rb +1 -1
- data/lib/playwright/url_matcher.rb +19 -0
- data/lib/playwright/version.rb +1 -1
- data/lib/playwright_api/accessibility.rb +46 -6
- data/lib/playwright_api/binding_call.rb +6 -6
- data/lib/playwright_api/browser.rb +76 -16
- data/lib/playwright_api/browser_context.rb +284 -30
- data/lib/playwright_api/browser_type.rb +54 -9
- data/lib/playwright_api/cdp_session.rb +23 -1
- data/lib/playwright_api/chromium_browser_context.rb +16 -6
- data/lib/playwright_api/console_message.rb +10 -10
- data/lib/playwright_api/dialog.rb +42 -0
- data/lib/playwright_api/download.rb +19 -4
- data/lib/playwright_api/element_handle.rb +174 -21
- data/lib/playwright_api/file_chooser.rb +8 -0
- data/lib/playwright_api/frame.rb +355 -68
- data/lib/playwright_api/js_handle.rb +45 -9
- data/lib/playwright_api/keyboard.rb +98 -8
- data/lib/playwright_api/mouse.rb +22 -0
- data/lib/playwright_api/page.rb +779 -127
- data/lib/playwright_api/playwright.rb +98 -19
- data/lib/playwright_api/request.rb +70 -23
- data/lib/playwright_api/response.rb +6 -6
- data/lib/playwright_api/route.rb +48 -0
- data/lib/playwright_api/selectors.rb +14 -6
- data/lib/playwright_api/video.rb +8 -0
- data/lib/playwright_api/web_socket.rb +3 -5
- data/lib/playwright_api/worker.rb +12 -0
- metadata +7 -2
@@ -0,0 +1,19 @@
|
|
1
|
+
module Playwright
|
2
|
+
class InputType
|
3
|
+
def initialize(channel)
|
4
|
+
@channel = channel
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
# namespace declaration
|
9
|
+
module InputTypes ; end
|
10
|
+
|
11
|
+
def self.define_input_type(class_name, &block)
|
12
|
+
klass = Class.new(InputType)
|
13
|
+
klass.class_eval(&block) if block
|
14
|
+
InputTypes.const_set(class_name, klass)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# load subclasses
|
19
|
+
Dir[File.join(__dir__, 'input_types', '*.rb')].each { |f| require f }
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Playwright
|
2
|
+
define_input_type :Keyboard do
|
3
|
+
def down(key)
|
4
|
+
@channel.send_message_to_server('keyboardDown', key: key)
|
5
|
+
nil
|
6
|
+
end
|
7
|
+
|
8
|
+
def up(key)
|
9
|
+
@channel.send_message_to_server('keyboardDown', key: key)
|
10
|
+
end
|
11
|
+
|
12
|
+
def insert_text(text)
|
13
|
+
@channel.send_message_to_server('keyboardInsertText', text: text)
|
14
|
+
end
|
15
|
+
|
16
|
+
def type_text(text, delay: nil)
|
17
|
+
params = {
|
18
|
+
text: text,
|
19
|
+
delay: delay,
|
20
|
+
}.compact
|
21
|
+
@channel.send_message_to_server('keyboardType', params)
|
22
|
+
end
|
23
|
+
|
24
|
+
def press(key, delay: nil)
|
25
|
+
params = {
|
26
|
+
key: key,
|
27
|
+
delay: delay,
|
28
|
+
}.compact
|
29
|
+
@channel.send_message_to_server('keyboardPress', params)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -25,6 +25,28 @@ module Playwright
|
|
25
25
|
)
|
26
26
|
::Playwright::ChannelOwner.from(resp)
|
27
27
|
end
|
28
|
+
|
29
|
+
def eval_on_selector(channel, selector)
|
30
|
+
value = channel.send_message_to_server(
|
31
|
+
'evalOnSelector',
|
32
|
+
selector: selector,
|
33
|
+
expression: @expression,
|
34
|
+
isFunction: false,
|
35
|
+
arg: @serialized_arg,
|
36
|
+
)
|
37
|
+
ValueParser.new(value).parse
|
38
|
+
end
|
39
|
+
|
40
|
+
def eval_on_selector_all(channel, selector)
|
41
|
+
value = channel.send_message_to_server(
|
42
|
+
'evalOnSelectorAll',
|
43
|
+
selector: selector,
|
44
|
+
expression: @expression,
|
45
|
+
isFunction: false,
|
46
|
+
arg: @serialized_arg,
|
47
|
+
)
|
48
|
+
ValueParser.new(value).parse
|
49
|
+
end
|
28
50
|
end
|
29
51
|
end
|
30
52
|
end
|
@@ -25,6 +25,28 @@ module Playwright
|
|
25
25
|
)
|
26
26
|
::Playwright::ChannelOwner.from(resp)
|
27
27
|
end
|
28
|
+
|
29
|
+
def eval_on_selector(channel, selector)
|
30
|
+
value = channel.send_message_to_server(
|
31
|
+
'evalOnSelector',
|
32
|
+
selector: selector,
|
33
|
+
expression: @definition,
|
34
|
+
isFunction: true,
|
35
|
+
arg: @serialized_arg,
|
36
|
+
)
|
37
|
+
ValueParser.new(value).parse
|
38
|
+
end
|
39
|
+
|
40
|
+
def eval_on_selector_all(channel, selector)
|
41
|
+
value = channel.send_message_to_server(
|
42
|
+
'evalOnSelectorAll',
|
43
|
+
selector: selector,
|
44
|
+
expression: @definition,
|
45
|
+
isFunction: true,
|
46
|
+
arg: @serialized_arg,
|
47
|
+
)
|
48
|
+
ValueParser.new(value).parse
|
49
|
+
end
|
28
50
|
end
|
29
51
|
end
|
30
52
|
end
|
@@ -7,53 +7,58 @@ module Playwright
|
|
7
7
|
# @param channel_owner [ChannelOwner]
|
8
8
|
# @note Intended for internal use only.
|
9
9
|
def self.from_channel_owner(channel_owner)
|
10
|
-
Factory.new(channel_owner).create
|
10
|
+
Factory.new(channel_owner, 'ChannelOwners').create
|
11
11
|
end
|
12
12
|
|
13
13
|
class Factory
|
14
|
-
def initialize(
|
15
|
-
|
16
|
-
|
14
|
+
def initialize(impl, module_name)
|
15
|
+
impl_class_name = impl.class.name
|
16
|
+
unless impl_class_name.include?("::#{module_name}::")
|
17
|
+
raise "#{impl_class_name} is not #{module_name}"
|
18
|
+
end
|
17
19
|
|
18
|
-
@
|
20
|
+
@impl = impl
|
21
|
+
@module_name = module_name
|
19
22
|
end
|
20
23
|
|
21
24
|
def create
|
22
|
-
api_class = detect_class_for(@
|
25
|
+
api_class = detect_class_for(@impl.class)
|
23
26
|
if api_class
|
24
|
-
api_class.new(@
|
27
|
+
api_class.new(@impl)
|
25
28
|
else
|
26
|
-
raise NotImplementedError.new("Playwright::#{expected_class_name_for(@
|
29
|
+
raise NotImplementedError.new("Playwright::#{expected_class_name_for(@impl.class)} is not implemented")
|
27
30
|
end
|
28
31
|
end
|
29
32
|
|
30
33
|
private
|
31
34
|
|
32
35
|
def expected_class_name_for(klass)
|
33
|
-
klass.name.split(
|
36
|
+
klass.name.split("::#{@module_name}::").last
|
37
|
+
end
|
38
|
+
|
39
|
+
def superclass_exist?(klass)
|
40
|
+
![::Playwright::ChannelOwner, ::Playwright::InputType, Object].include?(klass.superclass)
|
34
41
|
end
|
35
42
|
|
36
43
|
def detect_class_for(klass)
|
37
44
|
class_name = expected_class_name_for(klass)
|
38
45
|
if ::Playwright.const_defined?(class_name)
|
39
46
|
::Playwright.const_get(class_name)
|
47
|
+
elsif superclass_exist?(klass)
|
48
|
+
detect_class_for(klass.superclass)
|
40
49
|
else
|
41
|
-
|
42
|
-
nil
|
43
|
-
else
|
44
|
-
detect_class_for(klass.superclass)
|
45
|
-
end
|
50
|
+
nil
|
46
51
|
end
|
47
52
|
end
|
48
53
|
end
|
49
54
|
|
50
|
-
# @param
|
51
|
-
def initialize(
|
52
|
-
@
|
55
|
+
# @param impl [Playwright::ChannelOwner|Playwright::InputType]
|
56
|
+
def initialize(impl)
|
57
|
+
@impl = impl
|
53
58
|
end
|
54
59
|
|
55
60
|
def ==(other)
|
56
|
-
@
|
61
|
+
@impl.to_s == other.instance_variable_get(:'@impl').to_s
|
57
62
|
end
|
58
63
|
|
59
64
|
# @param block [Proc]
|
@@ -61,16 +66,19 @@ module Playwright
|
|
61
66
|
return nil unless block.is_a?(Proc)
|
62
67
|
|
63
68
|
-> (*args) {
|
64
|
-
wrapped_args = args.map { |arg|
|
69
|
+
wrapped_args = args.map { |arg| wrap_impl(arg) }
|
65
70
|
block.call(*wrapped_args)
|
66
71
|
}
|
67
72
|
end
|
68
73
|
|
69
|
-
private def
|
70
|
-
|
74
|
+
private def wrap_impl(object)
|
75
|
+
case object
|
76
|
+
when ChannelOwner
|
71
77
|
PlaywrightApi.from_channel_owner(object)
|
72
|
-
|
73
|
-
object
|
78
|
+
when InputType
|
79
|
+
Factory.new(object, 'InputTypes').create
|
80
|
+
when Array
|
81
|
+
object.map { |obj| wrap_impl(obj) }
|
74
82
|
else
|
75
83
|
object
|
76
84
|
end
|
@@ -9,7 +9,7 @@ module Playwright
|
|
9
9
|
attr_writer :default_timeout, :default_navigation_timeout
|
10
10
|
|
11
11
|
def navigation_timeout
|
12
|
-
@default_navigation_timeout || @default_timeout || @parent&.navigation_timeout ||
|
12
|
+
@default_navigation_timeout || @default_timeout || @parent&.navigation_timeout || DEFAULT_TIMEOUT
|
13
13
|
end
|
14
14
|
|
15
15
|
def timeout
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Playwright
|
2
|
+
class UrlMatcher
|
3
|
+
# @param url [String|Regexp]
|
4
|
+
def initialize(url)
|
5
|
+
@url = url
|
6
|
+
end
|
7
|
+
|
8
|
+
def match?(target_url)
|
9
|
+
case @url
|
10
|
+
when String
|
11
|
+
@url == target_url
|
12
|
+
when Regexp
|
13
|
+
@url.match?(target_url)
|
14
|
+
else
|
15
|
+
false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/playwright/version.rb
CHANGED
@@ -6,18 +6,18 @@ module Playwright
|
|
6
6
|
# Accessibility is a very platform-specific thing. On different platforms, there are different screen readers that might
|
7
7
|
# have wildly different output.
|
8
8
|
#
|
9
|
-
#
|
10
|
-
# platform-specific APIs. Accessibility namespace gives
|
9
|
+
# Rendering engines of Chromium, Firefox and Webkit have a concept of "accessibility tree", which is then translated into
|
10
|
+
# different platform-specific APIs. Accessibility namespace gives access to this Accessibility Tree.
|
11
11
|
#
|
12
|
-
# Most of the accessibility tree gets filtered out when converting from
|
13
|
-
# assistive technologies themselves. By default, Playwright tries to approximate this filtering, exposing
|
14
|
-
# "interesting" nodes of the tree.
|
12
|
+
# Most of the accessibility tree gets filtered out when converting from internal browser AX Tree to Platform-specific
|
13
|
+
# AX-Tree or by assistive technologies themselves. By default, Playwright tries to approximate this filtering, exposing
|
14
|
+
# only the "interesting" nodes of the tree.
|
15
15
|
class Accessibility < PlaywrightApi
|
16
16
|
|
17
17
|
# Captures the current state of the accessibility tree. The returned object represents the root accessible node of the
|
18
18
|
# page.
|
19
19
|
#
|
20
|
-
# >
|
20
|
+
# > NOTE: The Chromium accessibility tree contains nodes that go unused on most platforms and by most screen readers.
|
21
21
|
# Playwright will discard them as well for an easier to process tree, unless `interestingOnly` is set to `false`.
|
22
22
|
#
|
23
23
|
# An example of dumping the entire accessibility tree:
|
@@ -28,6 +28,16 @@ module Playwright
|
|
28
28
|
# console.log(snapshot);
|
29
29
|
# ```
|
30
30
|
#
|
31
|
+
# ```python async
|
32
|
+
# snapshot = await page.accessibility.snapshot()
|
33
|
+
# print(snapshot)
|
34
|
+
# ```
|
35
|
+
#
|
36
|
+
# ```python sync
|
37
|
+
# snapshot = page.accessibility.snapshot()
|
38
|
+
# print(snapshot)
|
39
|
+
# ```
|
40
|
+
#
|
31
41
|
# An example of logging the focused node's name:
|
32
42
|
#
|
33
43
|
#
|
@@ -46,6 +56,36 @@ module Playwright
|
|
46
56
|
# return null;
|
47
57
|
# }
|
48
58
|
# ```
|
59
|
+
#
|
60
|
+
# ```python async
|
61
|
+
# def find_focused_node(node):
|
62
|
+
# if (node.get("focused"))
|
63
|
+
# return node
|
64
|
+
# for child in (node.get("children") or []):
|
65
|
+
# found_node = find_focused_node(child)
|
66
|
+
# return found_node
|
67
|
+
# return None
|
68
|
+
#
|
69
|
+
# snapshot = await page.accessibility.snapshot()
|
70
|
+
# node = find_focused_node(snapshot)
|
71
|
+
# if node:
|
72
|
+
# print(node["name"])
|
73
|
+
# ```
|
74
|
+
#
|
75
|
+
# ```python sync
|
76
|
+
# def find_focused_node(node):
|
77
|
+
# if (node.get("focused"))
|
78
|
+
# return node
|
79
|
+
# for child in (node.get("children") or []):
|
80
|
+
# found_node = find_focused_node(child)
|
81
|
+
# return found_node
|
82
|
+
# return None
|
83
|
+
#
|
84
|
+
# snapshot = page.accessibility.snapshot()
|
85
|
+
# node = find_focused_node(snapshot)
|
86
|
+
# if node:
|
87
|
+
# print(node["name"])
|
88
|
+
# ```
|
49
89
|
def snapshot(interestingOnly: nil, root: nil)
|
50
90
|
raise NotImplementedError.new('snapshot is not implemented yet.')
|
51
91
|
end
|
@@ -4,20 +4,20 @@ module Playwright
|
|
4
4
|
|
5
5
|
# -- inherited from EventEmitter --
|
6
6
|
# @nodoc
|
7
|
-
def
|
8
|
-
|
7
|
+
def on(event, callback)
|
8
|
+
wrap_impl(@impl.on(event, callback))
|
9
9
|
end
|
10
10
|
|
11
11
|
# -- inherited from EventEmitter --
|
12
12
|
# @nodoc
|
13
|
-
def
|
14
|
-
|
13
|
+
def off(event, callback)
|
14
|
+
wrap_impl(@impl.off(event, callback))
|
15
15
|
end
|
16
16
|
|
17
17
|
# -- inherited from EventEmitter --
|
18
18
|
# @nodoc
|
19
|
-
def
|
20
|
-
|
19
|
+
def once(event, callback)
|
20
|
+
wrap_impl(@impl.once(event, callback))
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Playwright
|
2
|
-
# - extends: [EventEmitter]
|
2
|
+
# - extends: [EventEmitter]
|
3
3
|
#
|
4
4
|
# A Browser is created via [`method: BrowserType.launch`]. An example of using a `Browser` to create a [Page]:
|
5
5
|
#
|
@@ -15,8 +15,36 @@ module Playwright
|
|
15
15
|
# })();
|
16
16
|
# ```
|
17
17
|
#
|
18
|
-
#
|
19
|
-
#
|
18
|
+
# ```python async
|
19
|
+
# import asyncio
|
20
|
+
# from playwright.async_api import async_playwright
|
21
|
+
#
|
22
|
+
# async def run(playwright):
|
23
|
+
# firefox = playwright.firefox
|
24
|
+
# browser = await firefox.launch()
|
25
|
+
# page = await browser.new_page()
|
26
|
+
# await page.goto("https://example.com")
|
27
|
+
# await browser.close()
|
28
|
+
#
|
29
|
+
# async def main():
|
30
|
+
# async with async_playwright() as playwright:
|
31
|
+
# await run(playwright)
|
32
|
+
# asyncio.run(main())
|
33
|
+
# ```
|
34
|
+
#
|
35
|
+
# ```python sync
|
36
|
+
# from playwright.sync_api import sync_playwright
|
37
|
+
#
|
38
|
+
# def run(playwright):
|
39
|
+
# firefox = playwright.firefox
|
40
|
+
# browser = firefox.launch()
|
41
|
+
# page = browser.new_page()
|
42
|
+
# page.goto("https://example.com")
|
43
|
+
# browser.close()
|
44
|
+
#
|
45
|
+
# with sync_playwright() as playwright:
|
46
|
+
# run(playwright)
|
47
|
+
# ```
|
20
48
|
class Browser < PlaywrightApi
|
21
49
|
|
22
50
|
# In case this browser is obtained using [`method: BrowserType.launch`], closes the browser and all of its pages (if any
|
@@ -27,7 +55,7 @@ module Playwright
|
|
27
55
|
#
|
28
56
|
# The `Browser` object itself is considered to be disposed and cannot be used anymore.
|
29
57
|
def close
|
30
|
-
|
58
|
+
wrap_impl(@impl.close)
|
31
59
|
end
|
32
60
|
|
33
61
|
# Returns an array of all open browser contexts. In a newly created browser, this will return zero browser contexts.
|
@@ -40,13 +68,27 @@ module Playwright
|
|
40
68
|
# const context = await browser.newContext();
|
41
69
|
# console.log(browser.contexts().length); // prints `1`
|
42
70
|
# ```
|
71
|
+
#
|
72
|
+
# ```python async
|
73
|
+
# browser = await pw.webkit.launch()
|
74
|
+
# print(len(browser.contexts())) # prints `0`
|
75
|
+
# context = await browser.new_context()
|
76
|
+
# print(len(browser.contexts())) # prints `1`
|
77
|
+
# ```
|
78
|
+
#
|
79
|
+
# ```python sync
|
80
|
+
# browser = pw.webkit.launch()
|
81
|
+
# print(len(browser.contexts())) # prints `0`
|
82
|
+
# context = browser.new_context()
|
83
|
+
# print(len(browser.contexts())) # prints `1`
|
84
|
+
# ```
|
43
85
|
def contexts
|
44
|
-
|
86
|
+
wrap_impl(@impl.contexts)
|
45
87
|
end
|
46
88
|
|
47
89
|
# Indicates that the browser is connected.
|
48
90
|
def connected?
|
49
|
-
|
91
|
+
wrap_impl(@impl.connected?)
|
50
92
|
end
|
51
93
|
|
52
94
|
# Creates a new browser context. It won't share cookies/cache with other browser contexts.
|
@@ -62,6 +104,24 @@ module Playwright
|
|
62
104
|
# await page.goto('https://example.com');
|
63
105
|
# })();
|
64
106
|
# ```
|
107
|
+
#
|
108
|
+
# ```python async
|
109
|
+
# browser = await playwright.firefox.launch() # or "chromium" or "webkit".
|
110
|
+
# # create a new incognito browser context.
|
111
|
+
# context = await browser.new_context()
|
112
|
+
# # create a new page in a pristine context.
|
113
|
+
# page = await context.new_page()
|
114
|
+
# await page.goto("https://example.com")
|
115
|
+
# ```
|
116
|
+
#
|
117
|
+
# ```python sync
|
118
|
+
# browser = playwright.firefox.launch() # or "chromium" or "webkit".
|
119
|
+
# # create a new incognito browser context.
|
120
|
+
# context = browser.new_context()
|
121
|
+
# # create a new page in a pristine context.
|
122
|
+
# page = context.new_page()
|
123
|
+
# page.goto("https://example.com")
|
124
|
+
# ```
|
65
125
|
def new_context(
|
66
126
|
acceptDownloads: nil,
|
67
127
|
bypassCSP: nil,
|
@@ -87,7 +147,7 @@ module Playwright
|
|
87
147
|
videoSize: nil,
|
88
148
|
videosPath: nil,
|
89
149
|
viewport: nil)
|
90
|
-
|
150
|
+
wrap_impl(@impl.new_context(acceptDownloads: acceptDownloads, bypassCSP: bypassCSP, colorScheme: colorScheme, deviceScaleFactor: deviceScaleFactor, extraHTTPHeaders: extraHTTPHeaders, geolocation: geolocation, hasTouch: hasTouch, httpCredentials: httpCredentials, ignoreHTTPSErrors: ignoreHTTPSErrors, isMobile: isMobile, javaScriptEnabled: javaScriptEnabled, locale: locale, logger: logger, offline: offline, permissions: permissions, proxy: proxy, recordHar: recordHar, recordVideo: recordVideo, storageState: storageState, timezoneId: timezoneId, userAgent: userAgent, videoSize: videoSize, videosPath: videosPath, viewport: viewport))
|
91
151
|
end
|
92
152
|
|
93
153
|
# Creates a new page in a new browser context. Closing this page will close the context as well.
|
@@ -120,35 +180,35 @@ module Playwright
|
|
120
180
|
videoSize: nil,
|
121
181
|
videosPath: nil,
|
122
182
|
viewport: nil)
|
123
|
-
|
183
|
+
wrap_impl(@impl.new_page(acceptDownloads: acceptDownloads, bypassCSP: bypassCSP, colorScheme: colorScheme, deviceScaleFactor: deviceScaleFactor, extraHTTPHeaders: extraHTTPHeaders, geolocation: geolocation, hasTouch: hasTouch, httpCredentials: httpCredentials, ignoreHTTPSErrors: ignoreHTTPSErrors, isMobile: isMobile, javaScriptEnabled: javaScriptEnabled, locale: locale, logger: logger, offline: offline, permissions: permissions, proxy: proxy, recordHar: recordHar, recordVideo: recordVideo, storageState: storageState, timezoneId: timezoneId, userAgent: userAgent, videoSize: videoSize, videosPath: videosPath, viewport: viewport))
|
124
184
|
end
|
125
185
|
|
126
186
|
# Returns the browser version.
|
127
187
|
def version
|
128
|
-
|
188
|
+
wrap_impl(@impl.version)
|
129
189
|
end
|
130
190
|
|
131
191
|
# @nodoc
|
132
192
|
def after_initialize
|
133
|
-
|
193
|
+
wrap_impl(@impl.after_initialize)
|
134
194
|
end
|
135
195
|
|
136
196
|
# -- inherited from EventEmitter --
|
137
197
|
# @nodoc
|
138
|
-
def
|
139
|
-
|
198
|
+
def on(event, callback)
|
199
|
+
wrap_impl(@impl.on(event, callback))
|
140
200
|
end
|
141
201
|
|
142
202
|
# -- inherited from EventEmitter --
|
143
203
|
# @nodoc
|
144
|
-
def
|
145
|
-
|
204
|
+
def off(event, callback)
|
205
|
+
wrap_impl(@impl.off(event, callback))
|
146
206
|
end
|
147
207
|
|
148
208
|
# -- inherited from EventEmitter --
|
149
209
|
# @nodoc
|
150
|
-
def
|
151
|
-
|
210
|
+
def once(event, callback)
|
211
|
+
wrap_impl(@impl.once(event, callback))
|
152
212
|
end
|
153
213
|
end
|
154
214
|
end
|