- From: Lachlan Hunt <lachlan.hunt@lachy.id.au>
- Date: Thu, 17 Jul 2008 13:35:39 +0200
- To: Maciej Stachowiak <mjs@apple.com>
- Cc: John Resig <jresig@mozilla.com>, public-webapps <public-webapps@w3.org>
Maciej Stachowiak wrote: > On May 5, 2008, at 2:13 PM, Lachlan Hunt wrote: >> Define the methods to behave as if an implicit :scope selector and >> descendant combinator were prepended to each selector in the group. >> ... Consider the following selector: >> >> ">strong, >em" >> >> The expectation would be for this to become: >> >> ":scope >strong, :scope >em" >> >> The question is how to parse and convert it. > > ... then prepending ":scope " and inserting " :scope " after every > comma before parsing would work. I believe this is currently true of > Selectors, though it may change in the future. I would guess the only > likely place for commas to appear would be in parameters to > function-like pseudo-classes, in which case the algorithm above but > excluding commas nested inside parentheses would be more > future-proof. Detail of the algorithm: > > 1. Initialize nesting level to 0 > 2. Initialize the output string to the empty string > 3. While characters in the input string remain: > 3.a. read the current character > 3.b. if the current character is: > ",": if the nesting level is 0, append ", :scope " to the output > string > "(": increase the nesting level by 1, and append "(" to the > output string > ")": decrease the nesting level by 1, and append ")" to the > output string > anything else: append the current character to the output string > 3.c. advance to the next character > 4. return the output string I started looking into this for the possibility of introducing queryScopedSelector(), or similar, into version 2, but it seems that this proposed pre-parse doesn't handle enough cases to be relible enough. The solution would need to handle all of the following more complex cases involving escaped chars: span[title="\""] span[title='\''] span[title="\\"] span[title=\"\(\)] span[title=\'\"] div:foo(x,y) div:foo(\(\)) Plus many other varations. One possible solution would be to define that it uses a slightly modified grammar from ordinary Selectors. It would have everything the same, except that the selector production would become: selector : combinator? simple_selector_sequence [ combinator simple_selector_sequence ]* ; http://www.w3.org/TR/css3-selectors/#w3cselgrammar Then instead of requiring a pre-parse, inserting :scope and then parsing with the normal selector parser, implementations would modify their selector parsers to handle the optional combinator at the beginning and then I would define that :scope (or equivalent) is to be implied at the beginning of each selector. Another solution is to use a slightly more complicated pre-parse than the one proposed above. I believe the following would work, unless I made a mistake. 1. Initialise nesting level to 0 2. Initialise the output string to the empty string 3. Initialise the escape flag to false 4. Begin tokenising in the Normal state Normal state: Consume the next input character -> U+002C COMMA "," If the escape flag is true, append "," to the output string and set the flag to false Otherwise, if the nesting level is 0, append ", :scope " to the output string Otherwise, treat it as per the "anything else" entry below. -> U+0022 QUOTATION MARK '"' Append '"' to the output string If the escape flag is true, set the flag to false Otherwise, switch to the Double-quoted string state -> U+0027 APOSTROPHE "'" Append "'" to the output string If the escape flag is true, set the flag to false Otherwise, switch to the Single-quoted string state -> U+0028 LEFT PARENTHESIS "(" Append "(" to the output string If the escape flag is true, set the flag to false Otherwise, increase the nesting level by 1 -> U+0029 RIGHT PARENTHESIS "(" Append "(" to the output string If the escape flag is true, set the flag to false Otherwise, if the nesting level is greater than zero, decrease by 1 -> U+005C REVERSE SOLIDUS "\" Append "\" to the output string If the escape flag is true, set the flag to false Otherwise, set the escape flag to true -> EOF Return the output string -> Anything Else If the escape flag is true, set the flag to false Append the current character to the output string Double-quoted string state: Consume the next input character -> U+005C REVERSE SOLIDUS "\" Append "\" to the output string If the escape flag is true, set the flag to false Otherwise, set the escape flag to true -> U+0022 QUOTATION MARK '"' Append '"' to the output string If the escape flag is true, set the flag to false Otherwise, switch to the Normal state -> Anything Else Append the current character to the output string Single-quoted string state: Consume the next input character -> U+005C REVERSE SOLIDUS "\" Append "\" to the output string If the escape flag is true, set the flag to false Otherwise, set the escape flag to true -> U+0027 APOSTROPHE "'" Append "'" to the output string If the escape flag is true, set the flag to false Otherwise, switch to the Normal state -> Anything Else Append the current character to the output string If the escape flag is true, set the flag to false -- Lachlan Hunt - Opera Software http://lachy.id.au/ http://www.opera.com/
Received on Thursday, 17 July 2008 11:36:19 UTC