You are currently viewing a snapshot of www.mozilla.org taken on April 21, 2008. Most of this content is highly out of date (some pages haven't been updated since the project began in 1998) and exists for historical purposes only. If there are any pages on this archive site that you think should be added back to www.mozilla.org, please file a bug.



The NGLayout Document Object Model (DOM) Roadmap

Authors: Vidur Apparao, Tom Pixley

Warning: the contents of this file is out of date. We are in the process of updating the DOM documentation on mozilla.org. The official DOM documentation is now located here.

Introduction

The Document Object Model (DOM) is a set of interfaces implemented by the NGLayout content model that allow insertion, deletion and modification of HTML content. These interfaces are available to both JavaScript developers and C/C++ programmers (via xpcom). The majority of these interfaces are specified by the Level 1 W3C Document Object Model specification, while the remaining are extensions that provide backward compatibility with previous versions of Communicator.

The NGLayout engine will implement a union of the Communicator 4.0 and and W3C Level 1 Document Object Models. NGLayout's ability to incrementally relayout and redisplay content allow it to correctly handle arbitrary content modification, including element insertion/deletion, attribute value modifications and style changes. The following document describes the current state of implementation as well as an implementation strategy for a complete DOM.

The Current Implementation

The Core Interfaces

The implementation of the DOM released with the current version of the NGLayout source base contains most of the Level 1 Core interfaces. These interfaces are implemented directly by the base NGLayout classes (found in ns/layout). Specifically, the DOM Document interface is implemented by the NGLayout nsDocument class, the DOM Node interface is implemented by the NGLayout nsHTMLContent class and the DOM Element interfaces is implemented by the NGLayout nsHTMLTagContent class. The Level 1 interfaces have been translated into their xpcom equivalents (found in ns/dom/public/coreDom) using the following rules:
  • All interfaces inherit from nsISupports.
  • Interface names have been translated to include the nsIDOM prefix.
  • All method signatures have been changed to return a nsresult result code.
  • wstring parameters and return values have been replaced with nsString.
  • Return values from the original interfaces now become pointers or references.
  • All method names have been changed so that their first character is capitalized.
These interfaces represent the model that C++ developers can use to manipulate a NGLayout document. Currently, the nsIWebWidget API is not complete and does not include a mechanism for obtaining the root DOM object for the document. The specifics of this interface are key to the usage of the DOM by an application that embeds the NGLayout engine, and will be completed in the very near future.

JavaScript Classes

These interfaces are also the basis for implementing the classes that make the DOM visible to JavaScript developers (found in ns/dom/src). In general, these JavaScript classes are simple wrappers on top of the corresponding xpcom interfaces. The nsHTMLContent and nsDocument classes both implement the nsIScriptObjectOwner interface. This interface provides a method that can be queried for the JavaScript object representing the document or content object. These JavaScript objects are created on demand and stored by the document or content object. The JavaScript object also holds a reference to the corresponding xpcom interface in its private data.

The rules for generating the JavaScript classes described above are as follows:

  • A JSClass is created to represent the DOM interface. Instances of this JSClass are created on demand for each corresponding DOM object accessed from JavaScript. Currently, the class is initialized (and the corresponding prototype is created) at JavaScript console creation time. In the future, these classes will be initialized on demand. The name of the class is identical to the DOM interface name.
  • Each attribute represented in the W3C DOM IDL is converted into a JavaScript property, retrieved and set by the property getter and setter methods of the corresponding JSClass. The JavaScript getter and setter methods use the reference to the DOM interface stored in the JSObject's private data, invoke the corresponding getter or setter method in the DOM interface, and (for getters) convert the returned value to the correct JavaScript type. For interface return types, a QueryInterface is carried out to get a nsIScriptObjectOwner and the owned JavaScript object.
  • Each method represented in the W3C DOM IDL is converted into a JavaScript method. The JavaScript method use the reference to the DOM interface stored in the JSObject's private data, invoke the corresponding method in the DOM interface, and convert the returned value to correct JavaScript type.
  • Constants in the W3C DOM IDL are converted into static properties of the JSClass (i.e. properties of the class's constructor).
  • In cases where the W3C DOM IDL does not capture methods or behavior which are particular to the JavaScript bindings of the DOM, the content objects will implement the nsIScriptObject interface. This interface allows the implementing class to handle JavaScript calls directly. For example, the W3C NodeIterator interface implements the [] operator in JavaScript. This operator allows the user to address nodes by ordinal index. This behavior will be provided by implementing the GetProperty method of the nsIScriptObject interface and resolving values for property ids that represent ordinal indexes. None of the existing classes currently implement this interface.
  • For methods and properties that need to exist for backward compatibility, but are not specified in the Level 1 DOM interfaces, the corresponding content objects will implement an additional interface. For example, the IMG elements lowSrc property is reflected into JavaScript in Communicator 4.0, but is not part of the W3C HTML DOM ImageElement interface. The nsHTMLImage content class will probably implement an additional interface to allow manipulation of this property and others of its type.

JavaScript Evaluation

Currently, NGLayout does not support the SCRIPT tag. Scripts can be executed, however, using the JavaScript console. Note that the console is simply a preliminary, debugging tool that exists in lieu of SCRIPT tag parsing. This tool will be removed in a final product. The console can be brought up by selecting the JavaScript Console menu item in the Tools menu of the NGLayout viewer. Scripts can be loaded into the console and then executed by choosing the Evaluate All menu item.

While the method of script evaluation will change when NGLayout starts handling the SCRIPT tag, the underlying mechanism should remain relatively similar. Currently, script execution through the JavaScript console is driven by the Viewer application as follows:

  • The first step in evaluation involves obtaining the script context - an instance of the nsIScriptContext interface obtained from the web widget by calling its GetScriptContext method. The JavaScript runtime is initialized and a JSContext for script evaluation is created when this script context is first instantiated. There is a one-to-one correspondence between the JSContext and a global object. The global object is used as the default scoping object for all scripts. In previous versions of Communicator, the global object is the JavaScript window object. In the current NGLayout implementation of the DOM, the global object (implemented in ns/dom/src/nsJSWindow.cpp) is a JSObject that holds a reference to the nsIWebWidget interface. (A complete implementation of the Window interface is forthcoming.) An instance of the global object is created as side-effect of creating the script context. All JavaScript classes are intialized at this time.
  • The second step involves actually executing a script. This is performed by invoking the EvaluateString method of the nsIScriptContext, a thin wrapper on the JS_EvaluateString method from the JavaScript runtime. The global object defines the scope for the evaluation of the script. Currently, the global object has a single property that represents the Document object. Hence, unqualified references to "document" within the script will resolve to the JavaScript object representing the NGLayout document.

Implementation Strategy

What's Left

The implementation of the DOM in the released NGLayout source is very preliminary, but should serve as the model for future work. The following items represent the major categories of functionality necessary for completion of the DOM:
  • As mentioned above, only the Level 1 Core DOM interfaces have been included and only a portion of the functionality enabled by these interfaces currently works. We intend to complete the implementation of the core interfaces, as well as those detailed in the Level 1 HTML specification. The individual HTML element interfaces will be implemented by the corresponding content model classes created by NGLayout.
  • Backward compatibility with existing versions of the JavaScript DOM within Communicator is an important goal of the NGLayout project. Additional interfaces that incorporate functionality not provided in the W3C DOM will be implemented.
  • The DOM event model will be completed in a form that is usable by both C++ and JavaScript programmers. This will enable applications that embed the NGLayout engine to receive events that are targetted at the document elements. It will also allow scripts to specify event handlers for elements as in Communicator 4.0. The aim is to provide compatibility with the Communicator 4.0 event model as well as the W3C DOM event model standard (which is as yet unspecified). Ideally, these two models will not be mutually exclusive.
  • The W3C DOM standard will eventually include a mechanism for modifying the CSS style of a document. This will include ways of adding and removing style rules, modifying existing rules and changing the inline STYLE attribute of individual elements. The DOM style specification will be implemented by the NGLayout style system.
  • Some of the functionality required to implement the Window and Navigator classes from the existing Level 0 DOM involves interaction with the application containing NGLayout. For example, the creation of new windows and modification of toolbars fall outside the domain of the core NGLayout engine. Interfaces that represent the functionality necessary to create these classes will be specified and implemented by Communicator.
  • The JavaScript security model from Communicator 4.0 will be implemented, though the model itself may be modified to incorporate ongoing changes to the Java Capabilities API and the overall Java security model.

Auto-generation of JavaScript class files

The source files that represent the JavaScript classes corresponding to the individual DOM interfaces can be found in the directory ns/dom/src. These source files define the JavaScript classes by using a set of simple rules applied to the Corba IDL representing the DOM interfaces. Currently, these rules were applied by hand. We are currently in the process of modifying an IDL compiler to auto-generate these class files, as well as the xpcom versions of the interfaces. The tool and the process for generating the source files will be posted in a future release.

JavaScript Class Initialization

As stated previously, all JavaScript DOM classes are currently initialized directly after the JSContext is created. In its final form, the HTML DOM will contain a large number of interfaces (almost as many as the number of elements specified in the HTML 4.0 DTD) and the overhead for intialization of all of these classes on a per document basis is substantial. The current method of class initialization will be replaced by an on-demand registration scheme such that classes will be intialized only when an instance is first required or when a constructor is needed.

Known Bugs

  • While the Level 1 Core DOM interfaces have been implemented by the document and content classes, not all methods have been correctly hooked up. Currently, methods that allow the DOM user to query Document, Node and Element state work, while methods that modify state do not.
  • In many cases, attributes are only reflected in JavaScript through the corresponding getter and setter methods. This will be corrected in a future release in conjunction with the W3C DOM IDL e.g. the Node interfaces childNodes attribute will be implemented as node.childNodes in JavaScript and not node.getChildNodes.
  • Currently, IDL methods are incorrectly reflected into JavaScript with their first character capitalized. This will be corrected in a future release e.g. the Node interfaces RemoveChild method will be reflected as node.removeChild and not node.RemoveChild.
  • The nsJSEnvironment class is very much a preliminary implementation. It both initialized the JavaScript runtime and creates a new JSContext. This precludes the creation of multiple context per JavaScript runtime. This class will be fleshed out in greater detail.