Version 24 (modified by 13 years ago) ( diff ) | ,
---|
The Care and Feeding of WebCore Modules
This document describes how WebCore's module system works and how to use it when building a new feature.
Overview
As we add more features to WebCore, the project becomes more complex. Some self-contained features, like IndexedDB and MediaStream, expose JavaScript APIs but aren't otherwise involved in the core functionality of the engine, such as layout and rendering. The module system let us reduce the complexity of the project by loosening the coupling of between these features and the rest of WebCore. Often individual modules can be enabled with an ENABLE
macro, but some modules are always enabled.
Dependency diagram
The code for a module belongs in a subdirectory of the Modules directory and in a subdirectory of WebCore/platform. For example, the MediaStream module is contained in http://trac.webkit.org/browser/trunk/Source/WebCore/Modules/mediastream and http://trac.webkit.org/browser/trunk/Source/WebCore/platform/mediastream.
Keeping the code for your feature in a single directory reduces the burden that your feature places on other WebKit contributors as they develop other modules and core functionality of the engine. This dependency diagram shows how the WebAudio, MediaStream, and IndexedDB modules fit into the WebKit's dependency diagram. Notice, in particular, that WebCore proper should not have dependencies on your module.
Associating JavaScript APIs with "core" objects
Even self-contained features often need to expose JavaScript APIs on "catch-all" interfaces like DOMWindow
or Navigator
. If we declared these APIs in DOMWindow.idl and implemented them in DOMWindow.cpp, the complexity of DOMWindow
would increase with each added feature. To avoid complexity creep in these core classes, you can declare your JavaScript API in supplemental IDL files, mirroring the partial interfaces used in specifications. For more details, see the documentation of the Supplemental attribute.
For example, the MediaStream module uses this mechanism to add the webkitGetUserMedia
API to Navigator
. The API is implemented in NavigatorMediaStream.cpp, avoiding bloat in Navigator.cpp itself and helping to contain the MediaStream code in the MediaStream directory.
Associating state with "core" objects
Sometimes a module needs to associate state with a core object, such as Page
or Navigator
. Typically, this state doesn't interact with any of the core state and simply piggybacks on the lifetime of the core object. Rather than bloating the core objects with your feature-specific state, you can associate your feature's data with these objects using Supplementable.
For example, the Gampad module needs to associate a GamepadList
with Navigator
. Notice that in the implementation of its supplemental interface, the Gamepad module declares that NavigatorGamepad
inherits from Supplement<Navigator>
, which lets us store a NavigatorGamepad
in Navigator's m_supplements HashMap.