summaryrefslogtreecommitdiff
path: root/Docs/ideas
diff options
context:
space:
mode:
Diffstat (limited to 'Docs/ideas')
-rw-r--r--Docs/ideas/css-engine.txt224
1 files changed, 222 insertions, 2 deletions
diff --git a/Docs/ideas/css-engine.txt b/Docs/ideas/css-engine.txt
index 5b9c1a69b..1ea8778d5 100644
--- a/Docs/ideas/css-engine.txt
+++ b/Docs/ideas/css-engine.txt
@@ -32,8 +32,8 @@ typedef enum css_error {
typedef enum css_origin {
CSS_ORIGIN_UA,
- CSS_ORIGIN_AUTHOR,
- CSS_ORIGIN_USER
+ CSS_ORIGIN_USER,
+ CSS_ORIGIN_AUTHOR
} css_origin;
#define CSS_MEDIA_SCREEN (1<<0)
@@ -159,3 +159,223 @@ Imported stylesheets
to fetch the data and append it to the sheet. The imported sheet is then
stored in the sheet that imported it. This effectively creates a tree of
stylesheets beneath the initial top-level sheet created by the client.
+
+Style selection algorithm
+-------------------------
+
+ css_style_select(context, node, pseudo_classes, media,
+ property_list, property_list_length):
+ result = blank_style;
+ done_props = false;
+ foreach sheet in context:
+ # Assumes that sheets are in the order UA, USER, AUTHOR
+ if !done_props && css_stylesheet_get_origin(sheet) == CSS_ORIGIN_AUTHOR:
+ fake_rule = fake_rule(node, property_list, property_list_length);
+ cascade(result, fake_rule, CSS_ORIGIN_AUTHOR);
+ done_props = true;
+ process_sheet(sheet, node, pseudo_classes, media, result);
+ return result;
+
+ fake_rule(node, property_list, property_list_length):
+ rule = (node.name, 0); # Specificity is 0
+ foreach (property, value, importance) in property_list:
+ rule[property] = (value, importance);
+ return rule;
+
+ process_sheet(sheet, node, pseudo_classes, media, result):
+ if (css_stylesheet_get_media(sheet) & media) == 0:
+ return;
+ foreach import in sheet:
+ process_sheet(import, node, pseudo_classes, media, result);
+ origin = css_stylesheet_get_origin(sheet);
+ foreach rule in sheet:
+ if matches_rule(rule, node, pseudo_classes):
+ cascade(result, rule, origin);
+
+ cascade(result, rule, origin):
+ foreach (property, value, importance) in rule:
+ insert = false;
+ if result[property]:
+ rOrigin = result[property].origin;
+ rImportance = result[property].importance;
+ rSpecificity = result[property].specificity;
+ if rOrigin < origin:
+ if rImportance == "important":
+ if rOrigin != CSS_ORIGIN_USER:
+ insert = true;
+ else:
+ insert = true;
+ else if rOrigin == origin:
+ if rImportance == "" && importance == "important":
+ if rOrigin == CSS_ORIGIN_UA:
+ if rSpecificity <= rule.specificity:
+ insert = true;
+ else:
+ insert = true;
+ else if rImportance == "important" && importance == "":
+ if rOrigin == CSS_ORIGIN_UA:
+ if rSpecificity <= rule.specificity:
+ insert = true;
+ else:
+ if rSpecificity <= rule.specificity:
+ insert = true;
+ else:
+ if origin == CSS_ORIGIN_USER && importance == "important":
+ insert = true;
+ else:
+ insert = true;
+ if insert:
+ result[property] = (value, origin, importance, rule.specificity);
+
+Outstanding issues
+------------------
+
+ + Parsing/selection quirks.
+
+ Probably as an argument to css_stylesheet_create() and possibly
+ css_style_select(). This could either take the form of a blanket
+ full/almost/not quirks mode flag or be more granular and permit the
+ toggling of individual quirks.
+
+ References:
+
+ + http://developer.mozilla.org/en/docs/Mozilla_Quirks_Mode_Behavior
+ + http://www.opera.com/docs/specs/doctype/
+ + http://www.quirksmode.org/css/quirksmode.html
+ + http://www.cs.tut.fi/~jkorpela/quirks-mode.html
+ + Grep WebKit sources for inCompatMode()
+
+ + The :lang pseudo-class
+
+ Need to pass the current language string into css_style_select()
+
+ + Pseudo-elements
+
+ Probably as an argument to css_style_select(). Most likely a bitfield
+ like the way in which pseudo-classes are handled.
+
+ The inheritance model of :first-line and :first-letter is such that:
+
+ + css_style_select() must begin with a blank style and not the
+ parent node's style
+ + an API for cascading one style onto another is needed
+
+ This is because pseudo-elements may be nested inside children of the
+ node to which they are logically connected. e.g.:
+
+ <div>
+ <p>
+ first paragraph
+ </p>
+ </div>
+
+ is logically equivalent to
+
+ <div>
+ <p>
+ <div:first-line>
+ <p:first-line>
+ first paragraph
+ </p:first-line>
+ </div:first-line>
+ </p>
+ </div>
+
+ so the actual cascade order is only known at the time the render tree is
+ built. Note that, courtesy of scripting, the location of pseudo-elements
+ can move around (e.g. if some text was inserted just before the <p> within
+ the div, above, then <div:first-line> would move). Additionally, the actual
+ content that pseudo-elements apply to can change due to reflow.
+
+ Pseudo-elements may also affect the processing of inline boxes. e.g.:
+
+ <p>
+ <span>foo bar baz bat</span>
+ </p>
+
+ becomes (logically):
+
+ <p>
+ <p:first-line>
+ <span>foo bar baz </span>
+ </p:first-line>
+ <span>bat</span>
+ </p>
+
+ In terms of interaction between pseudo-elements, :first-letter inherits
+ from :first-line e.g.:
+
+ <p>
+ first line
+ second line
+ </p>
+
+ becomes (logically):
+
+ <p>
+ <p:first-line>
+ <p:first-letter>
+ f
+ </p:first-letter>
+ irst line
+ </p:first-line>
+ second line
+ </p>
+
+ :first-line and :first-letter apply to the relevant content _including_ any
+ text inserted using :before and :after.
+
+ List of CSS 3 pseudo-elements:
+
+ + :(:)?first-line
+ + :(:)?first-letter
+ + :(:)?before
+ + :(:)?after
+ + ::selection
+ + ::footnote-call
+ + ::footnote-marker
+ + ::before-page-break
+ + ::after-page-break
+ + ::line-number-left
+ + ::line-number-right
+ + ::line-number-inside
+ + ::line-number-outside
+ + ::slot()
+ + ::value
+ + ::choices
+ + ::repeat-item
+ + ::repeat-index
+ + ::marker
+ + ::outside
+ + ::alternate
+ + ::line-marker
+
+ References:
+
+ + CSS 2.1 $$5.12 and $$12.1
+
+ + Stylesheet charset handling
+
+ An embedded stylesheet shares the charset of the containing document.
+
+ The charset of a stand-alone stylesheet can be specified by (in order of
+ priority, highest -> lowest):
+
+ + the transport layer
+ + a BOM and/or @charset at the immediate start of the sheet
+ + <link charset=""> or other metadata from the linking mechanism
+ + charset of referring stylesheet or document
+ + assuming UTF-8
+
+ The API currently has no way of conveying the first, third, or fourth of
+ these to the engine. This can be realised through the addition of a
+ parameter to css_stylesheet_create()
+
+ CSS 2.1 $4.4 specifies that a stylesheet's transport encoding must be a
+ superset of US-ASCII.
+
+ The internal encoding will be UTF-8.
+
+ All strings passed in by the client are assumed to be UTF-8 encoded.
+ Strings retrieved from DOM nodes are assumed to be UTF-8 encoded.
+