You are here: Editor project page > Editor API Logging
The Editor API Logging Mechanism
Kin Blas (Netscape Communications Corporation)Follow-up and discussion on netscape.public.mozilla.editor
The Editor API Logging Mechanism allows a user to record and playback all the edits made to a document. This feature can be used by QA to create Editor test scripts, and scripts that can be used by engineers to recreate bugs.
Recording and Playback
To begin recording, select "Start Log" from the Debug menu:
This will create a journal.js
file in the same directory as the apprunner
executable which will contain a description of all the edits made to the
current document.
To stop recording, select "Stop Log" from the Debug menu:
To playback the edits you just made, simply restore the document back to the state it was when you started recording, via undo, or just reload the entire document, then select "Run Log" from the Debug menu:
It's important to note that the log information contained in the
journal.js
file is tied to the document used and the state it was in just
before you enabled recording. If you try to replay the edits on a different
file, or on the document while it is in any other state, unpredictable results
may happen.
Implementation Details
If you take a look at the contents of the journal.js file, you will see that it is just JavaScript. Playback involves loading this file and calling eval() so that the statements in the journal.js file get executed in the editor's JavaScript context and have access to the editor's public methods.
The actual logging mechanism involves two parts:
- Calls to
nsJSEditorLog
from the variousnsIEditor
,nsITextEditor
, andnsIHTMLEditor
methods that modify the document. - An
nsITransactionListener
that listens to the editor's transaction manager.
The nsJSEditorLog
class
implements the nsIHTMLEditor
interface
because it contained the union of all methods from nsIEditor
, nsITextEditor
,
and nsIHTMLEditor
that could modify the document. Implementing nsJSEditorLog
with the nsIHTMLEditor
interface also forces all developers who change these
editor interfaces, to update the nsJSEditorLog implementation whenever a
method is added, or it's signature changed.
As stated above, calls
to nsJSEditorLog
methods were added to the implementations for nsIEditor
,
nsITextEditor and nsIHTMLEditor
. This involved adding code like the following
to each method that modifies the content tree:
NS_IMETHODIMP InsertText(const nsString& aStringToInsert) { #ifdef ENABLE_JS_EDITOR_LOG if (mJSEditorLog) mJSEditorLog->InsertText(aStringToInsert); #endif // ENABLE_JS_EDITOR_LOG ... }
If you look at the implementation for nsJSEditorLog, you will see that each of it's methods write out the JavaScript that recreates the call to the method.
The nsJSTxnLog class implements the nsITransactionListener interface. When logging is started, we add nsJSTxnLog as a listener to the editor's transaction manager so that it gets notified whenever a transaction is executed, undone, or redone. nsJSTxnLog's main purpose is to write out JavaScript comments that describe the transaction being executed. Since one editor method call can result in several transactions being executed, these comments can aid engineers in seeing what transactions are being executed, and identifying which transaction is causing a specific problem.
Just for kicks, here's a link to the journal.js file generated during the creation of this document. To run it, Shift-Click on the link, then save it in the directory containing the apprunner executable. Start up the editor, then select Debug->Run Log from the menus.