console.log()
Firebug Lite is a portable, JavaScript-based debugger that claims to work with "all major browsers". This could be a very attractive, lightweight solution for debugging, if there aren't any critical bugs or limitations. I am told that Firebug Lite can be used with WebDialogs, but I don't know the exact procedure; please let me know if you have any information!
A Ruby-based web application framework such as Ruby on Rails or Sinatra could emulate portions of the SketchUp API. Using some sort of "push" technology, browser-based debugging and/or testing could then be supported. Emulating even a critical subset of SketchUp's API is not trivial, but I have heard of some early efforts in this direction.
This is the approach that Browser_Dialog takes. A proxy server, acting as a protocol converter of sorts, receives message files from the plugin and forwards them to the client code using WebSockets. Returning messages use corresponding communication paths. Again, this approach supports browser-based debugging and/or testing.
:bd_proxy setting in the sa_config.rb file),
the Plugin Framework creates an instance of the Browser_Dialog class
(rather than SketchUp's usual UI::WebDialog class) for the plugin.
Once the dialog instance has been created,
the plugin uses it in (approximately) the normal manner.
The main restriction, at this point, is that Browser_Dialog
only supports a few UI::WebDialog methods
(add_action_callback, execute_script, set_file, and show_modal).
These are the only methods my current set of plugins have needed,
but I expect to add support for others
(eg, get_element_value, show) over time.
Feel free to implement and contribute your own!
Like the plugin code,
the client-side code must also be modified slightly.
Specifically, it must use a set of wrapper methods for communication.
For example, jQuery event handlers use callback(),
rather than setting the location variable directly.
After the needed modifications are in place, the developer:
bd_proxy)
UI::WebDialog,
we can use either class to create a given dialog.
Thus, we can reserve Browser_Dialog instances for dialogs
which are currently being debugged.
We may also be able
to use some UI::WebDialog methods on Browser_Dialog objects.
UI::WebDialog#post_url can POST a message to an arbitrary URL.File#rename)
and I don't need to worry about message encapsulation.
Data Flow
The top part of the diagram below should be quite familiar.
The plugin creates some base files (eg, CSS, HTML, JavaScript)
which are loaded by a dialog and become the "client code".
The middle and bottom parts of the diagram vary, however,
between WebDialog and Browser_Dialog.
SketchUp's WebDialogs provide asynchronous data paths
between the plugin and client code.
Browser_Dialog emulates these paths,
using message files, a proxy server, and a WebSocket.
Browser_Dialog's library code handles the details of dealing
with message files (in the plugin) and WebSockets (in the client).
Plugin Support
Outgoing messages are easy to handle:
we simply create a file for each message.
Incoming messages are harder, because they can arrive at any time.
However, a sub-second timer (supported in SketchUp 8),
allows Browser_Dialog to check frequently for incoming messages:
@timer_id = UI.start_timer(0.05, true) do
paths = Dir.glob(patt)
paths.each {|path| process_input(path) } unless paths.empty?
end
Proxy Server
Using EventMachine,
I wrote a simple proxy server
which watches an input directory for activity.
The server forwards each outgoing message to the client via WebSockets.
Similarly, incoming WebSocket messages are turned into message files.
To support follow-on analysis, while minimizing disk overhead,
the proxy server collects the incoming and outgoing messages
for each (dialog-specific) session into a pair of log files.