Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
191465ac
Unverified
Commit
191465ac
authored
Apr 10, 2023
by
joshualitt
Committed by
GitHub
Apr 10, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[web] Migrate the bulk of JS interop to JS types. (#123286)
parent
1a98273a
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
179 additions
and
110 deletions
+179
-110
_capabilities_web.dart
packages/flutter/lib/src/foundation/_capabilities_web.dart
+2
-1
_network_image_web.dart
packages/flutter/lib/src/painting/_network_image_web.dart
+6
-6
dom.dart
packages/flutter/lib/src/services/dom.dart
+135
-73
_platform_selectable_region_context_menu_web.dart
...widgets/_platform_selectable_region_context_menu_web.dart
+1
-2
_test_http_request.dart
packages/flutter/test/painting/_test_http_request.dart
+35
-28
No files found.
packages/flutter/lib/src/foundation/_capabilities_web.dart
View file @
191465ac
...
...
@@ -2,12 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:js_interop'
;
import
'package:js/js.dart'
;
// This value is set by the engine. It is used to determine if the application is
// using canvaskit.
@JS
(
'window.flutterCanvasKit'
)
external
Object
?
get
_windowFlutterCanvasKit
;
external
JSAny
?
get
_windowFlutterCanvasKit
;
/// The web implementation of [isCanvasKit]
bool
get
isCanvasKit
=>
_windowFlutterCanvasKit
!=
null
;
packages/flutter/lib/src/painting/_network_image_web.dart
View file @
191465ac
...
...
@@ -3,11 +3,10 @@
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:
typed_data
'
;
import
'dart:
js_interop
'
;
import
'dart:ui'
as
ui
;
import
'package:flutter/foundation.dart'
;
import
'package:js/js.dart'
;
import
'../services/dom.dart'
;
import
'image_provider.dart'
as
image_provider
;
...
...
@@ -18,7 +17,7 @@ typedef HttpRequestFactory = DomXMLHttpRequest Function();
/// Default HTTP client.
DomXMLHttpRequest
_httpClient
(
)
{
return
create
DomXMLHttpRequest
();
return
DomXMLHttpRequest
();
}
/// Creates an overridable factory function.
...
...
@@ -148,7 +147,7 @@ class NetworkImage
});
}
request
.
addEventListener
(
'load'
,
allowInterop
((
DomEvent
e
)
{
request
.
addEventListener
(
'load'
,
createDomEventListener
((
DomEvent
e
)
{
final
int
?
status
=
request
.
status
;
final
bool
accepted
=
status
!
>=
200
&&
status
<
300
;
final
bool
fileUri
=
status
==
0
;
// file:// URIs have status of 0.
...
...
@@ -166,13 +165,14 @@ class NetworkImage
}
}));
request
.
addEventListener
(
'error'
,
allowInterop
(
completer
.
completeError
));
request
.
addEventListener
(
'error'
,
createDomEventListener
(
completer
.
completeError
));
request
.
send
();
await
completer
.
future
;
final
Uint8List
bytes
=
(
request
.
response
as
ByteBuffer
)
.
asUint8List
();
final
Uint8List
bytes
=
(
request
.
response
!
as
JSArrayBuffer
).
toDart
.
asUint8List
();
if
(
bytes
.
lengthInBytes
==
0
)
{
throw
image_provider
.
NetworkImageLoadException
(
...
...
packages/flutter/lib/src/services/dom.dart
View file @
191465ac
...
...
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:js_interop'
;
import
'package:js/js.dart'
;
import
'package:js/js_util.dart'
as
js_util
;
/// This file includes static interop helpers for Flutter Web.
// TODO(joshualitt): This file will eventually be removed,
...
...
@@ -16,8 +16,11 @@ class DomWindow {}
/// [DomWindow] required extension.
extension
DomWindowExtension
on
DomWindow
{
@JS
(
'matchMedia'
)
external
DomMediaQueryList
_matchMedia
(
JSString
?
query
);
/// Returns a [DomMediaQueryList] of the media that matches [query].
external
DomMediaQueryList
matchMedia
(
String
?
query
);
DomMediaQueryList
matchMedia
(
String
?
query
)
=>
_matchMedia
(
query
?.
toJS
);
/// Returns the [DomNavigator] associated with this window.
external
DomNavigator
get
navigator
;
...
...
@@ -37,8 +40,11 @@ class DomMediaQueryList {}
/// [DomMediaQueryList] required extension.
extension
DomMediaQueryListExtension
on
DomMediaQueryList
{
@JS
(
'matches'
)
external
JSBoolean
get
_matches
;
/// Whether or not the query matched.
external
bool
get
matches
;
bool
get
matches
=>
_matches
.
toDart
;
}
/// [DomNavigator] interop object.
...
...
@@ -48,8 +54,11 @@ class DomNavigator {}
/// [DomNavigator] required extension.
extension
DomNavigatorExtension
on
DomNavigator
{
@JS
(
'platform'
)
external
JSString
?
get
_platform
;
/// The underyling platform string.
external
String
?
get
platform
;
String
?
get
platform
=>
_platform
?.
toDart
;
}
/// A DOM event target.
...
...
@@ -59,56 +68,93 @@ class DomEventTarget {}
/// [DomEventTarget]'s required extension.
extension
DomEventTargetExtension
on
DomEventTarget
{
@JS
(
'addEventListener'
)
external
JSVoid
_addEventListener1
(
JSString
type
,
DomEventListener
?
listener
);
@JS
(
'addEventListener'
)
external
JSVoid
_addEventListener2
(
JSString
type
,
DomEventListener
?
listener
,
JSBoolean
useCapture
);
/// Adds an event listener to this event target.
@JS
(
'addEventListener'
)
void
addEventListener
(
String
type
,
DomEventListener
?
listener
,
[
bool
?
useCapture
])
{
if
(
listener
!=
null
)
{
js_util
.
callMethod
(
this
,
'addEventListener'
,
<
Object
>[
type
,
listener
,
if
(
useCapture
!=
null
)
useCapture
]);
if
(
useCapture
==
null
)
{
_addEventListener1
(
type
.
toJS
,
listener
);
}
else
{
_addEventListener2
(
type
.
toJS
,
listener
,
useCapture
.
toJS
);
}
}
}
}
/// [DomXMLHttpRequest] interop class.
@JS
()
@JS
(
'XMLHttpRequest'
)
@staticInterop
class
DomXMLHttpRequest
extends
DomEventTarget
{}
class
DomXMLHttpRequest
extends
DomEventTarget
{
/// Constructor for [DomXMLHttpRequest].
external
factory
DomXMLHttpRequest
();
}
/// [DomXMLHttpRequest] extension.
extension
DomXMLHttpRequestExtension
on
DomXMLHttpRequest
{
/// Gets the response.
external
dynamic
get
response
;
external
JSAny
?
get
response
;
@JS
(
'responseText'
)
external
JSString
?
get
_responseText
;
/// Gets the response text.
external
String
?
get
responseText
;
String
?
get
responseText
=>
_responseText
?.
toDart
;
@JS
(
'responseType'
)
external
JSString
get
_responseType
;
/// Gets the response type.
external
String
get
responseType
;
String
get
responseType
=>
_responseType
.
toDart
;
@JS
(
'status'
)
external
JSNumber
?
get
_status
;
/// Gets the status.
external
int
?
get
status
;
int
?
get
status
=>
_status
?.
toDart
.
toInt
();
@JS
(
'responseType'
)
external
set
_responseType
(
JSString
value
);
/// Set the response type.
external
set
responseType
(
String
value
);
set
responseType
(
String
value
)
=>
_responseType
=
value
.
toJS
;
@JS
(
'setRequestHeader'
)
external
void
_setRequestHeader
(
JSString
header
,
JSString
value
);
/// Set the request header.
external
void
setRequestHeader
(
String
header
,
String
value
);
void
setRequestHeader
(
String
header
,
String
value
)
=>
_setRequestHeader
(
header
.
toJS
,
value
.
toJS
);
@JS
(
'open'
)
external
JSVoid
_open
(
JSString
method
,
JSString
url
,
JSBoolean
isAsync
);
/// Open the request.
void
open
(
String
method
,
String
url
,
bool
isAsync
)
=>
js_util
.
callMethod
(
this
,
'open'
,
<
Object
>[
method
,
url
,
isAsync
]
);
void
open
(
String
method
,
String
url
,
bool
isAsync
)
=>
_open
(
method
.
toJS
,
url
.
toJS
,
isAsync
.
toJS
);
/// Send the request.
void
send
()
=>
js_util
.
callMethod
(
this
,
'send'
,
<
Object
>[]
);
external
JSVoid
send
(
);
}
/// Factory function for creating [DomXMLHttpRequest].
DomXMLHttpRequest
createDomXMLHttpRequest
(
)
=>
domCallConstructorString
(
'XMLHttpRequest'
,
<
Object
?>[])!
as
DomXMLHttpRequest
;
/// Type for event listener.
typedef
DomEventListener
=
void
Function
(
DomEvent
event
);
typedef
DartDomEventListener
=
JSVoid
Function
(
DomEvent
event
);
/// The type of [JSFunction] expected as an `EventListener`.
@JS
()
@staticInterop
class
DomEventListener
{}
/// Creates a [DomEventListener] from a [DartDomEventListener].
DomEventListener
createDomEventListener
(
DartDomEventListener
listener
)
=>
listener
.
toJS
as
DomEventListener
;
/// [DomEvent] interop object.
@JS
()
...
...
@@ -117,16 +163,15 @@ class DomEvent {}
/// [DomEvent] required extension.
extension
DomEventExtension
on
DomEvent
{
@JS
(
'type'
)
external
JSString
get
_type
;
/// Get the event type.
external
String
get
type
;
String
get
type
=>
_type
.
toDart
;
/// Initialize an event.
void
initEvent
(
String
type
,
[
bool
?
bubbles
,
bool
?
cancelable
])
=>
js_util
.
callMethod
(
this
,
'initEvent'
,
<
Object
>[
type
,
if
(
bubbles
!=
null
)
bubbles
,
if
(
cancelable
!=
null
)
cancelable
]);
external
JSVoid
initEvent
(
JSString
type
,
JSBoolean
bubbles
,
JSBoolean
cancelable
);
}
/// [DomProgressEvent] interop object.
...
...
@@ -136,24 +181,17 @@ class DomProgressEvent extends DomEvent {}
/// [DomProgressEvent] required extension.
extension
DomProgressEventExtension
on
DomProgressEvent
{
/// Amount of work done.
external
int
?
get
loaded
;
@JS
(
'loaded'
)
external
JSNumber
?
get
_
loaded
;
/// Total amount of work.
external
int
?
get
total
;
}
/// Amount of work done.
int
?
get
loaded
=>
_loaded
?.
toDart
.
toInt
();
/// Gets a constructor from a [String].
Object
?
domGetConstructor
(
String
constructorName
)
=>
js_util
.
getProperty
(
domWindow
,
constructorName
);
@JS
(
'total'
)
external
JSNumber
?
get
_total
;
/// Calls a constructor as a [String].
Object
?
domCallConstructorString
(
String
constructorName
,
List
<
Object
?>
args
)
{
final
Object
?
constructor
=
domGetConstructor
(
constructorName
);
if
(
constructor
==
null
)
{
return
null
;
}
return
js_util
.
callConstructor
(
constructor
,
args
);
/// Total amount of work.
int
?
get
total
=>
_total
?.
toDart
.
toInt
();
}
/// The underlying DOM document.
...
...
@@ -163,8 +201,11 @@ class DomDocument {}
/// [DomDocument]'s required extension.
extension
DomDocumentExtension
on
DomDocument
{
@JS
(
'createEvent'
)
external
DomEvent
_createEvent
(
JSString
eventType
);
/// Creates an event.
external
DomEvent
createEvent
(
String
eventType
);
DomEvent
createEvent
(
String
eventType
)
=>
_createEvent
(
eventType
.
toJS
);
/// Creates a range.
external
DomRange
createRange
();
...
...
@@ -172,10 +213,9 @@ extension DomDocumentExtension on DomDocument {
/// Gets the head element.
external
DomHTMLHeadElement
?
get
head
;
/// Creates a new element.
DomElement
createElement
(
String
name
,
[
Object
?
options
])
=>
js_util
.
callMethod
(
this
,
'createElement'
,
<
Object
>[
name
,
if
(
options
!=
null
)
options
])
as
DomElement
;
/// Creates a [DomElement].
@JS
(
'createElement'
)
external
DomElement
createElement
(
JSString
name
);
}
/// Returns the top level document.
...
...
@@ -185,14 +225,10 @@ external DomDocument get domDocument;
/// Creates a new DOM event.
DomEvent
createDomEvent
(
String
type
,
String
name
)
{
final
DomEvent
event
=
domDocument
.
createEvent
(
type
);
event
.
initEvent
(
name
,
true
,
true
);
event
.
initEvent
(
name
.
toJS
,
true
.
toJS
,
true
.
toJS
);
return
event
;
}
/// Defines a new property on an Object.
@JS
(
'Object.defineProperty'
)
external
void
objectDefineProperty
(
Object
o
,
String
symbol
,
dynamic
desc
);
/// A Range object.
@JS
()
@staticInterop
...
...
@@ -201,7 +237,7 @@ class DomRange {}
/// [DomRange]'s required extension.
extension
DomRangeExtension
on
DomRange
{
/// Selects the provided node.
external
v
oid
selectNode
(
DomNode
node
);
external
JSV
oid
selectNode
(
DomNode
node
);
}
/// A node in the DOM.
...
...
@@ -211,11 +247,14 @@ class DomNode extends DomEventTarget {}
/// [DomNode]'s required extension.
extension
DomNodeExtension
on
DomNode
{
@JS
(
'innerText'
)
external
set
_innerText
(
JSString
text
);
/// Sets the innerText of this node.
external
set
innerText
(
String
text
)
;
set
innerText
(
String
text
)
=>
_innerText
=
text
.
toJS
;
/// Appends a node this node.
external
v
oid
append
(
DomNode
node
);
external
JSV
oid
append
(
DomNode
node
);
}
/// An element in the DOM.
...
...
@@ -249,14 +288,23 @@ class DomMouseEvent extends DomUIEvent {}
/// [DomMouseEvent]'s required extension.
extension
DomMouseEventExtension
on
DomMouseEvent
{
@JS
(
'offsetX'
)
external
JSNumber
get
_offsetX
;
/// Returns the current x offset.
external
num
get
offsetX
;
num
get
offsetX
=>
_offsetX
.
toDart
;
@JS
(
'offsetY'
)
external
JSNumber
get
_offsetY
;
/// Returns the current y offset.
external
num
get
offsetY
;
num
get
offsetY
=>
_offsetY
.
toDart
;
@JS
(
'button'
)
external
JSNumber
get
_button
;
/// Returns the current button.
external
int
get
button
;
int
get
button
=>
_button
.
toDart
.
toInt
()
;
}
/// A DOM selection.
...
...
@@ -267,10 +315,10 @@ class DomSelection {}
/// [DomSelection]'s required extension.
extension
DomSelectionExtension
on
DomSelection
{
/// Removes all ranges from this selection.
external
v
oid
removeAllRanges
();
external
JSV
oid
removeAllRanges
();
/// Adds a range to this selection.
external
v
oid
addRange
(
DomRange
range
);
external
JSV
oid
addRange
(
DomRange
range
);
}
/// A DOM html div element.
...
...
@@ -280,7 +328,7 @@ class DomHTMLDivElement extends DomHTMLElement {}
/// Factory constructor for [DomHTMLDivElement].
DomHTMLDivElement
createDomHTMLDivElement
(
)
=>
domDocument
.
createElement
(
'div'
)
as
DomHTMLDivElement
;
domDocument
.
createElement
(
'div'
.
toJS
)
as
DomHTMLDivElement
;
/// An html style element.
@JS
()
...
...
@@ -295,7 +343,7 @@ extension DomHTMLStyleElementExtension on DomHTMLStyleElement {
/// Factory constructor for [DomHTMLStyleElement].
DomHTMLStyleElement
createDomHTMLStyleElement
(
)
=>
domDocument
.
createElement
(
'style'
)
as
DomHTMLStyleElement
;
domDocument
.
createElement
(
'style'
.
toJS
)
as
DomHTMLStyleElement
;
/// CSS styles.
@JS
()
...
...
@@ -310,11 +358,14 @@ extension DomCSSStyleDeclarationExtension on DomCSSStyleDeclaration {
/// Sets the height.
set
height
(
String
value
)
=>
setProperty
(
'height'
,
value
);
@JS
(
'setProperty'
)
external
JSVoid
_setProperty
(
JSString
propertyName
,
JSString
value
,
JSString
priority
);
/// Sets a CSS property by name.
void
setProperty
(
String
propertyName
,
String
value
,
[
String
?
priority
])
{
priority
??=
''
;
js_util
.
callMethod
(
this
,
'setProperty'
,
<
Object
>[
propertyName
,
value
,
priority
]);
_setProperty
(
propertyName
.
toJS
,
value
.
toJS
,
priority
.
toJS
);
}
}
...
...
@@ -335,12 +386,20 @@ class DomCSSStyleSheet extends DomStyleSheet {}
/// [DomCSSStyleSheet]'s required extension.
extension
DomCSSStyleSheetExtension
on
DomCSSStyleSheet
{
@JS
(
'insertRule'
)
external
JSNumber
_insertRule1
(
JSString
rule
);
@JS
(
'insertRule'
)
external
JSNumber
_insertRule2
(
JSString
rule
,
JSNumber
index
);
/// Inserts a rule into this style sheet.
int
insertRule
(
String
rule
,
[
int
?
index
])
=>
js_util
.
callMethod
<
double
>(
this
,
'insertRule'
,
<
Object
>[
rule
,
if
(
index
!=
null
)
index
.
toDouble
()
]).
toInt
();
int
insertRule
(
String
rule
,
[
int
?
index
])
{
if
(
index
==
null
)
{
return
_insertRule1
(
rule
.
toJS
).
toDart
.
toInt
();
}
else
{
return
_insertRule2
(
rule
.
toJS
,
index
.
toDouble
().
toJS
).
toDart
.
toInt
();
}
}
}
/// A list of token.
...
...
@@ -350,6 +409,9 @@ class DomTokenList {}
/// [DomTokenList]'s required extension.
extension
DomTokenListExtension
on
DomTokenList
{
@JS
(
'add'
)
external
JSVoid
_add
(
JSString
value
);
/// Adds a token to this token list.
external
void
add
(
String
value
);
void
add
(
String
value
)
=>
_add
(
value
.
toJS
);
}
packages/flutter/lib/src/widgets/_platform_selectable_region_context_menu_web.dart
View file @
191465ac
...
...
@@ -5,7 +5,6 @@
import
'dart:ui'
as
ui
;
import
'package:flutter/rendering.dart'
;
import
'package:js/js.dart'
;
import
'../services/dom.dart'
;
import
'basic.dart'
;
...
...
@@ -115,7 +114,7 @@ class PlatformSelectableRegionContextMenu extends StatelessWidget {
sheet
.
insertRule
(
_kClassRule
,
0
);
sheet
.
insertRule
(
_kClassSelectionRule
,
1
);
htmlElement
.
addEventListener
(
'mousedown'
,
allowInterop
((
DomEvent
event
)
{
htmlElement
.
addEventListener
(
'mousedown'
,
createDomEventListener
((
DomEvent
event
)
{
final
DomMouseEvent
mouseEvent
=
event
as
DomMouseEvent
;
if
(
mouseEvent
.
button
!=
_kRightClickButton
)
{
return
;
...
...
packages/flutter/test/painting/_test_http_request.dart
View file @
191465ac
...
...
@@ -2,19 +2,25 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:js_interop'
;
import
'package:flutter/src/services/dom.dart'
;
import
'package:js/js.dart'
;
import
'package:js/js_util.dart'
as
js_util
;
void
createGetter
<
T
>(
Object
mock
,
String
key
,
T
Function
()
get
)
{
/// Defines a new property on an Object.
@JS
(
'Object.defineProperty'
)
external
JSVoid
objectDefineProperty
(
JSAny
o
,
JSString
symbol
,
JSAny
desc
);
void
createGetter
(
JSAny
mock
,
String
key
,
JSAny
?
Function
()
get
)
{
objectDefineProperty
(
mock
,
key
,
key
.
toJS
,
js_util
.
jsify
(
<
dynamic
,
dynamic
>{
'get'
:
allowInterop
(()
=>
get
())
<
String
,
Object
>{
'get'
:
()
{
return
get
();
}.
toJS
}
));
)
as
JSAny
);
}
@JS
()
...
...
@@ -22,46 +28,47 @@ void createGetter<T>(Object mock, String key, T Function() get) {
@anonymous
class
DomXMLHttpRequestMock
{
external
factory
DomXMLHttpRequestMock
({
void
Function
(
String
method
,
String
url
,
bool
async
)
?
open
,
String
responseType
=
'invalid'
,
int
timeout
=
10
,
bool
withCredentials
=
false
,
void
Function
()
?
send
,
void
Function
(
String
name
,
String
value
)
?
setRequestHeader
,
void
Function
(
String
type
,
DomEventListener
listener
)
addEventListener
,
JSFunction
?
open
,
JSString
responseType
,
JSNumber
timeout
,
JSBoolean
withCredentials
,
JSFunction
?
send
,
JSFunction
?
setRequestHeader
,
JSFunction
addEventListener
,
});
}
class
TestHttpRequest
{
TestHttpRequest
()
{
_mock
=
DomXMLHttpRequestMock
(
open:
allowInterop
(
open
)
,
send:
allowInterop
(
send
)
,
setRequestHeader:
allowInterop
(
setRequestHeader
)
,
addEventListener:
a
llowInterop
(
addEventListener
)
,
open:
open
.
toJS
,
send:
send
.
toJS
,
setRequestHeader:
setRequestHeader
.
toJS
,
addEventListener:
a
ddEventListener
.
toJS
,
);
createGetter
(
_mock
,
'headers'
,
()
=>
headers
);
createGetter
(
_mock
,
'responseHeaders'
,
()
=>
responseHeaders
);
createGetter
(
_mock
,
'status'
,
()
=>
status
);
createGetter
(
_mock
,
'response'
,
()
=>
response
);
createGetter
(
_mock
,
'headers'
,
()
=>
js_util
.
jsify
(
headers
)
as
JSAny
);
createGetter
(
_mock
,
'responseHeaders'
,
()
=>
js_util
.
jsify
(
responseHeaders
)
as
JSAny
);
createGetter
(
_mock
,
'status'
,
()
=>
status
.
toJS
);
createGetter
(
_mock
,
'response'
,
()
=>
js_util
.
jsify
(
response
)
as
JSAny
);
}
late
DomXMLHttpRequestMock
_mock
;
MockEvent
?
mockEvent
;
Map
<
String
,
String
>
headers
=
<
String
,
String
>{};
int
status
=
-
1
;
dynamic
response
;
Object
?
response
;
Map
<
String
,
String
>
get
responseHeaders
=>
headers
;
void
open
(
String
method
,
String
url
,
bool
async
)
{}
v
oid
send
()
{}
void
setRequestHeader
(
String
name
,
String
value
)
{
headers
[
name
]
=
value
;
JSVoid
open
(
JSString
method
,
JSString
url
,
JSBoolean
async
)
{}
JSV
oid
send
()
{}
JSVoid
setRequestHeader
(
JSString
name
,
JS
String
value
)
{
headers
[
name
.
toDart
]
=
value
.
toDart
;
}
void
addEventListener
(
String
type
,
DomEventListener
listener
)
{
if
(
type
==
mockEvent
?.
type
)
{
listener
(
mockEvent
!.
event
);
JSVoid
addEventListener
(
JS
String
type
,
DomEventListener
listener
)
{
if
(
type
.
toDart
==
mockEvent
?.
type
)
{
(
listener
.
toDart
as
DartDomEventListener
)
(
mockEvent
!.
event
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment