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.
Should my feature be a module?
Not all features should be implemented as modules. For example, CSS features, such as flexbox or regions, are better implemented as part of the rest of the CSS machinery in WebCore because they often are tightly integrated with layout and rendering. Other features, such as IndexedDB, do not need to be tightly integrated with the rest of WebCore and are good candidates to be modules. Typically features defined in "satellite" specifications, such as those from the WebApps working group, are good module candidates, whereas features defined in the "core" specifications, such as those from the HTML, CSS, or SVG working groups, are more likely better implemented in WebCore proper.
If you're unsure whether you should implement your feature as a module, feel free to ask when you announce your feature on webkit-dev.
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.
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 Gamepad 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.