mithwire 0.50.3__py3-none-any.whl

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 (76) hide show
  1. mithwire/__init__.py +32 -0
  2. mithwire/cdp/README.md +4 -0
  3. mithwire/cdp/__init__.py +6 -0
  4. mithwire/cdp/accessibility.py +668 -0
  5. mithwire/cdp/animation.py +494 -0
  6. mithwire/cdp/audits.py +1995 -0
  7. mithwire/cdp/autofill.py +292 -0
  8. mithwire/cdp/background_service.py +215 -0
  9. mithwire/cdp/bluetooth_emulation.py +626 -0
  10. mithwire/cdp/browser.py +821 -0
  11. mithwire/cdp/cache_storage.py +311 -0
  12. mithwire/cdp/cast.py +172 -0
  13. mithwire/cdp/console.py +107 -0
  14. mithwire/cdp/crash_report_context.py +55 -0
  15. mithwire/cdp/css.py +2750 -0
  16. mithwire/cdp/database.py +179 -0
  17. mithwire/cdp/debugger.py +1405 -0
  18. mithwire/cdp/device_access.py +141 -0
  19. mithwire/cdp/device_orientation.py +45 -0
  20. mithwire/cdp/dom.py +2257 -0
  21. mithwire/cdp/dom_debugger.py +321 -0
  22. mithwire/cdp/dom_snapshot.py +876 -0
  23. mithwire/cdp/dom_storage.py +222 -0
  24. mithwire/cdp/emulation.py +1779 -0
  25. mithwire/cdp/event_breakpoints.py +56 -0
  26. mithwire/cdp/extensions.py +238 -0
  27. mithwire/cdp/fed_cm.py +283 -0
  28. mithwire/cdp/fetch.py +507 -0
  29. mithwire/cdp/file_system.py +115 -0
  30. mithwire/cdp/headless_experimental.py +115 -0
  31. mithwire/cdp/heap_profiler.py +401 -0
  32. mithwire/cdp/indexed_db.py +528 -0
  33. mithwire/cdp/input_.py +701 -0
  34. mithwire/cdp/inspector.py +95 -0
  35. mithwire/cdp/io.py +101 -0
  36. mithwire/cdp/layer_tree.py +464 -0
  37. mithwire/cdp/log.py +190 -0
  38. mithwire/cdp/media.py +313 -0
  39. mithwire/cdp/memory.py +305 -0
  40. mithwire/cdp/network.py +5342 -0
  41. mithwire/cdp/overlay.py +1468 -0
  42. mithwire/cdp/page.py +3972 -0
  43. mithwire/cdp/performance.py +124 -0
  44. mithwire/cdp/performance_timeline.py +200 -0
  45. mithwire/cdp/preload.py +575 -0
  46. mithwire/cdp/profiler.py +420 -0
  47. mithwire/cdp/pwa.py +278 -0
  48. mithwire/cdp/py.typed +0 -0
  49. mithwire/cdp/runtime.py +1589 -0
  50. mithwire/cdp/schema.py +50 -0
  51. mithwire/cdp/security.py +518 -0
  52. mithwire/cdp/service_worker.py +401 -0
  53. mithwire/cdp/smart_card_emulation.py +891 -0
  54. mithwire/cdp/storage.py +1573 -0
  55. mithwire/cdp/system_info.py +327 -0
  56. mithwire/cdp/target.py +829 -0
  57. mithwire/cdp/tethering.py +65 -0
  58. mithwire/cdp/tracing.py +377 -0
  59. mithwire/cdp/util.py +18 -0
  60. mithwire/cdp/web_audio.py +606 -0
  61. mithwire/cdp/web_authn.py +598 -0
  62. mithwire/cdp/web_mcp.py +293 -0
  63. mithwire/core/_contradict.py +142 -0
  64. mithwire/core/browser.py +923 -0
  65. mithwire/core/cf_templates/cf_dark_checkbox.png +0 -0
  66. mithwire/core/cf_templates/cf_light_checkbox.png +0 -0
  67. mithwire/core/config.py +323 -0
  68. mithwire/core/connection.py +564 -0
  69. mithwire/core/element.py +1205 -0
  70. mithwire/core/tab.py +2202 -0
  71. mithwire/core/util.py +5063 -0
  72. mithwire-0.50.3.dist-info/METADATA +1049 -0
  73. mithwire-0.50.3.dist-info/RECORD +76 -0
  74. mithwire-0.50.3.dist-info/WHEEL +5 -0
  75. mithwire-0.50.3.dist-info/licenses/LICENSE.txt +619 -0
  76. mithwire-0.50.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,95 @@
