Opera DOM Inspector

The Opera DOM inspector is a standalone application running outside the Opera browser than can be used to query any DOM property from an instance of the browser. The DOM Inspector can be joined together with the planned CSS Inspector to make the infamous Live Inspector.

Phases

The DOM Inspector work is done in two phases.

Phase 1

The first phase will get the basic functionality up and running as a proof of concept. The UI will be a command line and no real GUI. All the basic features of quering and setting DOM properties will be in place.

Phase 1 is to be finished early December 2006.

Phase 2

The second phase is for refining the user experience with a better UI and some added functionality.

Phase 2 is to be finished some time after phase 1 :-)

Features

Functional requirements

The functional requirements mainly describes which services must be supported by the browser.

Phase 1

List loaded documents

The client must be able to request a list of the documents that are currently loaded. Each tab counts for one document and every frame or inline frame counts as one document.

Each document is represented by a unique identifier.

Select active document

The client must be able to specify which document to inspect. The document is selected by the unique identifier returned by the listing of loaded documents.

The DOM properties of the document node is returned in the response from the browser.

Load and inspect document

The client must be able to specify a URL that the browser will use as the active document and load it.

The unique identifier of the document is returned in the response from the browser.

Query parent, siblings and children of a node

The client must be able to send a message to the browser requesting the parent node, the previous sibling, the next sibling or a list of the child nodes of a node specified by the unique identifier.

The browser must return a list of unique identifiers for the requested nodes and indicate if the nodes has children.

Query any DOM property on a node

The client must be able to send a message to the browser requesting a list of DOM properties and values or the value of a single property for a node specified by the unique identifier.

The browser must return either a list of name/value pairs or the value of a single specified property.

Change any DOM property on a node

The client must be able to send a message to the browser telling it the new value of a single DOM property for a node specified by a unique identifier.

The browser must return a status value telling if the setting was successful or not. Should return why it failed if it did, like out of memory or access denied.

Highlight an element in the browser

The client must be able to send a message to the browser telling it that an element is the current one. The current element should be highlighted in the browser somehow.

Receive event from browser when the DOM changes

The browser must send a notification to the client when a new element is inserted into the document or a property on an element changes.

To avoid too much traffic, there might be a need to filter out which changes should be reported to the client. Examples of filters could be to suppress the changes done during parsing or only send events for elements that the client has subscribed to (are visible at the moment.)

Receive UI events from browser

The browser must send a notification to the client when a UI event is triggered

To avoid too much traffic, there might be a need to filter out which events should be reported to the client. Examples of filters could be to suppress the mouse move events or only send events for elements that the client has subscribed to.

Phase 2

Enumerate ECMAScript properties

Enumerate all the ECMAScript properties on the selected node not only the DOM properties.

The browser must return a list of all the ECMASCript properties and their values.

Search for elements with a certain name or id

Make it possible to search for nodes in the DOM tree by tag name or attribute values like id, class or name.

The browser must return a list of the unique identifiers for all the nodes matching the search.

Search for elemenst with certain property values

Make it possible to search for nodes in the DOM tree by certain values for the DOM properties like text color or position.

The browser must return a list of the unique identifiers for all the nodes matching the search.

UI requirements

The UI requirements describes mainly how the user can interact with the DOM Inspector and how data is to be presented.

Phase 1

In phase 1 there will only be a comman line interface and no "real" GUI.

List loaded documents

The user must be able to get a list of the loaded documents. Each window, tab, frame or iframe represents one document.

The documents are represented by the unique identifier and the URL.

Select document to debug

The user must be able to select which document to inspect. The selected document will be the root node of the DOM.

The document is selected by the unique identifier which can be found by the listing of loaded documents

The user must be able to set the current node by going to the parent-, sibling- and child-nodes of the curent node.

After the user has issued a navigation command the result of the navigation will be the next current node.

View all current DOM properties on selected element

The user must be able to get a list of the DOM properties of the current node. The DOM properties are the ones specified in the DOM 2 specifications from W3C.

There are many properties for each node so the UI should group them somehow to make it easier to read for the user.

Change properties live

The user must be able to change any property that is not read only on the current node.

The property is specified by the name from the DOM 2 spec and the value must be a valid value also specified by the DOM 2 spec.

The user must get feedback on how the change request was handled.

Indicate element in document when selected

When the user changes the current element it should be indicated visually in the document being inspected.

Point to stuff in document and select

The user must be able to set the current element by selecting the element in the rendered page. Clicking the mouse on an element should select it.

Phase 2

Treeview of DOM nodes in the document

The nodes in the document should be presented to the user as a treeview with collapsing branches for the children. The treeview should make it possible to hide the details of the unique identifiers from the user.

Search for elements by different properties

The user should be able to find elements by searching for them by tag name, class name, id or any other attribute or property. The user should be able to cycle through the returned results one by one.

Enumerate ECMAScript properties

