DOM inspector protocol

PROTOCOL ::= (COMMAND | EVENT)* ;
# Extend commands with the following

COMMAND ::= INSPECT-DOM ;

# Extend events with the following

EVENT ::= DOM-INSPECTION-REPLY ;

# The FORMAT option is for testing only, and will be removed in the final
# version (choosing either XML or JSON)

INSPECT-DOM ::=
  "<inspect-dom>"
    TAG
    OBJECT-ID
    TRAVERSAL
    FORMAT
  "</inspect-dom>" ;

FORMAT ::=
  "<format>"
    ( "xml" | "json" )
  "</format>" ;

# The traversal method can be any of the following:
#
# - "parent-node-chain-with-children" 
#     - take the parent node chain for the target node:
#     - add for each node in that chain all children, 
#       and for all children there first child,
#       if that is a text node and the only node, 
#       starting with the document node:
#
#         as pseudocode:
#
#           data
#           parentNodeChain
#           function getNodeData(node)
#             ...
#
#           function getView(node):
#             for child in node.childNodes:
#               data.add(getNodeData(child))
#               if child.childNodes.length == 1 and child.childNodes[0].nodeType == 3:
#                 data.add(getNodeData(child.childNodes[0]))
#               if child in parentNodeChain:
#                 getView(child)
#           data.add(getNodeData(parentNodeChain[0]))
#           getView(parentNodeChain[0])
#
# - "children"
#     - get node data for all children in their flow
#
# - "node"
#     - get node data for that node
#
# - "subtree"
#     - get node data for the whole document in the flow of it
#
#       as pseudocode:
#
#         data
#         function getNodeData(node)
#           ...
#
#         function getView(node):
#           for child in node.childNodes:
#             data.add(getNodeData(child))
#             if child.nodeType == 1:
#               getView(child)
#         data.add(getNodeData(documentNode))
#         getView(documentNode)

TRAVERSAL ::=
  "<traversal>"
    ( "subtree" | "node" | "children" | "parent-node-chain-with-children" )
  "</traversal>" ;

DOM-INSPECTION-REPLY ::=
  "<dom-inspection-reply>"
    TAG
    FLAT-DOM-DATA
  "</dom-inspection-reply>" ;

FLAT-DOM-DATA ::= NODE* ;

# NAMESPACE-PREFIX, ATTRIBUTES and CHILDREN-LENGTH only for type 1
# VALUE only for types 3, 4, 8
# PUBLIC-ID and SYSTEM-ID only for type 10
#
# Note to implementors changing from JSON:
#    Some names have changed from the JSON-protocol, namely dropping the -NODE
#    suffix and ATTRIBUTE- prefix, since it follows from the parent node.
#    Also, the order have changed to keep optional arguments grouped.

NODE ::=
  "<node>"
    OBJECT-ID
    TYPE
    NAME
    DEPTH
    NAMESPACE-PREFIX?
    ATTRIBUTES?
    CHILDREN-LENGTH?
    VALUE?
    PUBLIC-ID?
    SYSTEM-ID?
  "</node>" ;

TYPE ::= "<type>" UNSIGNED "</type>" ;
NAME ::= "<name>" TEXT "</name>" ;
NAMESPACE-PREFIX ::= "<namespace-prefix>" TEXT "</namespace-prefix>" ;
VALUE ::= "<value>" TEXT "</value>" ;
DEPTH ::= "<depth>" UNSIGNED "</depth>" ;
CHILDREN-LENGTH ::= "<children-length>" UNSIGNED "</children-length>" ;
PUBLIC-ID ::= "<public-id>" TEXT "</public-id>" ;
SYSTEM-ID ::= "<system-id>" TEXT "</system-id>" ;
ATTRIBUTES ::= "<attributes>" ATTRIBUTE* "</attributes>" ;

ATTRIBUTE ::=
  "<attribute>"
    NAME-PREFIX?
    NAME
    VALUE
  "</attribute>" ;

NAME-PREFIX ::= "<name-prefix>" TEXT "</name-prefix>" ;

###
# From ecmascript-debugger-protocol.html
#

TAG ::= "<tag>" UNSIGNED "</tag>" ;
OBJECT-ID ::= "<object-id>" UNSIGNED "</object-id>" ;
UNSIGNED ::= [0-9]+ ;
TEXT ::= BASE64-ENCODED-DATA | textual-data ;
BASE64-ENCODED-DATA ::= "<base64-encoded-data>" textual-data "</base64-encoded-data>" ;