blob: cf49f783e66ff4b747a59ea1809176981f346846 [file] [log] [blame]
// Copyright 2015 Google. All rights reserved. Use of this source code is
// governed by a BSD-style license that can be found in the LICENSE file.
part of wip;
/// Implementation of the
/// https://developer.chrome.com/devtools/docs/protocol/1.1/dom
class WipDom extends WipDomain {
WipDom(WipConnection connection) : super(connection);
Future<Map<String, String>> getAttributes(int nodeId) async {
WipResponse resp =
await _sendCommand('DOM.getAttributes', {'nodeId': nodeId});
return _attributeListToMap(resp.result['attributes']);
}
Future<Node> getDocument() async =>
new Node((await _sendCommand('DOM.getDocument')).result['root']);
Future<String> getOuterHtml(int nodeId) async =>
(await _sendCommand('DOM.getOuterHTML', {'nodeId': nodeId}))
.result['root'];
Future hideHighlight() => _sendCommand('DOM.hideHighlight');
Future highlightNode(int nodeId,
{Rgba borderColor,
Rgba contentColor,
Rgba marginColor,
Rgba paddingColor,
bool showInfo}) {
var params = {'nodeId': nodeId, 'highlightConfig': {}};
if (borderColor != null) {
params['highlightConfig']['borderColor'] = borderColor;
}
if (contentColor != null) {
params['highlightConfig']['contentColor'] = contentColor;
}
if (marginColor != null) {
params['highlightConfig']['marginColor'] = marginColor;
}
if (paddingColor != null) {
params['highlightConfig']['paddingColor'] = paddingColor;
}
if (showInfo != null) {
params['highlightConfig']['showInfo'] = showInfo;
}
return _sendCommand('DOM.highlightNode', params);
}
Future highlightRect(int x, int y, int width, int height,
{Rgba color, Rgba outlineColor}) {
var params = {'x': x, 'y': y, 'width': width, 'height': height};
if (color != null) {
params['color'] = color;
}
if (outlineColor != null) {
params['outlineColor'] = outlineColor;
}
return _sendCommand('DOM.highlightRect', params);
}
Future<int> moveTo(int nodeId, int targetNodeId,
{int insertBeforeNodeId}) async {
var params = {'nodeId': nodeId, 'targetNodeId': targetNodeId};
if (insertBeforeNodeId != null) {
params['insertBeforeNodeId'] = insertBeforeNodeId;
}
var resp = await _sendCommand('DOM.moveTo', params);
return resp.result['nodeId'];
}
Future<int> querySelector(int nodeId, String selector) async {
var resp = await _sendCommand(
'DOM.querySelector', {'nodeId': nodeId, 'selector': selector});
return resp.result['nodeId'];
}
Future<List<int>> querySelectorAll(int nodeId, String selector) async {
var resp = await _sendCommand(
'DOM.querySelectorAll', {'nodeId': nodeId, 'selector': selector});
return resp.result['nodeIds'];
}
Future removeAttribute(int nodeId, String name) =>
_sendCommand('DOM.removeAttribute', {'nodeId': nodeId, 'name': name});
Future removeNode(int nodeId) =>
_sendCommand('DOM.removeNode', {'nodeId': nodeId});
Future requestChildNodes(int nodeId) =>
_sendCommand('DOM.requestChildNodes', {'nodeId': nodeId});
Future<int> requestNode(String objectId) async {
var resp = await _sendCommand('DOM.requestNode', {'objectId': objectId});
return resp.result['nodeId'];
}
Future<WipRemoteObject> resolveNode(int nodeId, {String objectGroup}) async {
var params = {'nodeId': nodeId};
if (objectGroup != null) {
params['objectGroup'] = objectGroup;
}
var resp = await _sendCommand('DOM.resolveNode', params);
return new WipRemoteObject(resp.result['object']);
}
Future setAttributeValue(int nodeId, String name, String value) =>
_sendCommand('DOM.setAttributeValue',
{'nodeId': nodeId, 'name': name, 'value': value});
Future setAttributesAsText(int nodeId, String text, {String name}) {
var params = {'nodeId': nodeId, 'text': text};
if (name != null) {
params['name'] = name;
}
return _sendCommand('DOM.setAttributeValue', params);
}
Future<int> setNodeName(int nodeId, String name) async {
var resp =
await _sendCommand('DOM.setNodeName', {'nodeId': nodeId, 'name': name});
return resp.result['nodeId'];
}
Future setNodeValue(int nodeId, String value) =>
_sendCommand('DOM.setNodeValue', {'nodeId': nodeId, 'value': value});
Future setOuterHtml(int nodeId, String outerHtml) => _sendCommand(
'DOM.setOuterHTML', {'nodeId': nodeId, 'outerHtml': outerHtml});
Stream<AttributeModifiedEvent> get onAttributeModified => _eventStream(
'DOM.attributeModified',
(WipEvent event) => new AttributeModifiedEvent(event));
Stream<AttributeRemovedEvent> get onAttributeRemoved => _eventStream(
'DOM.attributeRemoved',
(WipEvent event) => new AttributeRemovedEvent(event));
Stream<CharacterDataModifiedEvent> get onCharacterDataModified =>
_eventStream('DOM.characterDataModified',
(WipEvent event) => new CharacterDataModifiedEvent(event));
Stream<ChildNodeCountUpdatedEvent> get onChildNodeCountUpdated =>
_eventStream('DOM.childNodeCountUpdated',
(WipEvent event) => new ChildNodeCountUpdatedEvent(event));
Stream<ChildNodeInsertedEvent> get onChildNodeInserted => _eventStream(
'DOM.childNodeInserted',
(WipEvent event) => new ChildNodeInsertedEvent(event));
Stream<ChildNodeRemovedEvent> get onChildNodeRemoved => _eventStream(
'DOM.childNodeRemoved',
(WipEvent event) => new ChildNodeRemovedEvent(event));
Stream<DocumentUpdatedEvent> get onDocumentUpdated => _eventStream(
'DOM.documentUpdated',
(WipEvent event) => new DocumentUpdatedEvent(event));
Stream<SetChildNodesEvent> get onSetChildNodes => _eventStream(
'DOM.setChildNodes', (WipEvent event) => new SetChildNodesEvent(event));
}
class AttributeModifiedEvent extends _WrappedWipEvent {
AttributeModifiedEvent(WipEvent event) : super(event);
int get nodeId => params['nodeId'];
String get name => params['name'];
String get value => params['value'];
}
class AttributeRemovedEvent extends _WrappedWipEvent {
AttributeRemovedEvent(WipEvent event) : super(event);
int get nodeId => params['nodeId'];
String get name => params['name'];
}
class CharacterDataModifiedEvent extends _WrappedWipEvent {
CharacterDataModifiedEvent(WipEvent event) : super(event);
int get nodeId => params['nodeId'];
String get characterData => params['characterData'];
}
class ChildNodeCountUpdatedEvent extends _WrappedWipEvent {
ChildNodeCountUpdatedEvent(WipEvent event) : super(event);
int get nodeId => params['nodeId'];
int get childNodeCount => params['childNodeCount'];
}
class ChildNodeInsertedEvent extends _WrappedWipEvent {
ChildNodeInsertedEvent(WipEvent event) : super(event);
int get parentNodeId => params['parentNodeId'];
int get previousNodeId => params['previousNodeId'];
Node _node;
Node get node {
if (_node == null) {
_node = new Node(params['node']);
}
return _node;
}
}
class ChildNodeRemovedEvent extends _WrappedWipEvent {
ChildNodeRemovedEvent(WipEvent event) : super(event);
int get parentNodeId => params['parentNodeId'];
int get nodeId => params['nodeId'];
}
class DocumentUpdatedEvent extends _WrappedWipEvent {
DocumentUpdatedEvent(WipEvent event) : super(event);
}
class SetChildNodesEvent extends _WrappedWipEvent {
SetChildNodesEvent(WipEvent event) : super(event);
int get nodeId => params['parentId'];
Iterable<Node> get nodes sync* {
for (Map node in params['nodes']) {
yield new Node(node);
}
}
String toString() => 'SetChildNodes $nodeId: $nodes';
}
/// The backend keeps track of which DOM nodes have been sent,
/// will only send each node once, and will only send events
/// for nodes that have been sent.
class Node {
final Map<String, dynamic> _map;
Node(this._map);
var _attributes;
Map<String, String> get attributes {
if (_attributes == null && _map.containsKey('attributes')) {
_attributes = _attributeListToMap(_map['attributes']);
}
return _attributes;
}
int get childNodeCount => _map['childNodeCount'];
var _children;
List<Node> get children {
if (_children == null && _map.containsKey('children')) {
_children =
new UnmodifiableListView(_map['children'].map((c) => new Node(c)));
}
return _children;
}
Node get contentDocument {
if (_map.containsKey('contentDocument')) {
return new Node(_map['contentDocument']);
}
return null;
}
String get documentUrl => _map['documentURL'];
String get internalSubset => _map['internalSubset'];
String get localName => _map['localName'];
String get name => _map['name'];
int get nodeId => _map['nodeId'];
String get nodeName => _map['nodeName'];
int get nodeType => _map['nodeType'];
String get nodeValue => _map['nodeValue'];
String get publicId => _map['publicId'];
String get systemId => _map['systemId'];
String get value => _map['value'];
String get xmlVersion => _map['xmlVersion'];
String toString() => '$nodeName: $nodeId $attributes';
}
class Rgba {
final int a;
final int b;
final int r;
final int g;
Rgba(this.r, this.g, this.b, [this.a]);
Map toJson() {
var json = {'r': r, 'g': g, 'b': b};
if (a != null) {
json['a'] = a;
}
return json;
}
}
Map<String, String> _attributeListToMap(List<String> attrList) {
var attributes = {};
for (int i = 0; i < attrList.length; i += 2) {
attributes[attrList[i]] = attrList[i + 1];
}
return new UnmodifiableMapView(attributes);
}