Changeset 3103:ef5c522dc188 in livinglogic.python.xist

Show
Ignore:
Timestamp:
01/04/08 16:34:08 (12 years ago)
Author:
Walter Doerwald <walter@…>
Branch:
default
Message:

Use the specificity as defined for CSS 2.1 and CSS 3 (instead of CSS 1).

Files:
3 modified

Legend:

Unmodified
Added
Removed
  • src/ll/xist/css.py

    r3102 r3103  
    1515from __future__ import with_statement 
    1616 
    17 import contextlib, operator 
     17import contextlib 
    1818 
    1919try: 
     
    146146    """ 
    147147    def iterstyles(node, rules): 
     148        for data in rules: 
     149            yield data 
     150        # According to CSS 2.1 (http://www.w3.org/TR/CSS21/cascade.html#specificity) 
     151        # style attributes have the highest weight, so we yield it last 
     152        # (CSS 3 uses the same weight) 
    148153        if "style" in node.attrs: 
    149154            style = node.attrs["style"] 
    150155            if not style.isfancy(): 
    151                 styledata = ( 
    152                     xfind.CSSWeight(1, 0, 0), 
     156                yield ( 
    153157                    xfind.IsSelector(node), 
    154158                    cssutils.parseString(u"*{%s}" % style).cssRules[0].style # parse the style out of the style attribute 
    155159                ) 
    156                 # put the style attribute into the order as the last of the selectors with ID weight (see http://www.w3.org/TR/REC-CSS1#cascading-order) 
    157                 def doiter(): 
    158                     done = False 
    159                     for data in rules: 
    160                         if not done and data[0] > styledata[0]: 
    161                             yield styledata 
    162                             done = True 
    163                         yield data 
    164                     if not done: 
    165                         yield styledata 
    166                 return doiter() 
    167         return rules 
    168160 
    169161    rules = [] 
    170162    for (i, rule) in enumerate(iterrules(node, base=base, media=media)): 
    171163        for sel in rule.selectorList: 
    172             sel = selector(sel) 
    173             rules.append((sel.cssweight(), sel, rule.style)) 
    174     rules.sort(key=operator.itemgetter(0)) 
     164            rules.append((selector(sel), rule.style)) 
     165    rules.sort(key=lambda(sel, rule): sel.cssweight()) 
    175166    count = 0 
    176167    for path in node.walk(xsc.Element): 
     
    178169        if path[-1].Attrs.isallowed("style"): 
    179170            styles = {} 
    180             for (weight, sel, style) in iterstyles(path[-1], rules): 
     171            for (sel, style) in iterstyles(path[-1], rules): 
    181172                if sel.matchpath(path): 
    182173                    for prop in style.seq: 
     
    184175                            styles[prop.name] = (count, prop.name, prop.cssValue.cssText) 
    185176                            count += 1 
    186                     style = " ".join("%s: %s;" % (name, value) for (count, name, value) in sorted(styles.itervalues())) 
    187                     if style: 
    188                         path[-1].attrs["style"] = style 
     177            style = " ".join("%s: %s;" % (name, value) for (count, name, value) in sorted(styles.itervalues())) 
     178            if style: 
     179                path[-1].attrs["style"] = style 
    189180 
    190181 
     
    533524 
    534525    def cssweight(self): 
    535         result = xfind.CSSWeight(0, 0, int(self.type != "*")) 
     526        result = xfind.CSSWeight(0, 0, 0, int(self.type != "*")) 
    536527        for selector in self.selectors: 
    537528            result += selector.cssweight() 
  • src/ll/xist/xfind.py

    r3100 r3103  
    3030    """ 
    3131 
    32     def __new__(cls, a=0, b=0, c=0): 
    33         return tuple.__new__(cls, (a, b, c)) 
     32    def __new__(cls, a=0, b=0, c=0, d=0): 
     33        return tuple.__new__(cls, (a, b, c, d)) 
    3434 
    3535    def __add__(self, other): 
    36         return CSSWeight(self[0]+other[0], self[1]+other[1], self[2]+other[2]) 
     36        return CSSWeight(self[0]+other[0], self[1]+other[1], self[2]+other[2], self[3]+other[3]) 
    3737 
    3838    def __repr__(self): 
    39         return "CSSWeight(%r, %r, %r)" % (self[0], self[1], self[2]) 
     39        return "CSSWeight(%r, %r, %r, %r)" % (self[0], self[1], self[2], self[3]) 
    4040 
    4141 
     
    723723 
    724724    def cssweight(self): 
    725         return CSSWeight(1, 0, 0) 
     725        return CSSWeight(0, 1, 0, 0) 
    726726 
    727727 
     
    762762 
    763763    def cssweight(self): 
    764         return CSSWeight(0, 1, 0) 
     764        return CSSWeight(0, 0, 1, 0) 
    765765 
    766766 
  • test/test_css.py

    r3080 r3103  
    8383def test_cssweight(): 
    8484    # from http://www.w3.org/TR/css3-selectors/#specificity 
    85     assert css.selector("*").cssweight() == (0, 0, 0) 
    86     assert css.selector("LI").cssweight() == (0, 0, 1) 
    87     assert css.selector("UL LI").cssweight() == (0, 0, 2) 
    88     assert css.selector("UL OL+LI").cssweight() == (0, 0, 3) 
    89     assert css.selector("UL OL LI.red").cssweight() == (0, 1, 3) 
    90     assert css.selector("LI.red.level").cssweight() == (0, 2, 1) 
    91     assert css.selector("#x34y").cssweight() == (1, 0, 0) 
     85    assert css.selector("*").cssweight() == (0, 0, 0, 0) 
     86    assert css.selector("LI").cssweight() == (0, 0, 0, 1) 
     87    assert css.selector("UL LI").cssweight() == (0, 0, 0, 2) 
     88    assert css.selector("UL OL+LI").cssweight() == (0, 0, 0, 3) 
     89    assert css.selector("UL OL LI.red").cssweight() == (0, 0, 1, 3) 
     90    assert css.selector("LI.red.level").cssweight() == (0, 0, 2, 1) 
     91    assert css.selector("#x34y").cssweight() == (0, 1, 0, 0) 
    9292    # The following is not supported 
    93     # assert css.selector("#s12:not(FOO)").cssweight() == (1, 0, 1) 
     93    # assert css.selector("#s12:not(FOO)").cssweight() == (0, 1, 0, 1) 
    9494 
    9595 
     
    145145    css.applystylesheets(e) 
    146146 
    147     # style attribute wins (same specificity, but it is considered to come last) 
     147    # style attribute wins 
    148148    assert str(e.walknode(html.p)[0].attrs.style) == "color: blue;" 
    149149    assert list(e.walknode(html.style)) == [] 
     
    159159    css.applystylesheets(e) 
    160160 
    161     # stylesheet wins (because element name + id has a greater specificity) 
    162     assert str(e.walknode(html.p)[0].attrs.style) == "color: red;" 
     161    # stylesheet always wins (at least in CSS 2.1 und 3) 
     162    assert str(e.walknode(html.p)[0].attrs.style) == "color: blue;" 
    163163    assert list(e.walknode(html.style)) == [] 
    164164