1
+ # DO NOT EDIT THIS FILE!
2
+ #
3
+ # This file is generated from the CDP specification. If you need to make
4
+ # changes, edit the generator and regenerate all of the modules.
5
+ #
6
+ # CDP domain: Inspector (experimental)
7
+
8
+ from __future__ import annotations
9
+ import enum
10
+ import typing
11
+ from dataclasses import dataclass
12
+ from .util import event_class, T_JSON_DICT
13
+
14
+
15
+ def disable() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
16
+ '''
17
+ Disables inspector domain notifications.
18
+ '''
19
+ cmd_dict: T_JSON_DICT = {
20
+ 'method': 'Inspector.disable',
21
+ }
22
+ json = yield cmd_dict
23
+
24
+
25
+ def enable() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
26
+ '''
27
+ Enables inspector domain notifications.
28
+ '''
29
+ cmd_dict: T_JSON_DICT = {
30
+ 'method': 'Inspector.enable',
31
+ }
32
+ json = yield cmd_dict
33
+
34
+
35
+ @event_class('Inspector.detached')
36
+ @dataclass
37
+ class Detached:
38
+ '''
39
+ Fired when remote debugging connection is about to be terminated. Contains detach reason.
40
+ '''
41
+ #: The reason why connection has been terminated.
42
+ reason: str
43
+
44
+ @classmethod
45
+ def from_json(cls, json: T_JSON_DICT) -> Detached:
46
+ return cls(
47
+ reason=str(json['reason'])
48
+ )
49
+
50
+
51
+ @event_class('Inspector.targetCrashed')
52
+ @dataclass
53
+ class TargetCrashed:
54
+ '''
55
+ Fired when debugging target has crashed
56
+ '''
57
+
58
+
59
+ @classmethod
60
+ def from_json(cls, json: T_JSON_DICT) -> TargetCrashed:
61
+ return cls(
62
+
63
+ )
64
+
65
+
66
+ @event_class('Inspector.targetReloadedAfterCrash')
67
+ @dataclass
68
+ class TargetReloadedAfterCrash:
69
+ '''
70
+ Fired when debugging target has reloaded after crash
71
+ '''
72
+
73
+
74
+ @classmethod
75
+ def from_json(cls, json: T_JSON_DICT) -> TargetReloadedAfterCrash:
76
+ return cls(
77
+
78
+ )
79
+
80
+
81
+ @event_class('Inspector.workerScriptLoaded')
82
+ @dataclass
83
+ class WorkerScriptLoaded:
84
+ '''
85
+ **EXPERIMENTAL**
86
+
87
+ Fired on worker targets when main worker script and any imported scripts have been evaluated.
88
+ '''
89
+
90
+
91
+ @classmethod
92
+ def from_json(cls, json: T_JSON_DICT) -> WorkerScriptLoaded:
93
+ return cls(
94
+
95
+ )
mithwire/cdp/io.py ADDED
@@ -0,0 +1,101 @@
1
+ # DO NOT EDIT THIS FILE!
2
+ #
3
+ # This file is generated from the CDP specification. If you need to make
4
+ # changes, edit the generator and regenerate all of the modules.
5
+ #
6
+ # CDP domain: IO
7
+
8
+ from __future__ import annotations
9
+ import enum
10
+ import typing
11
+ from dataclasses import dataclass
12
+ from .util import event_class, T_JSON_DICT
13
+
14
+ from . import runtime
15
+
16
+
17
+ class StreamHandle(str):
18
+ '''
19
+ This is either obtained from another method or specified as ``blob:<uuid>`` where
20
+ ``<uuid>`` is an UUID of a Blob.
21
+ '''
22
+ def to_json(self) -> str:
23
+ return self
24
+
25
+ @classmethod
26
+ def from_json(cls, json: str) -> StreamHandle:
27
+ return cls(json)
28
+
29
+ def __repr__(self):
30
+ return 'StreamHandle({})'.format(super().__repr__())
31
+
32
+
33
+ def close(
34
+ handle: StreamHandle
35
+ ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
36
+ '''
37
+ Close the stream, discard any temporary backing storage.
38
+
39
+ :param handle: Handle of the stream to close.
40
+ '''
41
+ params: T_JSON_DICT = dict()
42
+ params['handle'] = handle.to_json()
43
+ cmd_dict: T_JSON_DICT = {
44
+ 'method': 'IO.close',
45
+ 'params': params,
46
+ }
47
+ json = yield cmd_dict
48
+
49
+
50
+ def read(
51
+ handle: StreamHandle,
52
+ offset: typing.Optional[int] = None,
53
+ size: typing.Optional[int] = None
54
+ ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.Tuple[typing.Optional[bool], str, bool]]:
55
+ '''
56
+ Read a chunk of the stream
57
+
58
+ :param handle: Handle of the stream to read.
59
+ :param offset: *(Optional)* Seek to the specified offset before reading (if not specified, proceed with offset following the last read). Some types of streams may only support sequential reads.
60
+ :param size: *(Optional)* Maximum number of bytes to read (left upon the agent discretion if not specified).
61
+ :returns: A tuple with the following items:
62
+
63
+ 0. **base64Encoded** - *(Optional)* Set if the data is base64-encoded
64
+ 1. **data** - Data that were read.
65
+ 2. **eof** - Set if the end-of-file condition occurred while reading.
66
+ '''
67
+ params: T_JSON_DICT = dict()
68
+ params['handle'] = handle.to_json()
69
+ if offset is not None:
70
+ params['offset'] = offset
71
+ if size is not None:
72
+ params['size'] = size
73
+ cmd_dict: T_JSON_DICT = {
74
+ 'method': 'IO.read',
75
+ 'params': params,
76
+ }
77
+ json = yield cmd_dict
78
+ return (
79
+ bool(json['base64Encoded']) if json.get('base64Encoded', None) is not None else None,
80
+ str(json['data']),
81
+ bool(json['eof'])
82
+ )
83
+
84
+
85
+ def resolve_blob(
86
+ object_id: runtime.RemoteObjectId
87
+ ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,str]:
88
+ '''
89
+ Return UUID of Blob object specified by a remote object id.
90
+
91
+ :param object_id: Object id of a Blob object wrapper.
92
+ :returns: UUID of the specified Blob.
93
+ '''
94
+ params: T_JSON_DICT = dict()
95
+ params['objectId'] = object_id.to_json()
96
+ cmd_dict: T_JSON_DICT = {
97
+ 'method': 'IO.resolveBlob',
98
+ 'params': params,
99
+ }
100
+ json = yield cmd_dict
101
+ return str(json['uuid'])
@@ -0,0 +1,464 @@
1
+ # DO NOT EDIT THIS FILE!
2
+ #
3
+ # This file is generated from the CDP specification. If you need to make
4
+ # changes, edit the generator and regenerate all of the modules.
5
+ #
6
+ # CDP domain: LayerTree (experimental)
7
+
8
+ from __future__ import annotations
9
+ import enum
10
+ import typing
11
+ from dataclasses import dataclass
12
+ from .util import event_class, T_JSON_DICT
13
+
14
+ from . import dom
15
+
16
+
17
+ class LayerId(str):
18
+ '''
19
+ Unique Layer identifier.
20
+ '''
21
+ def to_json(self) -> str:
22
+ return self
23
+
24
+ @classmethod
25
+ def from_json(cls, json: str) -> LayerId:
26
+ return cls(json)
27
+
28
+ def __repr__(self):
29
+ return 'LayerId({})'.format(super().__repr__())
30
+
31
+
32
+ class SnapshotId(str):
33
+ '''
34
+ Unique snapshot identifier.
35
+ '''
36
+ def to_json(self) -> str:
37
+ return self
38
+
39
+ @classmethod
40
+ def from_json(cls, json: str) -> SnapshotId:
41
+ return cls(json)
42
+
43
+ def __repr__(self):
44
+ return 'SnapshotId({})'.format(super().__repr__())
45
+
46
+
47
+ @dataclass
48
+ class ScrollRect:
49
+ '''
50
+ Rectangle where scrolling happens on the main thread.
51
+ '''
52
+ #: Rectangle itself.
53
+ rect: dom.Rect
54
+
55
+ #: Reason for rectangle to force scrolling on the main thread
56
+ type_: str
57
+
58
+ def to_json(self) -> T_JSON_DICT:
59
+ json: T_JSON_DICT = dict()
60
+ json['rect'] = self.rect.to_json()
61
+ json['type'] = self.type_
62
+ return json
63
+
64
+ @classmethod
65
+ def from_json(cls, json: T_JSON_DICT) -> ScrollRect:
66
+ return cls(
67
+ rect=dom.Rect.from_json(json['rect']),
68
+ type_=str(json['type']),
69
+ )
70
+
71
+
72
+ @dataclass
73
+ class StickyPositionConstraint:
74
+ '''
75
+ Sticky position constraints.
76
+ '''
77
+ #: Layout rectangle of the sticky element before being shifted
78
+ sticky_box_rect: dom.Rect
79
+
80
+ #: Layout rectangle of the containing block of the sticky element
81
+ containing_block_rect: dom.Rect
82
+
83
+ #: The nearest sticky layer that shifts the sticky box
84
+ nearest_layer_shifting_sticky_box: typing.Optional[LayerId] = None
85
+
86
+ #: The nearest sticky layer that shifts the containing block
87
+ nearest_layer_shifting_containing_block: typing.Optional[LayerId] = None
88
+
89
+ def to_json(self) -> T_JSON_DICT:
90
+ json: T_JSON_DICT = dict()
91
+ json['stickyBoxRect'] = self.sticky_box_rect.to_json()
92
+ json['containingBlockRect'] = self.containing_block_rect.to_json()
93
+ if self.nearest_layer_shifting_sticky_box is not None:
94
+ json['nearestLayerShiftingStickyBox'] = self.nearest_layer_shifting_sticky_box.to_json()
95
+ if self.nearest_layer_shifting_containing_block is not None:
96
+ json['nearestLayerShiftingContainingBlock'] = self.nearest_layer_shifting_containing_block.to_json()
97
+ return json
98
+
99
+ @classmethod
100
+ def from_json(cls, json: T_JSON_DICT) -> StickyPositionConstraint:
101
+ return cls(
102
+ sticky_box_rect=dom.Rect.from_json(json['stickyBoxRect']),
103
+ containing_block_rect=dom.Rect.from_json(json['containingBlockRect']),
104
+ nearest_layer_shifting_sticky_box=LayerId.from_json(json['nearestLayerShiftingStickyBox']) if json.get('nearestLayerShiftingStickyBox', None) is not None else None,
105
+ nearest_layer_shifting_containing_block=LayerId.from_json(json['nearestLayerShiftingContainingBlock']) if json.get('nearestLayerShiftingContainingBlock', None) is not None else None,
106
+ )
107
+
108
+
109
+ @dataclass
110
+ class PictureTile:
111
+ '''
112
+ Serialized fragment of layer picture along with its offset within the layer.
113
+ '''
114
+ #: Offset from owning layer left boundary
115
+ x: float
116
+
117
+ #: Offset from owning layer top boundary
118
+ y: float
119
+
120
+ #: Base64-encoded snapshot data. (Encoded as a base64 string when passed over JSON)
121
+ picture: str
122
+
123
+ def to_json(self) -> T_JSON_DICT:
124
+ json: T_JSON_DICT = dict()
125
+ json['x'] = self.x
126
+ json['y'] = self.y
127
+ json['picture'] = self.picture
128
+ return json
129
+
130
+ @classmethod
131
+ def from_json(cls, json: T_JSON_DICT) -> PictureTile:
132
+ return cls(
133
+ x=float(json['x']),
134
+ y=float(json['y']),
135
+ picture=str(json['picture']),
136
+ )
137
+
138
+
139
+ @dataclass
140
+ class Layer:
141
+ '''
142
+ Information about a compositing layer.
143
+ '''
144
+ #: The unique id for this layer.
145
+ layer_id: LayerId
146
+
147
+ #: Offset from parent layer, X coordinate.
148
+ offset_x: float
149
+
150
+ #: Offset from parent layer, Y coordinate.
151
+ offset_y: float
152
+
153
+ #: Layer width.
154
+ width: float
155
+
156
+ #: Layer height.
157
+ height: float
158
+
159
+ #: Indicates how many time this layer has painted.
160
+ paint_count: int
161
+
162
+ #: Indicates whether this layer hosts any content, rather than being used for
163
+ #: transform/scrolling purposes only.
164
+ draws_content: bool
165
+
166
+ #: The id of parent (not present for root).
167
+ parent_layer_id: typing.Optional[LayerId] = None
168
+
169
+ #: The backend id for the node associated with this layer.
170
+ backend_node_id: typing.Optional[dom.BackendNodeId] = None
171
+
172
+ #: Transformation matrix for layer, default is identity matrix
173
+ transform: typing.Optional[typing.List[float]] = None
174
+
175
+ #: Transform anchor point X, absent if no transform specified
176
+ anchor_x: typing.Optional[float] = None
177
+
178
+ #: Transform anchor point Y, absent if no transform specified
179
+ anchor_y: typing.Optional[float] = None
180
+
181
+ #: Transform anchor point Z, absent if no transform specified
182
+ anchor_z: typing.Optional[float] = None
183
+
184
+ #: Set if layer is not visible.
185
+ invisible: typing.Optional[bool] = None
186
+
187
+ #: Rectangles scrolling on main thread only.
188
+ scroll_rects: typing.Optional[typing.List[ScrollRect]] = None
189
+
190
+ #: Sticky position constraint information
191
+ sticky_position_constraint: typing.Optional[StickyPositionConstraint] = None
192
+
193
+ def to_json(self) -> T_JSON_DICT:
194
+ json: T_JSON_DICT = dict()
195
+ json['layerId'] = self.layer_id.to_json()
196
+ json['offsetX'] = self.offset_x
197
+ json['offsetY'] = self.offset_y
198
+ json['width'] = self.width
199
+ json['height'] = self.height
200
+ json['paintCount'] = self.paint_count
201
+ json['drawsContent'] = self.draws_content
202
+ if self.parent_layer_id is not None:
203
+ json['parentLayerId'] = self.parent_layer_id.to_json()
204
+ if self.backend_node_id is not None:
205
+ json['backendNodeId'] = self.backend_node_id.to_json()
206
+ if self.transform is not None:
207
+ json['transform'] = [i for i in self.transform]
208
+ if self.anchor_x is not None:
209
+ json['anchorX'] = self.anchor_x
210
+ if self.anchor_y is not None:
211
+ json['anchorY'] = self.anchor_y
212
+ if self.anchor_z is not None:
213
+ json['anchorZ'] = self.anchor_z
214
+ if self.invisible is not None:
215
+ json['invisible'] = self.invisible
216
+ if self.scroll_rects is not None:
217
+ json['scrollRects'] = [i.to_json() for i in self.scroll_rects]
218
+ if self.sticky_position_constraint is not None:
219
+ json['stickyPositionConstraint'] = self.sticky_position_constraint.to_json()
220
+ return json
221
+
222
+ @classmethod
223
+ def from_json(cls, json: T_JSON_DICT) -> Layer:
224
+ return cls(
225
+ layer_id=LayerId.from_json(json['layerId']),
226
+ offset_x=float(json['offsetX']),
227
+ offset_y=float(json['offsetY']),
228
+ width=float(json['width']),
229
+ height=float(json['height']),
230
+ paint_count=int(json['paintCount']),
231
+ draws_content=bool(json['drawsContent']),
232
+ parent_layer_id=LayerId.from_json(json['parentLayerId']) if json.get('parentLayerId', None) is not None else None,
233
+ backend_node_id=dom.BackendNodeId.from_json(json['backendNodeId']) if json.get('backendNodeId', None) is not None else None,
234
+ transform=[float(i) for i in json['transform']] if json.get('transform', None) is not None else None,
235
+ anchor_x=float(json['anchorX']) if json.get('anchorX', None) is not None else None,
236
+ anchor_y=float(json['anchorY']) if json.get('anchorY', None) is not None else None,
237
+ anchor_z=float(json['anchorZ']) if json.get('anchorZ', None) is not None else None,
238
+ invisible=bool(json['invisible']) if json.get('invisible', None) is not None else None,
239
+ scroll_rects=[ScrollRect.from_json(i) for i in json['scrollRects']] if json.get('scrollRects', None) is not None else None,
240
+ sticky_position_constraint=StickyPositionConstraint.from_json(json['stickyPositionConstraint']) if json.get('stickyPositionConstraint', None) is not None else None,
241
+ )
242
+
243
+
244
+ class PaintProfile(list):
245
+ '''
246
+ Array of timings, one per paint step.
247
+ '''
248
+ def to_json(self) -> typing.List[float]:
249
+ return self
250
+
251
+ @classmethod
252
+ def from_json(cls, json: typing.List[float]) -> PaintProfile:
253
+ return cls(json)
254
+
255
+ def __repr__(self):
256
+ return 'PaintProfile({})'.format(super().__repr__())
257
+
258
+
259
+ def compositing_reasons(
260
+ layer_id: LayerId
261
+ ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.Tuple[typing.List[str], typing.List[str]]]:
262
+ '''
263
+ Provides the reasons why the given layer was composited.
264
+
265
+ :param layer_id: The id of the layer for which we want to get the reasons it was composited.
266
+ :returns: A tuple with the following items:
267
+
268
+ 0. **compositingReasons** - A list of strings specifying reasons for the given layer to become composited.
269
+ 1. **compositingReasonIds** - A list of strings specifying reason IDs for the given layer to become composited.
270
+ '''
271
+ params: T_JSON_DICT = dict()
272
+ params['layerId'] = layer_id.to_json()
273
+ cmd_dict: T_JSON_DICT = {
274
+ 'method': 'LayerTree.compositingReasons',
275
+ 'params': params,
276
+ }
277
+ json = yield cmd_dict
278
+ return (
279
+ [str(i) for i in json['compositingReasons']],
280
+ [str(i) for i in json['compositingReasonIds']]
281
+ )
282
+
283
+
284
+ def disable() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
285
+ '''
286
+ Disables compositing tree inspection.
287
+ '''
288
+ cmd_dict: T_JSON_DICT = {
289
+ 'method': 'LayerTree.disable',
290
+ }
291
+ json = yield cmd_dict
292
+
293
+
294
+ def enable() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
295
+ '''
296
+ Enables compositing tree inspection.
297
+ '''
298
+ cmd_dict: T_JSON_DICT = {
299
+ 'method': 'LayerTree.enable',
300
+ }
301
+ json = yield cmd_dict
302
+
303
+
304
+ def load_snapshot(
305
+ tiles: typing.List[PictureTile]
306
+ ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,SnapshotId]:
307
+ '''
308
+ Returns the snapshot identifier.
309
+
310
+ :param tiles: An array of tiles composing the snapshot.
311
+ :returns: The id of the snapshot.
312
+ '''
313
+ params: T_JSON_DICT = dict()
314
+ params['tiles'] = [i.to_json() for i in tiles]
315
+ cmd_dict: T_JSON_DICT = {
316
+ 'method': 'LayerTree.loadSnapshot',
317
+ 'params': params,
318
+ }
319
+ json = yield cmd_dict
320
+ return SnapshotId.from_json(json['snapshotId'])
321
+
322
+
323
+ def make_snapshot(
324
+ layer_id: LayerId
325
+ ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,SnapshotId]:
326
+ '''
327
+ Returns the layer snapshot identifier.
328
+
329
+ :param layer_id: The id of the layer.
330
+ :returns: The id of the layer snapshot.
331
+ '''
332
+ params: T_JSON_DICT = dict()
333
+ params['layerId'] = layer_id.to_json()
334
+ cmd_dict: T_JSON_DICT = {
335
+ 'method': 'LayerTree.makeSnapshot',
336
+ 'params': params,
337
+ }
338
+ json = yield cmd_dict
339
+ return SnapshotId.from_json(json['snapshotId'])
340
+
341
+
342
+ def profile_snapshot(
343
+ snapshot_id: SnapshotId,
344
+ min_repeat_count: typing.Optional[int] = None,
345
+ min_duration: typing.Optional[float] = None,
346
+ clip_rect: typing.Optional[dom.Rect] = None
347
+ ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.List[PaintProfile]]:
348
+ '''
349
+ :param snapshot_id: The id of the layer snapshot.
350
+ :param min_repeat_count: *(Optional)* The maximum number of times to replay the snapshot (1, if not specified).
351
+ :param min_duration: *(Optional)* The minimum duration (in seconds) to replay the snapshot.
352
+ :param clip_rect: *(Optional)* The clip rectangle to apply when replaying the snapshot.
353
+ :returns: The array of paint profiles, one per run.
354
+ '''
355
+ params: T_JSON_DICT = dict()
356
+ params['snapshotId'] = snapshot_id.to_json()
357
+ if min_repeat_count is not None:
358
+ params['minRepeatCount'] = min_repeat_count
359
+ if min_duration is not None:
360
+ params['minDuration'] = min_duration
361
+ if clip_rect is not None:
362
+ params['clipRect'] = clip_rect.to_json()
363
+ cmd_dict: T_JSON_DICT = {
364
+ 'method': 'LayerTree.profileSnapshot',
365
+ 'params': params,
366
+ }
367
+ json = yield cmd_dict
368
+ return [PaintProfile.from_json(i) for i in json['timings']]
369
+
370
+
371
+ def release_snapshot(
372
+ snapshot_id: SnapshotId
373
+ ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
374
+ '''
375
+ Releases layer snapshot captured by the back-end.
376
+
377
+ :param snapshot_id: The id of the layer snapshot.
378
+ '''
379
+ params: T_JSON_DICT = dict()
380
+ params['snapshotId'] = snapshot_id.to_json()
381
+ cmd_dict: T_JSON_DICT = {
382
+ 'method': 'LayerTree.releaseSnapshot',
383
+ 'params': params,
384
+ }
385
+ json = yield cmd_dict
386
+
387
+
388
+ def replay_snapshot(
389
+ snapshot_id: SnapshotId,
390
+ from_step: typing.Optional[int] = None,
391
+ to_step: typing.Optional[int] = None,
392
+ scale: typing.Optional[float] = None
393
+ ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,str]:
394
+ '''
395
+ Replays the layer snapshot and returns the resulting bitmap.
396
+
397
+ :param snapshot_id: The id of the layer snapshot.
398
+ :param from_step: *(Optional)* The first step to replay from (replay from the very start if not specified).
399
+ :param to_step: *(Optional)* The last step to replay to (replay till the end if not specified).
400
+ :param scale: *(Optional)* The scale to apply while replaying (defaults to 1).
401
+ :returns: A data: URL for resulting image.
402
+ '''
403
+ params: T_JSON_DICT = dict()
404
+ params['snapshotId'] = snapshot_id.to_json()
405
+ if from_step is not None:
406
+ params['fromStep'] = from_step
407
+ if to_step is not None:
408
+ params['toStep'] = to_step
409
+ if scale is not None:
410
+ params['scale'] = scale
411
+ cmd_dict: T_JSON_DICT = {
412
+ 'method': 'LayerTree.replaySnapshot',
413
+ 'params': params,
414
+ }
415
+ json = yield cmd_dict
416
+ return str(json['dataURL'])
417
+
418
+
419
+ def snapshot_command_log(
420
+ snapshot_id: SnapshotId
421
+ ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.List[dict]]:
422
+ '''
423
+ Replays the layer snapshot and returns canvas log.
424
+
425
+ :param snapshot_id: The id of the layer snapshot.
426
+ :returns: The array of canvas function calls.
427
+ '''
428
+ params: T_JSON_DICT = dict()
429
+ params['snapshotId'] = snapshot_id.to_json()
430
+ cmd_dict: T_JSON_DICT = {
431
+ 'method': 'LayerTree.snapshotCommandLog',
432
+ 'params': params,
433
+ }
434
+ json = yield cmd_dict
435
+ return [dict(i) for i in json['commandLog']]
436
+
437
+
438
+ @event_class('LayerTree.layerPainted')
439
+ @dataclass
440
+ class LayerPainted:
441
+ #: The id of the painted layer.
442
+ layer_id: LayerId
443
+ #: Clip rectangle.
444
+ clip: dom.Rect
445
+
446
+ @classmethod
447
+ def from_json(cls, json: T_JSON_DICT) -> LayerPainted:
448
+ return cls(
449
+ layer_id=LayerId.from_json(json['layerId']),
450
+ clip=dom.Rect.from_json(json['clip'])
451
+ )
452
+
453
+
454
+ @event_class('LayerTree.layerTreeDidChange')
455
+ @dataclass
456
+ class LayerTreeDidChange:
457
+ #: Layer tree, absent if not in the compositing mode.
458
+ layers: typing.Optional[typing.List[Layer]]
459
+
460
+ @classmethod
461
+ def from_json(cls, json: T_JSON_DICT) -> LayerTreeDidChange:
462
+ return cls(
463
+ layers=[Layer.from_json(i) for i in json['layers']] if json.get('layers', None) is not None else None
464
+ )