This document describes the programmable interface for embedding Gecko into third party applications.
It discusses the webbrowser and docshell objects and the interfaces that must be used control them.
Terms such as XPCOM, CID, interface and IDL are sprinkled liberally throughout. If you are unfamiliar with XPCOM then read through http://www.mozilla.org/projects/xpcom/ to get an idea with what the terms mean. Windows programmers familiar with COM/ActiveX should be understand XPCOM because the two are closely related.
Italics are used to represent draft notes.
When you start Mozilla, a browser window appears. This is made up of frames representing the chrome, content, side panel, buttons and so on. Frames are nested inside other frames to form a hierarchy. The root frame represents the browser window with sub-frames managing each discrete component. Each frame is associated with a document which is it's content.
Content is trusted or untrusted. Trusted content is known as chrome, usually loaded from local store with greater privileges to interact with the host machine. Usually the topmost frames are chrome and contain a content sub-frames.
Until recently the object responsible for managing a frame and the associated document was called the webshell. The topmost webshell was controlled by the host application and each child was managed in turn by its parent webshell.
Figure 1: How it used to be done
The webshell had methods for child and parent webshell traversal. It also had methods for sizing and positioning, loading and refreshing documents, back and forward navigation, chrome, registering progress callbacks, setting preferences and much more besides. As you can imagine, webshell became very complicated and bloated. Even worse, all the exposed methods were defined on a single interface! The nsIWebShell interface had over 30 methods and properties and it was practically impossible to make it immutable because it kept changing so much. It was clear that Mozilla would be much better if webshell could be rewritten.
Take a look here to see how many methods were added to nsIWebShell between during its lifetime. You may also notice that nsIWebShell was defined in C++ rather than being generated from IDL. This prevented it from being used by XPConnect, lead to all kinds of XPCOM abuses and meant the in/out semantics of the methods were vague to say the least.
Travis Bogard initiated a redesign of the webshell object and the nsIWebShell interface. Methods were broken out into new, more logical interfaces and functionality from webshell was rewritten cleanly into a new base class called the docshell. Embedding-specific functionality was moved into a new object called the webbrowser.
The docshell is a clean replacement for webshell focussing on functionality required by each node in the hierarchy. The webbrowser object is used by client applications that want to do embedding.
The name docshell is a more suitable name for an object that manages a document rather than a webshell, which implies an HTML document. A docshell can hold any type of document though that normally it holds one that can be parsed and represented by a DOM. HTML or XML that is parsed into a DOM, is managed by a docshell during its lifetime.
Figure 2: Docshell hierarchy
The new design splits the embedding specific stuff away from the document traversal interfaces, so that only the topmost document that directly touches the embedding client app contains the subscription and notification code needed to keep the client informed of what is going on.
Each docshell manages one document that is set onto the docshell during or after it has been loaded. Loading is initiated by navigation interface methods on the docshell. The docshell specifies the presentation area and context into which the document is drawn, whether the context has scroll bars, whether it represents chrome or content, whether it supports plugins, and whether it has parent and child docshells.
Webshell has not gone away entirely but is slowly atrophying as more and more stuff is moved into the docshell base class. Eventually the webshell object and the nsIWebShell interface will disappear. Neither webshell or nsIWebShell are documented here to discourage their use.
Here is an overview of the principle embedding objects.
Figure 3 Embedding objects and their principal interfaces
22.214.171.124 Class: nsDocShell
The docshell XPCOM object is implemented by the nsDocShell C++ class.
This class is responsible for initiating the loading and viewing of a document.
In the case of loading a URI, the docshell creates a URI loader object, instructs it to fetch content and listens content arriving via a helper object nsDSURIContentListener. When the first content arrives, the docshell creates a content viewer object that is responsible for rendering it.
When SetDocument is called on the docshell, specifying a new DOM to display, it creates a new document and document view to manage it and then associates the viewer with docshell. Next it associates the root node of the DOM with the document object through each presentation shell of the document sizing the presshell to be the same size as the docshell. Once completed it fires an EndDocumentLoad event to notify observers that a document has loaded.
A docshell is an XPCOM object controlled via the interfaces it exposes. It possesses methods to load new content, to change the current document it holds onto, to see the current scroll bar positions and affect the scroll view methods, to get its parent and child docshells to be re
126.96.36.199 Sequence diagrams
TODO Add more sequence diagrams
When a document is requested (e.g. by telling the docshell to load a particular URL), the docshell kicks off the process that ultimately leads to a content viewer being created that displays the document content into a presentation shell.
Figure 4 Loading Sequence
188.8.131.52 Interfaces implemented by docshell
184.108.40.206 Class: nsWebBrowser
The webbrowser object is implemented by the C++ class nsWebBrowser. Embedding clients must create an instance of this class to embed Gecko into their applications.
The principle interface on this object is nsIWebBrowser. This interface has methods and attributes that client may use to load content and register callback interfaces to receive progress and navigation notifications.
Functionality is broken down into separate interfaces, so that web navigation functionality is distinct for that used to position or size the webbrowser component which is different from that used to scroll the display. This is in contrast to the monolithic nsIWebShell where everything was on the one interface.
For every webbrowser that client instantiates, it must also create a companion container/site object that handles callbacks that the webbrowser needs to function correctly.
The webbrowser site object is an XPCOM object that receives calls through the interfaces it implements when the before/during/after loading, when the webbrowser wants the site to be resize, for progress notifications and so on.
220.127.116.11 Sequence diagrams
18.104.22.168 Interfaces implemented by WebBrowser
This object must be implemented by the client application to interact with the webbrowser object. It’s referred to here as a site object but is sometimes called a container elsewhere.
The interfaces on this object make it the owner of the docshell hierarchy and capable of receiving callbacks when a document is being loaded or when the content wishes to display some user interaction such as to display a message box.
Figure 5: The webbrowser and the associated site
22.214.171.124 Sequence diagrams
126.96.36.199 Implemented by the webbrowser site
Most of these interfaces should be optional but they are not. Webbrowser and docshell should be modified to be more tolerant of missing interface on the site object because it is such a pain for embedders to write one.
- nsIBaseWindow - I’m not sure why this interface is needed
- nsIWebBrowserChrome -
- nsIDocumentLoaderObserver - Obselete
- nsIPrompt - Optional
Widget containers implement this interface. It contains methods for creating, destroying, initialising, resizing and moving a window.
- Webbrowser site
A content viewer container implements this interface. It contains a single method that is called when to insert a content viewer object into the container.
Not defined as an IDL file when it should be!
The docshell object implements this interface. The interface contains methods to set the contained document, load a URI, register handlers and listeners.
Items in the docshell tree hierarchy implement this interface. It contains methods for getting the parent item and named children. It also contains properties to indicate whether the item represents chrome or content.
Items in the docshell tree hierarchy implement this interface. It contains methods to add, remove and enumerate through child nodes.
The owner of a docshell tree hierarchy implements this interface. The interface contains methods to locate named docshells, callbacks to request sizing. Implemented by the owner of the docshell tree.
- Webbrowser site
The nsIInterfaceRequestor allows an object to return
- Webbrowser site
Allows the client to implement its own version of the dialogs that Gecko may need to display such as when a user goes from a secure to a non-secure page, or when page loading times out.
- Webbrowser site – or a helper object via nsIInterfaceRequestor
Docshell objects implement this interface. It contains methods to set and cancel content refresh timers.
Method to return the global script object
Methods for obtaining the current scrollbar positions and properties for affecting their behavior.
- Webbrowser site
Methods to scroll the display up or down by lines or pages.
Properties for the client to register listeners and to obtain the nsIDocShell of the root object.
The content may request that your container behaves in a certain way, such as to show itself modally, or to hide certain decorations, such as status bars. This is the interface that such requests will be made through.
- Webbrowser site
Interface used for web navigation. Contains methods for loading new URIs, stopping loading, reloading, back/forward history, properties indicating the current URI, the root document.
Methods to register an nsIWebProgressListener interface that will be called with notification of the current state of downloads.
- Webbrowser site
This interface is called during loading to indicate the current loading progress.
- Webbrowser site
Before you can create a browser object, you must initialise your application for embedding:
If your application runs outside the Mozilla bin directory. You must specify the path as a parameter so that Gecko can locate the components it needs to work.
const char *szPath = “/usr/local/mozilla/bin”;
The webbrowser component is instantiated via its class ID (CID) or its program ID (PROGID). The PROGID is a human-readable character string equivalent to the CID for scripting languages who cannot represent a CID as a primitive. Generally speaking the CID should be used in C++ since it is a non-ambiguous way to specify an object.
The root docshell is the topmost frame of content. You need this if you want to load content from a particular URI, parse the DOM and pretty much everything else. The webbrowser manages this object so you don’t have to, but you need to store it to do anything useful.
It was already been shown that docshells are nested and that the embedding client connects to the topmost one via the webbrowser. The client application must register a site object with the webbrowser that contains callbacks XXXX
Use the nsIWebNavigation interface off of the root docshell to load a specified URL.
Call LoadURI(), passing the URL as a parameter, e.g.
nsCOMPtr<nsIWebNavigation> webNav =
Clipboard operations are available from the context viewer. The nsIContentViewerEdit interface has methods for copying, pasting, cutting and selecting text, e.g.
Some clients need to be notified when a user right-mouse clicks on a link or other element so that a popup menu can be displayed. A client can receive this notification by implementing nsIContextMenuListener on their webbrowser site object, or providing it via the nsIInterfaceRequestor interface.