📄 readme
字号:
This is a super-simplistic CSS micro-engine. PhasesThe CSS handling is divided into:* The scannerIt takes care of composing tokens from a string containing CSS source. Italso takes care of eliminating either garbage code that was not recognizedor things like whitespace and comments. The scanner will not attempt torecover from this garbage code but merely signal them to the upper layers.The scanner only works with strings but is a bit more high level thanscanners in the sense of flex. The string "10em" will not just generate thetwo tokens <number>, <identifier> but rather combine them into one token.This only leads to problems with tokens of the sort #<identifier> that canbe both a hex color or hash so should not be a problem but rather mean thatwe will do less scanner calls.The scanner lives in scanner.** The parserIt takes a string with CSS code, composes tokens (from the scanner) intosome meaningful syntax and transforms it to an internal set of structuresdescribing the data (let's call it a "rawer"). It currently does no recoverywhen something unexpected shows up but skips to next special control char.The parser lives in parser.* and value.** The applierIt applies style info from a syntax tree (parsed ELinks or documentstylesheet) or fragment of one (in the case of style="" attributes) to thecurrent element.The applier lives in apply.* The current stateCurrently we both check the element's 'style' attribute, content of <style>tags and imports from either <link> tags in the HTML header or @imports fromthe CSS code. But we lack a proper way to handle the cascading. Now it willautomatically scan the current element, and if a 'style' attribute is found,it is parsed and applied to the current element. If there is no 'style'attribute it will look up any styles retrieved from the document stylesheetand last try styles from the default user controlled stylesheet. TODO: Weshould always look up <style> tags and only apply those not found in any'style' attribute.One big problem with the current way of doing things is inheritance, thereis no way we are telling the HTML engine what is going to be inherited andwhat is not. The other problem is precedence, currently even globalstylesheet takes precedence over local classic-formatting attributes (wejust css_apply() like mad on various places to make sure the CSS attributesare stuffed through HTML engine's throat). These two problems will be solvedwhen the HTML engine is converted to work with stylesheets natively (insteadof format + par_format). The selectors treeIn order to handle any non-trivial selectors, we need them to form a certainstructure. A hierarchical one was chosen, where we initially focus on athe most specific element, then we build the way down through ids, classesand pseudo-classes and then back the way up through parent elements.Assume two statements: "div#foo p a>b i:baz { color: black; }" and"div#foo.bar p a>b i:baz { text-decoration: underline; }". The tree we build upis: element[i] | (pseudo_classes) pseudo_class[baz] | (ancestors) element[b] | (parents) element[a] | (ancestors) element[p] | (ancestors) element[div] | (ids) id[foo] -> (color: black) | (classes) class[bar] -> (text-decoration: underline)As you can see, the combinators hierarchy is reverse, while the other selectorshierarchy is as usual. This is to aid the applier, it goes from the general tothe specific (that's how it is from the POV of applying stuff to singleelements, even though the ancestors are more "general" from the POV of thedocument stucture). This approach has its deficiencies as well (it can beexpensive to match long complex combinators since we need to walk through theancestry each time we match an element, or even more frequently when weconsider the element with varied specificities ("i", "i#x", "i:baz","i#x:baz")) but it still looks like the best way (because of the variedspecificities, you can't well go the other way by narrowing down the selectorsas you descend the elements tree).Let's close the discourse by adding another two selectors to the stylesheet:"b i#x:baz { color: blue; }" and "a>b#foo i:baz { background: white; }". element[i] -------------. | (pseudo_classes) | (ids) pseudo_class[baz] id[x] | (ancestors) | (pseudo_classes) .------------ element[b] pseudo_class[baz] | (ids) | (parents) | (ancestors) id[foo] element[a] element[b] -> (color: blue) | (parents) | (ancestors) element[a] element[p] -> (b: w) | (ancestors) element[div] | (ids) id[foo] -> (color: black) | (classes) class[bar] -> (text-decoration: underline)As you can see a tiny alternation of specificity at the top of the tree willduplicate the whole path of combinators, but you can't get away without that,I think.You can get probably a much better overview of how it looks by #defineDEBUG_CSS at the top of src/document/css/stylesheet.h, recompiling and thengrabbing a dumped stylesheet tree from stderr. Translate the 'type' and 'rel'fields from numbers to actual values accordingly to the enums in theaforementioned header file. The future of selectorsXXX: I keep this here only for a historical reference now. The order matters,the connecting lines probably not. --paskySpecificity111 a#id.nav. |. .---'---.. V |101 a#id |. | |. | |. | |13 | | div p a.nav. | | |. | | .--------------'|. | | V |12 | | p a.nav |. | | | |. | `-.---------' |. | V |11 | a.nav |. | | |. | | |. | | |2 | | p a |. | | | |. `---------`-.---'---. |. V V |1 a p img div. | | | |. `-------+---+---+-------'. V0 * (universal selector)$Id: README,v 1.14 2004/10/13 15:34:46 zas Exp $
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -