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.




New Layout: Style System

Author: Peter Linss
Updated: 5/1/98

Overview
The NGLayout Style System is comprised of three sections that together provide the mapping and management of style data onto document content in a given presentation. In NGLayout, style data is ultimately bound to a Frame, this Frame is a geometric map of a Content node in its presentation.

The NGLayout Style System was designed with the goals of reasonable extensibility, high performance and a reasonable runtime footprint. The current implementation of the Style System is centered around mapping HTML Attributes and CSS2.
Major Components
StyleSet
The central management object of the Style System is the StyleSet. The StyleSet is constructed by the UA and passed to the PresentationShell during initialization. The UA controls the presentation of the document by specifying which StyleSheets get applied to the document in that presentation. Typically, the StyleSet will contain references to the StyleSheets contained within, or linked to, the document, as well as a collection of UA override and backstop StyleSheets. The StyleSet also has the responsibility for creating, resolving and caching StyleContexts.

StyleSheets and StyleRules

StyleSheets are the objects that contain the specific style data that gets applied to the document, as well as the logic for applying the data. Generally, the actual style data is kept in a nsIStyleRule. The StyleSheet is responsible for determining the set of StyleRules to apply to a given piece of content in a given situation. The StyleRule will in turn, be told to apply its data to a given StyleContext.

StyleContext

The StyleContext is the sum total of style data that has been applied to a given piece of content in a given situation. StyleContexts are created and managed by the StyleSet. Only one StyleContext will be created for each unique stylistic situation. In other words, all content nodes that have the identical set of StyleRules applied to them, in the same parental context, will share one StyleContext instance. StyleContexts contain a reference to their parent StyleContext, a list of all the StyleRules that were applied to them, and a collection a data structs that hold the actual, resolved style data.
Implementation
NGLayout

The NGLayout side of the Style System consists of the StyleSet, interface declarations for StyleSheets and StyleRules, the StyleContext, and specific style data structures contained within the StyleContext.

StyleSet
In addition to implementing the storage of StyleSheets (an ordered set). The StyleSet implements the basic StyleContext resolution algorithm.

To establish a StyleContext, the StyleSet is passed three items: a pointer to the current Presentation Context, a pointer to the Frame that will contain the StyleContext, and a pointer to the Content node (or pseudo content) that style is being mapped for. Given this data, the StyleSet follows the following algorithm: first the parent frame is given an opportunity to return a cached StyleContext for the Content. The implementation of that caching is Frame dependent and should be used carefully. Failing to obtain a cached StyleContext, the StyleSet then iterates all the StyleSheets, collecting from them a list of StyleRules to apply to that Content in that Frame. Determining what rules apply is a StyleSheet specific behavior, however, the rules are returned in order of precedence.

Once a set of StyleRules is established, the StyleSet attempts to find an already established StyleContext that uses the exact set of StyleRules with the same parent StyleContext (from the parent Frame). If an established StyleContext isn't found, a new instance is finally created. This instance then processes its set of StyleRules to determine the actual style data for that StyleContext.

StyleContext

The StyleContext contains a collection of StyleStructs. These structs hold the actual style data that is needed for the layout, rendering and operation of a NGLayout document. The collection of structs is extensible, and individual structs are queried for by ID. The set of structs implemented in NGLayout is a sum of that needed to handle HTML and XML documents with CSS applied.

When a StyleContext is created, first all style data is initialized to starting values. Inheritable attributes are copied from the parent context, then the StyleRules are iterated in reverse order (so that higher precedence data is set last). Each StyleRule gets passed the StyleContext and PresentationContext, and then maps its data into the StyleContext's data structs.

CSS

The handling of CSS data in NGLayout is achieved by a custom parser, StyleSheet and StyleRule class. The parser is invoked during document load for each CSS StyleSheet encountered, it produces a CSSStyleSheet object that contains all the StyleRules and child StyleSheets (from @import rules). The StyleSheet contains the StyleRules and sorts them according to CSS cascading order. The StyleRules contain the Selectors and Declarations.
When the StyleSheet is asked for a list of StyleRules for a given Content node in a given Frame. It searches through its list of StyleRules applying the CSS Selector algorithm to determine which StyleRules apply.

The StyleRules, when asked to map their data into a StyleContext, simply convert from CSS data into the simplified NGLayout data stored in the StyleContext.

HTML

The HTML StyleSheet class in NGLayout serves as an adapter between HTML Attributes and the Style System. The StyleSheet contains no data, the actual Attributes are stored by each HTML Content node in a special class. This class, nsHTMLAttributes, contains a list of all the Attributes for a Content node, and also implements the StyleRule interface.

When a HTML StyleSheet is asked for a list of StyleRules for a given piece of Content, it simply asks the Content if it has any Attributes. If so, the Attribute class is returned as a StyleRule. If the Content has a STYLE attribute, then a second rule is returned for the contents of that Attribute.

When the Attributes are asked to map their data into a StyleContext, a method of the Content, MapAttributesInto, is invoked to allow the Content node to interpret its Attributes and convert them to NGLayout style data.
Dependencies
The NGLayout Style System is heavily dependent on the Content and Frame models. The whole notion of StyleContexts is based on applying style to Content that is mapped into a Frame model. See Layout documentation for more details there.
Roadmap

  • Flushing out implementation of CSS & HTML attributes.
    • The set of style attributes implemented so far has been driven by dependencies on the Style System from implementations of Layout and Rendering behavior.
      The short term goal is to flush out all the attributes that need to be stored in a StyleContext.
  • CSS Pseudo-element & pseudo-class support.
    • Pseudo-elements will be implemented by style support for Pseudo-Frames (see Layout docs). This will require some extensions to the Style Resolution apis, since there won't be an actual Content node to be mapped. Pseudo-class support will be implemented in the CSS StyleSheet by extending the Selector match algorithm to account for document state.
  • Style mapping performance
    • Several performance aspects have yet to be implemented: the first level cache of StyleContexts by Frames, CSS Selector matching and possible special handling of the UA StyleSheet.
      The CSS Selector matching algorithm currently searches through all StyleRules in the StyleSheet. This will be reduced by pre-sorting the StyleRules by Tag, Class and ID.

      The UA StyleSheet used in NGLayout is currently a CSS StyleSheet. Since UA processing doesn't need full CSS support to implement backward compatible behavior, we may implement a third StyleSheet class to special case the UA behavior with increased performance.

  • DOM support
    • The CSS StyleSheet and StyleRules classes need to be connected to the DOM implementation. This will involve flushing out the DOM apis for CSS, as well as guaranteeing correct behavior of the System when style data changes.
  • Full CSS2 support
    • At this point we'll be going through the CSS2 spec with a fine-toothed comb and making sure that all desired behaviors are implemented.
  • Full HTML support
    • Here we'll be going though the Content model and ensuring that all Attributes are present and accounted for.
    Known Bugs
    • CSS Selector matching performance is known to be an issue, but that's because we haven't gotten there yet.
    • Many style attributes have only been implemented to a limited degree to date. Furthermore, layout and rendering code isn't completely implemented to interpret all possible values.
    Contact Info
    The owner of this module is Peter Linss, he can be reached via email at: peterl@netscape.com.
    Feel free to send questions, comments or interest in helping to develop this system.