The scope module provides facilities for interaction
with external or semi-external content debuggers. Examples are
javascript debuggers, document inspectors, logging services, and
playback services.
...
A module that wishes to provide debugging services will implement
this service in two parts, a "back end" close to the module code (and
usually located with the module in the CVS) and a "front end" that
serializes and deserializes data and communicates with the debugger
(usually located in the scope module). The back end and
front end will normally communicate by a simple API using data
structures defined in the back end. Thus the scope
module contains code pertaining to the debugging needs of many
modules.
The two-layer architecture for the debugging support makes it simple to implement custom or multiple communication protocols or to move parts of the debugger into Opera for performance or other reasons.
For debuggers that are in fact external to Opera, there is a third transport layer below the front end that is responsible for sending and receiving data over a network connection.
The back end is structured in part as an event listener. An event in the debugged module will be signalled as a call to the back end. It will extract the necessary data pertaining to the event from the module state, package these data somehow, and call the front end to have them delivered to the debugger. For an external debugger, the front end transforms the data to XML and delivers them to the network layer for delivery. The network layer returns to the front end, which returns to the back end, which can either block (when it has just sent an event that the debugger wants it to stop at) or just continue.
If there is a debugger that wants to control Opera in some way, then the transport layer will receive data from the debugger. It delivers these data to the front end, which deserializes them into data structures understood by the back end and finally delivers them to the back end. The back end then implements the necessary operations on its module.
The preferred representation for messages to and from external debugging agents is ASCII-encoded XML, and the scope module provides numerous utilities to ease the use of this representation.
Though an XML representation will typically be larger and slower than a well-designed binary representation, it is human-readable and therefore more easily debuggable. XML libraries exist for many programming languages and therefore places few restrictions on the technology chosen for a particular debugger.
The following style guidelines apply to all the XML protocols.
Attribute values never contain characters outside ASCII. They are escaped if necessary, using the normal "%xx" scheme.
Element text data can contain characters from the entire Unicode character set. These data are always base-64 encoded.
Following the preceding two translations, the message is representable in ASCII and therefore also UTF-8.
The file js-protocol.txt contains the protocol specification for the Javascript debugger.
This is currently done by ad-hoc methods in a utility class, "ScopeDebugMessage". For the moment this seems to be adequate.
This is done by a wrapper class around the XML parser, "XMLFragmentParser". This wrapper class also functions as an interator over the generated parse tree, allowing the conversion from XML to an internal data structure to be implemented by ad-hoc code. This too seems to be adequate.
Previously the Javascript debugger used custom code for transport.
For the scope module, I am planning to instead use the probetools "shell" functionality as the transport layer, since it was designed to provide this type of service anyway.