Not only DOM properties but all the ECMAScript properties of the nodes should be listed. And it should be possible to change all these properties that are not read only just like the DOM properties.

Set breakpoints when properties change

The user should be able to specify that the page parsing and rendering should stop when certain properties on certain elements change. When a breakpoint is triggered the inspector must make the targeted node the current node and show it to the user.

Set breakpoints on special events

The user should be able to specify that the page parsing and rendering should stop when certain events are triggered. When a breakpoint is triggered the targeted node should be made the current node and show it to the user.

Implementation

The implementation of the DOM Inspector will be using the ECMAScript debugger protocol to set and get nodes and properties from the browser.

List loaded documents
Sends: <runtimes><tag>{UNSIGNED}</tag></runtimes>
Receives: <runtimes-reply><tag>{UNSIGNED}</tag> <runtime>...</runtime>*</runtimes-reply>
Example:
<runtimes><tag>007</tag></runtimes> <runtime-reply> <tag>007</tag> <runtime> <runtime-id>1</runtime-id> <html-frame-path>stuff</html-frame-path> <object-id>5</object-id> <uri>http://test.net/</uri> </runtime> </runtime-reply>
Select active document

Sends: <examine-objects> with the correct runtime and the object number for the document node. The object number is found by examining the global object of the runtime and finding the document object.
Receives: <examine-reply type="examine-objects"> with the objects and properties on the document. The document node becomes the current node.

Example:
<examine-objects> <tag>007</tag> <runtime-id>1</runtime-id> <object>1</object> </examine-objects> <examine-reply> <tag>007</tag> <examine-type>object</examine-type> <object> <object-value> <object-id>7</object-id> <prototype-id>3</prototype-id> <object-attributes /> <class-name>documentElement</class-name> </object-value> <property> <name>title</name> <value> <type>string</type> <bits>Test document</bits> </value> </property> </object> </examine-reply>
Load and inspect document

The client must be able to specify a URL that the browser will use as the active document and load it.

The unique identifier of the document is returned in the response from the browser.

Query parent, siblings and children of a node

Sends: <examine-objects> with the object number of the current node.
Receives: <examine-reply type="examine-objects"> with the objects and properties on the current node. The parentNode, firstChild, lastChild, previousSibling and nextSibling properties returned indicate the neighbouring nodes. These have to be examined in turn to find names and children.

Example:
<examine-objects> <tag>007</tag> <runtime-id>1</runtime-id> <object-id>7</object-id> </examine-objects> <examine-reply> <tag>007</tag> <examine-type>object</examine-type> <object> <object-value> <object-id>10</object-id> <prototype-id>3</prototype-id> <object-attributes /> <class-name>parentNode</class-name> </object-value> ... </object> </examine-reply>
Query any DOM property on a node

The client must be able to send a message to the browser requesting a list of DOM properties and values or the value of a single property for a node specified by the unique identifier.

The browser must return either a list of name/value pairs or the value of a single specified property.

Example:
<examine-objects> <tag>007</tag> <runtime-id>1</runtime-id> <object-id>7</object-id> </examine-objects> <examine-reply> <tag>007</tag> <examine-type>object</examine-type> <object> <object-value> <object-id>7</object-id> <prototype-id>3</prototype-id> <object-attributes /> <class-name>DOMNode</class-name> </object-value> <property> <property-name>parentNode</property-name> <value-data> <datatype>object</datatype> <object-value><object-id>5</object-id></object-value> </value-data> </property> ... </object> </examine-reply>
Change any DOM property on a node

The client must be able to send a message to the browser telling it the new value of a single DOM property for a node specified by a unique identifier.

The browser must return a status value telling if the setting was successful or not. Should return why it failed if it did, like out of memory or access denied.

Example:
<eval> <tag>007</tag> <runtime-id>1</runtime-id> <thread-id>1</thread-id> <property> <object-id>10</object-id> <property-name>title</property-name> <value-data> <data-type>string</data-type> <string>document title</string> </value-data> </property> </eval>
Highlight an element in the browser

The client must be able to send a message to the browser telling it that an element is the current one. The current element should be highlighted in the browser somehow.

Receive event from browser when the DOM changes

The browser must send a notification to the client when a new element is inserted into the document or a property on an element changes.

To avoid too much traffic, there might be a need to filter out which changes should be reported to the client. Examples of filters could be to suppress the changes done during parsing or only send events for elements that the client has subscribed to (are visible at the moment.)

Example:
<add-breakpoint> <breakpoint-id>1</breakpoint-id> <event-type>DOMNodeRemoved</event-type> </add-breakpoint>
Receive UI events from browser

The browser must send a notification to the client when a UI event is triggered

To avoid too much traffic, there might be a need to filter out which events should be reported to the client. Examples of filters could be to suppress the mouse move events or only send events for elements that the client has subscribed to.

Example:
<add-breakpoint> <breakpoint-id>1</breakpoint-id> <event-type>onclick</event-type> </add-breakpoint>

stighal, 2006-10-18