Skip to content
Snippets Groups Projects
Unverified Commit 0b1eaf92 authored by Bjoern Esswein's avatar Bjoern Esswein
Browse files

WIP: implement DomNodeWrapper

parent d7ba8822
No related branches found
No related tags found
No related merge requests found
Showing with 736 additions and 97 deletions
...@@ -14,7 +14,7 @@ namespace bessw.Unity.WebView.ChromeDevTools ...@@ -14,7 +14,7 @@ namespace bessw.Unity.WebView.ChromeDevTools
{ {
/* singleton */ /* singleton */
private static Browser instance; private static Browser instance;
private static Process browserProcess; private Process browserProcess;
/* browser settings */ /* browser settings */
public static string browserExecutablePath = "chrome"; public static string browserExecutablePath = "chrome";
...@@ -37,7 +37,7 @@ namespace bessw.Unity.WebView.ChromeDevTools ...@@ -37,7 +37,7 @@ namespace bessw.Unity.WebView.ChromeDevTools
*/ */
public static Browser getInstance() public static Browser getInstance()
{ {
if (instance == null) if (instance == null || instance.browserProcess.HasExited)
{ {
instance = new Browser(); instance = new Browser();
instance.launchBrowser(); instance.launchBrowser();
...@@ -64,31 +64,45 @@ namespace bessw.Unity.WebView.ChromeDevTools ...@@ -64,31 +64,45 @@ namespace bessw.Unity.WebView.ChromeDevTools
private void launchBrowser() private void launchBrowser()
{ {
// allow only one instance of chrome // allow only one instance of chrome
if (Browser.browserProcess == null || Browser.browserProcess.HasExited) if (browserProcess == null || browserProcess.HasExited)
{ {
Browser.browserProcess = new Process(); browserProcess = new Process();
Browser.browserProcess.StartInfo.FileName = browserExecutablePath; browserProcess.StartInfo.FileName = browserExecutablePath;
Browser.browserProcess.StartInfo.Arguments = $"--user-data-dir={Path.Join(Application.temporaryCachePath, "BrowserView")} --remote-debugging-port={debugPort} --remote-allow-origins=http://localhost:{debugPort} --hide-crash-restore-bubble"; browserProcess.StartInfo.Arguments = String.Join(" ", new []{
$"--user-data-dir={Path.Join(Application.temporaryCachePath, "BrowserView")}",
$"--remote-debugging-port={debugPort}",
$"--remote-allow-origins=http://localhost:{debugPort}",
"--hide-crash-restore-bubble",
"--disable-first-run-ui",
"--no-first-run"
});
// set headlessBrowser to false to see the browser window // set headlessBrowser to false to see the browser window
if (headless) if (headless)
{ {
Browser.browserProcess.StartInfo.Arguments = string.Concat(Browser.browserProcess.StartInfo.Arguments, " --headless=new"); browserProcess.StartInfo.Arguments = string.Concat(browserProcess.StartInfo.Arguments, " --headless=new");
} }
else else
{ {
Browser.browserProcess.StartInfo.WindowStyle = ProcessWindowStyle.Minimized; browserProcess.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
} }
Browser.browserProcess.Start(); // register an error handler
UnityEngine.Debug.Log($"launched '{Browser.browserProcess.StartInfo.FileName} {Browser.browserProcess.StartInfo.Arguments}'"); browserProcess.ErrorDataReceived += (sender, e) => UnityEngine.Debug.LogError($"Browser Error: {e.Data} ExitCode: {browserProcess.ExitCode}");
browserProcess.Exited += (sender, e) => UnityEngine.Debug.LogError($"Browser Exited, ExitCode: {browserProcess.ExitCode}");
browserProcess.Start();
if (browserProcess.HasExited) {
UnityEngine.Debug.LogError("Failed to start browser");
}
UnityEngine.Debug.Log($"launched '{browserProcess.StartInfo.FileName} {browserProcess.StartInfo.Arguments}'");
} }
} }
/** /**
* send web request to the devTools API * send web request to the devTools API
*/ */
private IEnumerator DevToolsApiRequest(bool isPUT, string apiAddress, System.Action<string> callback) private IEnumerator DevToolsApiRequest(bool isPUT, string apiAddress, Action<string> callback)
{ {
UnityEngine.Debug.Log($"DevTools api Request: {apiAddress}"); UnityEngine.Debug.Log($"DevTools api Request: {apiAddress}");
UnityWebRequest webRequest; UnityWebRequest webRequest;
...@@ -114,7 +128,7 @@ namespace bessw.Unity.WebView.ChromeDevTools ...@@ -114,7 +128,7 @@ namespace bessw.Unity.WebView.ChromeDevTools
} }
} }
public IEnumerator OpenNewTab(string targetUrl, System.Action<BrowserTab> callback) public IEnumerator OpenNewTab(string targetUrl, Action<BrowserTab> callback)
{ {
yield return DevToolsApiRequest(true, $"/json/new?{targetUrl}", (response) => yield return DevToolsApiRequest(true, $"/json/new?{targetUrl}", (response) =>
{ {
......
...@@ -3,6 +3,7 @@ using bessw.Unity.WebView.ChromeDevTools.Protocol.Page; ...@@ -3,6 +3,7 @@ using bessw.Unity.WebView.ChromeDevTools.Protocol.Page;
using bessw.Unity.WebView.ChromeDevTools.Protocol.Target; using bessw.Unity.WebView.ChromeDevTools.Protocol.Target;
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using UnityEngine.EventSystems; using UnityEngine.EventSystems;
...@@ -12,19 +13,31 @@ namespace bessw.Unity.WebView.ChromeDevTools ...@@ -12,19 +13,31 @@ namespace bessw.Unity.WebView.ChromeDevTools
public class BrowserTab public class BrowserTab
{ {
private PageTargetInfo pageTarget; private PageTargetInfo pageTarget;
private DevtoolsProtocolHandler devtools; public DevtoolsProtocolHandler devtools;
/// <summary> /// <summary>
/// width and height of the brower device /// width and height of the brower device
/// </summary> /// </summary>
public Vector2Int size { get; private set; } public Vector2Int size { get; private set; }
public Dictionary<int, DomNodeWrapper> domNodes = new Dictionary<int, DomNodeWrapper>();
public BrowserTab(PageTargetInfo pageTarget) public BrowserTab(PageTargetInfo pageTarget)
{ {
this.pageTarget = pageTarget; this.pageTarget = pageTarget;
Debug.Log($"tab WebSocket: '{pageTarget.WebSocketDebuggerUrl}'"); Debug.Log($"tab WebSocket: '{pageTarget.WebSocketDebuggerUrl}'");
this.devtools = new DevtoolsProtocolHandler(new DevtoolsWebsocket(pageTarget.WebSocketDebuggerUrl)); this.devtools = new DevtoolsProtocolHandler(new DevtoolsWebsocket(pageTarget.WebSocketDebuggerUrl));
// register DOM event handlers
this.devtools.DOM_AttributeModifiedEventHandler += (attributeModifiedEvent) => DomNodeWrapper.onAttributeModified(this, attributeModifiedEvent);
this.devtools.DOM_AttributeRemovedEventHandler += (attributeRemovedEvent) => DomNodeWrapper.onAttributeRemoved(this, attributeRemovedEvent);
this.devtools.DOM_CharacterDataModifiedEventHandler += (characterDataModifiedEvent) => DomNodeWrapper.onCharacterDataModified(this, characterDataModifiedEvent);
this.devtools.DOM_ChildNodeCountUpdatedEventHandler += (childNodeCountUpdatedEvent) => DomNodeWrapper.onChildNodeCountUpdated(this, childNodeCountUpdatedEvent);
this.devtools.DOM_ChildNodeInsertedEventHandler += (childNodeInsertedEvent) => DomNodeWrapper.onChildNodeInserted(this, childNodeInsertedEvent);
this.devtools.DOM_ChildNodeRemovedEventHandler += (childNodeRemovedEvent) => DomNodeWrapper.onChildNodeRemoved(this, childNodeRemovedEvent);
this.devtools.DOM_DocumentUpdatedEventHandler += (documentUpdatedEvent) => DomNodeWrapper.onDocumentUpdated(this, documentUpdatedEvent);
this.devtools.DOM_SetChildNodesEventHandler += (setChildNodesEvent) => DomNodeWrapper.onSetChildNodes(this, setChildNodesEvent);
} }
public IEnumerator Update() public IEnumerator Update()
...@@ -34,10 +47,14 @@ namespace bessw.Unity.WebView.ChromeDevTools ...@@ -34,10 +47,14 @@ namespace bessw.Unity.WebView.ChromeDevTools
public IEnumerator CreateScreenshot(double width, double height, Action<Texture2D> callback) public IEnumerator CreateScreenshot(double width, double height, Action<Texture2D> callback)
{ {
var screenshotCommand = new captureScreenshot(); var screenshotCommand = new captureScreenshot
screenshotCommand.Clip = new Protocol.Types.Viewport(); {
screenshotCommand.Clip.Width = width; Clip = new Protocol.Types.Viewport
screenshotCommand.Clip.Height = height; {
Width = width,
Height = height
}
};
return devtools.SendCommand(screenshotCommand, return devtools.SendCommand(screenshotCommand,
(response) => { (response) => {
...@@ -59,8 +76,10 @@ namespace bessw.Unity.WebView.ChromeDevTools ...@@ -59,8 +76,10 @@ namespace bessw.Unity.WebView.ChromeDevTools
devtools.screencastFrameEventHandler += (screencastFrameEvent frameEvent) => devtools.screencastFrameEventHandler += (screencastFrameEvent frameEvent) =>
{ {
// send an ack for this frame // send an ack for this frame
var frameAck = new screencastFrameAck(); var frameAck = new screencastFrameAck
frameAck.sessionId = frameEvent.sessionId; {
sessionId = frameEvent.sessionId
};
_ = devtools.SendCommandAsync(frameAck); _ = devtools.SendCommandAsync(frameAck);
size = new Vector2Int(frameEvent.metadata.deviceWidth, frameEvent.metadata.deviceHeight); size = new Vector2Int(frameEvent.metadata.deviceWidth, frameEvent.metadata.deviceHeight);
...@@ -76,10 +95,12 @@ namespace bessw.Unity.WebView.ChromeDevTools ...@@ -76,10 +95,12 @@ namespace bessw.Unity.WebView.ChromeDevTools
callback(frameTexture); callback(frameTexture);
}; };
var startScreencast = new startScreencast(); var startScreencast = new startScreencast
startScreencast.MaxWidth = maxWidth; {
startScreencast.maxHeight = maxHeight; MaxWidth = maxWidth,
startScreencast.everyNthFrame = 1; maxHeight = maxHeight,
everyNthFrame = 1
};
return devtools.SendCommand(startScreencast); return devtools.SendCommand(startScreencast);
} }
...@@ -139,6 +160,11 @@ namespace bessw.Unity.WebView.ChromeDevTools ...@@ -139,6 +160,11 @@ namespace bessw.Unity.WebView.ChromeDevTools
_ = devtools.SendCommandAsync(new cancelDragging()); _ = devtools.SendCommandAsync(new cancelDragging());
} }
public IEnumerator GetDocument(Action<DomNodeWrapper> callback)
{
return DomNodeWrapper.getDocument(this, callback);
}
/** /**
* close this tab * close this tab
*/ */
......
using bessw.Unity.WebView.ChromeDevTools.Protocol; using bessw.Unity.WebView.ChromeDevTools.Protocol;
using bessw.Unity.WebView.ChromeDevTools.Protocol.DOM;
using bessw.Unity.WebView.ChromeDevTools.Protocol.Page; using bessw.Unity.WebView.ChromeDevTools.Protocol.Page;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
...@@ -25,6 +26,19 @@ namespace bessw.Unity.WebView.ChromeDevTools ...@@ -25,6 +26,19 @@ namespace bessw.Unity.WebView.ChromeDevTools
public event Action<screencastFrameEvent> screencastFrameEventHandler; public event Action<screencastFrameEvent> screencastFrameEventHandler;
public event Action<screencastVisibilityChangedEvent> screencastVisibilityChangedEventHandler; public event Action<screencastVisibilityChangedEvent> screencastVisibilityChangedEventHandler;
#region DOM events
public event Action<attributeModifiedEvent> DOM_AttributeModifiedEventHandler;
public event Action<attributeRemovedEvent> DOM_AttributeRemovedEventHandler;
public event Action<characterDataModifiedEvent> DOM_CharacterDataModifiedEventHandler;
public event Action<childNodeCountUpdatedEvent> DOM_ChildNodeCountUpdatedEventHandler;
public event Action<childNodeInsertedEvent> DOM_ChildNodeInsertedEventHandler;
public event Action<childNodeRemovedEvent> DOM_ChildNodeRemovedEventHandler;
public event Action<documentUpdatedEvent> DOM_DocumentUpdatedEventHandler;
public event Action<setChildNodesEvent> DOM_SetChildNodesEventHandler;
#endregion DOM events
public event Action<DevtoolsEventWrapper> unknownEventHandler;
public DevtoolsProtocolHandler(IDevtoolsConnection devtools) public DevtoolsProtocolHandler(IDevtoolsConnection devtools)
{ {
this.devtools = devtools; this.devtools = devtools;
...@@ -113,10 +127,44 @@ namespace bessw.Unity.WebView.ChromeDevTools ...@@ -113,10 +127,44 @@ namespace bessw.Unity.WebView.ChromeDevTools
case "Page.screencastVisibilityChanged": case "Page.screencastVisibilityChanged":
screencastVisibilityChangedEventHandler?.Invoke( ev.Params.ToObject<screencastVisibilityChangedEvent>(Browser.devtoolsSerializer) ); screencastVisibilityChangedEventHandler?.Invoke( ev.Params.ToObject<screencastVisibilityChangedEvent>(Browser.devtoolsSerializer) );
break; break;
// switch cases that invoke the event handlers for the DOM events
#region DOM events
case "DOM.attributeModified":
DOM_AttributeModifiedEventHandler?.Invoke( ev.Params.ToObject<attributeModifiedEvent>(Browser.devtoolsSerializer) );
break;
case "DOM.attributeRemoved":
DOM_AttributeRemovedEventHandler?.Invoke( ev.Params.ToObject<attributeRemovedEvent>(Browser.devtoolsSerializer) );
break;
case "DOM.characterDataModified":
DOM_CharacterDataModifiedEventHandler?.Invoke( ev.Params.ToObject<characterDataModifiedEvent>(Browser.devtoolsSerializer) );
break;
case "DOM.childNodeCountUpdated":
DOM_ChildNodeCountUpdatedEventHandler?.Invoke( ev.Params.ToObject<childNodeCountUpdatedEvent>(Browser.devtoolsSerializer) );
break;
case "DOM.childNodeInserted":
DOM_ChildNodeInsertedEventHandler?.Invoke( ev.Params.ToObject<childNodeInsertedEvent>(Browser.devtoolsSerializer) );
break;
case "DOM.childNodeRemoved":
DOM_ChildNodeRemovedEventHandler?.Invoke( ev.Params.ToObject<childNodeRemovedEvent>(Browser.devtoolsSerializer) );
break;
case "DOM.documentUpdated":
DOM_DocumentUpdatedEventHandler?.Invoke( ev.Params.ToObject<documentUpdatedEvent>(Browser.devtoolsSerializer) );
break;
case "DOM.setChildNodes":
DOM_SetChildNodesEventHandler?.Invoke( ev.Params.ToObject<setChildNodesEvent>(Browser.devtoolsSerializer) );
break;
#endregion DOM events
default: default:
if (unknownEventHandler != null) {
unknownEventHandler.Invoke(ev);
break;
} else {
throw new UnexpectedMessageException($"Event of type '{ev}' is not implemented"); throw new UnexpectedMessageException($"Event of type '{ev}' is not implemented");
} }
} }
}
/// <summary> /// <summary>
......
using bessw.Unity.WebView.ChromeDevTools.Protocol.DOM;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
#nullable enable
namespace bessw.Unity.WebView.ChromeDevTools
{
public class DomNodeWrapper
{
/// <summary>
/// Node identifier that is passed into the rest of the DOM messages as the `nodeId`. Backend
/// will only push node with given `id` once. It is aware of all requested nodes and will only
/// fire DOM events for nodes known to the client.
/// </summary>
public int NodeId
{
get => Node.nodeId;
protected set => Node.nodeId = value;
}
/// <summary>
/// The id of the parent node if any.
/// </summary>
public int? ParentId
{
get => Node.parentId;
protected set => Node.parentId = value;
}
/// <summary>
/// The `Node`object returend by the browser
/// </summary>
/// <remarks>May be null if it has not jet been requested from the browser</remarks>
public Node Node { get; protected set; }
/// <summary>
/// Reference to the browser tab that this dom node belongs to
/// </summary>
private BrowserTab tab;
/// <summary>
/// private constructor, create instances with the static method <see cref="getDocument"/>,
/// or by calling instance methods on a <see cref="DomNodeWrapper"/> to get its child nodes.
/// </summary>
/// <param name="tab"></param>
private DomNodeWrapper(BrowserTab tab, Node node)
{
this.tab = tab;
this.Node = node;
}
private static DomNodeWrapper createOrUpdateNode(BrowserTab tab, int nodeId, int? parentId = null, int? backendNodeId = null, Node? node = null)
{
if (tab.domNodes.ContainsKey(nodeId))
{
var domNode = tab.domNodes[nodeId];
if (node != null) domNode.Node = node;
if (parentId != null) domNode.ParentId = parentId;
if (backendNodeId != null) domNode.Node.backendNodeId = (int)backendNodeId;
return domNode;
}
else
{
var domNode = new DomNodeWrapper(tab, node ?? new Node()
{
nodeId = nodeId,
parentId = parentId
});
tab.domNodes[nodeId] = domNode;
return domNode;
}
}
#region Event Handlers
public static void onAttributeModified(BrowserTab tab, attributeModifiedEvent eventData)
{
var domNode = createOrUpdateNode(tab, eventData.nodeId);
if (domNode.Node != null)
{
domNode.Node.attributes[eventData.name] = eventData.value;
} else {
throw new InvalidOperationException("AttributeModified event was fired, the node info has not yet been recieved");
}
}
public static void onAttributeRemoved(BrowserTab tab, attributeRemovedEvent eventData)
{
var domNode = createOrUpdateNode(tab, eventData.nodeId);
if (domNode.Node != null)
{
domNode.Node.attributes.Remove(eventData.name);
} else {
throw new InvalidOperationException("AttributeRemoved event was fired, the node info has not yet been recieved");
}
}
public static void onCharacterDataModified(BrowserTab tab, characterDataModifiedEvent eventData)
{
var domNode = createOrUpdateNode(tab, eventData.nodeId);
if (domNode.Node != null)
{
domNode.Node.nodeValue = eventData.characterData;
} else {
throw new InvalidOperationException("CharacterDataModified event was fired, the node info has not yet been recieved");
}
}
public static void onChildNodeCountUpdated(BrowserTab tab, childNodeCountUpdatedEvent eventData)
{
var domNode = createOrUpdateNode(tab, eventData.nodeId);
if (domNode.Node != null)
{
domNode.Node.childNodeCount = eventData.childNodeCount;
} else {
throw new InvalidOperationException("ChildNodeCountUpdated event was fired, the node info has not yet been recieved");
}
}
public static void onChildNodeInserted(BrowserTab tab, childNodeInsertedEvent eventData)
{
var parentNode = createOrUpdateNode(tab, eventData.parentNodeId);
var childNode = createOrUpdateNode(tab, eventData.node.nodeId, eventData.parentNodeId, eventData.node.backendNodeId, eventData.node);
if (parentNode.Node != null && childNode.Node != null)
{
parentNode.Node.children.Insert(eventData.previousNodeId, childNode.Node);
} else {
throw new InvalidOperationException("ChildNodeInserted event was fired, the node info has not yet been recieved");
}
}
public static void onChildNodeRemoved(BrowserTab tab, childNodeRemovedEvent eventData)
{
if (
tab.domNodes.TryGetValue(eventData.parentNodeId, out var parentNode) &&
tab.domNodes.TryGetValue(eventData.nodeId, out var childNode) &&
parentNode.Node != null &&
childNode.Node != null)
{
parentNode.Node.children.Remove(childNode.Node);
} else {
//throw new InvalidOperationException("ChildNodeRemoved event was fired, the node info has not yet been recieved");
}
}
public static void onDocumentUpdated(BrowserTab tab, documentUpdatedEvent eventData)
{
// clear the domNodes dictionary
tab.domNodes.Clear();
}
public static void onSetChildNodes(BrowserTab tab, setChildNodesEvent eventData)
{
var parentNode = createOrUpdateNode(tab, eventData.parentId);
if (parentNode.Node != null)
{
foreach (var node in eventData.nodes)
{
createOrUpdateNode(tab, node.nodeId, eventData.parentId, node.backendNodeId, node);
}
parentNode.Node.children = new(eventData.nodes);
} else {
throw new InvalidOperationException("SetChildNodes event was fired, the node info has not yet been recieved");
}
}
#endregion Event Handlers
#region Commands
/// <summary>
/// Enables DOM agent for the given page.
/// </summary>
public static IEnumerator enable(BrowserTab tab)
{
var enableCommand = new enable();
return tab.devtools.SendCommand(enableCommand);
}
/// <summary>
/// Disables DOM agent for the given page.
/// </summary>
public static IEnumerator disable(BrowserTab tab)
{
return tab.devtools.SendCommand( new disable() );
}
/// <summary>
/// Get the root node of the document, the root node is returned as an argument to the callback.
/// </summary>
/// <param name="tab"></param>
/// <param name="callback">The callback recieves the root node as argument</param>
/// <returns><see cref="DomNodeWrapper"/></returns>
public static IEnumerator getDocument(BrowserTab tab, Action<DomNodeWrapper> callback)
{
var domCommand = new getDocument();
return tab.devtools.SendCommand(domCommand, (response) =>
{
Node documentRoot = ((getDocumentCommandResponse)response).root;
var domNode = createOrUpdateNode(tab,
documentRoot.nodeId,
documentRoot.parentId,
documentRoot.backendNodeId,
documentRoot
);
callback(domNode);
});
}
/// <summary>
/// Describes the node, does not require domain to be enabled. Does not start tracking any
/// objects, can be used for automation.
/// </summary>
/// <param name="callback">The callback recieves the node as argument</param>
public IEnumerator describeNode(Action<Node> callback, int? depth = null, bool? pierce = null)
{
var describeNodeCommand = new describeNode
{
nodeId = NodeId,
depth = depth,
pierce = pierce
};
return tab.devtools.SendCommand(describeNodeCommand, (response) =>
{
callback(((describeNodeCommandResponse)response).node);
});
}
/// <summary>
/// Focus this node.
/// </summary>
public IEnumerator focus()
{
var focusCommand = new focus
{
nodeId = NodeId
};
return tab.devtools.SendCommand(focusCommand);
}
/// <summary>
/// Gets the nodes Attributes
/// </summary>
public IEnumerator getAttributes(Action<Dictionary<string, string>> callback)
{
var attributesCommand = new getAttributes
{
nodeId = NodeId
};
return tab.devtools.SendCommand(attributesCommand, (response) =>
{
var attibutes = ((getAttributesCommandResponse)response).attributes;
tab.domNodes[NodeId].Node.attributes = attibutes;
callback(attibutes);
});
}
public IEnumerator getBoxModel(Action<BoxModel> callback)
{
var boxModelCommand = new getBoxModel
{
nodeId = NodeId
};
return tab.devtools.SendCommand(boxModelCommand, (response) =>
{
callback(((getBoxModelCommandResponse) response).model);
});
}
public IEnumerator getNodeForLocation(int x, int y, Action<DomNodeWrapper> callback, Action<string>? errorCallback = null)
{
var nodeForLocationCommand = new getNodeForLocation
{
x = x,
y = y
};
return tab.devtools.SendCommand(nodeForLocationCommand, (response) =>
{
var responseNodeId = ((getNodeForLocationCommandResponse) response).nodeId;
if (responseNodeId != null) {
var domNode = createOrUpdateNode(tab, (int)responseNodeId);
callback(domNode);
} else {
errorCallback?.Invoke("nodeId was not provided, is the dom domain enabled?");
}
});
}
/// <summary>
/// Returns node's HTML markup.
/// </summary>
public IEnumerator getOuterHtml(Action<string> callback)
{
var outerHtmlCommand = new getOuterHTML
{
nodeId = NodeId
};
return tab.devtools.SendCommand(outerHtmlCommand, (response) =>
{
callback(((getOuterHTMLCommandResponse) response).outerHTML);
});
}
/// <summary>
/// Moves node into an other container node
/// </summary>
public IEnumerator moveTo(DomNodeWrapper targetNode, DomNodeWrapper? insertBeforeNode = null)
{
var moveToCommand = new moveTo
{
nodeId = NodeId,
targetNodeId = targetNode.NodeId,
insertBeforeNodeId = insertBeforeNode?.NodeId
};
return tab.devtools.SendCommand(moveToCommand, (response) =>
{
// update the new node id of the moved node
tab.domNodes.Remove(NodeId);
NodeId = ((moveToCommandResponse) response).nodeId;
tab.domNodes[NodeId] = this;
});
}
/// <summary>
/// search a child node by querySelector
/// </summary>
public IEnumerator querySelector(string selector, Action<DomNodeWrapper> callback)
{
var querySelectorCommand = new querySelector
{
nodeId = NodeId,
selector = selector
};
return tab.devtools.SendCommand(querySelectorCommand, (response) =>
{
var domNode = createOrUpdateNode(tab, ((querySelectorCommandResponse) response).nodeId);
callback(domNode);
});
}
/// <summary>
/// search all child nodes matching the querySelector
/// </summary>
public IEnumerator querySelectorAll(string selector, Action<DomNodeWrapper[]> callback)
{
var querySelectorAllCommand = new querySelectorAll
{
nodeId = NodeId,
selector = selector
};
return tab.devtools.SendCommand(querySelectorAllCommand, (response) =>
{
var nodeIds = ((querySelectorAllCommandResponse) response).nodeIds;
var domNodes = new DomNodeWrapper[nodeIds.Length];
for (int i = 0; i < nodeIds.Length; i++)
{
domNodes[i] = createOrUpdateNode(tab, nodeIds[i]);
}
callback(domNodes);
});
}
//TODO: implement the other commands of the DOM domain
#endregion Commands
}
}
fileFormatVersion: 2
guid: 9a49fdc400bfe5d46b76c0c1e154940e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
#nullable enable annotations
namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
{ {
#region commands #region commands
...@@ -5,30 +11,35 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -5,30 +11,35 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// Describes node given its id, does not require domain to be enabled. Does not start tracking any /// Describes node given its id, does not require domain to be enabled. Does not start tracking any
/// objects, can be used for automation. /// objects, can be used for automation.
/// </summary> /// </summary>
[CommandResponseAttribute(typeof(describeNodeCommandResponse))] [CommandResponse(typeof(describeNodeCommandResponse))]
public class describeNode : IDevtoolsCommand public class describeNode : IDevtoolsCommandWithResponse
{ {
/// <summary> /// <summary>
/// Identifier of the node. /// Identifier of the node.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? nodeId { get; set; } public int? nodeId { get; set; }
/// <summary> /// <summary>
/// Identifier of the backend node. /// Identifier of the backend node.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? backendNodeId { get; set; } public int? backendNodeId { get; set; }
/// <summary> /// <summary>
/// JavaScript object id of the node wrapper. /// JavaScript object id of the node wrapper.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? objectId { get; set; } public string? objectId { get; set; }
/// <summary> /// <summary>
/// The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the /// The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the
/// entire subtree or provide an integer larger than 0. /// entire subtree or provide an integer larger than 0.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? depth { get; set; } public int? depth { get; set; }
/// <summary> /// <summary>
/// Whether or not iframes and shadow roots should be traversed when returning the subtree /// Whether or not iframes and shadow roots should be traversed when returning the subtree
/// (default is false). /// (default is false).
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public bool? pierce { get; set; } public bool? pierce { get; set; }
} }
...@@ -57,6 +68,7 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -57,6 +68,7 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// Whether to include whitespaces in the children array of returned Nodes. /// Whether to include whitespaces in the children array of returned Nodes.
/// </summary> /// </summary>
/// <remarks>experimental</remarks> /// <remarks>experimental</remarks>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? includeWhitespace { get; set; } public string? includeWhitespace { get; set; }
} }
...@@ -68,22 +80,25 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -68,22 +80,25 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// <summary> /// <summary>
/// Identifier of the node. /// Identifier of the node.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? nodeId { get; set; } public int? nodeId { get; set; }
/// <summary> /// <summary>
/// Identifier of the backend node. /// Identifier of the backend node.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? backendNodeId { get; set; } public int? backendNodeId { get; set; }
/// <summary> /// <summary>
/// JavaScript object id of the node wrapper. /// JavaScript object id of the node wrapper.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? objectId { get; set; } public string? objectId { get; set; }
} }
/// <summary> /// <summary>
/// Returns attributes for the specified node. /// Returns attributes for the specified node.
/// </summary> /// </summary>
[CommandResponseAttribute(typeof(getAttributesCommandResponse))] [CommandResponse(typeof(getAttributesCommandResponse))]
public class getAttributes : IDevtoolsCommand public class getAttributes : IDevtoolsCommandWithResponse
{ {
/// <summary> /// <summary>
/// Id of the node to retrieve attibutes for. /// Id of the node to retrieve attibutes for.
...@@ -99,26 +114,30 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -99,26 +114,30 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// <summary> /// <summary>
/// An interleaved array of node attribute names and values. /// An interleaved array of node attribute names and values.
/// </summary> /// </summary>
public string[] attributes { get; set; } [JsonConverter(typeof(JsonInterleavedArrayConverter<string, string>))]
public Dictionary<string, string> attributes { get; set; }
} }
/// <summary> /// <summary>
/// Returns boxes for the currently selected nodes. /// Returns boxes for the currently selected nodes.
/// </summary> /// </summary>
[CommandResponseAttribute(typeof(getBoxModelCommandResponse))] [CommandResponse(typeof(getBoxModelCommandResponse))]
public class getBoxModel : IDevtoolsCommand public class getBoxModel : IDevtoolsCommandWithResponse
{ {
/// <summary> /// <summary>
/// Identifier of the node. /// Identifier of the node.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? nodeId { get; set; } public int? nodeId { get; set; }
/// <summary> /// <summary>
/// Identifier of the backend node. /// Identifier of the backend node.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? backendNodeId { get; set; } public int? backendNodeId { get; set; }
/// <summary> /// <summary>
/// JavaScript object id of the node wrapper. /// JavaScript object id of the node wrapper.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? objectId { get; set; } public string? objectId { get; set; }
} }
...@@ -138,18 +157,20 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -138,18 +157,20 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// Returns the root DOM node (and optionally the subtree) to the caller. /// Returns the root DOM node (and optionally the subtree) to the caller.
/// Implicitly enables the DOM domain events for the current target. /// Implicitly enables the DOM domain events for the current target.
/// </summary> /// </summary>
[CommandResponseAttribute(typeof(getDocumentCommandResponse))] [CommandResponse(typeof(getDocumentCommandResponse))]
public class getDocument : IDevtoolsCommand public class getDocument : IDevtoolsCommandWithResponse
{ {
/// <summary> /// <summary>
/// The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the /// The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the
/// entire subtree or provide an integer larger than 0. /// entire subtree or provide an integer larger than 0.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? depth { get; set; } public int? depth { get; set; }
/// <summary> /// <summary>
/// Whether or not iframes and shadow roots should be traversed when returning the subtree /// Whether or not iframes and shadow roots should be traversed when returning the subtree
/// (default is false). /// (default is false).
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public bool? pierce { get; set; } public bool? pierce { get; set; }
} }
...@@ -169,8 +190,8 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -169,8 +190,8 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// Returns node id at given location. Depending on whether DOM domain is enabled, nodeId is /// Returns node id at given location. Depending on whether DOM domain is enabled, nodeId is
/// either returned or not. /// either returned or not.
/// </summary> /// </summary>
[CommandResponseAttribute(typeof(getNodeForLocationCommandResponse))] [CommandResponse(typeof(getNodeForLocationCommandResponse))]
public class getNodeForLocation : IDevtoolsCommand public class getNodeForLocation : IDevtoolsCommandWithResponse
{ {
/// <summary> /// <summary>
/// X coordinate. /// X coordinate.
...@@ -183,10 +204,12 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -183,10 +204,12 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// <summary> /// <summary>
/// False to skip to the nearest non-UA shadow root ancestor (default: false). /// False to skip to the nearest non-UA shadow root ancestor (default: false).
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public bool? includeUserAgentShadowDOM { get; set; } public bool? includeUserAgentShadowDOM { get; set; }
/// <summary> /// <summary>
/// Whether to ignore pointer-events: none on elements and hit test them. /// Whether to ignore pointer-events: none on elements and hit test them.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public bool? ignorePointerEventsNone { get; set; } public bool? ignorePointerEventsNone { get; set; }
} }
...@@ -198,14 +221,15 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -198,14 +221,15 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// <summary> /// <summary>
/// Resulting node. /// Resulting node.
/// </summary> /// </summary>
public int? backendNodeId { get; set; } public int backendNodeId { get; set; }
/// <summary> /// <summary>
/// Frame this node belongs to. /// Frame this node belongs to.
/// </summary> /// </summary>
public string frameId { get; set; } public string frameId { get; set; }
/// <summary> /// <summary>
/// Id of the node at given coordinates. /// Id of the node at given coordinates, only when enabled and requested document.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? nodeId { get; set; } public int? nodeId { get; set; }
} }
...@@ -213,20 +237,23 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -213,20 +237,23 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// <summary> /// <summary>
/// Returns node's HTML markup. /// Returns node's HTML markup.
/// </summary> /// </summary>
[CommandResponseAttribute(typeof(getOuterHTMLCommandResponse))] [CommandResponse(typeof(getOuterHTMLCommandResponse))]
public class getOuterHTML : IDevtoolsCommand public class getOuterHTML : IDevtoolsCommandWithResponse
{ {
/// <summary> /// <summary>
/// Identifier of the node. /// Identifier of the node.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? nodeId { get; set; } public int? nodeId { get; set; }
/// <summary> /// <summary>
/// Identifier of the backend node. /// Identifier of the backend node.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? backendNodeId { get; set; } public int? backendNodeId { get; set; }
/// <summary> /// <summary>
/// JavaScript object id of the node wrapper. /// JavaScript object id of the node wrapper.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? objectId { get; set; } public string? objectId { get; set; }
} }
...@@ -245,6 +272,7 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -245,6 +272,7 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// <summary> /// <summary>
/// Hides any highlight. /// Hides any highlight.
/// </summary> /// </summary>
/// <remarks>see Overlay.hideHighlight</remarks>
public class hideHighlight : IDevtoolsCommand public class hideHighlight : IDevtoolsCommand
{ {
} }
...@@ -252,6 +280,7 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -252,6 +280,7 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// <summary> /// <summary>
/// Highlights DOM node. /// Highlights DOM node.
/// </summary> /// </summary>
/// <remarks>see Overlay.highlightNode</remarks>
public class highlightNode : IDevtoolsCommand public class highlightNode : IDevtoolsCommand
{ {
} }
...@@ -259,6 +288,7 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -259,6 +288,7 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// <summary> /// <summary>
/// highlights given rectangle. /// highlights given rectangle.
/// </summary> /// </summary>
/// <remarks>see Overlay.highlightRect</remarks>
public class highlightRect : IDevtoolsCommand public class highlightRect : IDevtoolsCommand
{ {
} }
...@@ -266,8 +296,8 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -266,8 +296,8 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// <summary> /// <summary>
/// Moves node into the new container, places it before the given anchor. /// Moves node into the new container, places it before the given anchor.
/// </summary> /// </summary>
[CommandResponseAttribute(typeof(moveToCommandResponse))] [CommandResponse(typeof(moveToCommandResponse))]
public class moveTo : IDevtoolsCommand public class moveTo : IDevtoolsCommandWithResponse
{ {
/// <summary> /// <summary>
/// Id of the node to move. /// Id of the node to move.
...@@ -281,6 +311,7 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -281,6 +311,7 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// Drop node before this one (if absent, the moved node becomes the last child of /// Drop node before this one (if absent, the moved node becomes the last child of
/// `targetNodeId`). /// `targetNodeId`).
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? insertBeforeNodeId { get; set; } public int? insertBeforeNodeId { get; set; }
} }
...@@ -299,8 +330,8 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -299,8 +330,8 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// <summary> /// <summary>
/// Executes `querySelector` on a given node. /// Executes `querySelector` on a given node.
/// </summary> /// </summary>
[CommandResponseAttribute(typeof(querySelectorCommandResponse))] [CommandResponse(typeof(querySelectorCommandResponse))]
public class querySelector : IDevtoolsCommand public class querySelector : IDevtoolsCommandWithResponse
{ {
/// <summary> /// <summary>
/// Id of the node to query upon. /// Id of the node to query upon.
...@@ -327,8 +358,8 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -327,8 +358,8 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// <summary> /// <summary>
/// Executes `querySelectorAll` on a given node. /// Executes `querySelectorAll` on a given node.
/// </summary> /// </summary>
[CommandResponseAttribute(typeof(querySelectorAllCommandResponse))] [CommandResponse(typeof(querySelectorAllCommandResponse))]
public class querySelectorAll : IDevtoolsCommand public class querySelectorAll : IDevtoolsCommandWithResponse
{ {
/// <summary> /// <summary>
/// Id of the node to query upon. /// Id of the node to query upon.
...@@ -393,11 +424,13 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -393,11 +424,13 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the /// The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the
/// entire subtree or provide an integer larger than 0. /// entire subtree or provide an integer larger than 0.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? depth { get; set; } public int? depth { get; set; }
/// <summary> /// <summary>
/// Whether or not iframes and shadow roots should be traversed when returning the sub-tree /// Whether or not iframes and shadow roots should be traversed when returning the sub-tree
/// (default is false). /// (default is false).
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public bool? pierce { get; set; } public bool? pierce { get; set; }
} }
...@@ -406,8 +439,8 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -406,8 +439,8 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// nodes that form the path from the node to the root are also sent to the client as a series of /// nodes that form the path from the node to the root are also sent to the client as a series of
/// `setChildNodes` notifications. /// `setChildNodes` notifications.
/// </summary> /// </summary>
[CommandResponseAttribute(typeof(requestNodeCommandResponse))] [CommandResponse(typeof(requestNodeCommandResponse))]
public class requestNode : IDevtoolsCommand public class requestNode : IDevtoolsCommandWithResponse
{ {
/// <summary> /// <summary>
/// JavaScript object id to convert into node. /// JavaScript object id to convert into node.
...@@ -431,8 +464,8 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -431,8 +464,8 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// <summary> /// <summary>
/// Resolves the JavaScript node object for a given NodeId or BackendNodeId. /// Resolves the JavaScript node object for a given NodeId or BackendNodeId.
/// </summary> /// </summary>
[CommandResponseAttribute(typeof(resolveNodeCommandResponse))] [CommandResponse(typeof(resolveNodeCommandResponse))]
public class resolveNode : IDevtoolsCommand public class resolveNode : IDevtoolsCommandWithResponse
{ {
/// <summary> /// <summary>
/// Id of the node to resolve. /// Id of the node to resolve.
...@@ -474,19 +507,23 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -474,19 +507,23 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// <summary> /// <summary>
/// Identifier of the node. /// Identifier of the node.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? nodeId { get; set; } public int? nodeId { get; set; }
/// <summary> /// <summary>
/// Identifier of the backend node. /// Identifier of the backend node.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? backendNodeId { get; set; } public int? backendNodeId { get; set; }
/// <summary> /// <summary>
/// JavaScript object id of the node wrapper. /// JavaScript object id of the node wrapper.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? objectId { get; set; } public string? objectId { get; set; }
/// <summary> /// <summary>
/// The rect to be scrolled into view, relative to the node's border box, in CSS pixels. /// The rect to be scrolled into view, relative to the node's border box, in CSS pixels.
/// When omitted, center of the node will be used, similar to Element.scrollIntoView. /// When omitted, center of the node will be used, similar to Element.scrollIntoView.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public Rect? rect { get; set; } public Rect? rect { get; set; }
} }
...@@ -508,6 +545,7 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -508,6 +545,7 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// Attribute name to replace with new attributes derived from text in case text parsed /// Attribute name to replace with new attributes derived from text in case text parsed
/// successfully. /// successfully.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? name { get; set; } public string? name { get; set; }
} }
...@@ -542,22 +580,25 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -542,22 +580,25 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// <summary> /// <summary>
/// Identifier of the node. /// Identifier of the node.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? nodeId { get; set; } public int? nodeId { get; set; }
/// <summary> /// <summary>
/// Identifier of the backend node. /// Identifier of the backend node.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? backendNodeId { get; set; } public int? backendNodeId { get; set; }
/// <summary> /// <summary>
/// JavaScript object id of the node wrapper. /// JavaScript object id of the node wrapper.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? objectId { get; set; } public string? objectId { get; set; }
} }
/// <summary> /// <summary>
/// Set node name for a node with given id. /// Set node name for a node with given id.
/// </summary> /// </summary>
[CommandResponseAttribute(typeof(setNodeNameCommandResponse))] [CommandResponse(typeof(setNodeNameCommandResponse))]
public class setNodeName : IDevtoolsCommand public class setNodeName : IDevtoolsCommandWithResponse
{ {
/// <summary> /// <summary>
/// Id of the node to set name for. /// Id of the node to set name for.
...@@ -599,8 +640,8 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -599,8 +640,8 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// <summary> /// <summary>
/// Sets node HTML markup, returns new node id. /// Sets node HTML markup, returns new node id.
/// </summary> /// </summary>
[CommandResponseAttribute(typeof(setOuterHTMLCommandResponse))] [CommandResponse(typeof(setOuterHTMLCommandResponse))]
public class setOuterHTML : IDevtoolsCommand public class setOuterHTML : IDevtoolsCommandWithResponse
{ {
/// <summary> /// <summary>
/// Id of the node to set markup for. /// Id of the node to set markup for.
...@@ -802,6 +843,7 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -802,6 +843,7 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// <summary> /// <summary>
/// Shape outside coordinates /// Shape outside coordinates
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public ShapeOutsideInfo? shapeOutside { get; set; } public ShapeOutsideInfo? shapeOutside { get; set; }
} }
...@@ -850,6 +892,7 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -850,6 +892,7 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// <summary> /// <summary>
/// The id of the parent node if any. /// The id of the parent node if any.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? parentId { get; set; } public int? parentId { get; set; }
/// <summary> /// <summary>
/// The BackendNodeId for this node. /// The BackendNodeId for this node.
...@@ -874,79 +917,97 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -874,79 +917,97 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// <summary> /// <summary>
/// Child count for `Container` nodes. /// Child count for `Container` nodes.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? childNodeCount { get; set; } public int? childNodeCount { get; set; }
/// <summary> /// <summary>
/// Child nodes of this node when requested with children. /// Child nodes of this node when requested with children.
/// </summary> /// </summary>
public Node[]? children { get; set; } public List<Node> children { get; set; }
/// <summary> /// <summary>
/// Attributes of the `Element` node in the form of flat array `[name1, value1, name2, value2]`. /// Attributes of the `Element` node in the form of flat array `[name1, value1, name2, value2]`.
/// </summary> /// </summary>
public string[]? attributes { get; set; } [JsonConverter(typeof(JsonInterleavedArrayConverter<string, string>))]
public Dictionary<string,string> attributes { get; set; }
/// <summary> /// <summary>
/// Document URL that `Document` or `FrameOwner` node points to. /// Document URL that `Document` or `FrameOwner` node points to.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? documentURL { get; set; } public string? documentURL { get; set; }
/// <summary> /// <summary>
/// Base URL that `Document` or `FrameOwner` node uses for URL completion. /// Base URL that `Document` or `FrameOwner` node uses for URL completion.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? baseURL { get; set; } public string? baseURL { get; set; }
/// <summary> /// <summary>
/// `DocumentType`'s publicId. /// `DocumentType`'s publicId.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? publicId { get; set; } public string? publicId { get; set; }
/// <summary> /// <summary>
/// `DocumentType`'s systemId. /// `DocumentType`'s systemId.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? systemId { get; set; } public string? systemId { get; set; }
/// <summary> /// <summary>
/// `DocumentType`'s internalSubset. /// `DocumentType`'s internalSubset.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? internalSubset { get; set; } public string? internalSubset { get; set; }
/// <summary> /// <summary>
/// `Document`'s XML version in case of XML documents. /// `Document`'s XML version in case of XML documents.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? xmlVersion { get; set; } public string? xmlVersion { get; set; }
/// <summary> /// <summary>
/// `Attr`'s name. /// `Attr`'s name.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? name { get; set; } public string? name { get; set; }
/// <summary> /// <summary>
/// `Attr`'s value. /// `Attr`'s value.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? value { get; set; } public string? value { get; set; }
/// <summary> /// <summary>
/// Pseudo element type for this node. /// Pseudo element type for this node.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public PseudoType? pseudoType { get; set; } public PseudoType? pseudoType { get; set; }
/// <summary> /// <summary>
/// Pseudo element identifier for this node. Only present if there is a /// Pseudo element identifier for this node. Only present if there is a
/// valid pseudoType. /// valid pseudoType.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? pseudoIdentifier { get; set; } public string? pseudoIdentifier { get; set; }
/// <summary> /// <summary>
/// Shadow root type. /// Shadow root type.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public ShadowRootType? shadowRootType { get; set; } public ShadowRootType? shadowRootType { get; set; }
/// <summary> /// <summary>
/// Frame ID for frame owner elements. /// Frame ID for frame owner elements.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? frameId { get; set; } public string? frameId { get; set; }
/// <summary> /// <summary>
/// Content document for frame owner elements. /// Content document for frame owner elements.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public Node? contentDocument { get; set; } public Node? contentDocument { get; set; }
/// <summary> /// <summary>
/// Shadow root list for given element host. /// Shadow root list for given element host.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public Node[]? shadowRoots { get; set; } public Node[]? shadowRoots { get; set; }
/// <summary> /// <summary>
/// Content document fragment for template elements. /// Content document fragment for template elements.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public Node? templateContent { get; set; } public Node? templateContent { get; set; }
/// <summary> /// <summary>
/// Pseudo elements associated with this node. /// Pseudo elements associated with this node.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public Node[]? pseudoElements { get; set; } public Node[]? pseudoElements { get; set; }
/// <summary> /// <summary>
/// Deprecated, as the HTML Imports API has been removed (crbug.com/937746). /// Deprecated, as the HTML Imports API has been removed (crbug.com/937746).
...@@ -954,16 +1015,21 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -954,16 +1015,21 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// The property is always undefined now. /// The property is always undefined now.
/// </summary> /// </summary>
/// <remarks>deprecated</remarks> /// <remarks>deprecated</remarks>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public Node? importedDocument { get; set; } public Node? importedDocument { get; set; }
/// <summary> /// <summary>
/// Distributed nodes for given insertion point. /// Distributed nodes for given insertion point.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public BackendNode[]? distributedNodes { get; set; } public BackendNode[]? distributedNodes { get; set; }
/// <summary> /// <summary>
/// Whether the node is SVG. /// Whether the node is SVG.
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public bool? isSVG { get; set; } public bool? isSVG { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public CompatibilityMode? compatibilityMode { get; set; } public CompatibilityMode? compatibilityMode { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public BackendNode? assignedSlot { get; set; } public BackendNode? assignedSlot { get; set; }
} }
...@@ -985,6 +1051,17 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -985,6 +1051,17 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
firstLine, firstLetter, before, after, marker, backdrop, selection, targetText, spellingError, grammarError, highlight, firstLineInherited, scrollbar, scrollbarThumb, scrollbarButton, scrollbarTrack, scrollbarTrackPiece, scrollbarCorner, resizer, inputListButton, viewTransition, viewTransitionGroup, viewTransitionImagePair, viewTransitionOld, viewTransitionNew firstLine, firstLetter, before, after, marker, backdrop, selection, targetText, spellingError, grammarError, highlight, firstLineInherited, scrollbar, scrollbarThumb, scrollbarButton, scrollbarTrack, scrollbarTrackPiece, scrollbarCorner, resizer, inputListButton, viewTransition, viewTransitionGroup, viewTransitionImagePair, viewTransitionOld, viewTransitionNew
} }
/// <summary>
/// An array of quad vertices, x immediately followed by y for each point, points clock-wise.
/// </summary>
public class Quad
{
/// <summary>
/// Quad vertices
/// </summary>
public double[] quad { get; set; }
}
/// <summary> /// <summary>
/// Rectangle. /// Rectangle.
/// </summary> /// </summary>
...@@ -1028,6 +1105,7 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM ...@@ -1028,6 +1105,7 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
/// <summary> /// <summary>
/// The alpha component, in the [0-1] range (default: 1). /// The alpha component, in the [0-1] range (default: 1).
/// </summary> /// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public double? a { get; set; } public double? a { get; set; }
} }
......
fileFormatVersion: 2
guid: f4e9b65319713e3478ca1d350419f8c4
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
...@@ -5,6 +5,7 @@ using Newtonsoft.Json.Serialization; ...@@ -5,6 +5,7 @@ using Newtonsoft.Json.Serialization;
using UnityEngine.EventSystems; using UnityEngine.EventSystems;
using static UnityEngine.EventSystems.PointerEventData; using static UnityEngine.EventSystems.PointerEventData;
#nullable enable annotations
namespace bessw.Unity.WebView.ChromeDevTools.Protocol.Input namespace bessw.Unity.WebView.ChromeDevTools.Protocol.Input
{ {
#region dispatchMouseEvent #region dispatchMouseEvent
......
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
namespace bessw.Unity.WebView.ChromeDevTools.Protocol
{
/// <summary>
/// Converts a interleaved JSON array like `[key1, value1, key2, value2, ...]` to a C# dictionary.
/// </summary>
/// <typeparam name="keyT"></typeparam>
/// <typeparam name="valueT"></typeparam>
public class JsonInterleavedArrayConverter<keyT, valueT> : JsonConverter<Dictionary<keyT,valueT>>
{
public override void WriteJson(JsonWriter writer, Dictionary<keyT,valueT> value, JsonSerializer serializer)
{
JArray obj = new JArray();
foreach (var pair in value)
{
obj.Add(pair.Key);
obj.Add(pair.Value);
}
obj.WriteTo(writer);
}
public override Dictionary<keyT,valueT> ReadJson(JsonReader reader, Type objectType, Dictionary<keyT,valueT> existingValue, bool hasExistingValue, JsonSerializer serializer)
{
JArray obj = JArray.Load(reader);
Dictionary<keyT,valueT> result = new Dictionary<keyT,valueT>();
for (int i = 0; i < obj.Count; i+=2)
{
result.Add(obj[i].Value<keyT>(), obj[i+1].Value<valueT>());
}
return result;
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 31c472a5e6adcf247b4e0d9835835e75
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
...@@ -39,7 +39,7 @@ namespace bessw.Unity.WebView ...@@ -39,7 +39,7 @@ namespace bessw.Unity.WebView
#endregion json serializer #endregion json serializer
private Browser browser; private Browser browser;
private BrowserTab tab; protected BrowserTab tab;
private RawImage rawImage; private RawImage rawImage;
private RectTransform rectTransform; private RectTransform rectTransform;
...@@ -87,6 +87,32 @@ namespace bessw.Unity.WebView ...@@ -87,6 +87,32 @@ namespace bessw.Unity.WebView
}); });
} }
private IEnumerator getDropzoneState ()
{
Debug.LogWarning($"dropzone pre");
DomNodeWrapper doc = null;
yield return DomNodeWrapper.getDocument(tab, (document) => {
Debug.LogWarning($"dropzone 1: '{document}'");
doc = document;
StartCoroutine(document.querySelectorAll("[dropzone='copy']", (dropzones) => {
foreach (var dropzone in dropzones)
{
Debug.LogWarning($"dropzone 2: Node is Null?: '{dropzone.Node == null}'");
StartCoroutine(dropzone.getAttributes((attributes) =>
{
Debug.LogWarning($"dropzone 3 getAttributes: '{string.Join(", ", attributes.Values)}'");
}));
}
}));
});
Debug.LogWarning($"dropzone post: '{doc}'");
// alternative way to get the dropzone state
}
// Update is called once per frame // Update is called once per frame
private void Update() private void Update()
{ {
...@@ -132,12 +158,13 @@ namespace bessw.Unity.WebView ...@@ -132,12 +158,13 @@ namespace bessw.Unity.WebView
} }
} }
// TODO: OnDragMove -> PointerMove
public void OnDrop(PointerEventData eventData) public void OnDrop(PointerEventData eventData)
{ {
Debug.LogWarning($"OnDrop: {eventData.position}"); Debug.LogWarning($"OnDrop: {eventData.position}");
createDragEvent(DragEventType.drop, eventData); createDragEvent(DragEventType.drop, eventData);
// TODO: remove debug code
StartCoroutine(getDropzoneState());
} }
public void OnPointerExit(PointerEventData eventData) public void OnPointerExit(PointerEventData eventData)
......
...@@ -34,11 +34,11 @@ RectTransform: ...@@ -34,11 +34,11 @@ RectTransform:
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 0 m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: -444.39624, y: -175.33963} m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 100, y: 100} m_SizeDelta: {x: 100, y: 100}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0, y: 0}
--- !u!222 &5559415116192402672 --- !u!222 &5559415116192402672
CanvasRenderer: CanvasRenderer:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -87,3 +87,4 @@ MonoBehaviour: ...@@ -87,3 +87,4 @@ MonoBehaviour:
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
headlessBrowser: 1 headlessBrowser: 1
targetUrl: https://google.de
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment