Changeset 2812:54fd67a0919f in livinglogic.python.xist

Show
Ignore:
Timestamp:
07/26/07 13:08:41 (12 years ago)
Author:
Walter Doerwald <walter@…>
Branch:
default
Message:

SiblingCombinators? now consider all siblings. Introduce CSS variants that don't.

AdjacentSiblingCombinator? and GeneralSiblingCombinator? now consider all siblings
not just elements. However CSS requires that only elements are considered: Add
new classes CSSAdjacentSiblingCombinator and CSSGeneralSiblingCombinator that
have the old behaviour.

Files:
2 modified

Legend:

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

    r2811 r2812  
    954954            node = path[-1] 
    955955            sibling = None 
    956             for child in path[-2][xsc.Element]: 
     956            for child in path[-2]: 
    957957                if child is node: 
    958958                    break 
     
    10011001        if len(path) >= 2 and self.right.match(path): 
    10021002            node = path[-1] 
    1003             for child in path[-2][xsc.Element]: 
     1003            for child in path[-2]: 
    10041004                if child is node: 
    10051005                    return False 
     
    15651565 
    15661566 
     1567class CSSAdjacentSiblingCombinator(BinaryCombinator): 
     1568    """ 
     1569    <par>A <class>CSSAdjacentSiblingCombinator</class> work similar to an 
     1570    <class>AdjacentSiblingCombinator</class> except that only preceding elements 
     1571    are considered.</par> 
     1572    """ 
     1573 
     1574    def match(self, path): 
     1575        if len(path) >= 2 and self.right.match(path): 
     1576            # Find sibling 
     1577            node = path[-1] 
     1578            sibling = None 
     1579            for child in path[-2][xsc.Element]: 
     1580                if child is node: 
     1581                    break 
     1582                sibling = child 
     1583            if sibling is not None: 
     1584                return self.left.match(path[:-1]+[sibling]) 
     1585        return False 
     1586 
     1587    reprsymbol = " + " 
     1588 
     1589    def __str__(self): 
     1590        return "%s+%s" % (self.left, self.right) 
     1591 
     1592 
     1593class CSSGeneralSiblingCombinator(BinaryCombinator): 
     1594    """ 
     1595    <par>A <class>CSSGeneralSiblingCombinator</class> work similar to an 
     1596    <class>GeneralSiblingCombinator</class> except that only preceding elements 
     1597    are considered.</par> 
     1598    """ 
     1599 
     1600    def match(self, path): 
     1601        if len(path) >= 2 and self.right.match(path): 
     1602            node = path[-1] 
     1603            for child in path[-2][xsc.Element]: 
     1604                if child is node: 
     1605                    return False 
     1606                if self.left.match(path[:-1]+[child]): 
     1607                    return True 
     1608        return False 
     1609 
     1610    reprsymbol = " ** " 
     1611 
     1612    def __str__(self): 
     1613        return "%s~%s" % (self.left, self.right) 
     1614 
     1615 
    15671616_attributecombinator2class = { 
    15681617    "=": attrhasvalue_xml, 
     
    15771626    " ": DescendantCombinator, 
    15781627    ">": ChildCombinator, 
    1579     "+": AdjacentSiblingCombinator, 
    1580     "~": GeneralSiblingCombinator, 
     1628    "+": CSSAdjacentSiblingCombinator, 
     1629    "~": CSSGeneralSiblingCombinator, 
    15811630} 
    15821631 
  • test/test_xfind.py

    r2804 r2812  
    343343    assert list(e.walknode(xfind.css("div>*:empty"))) == [] 
    344344    assert list(e.walknode(xfind.css("div>:empty"))) == [] 
    345     assert list(e.walknode(xfind.css("li+li"))) == [e[0][1]] 
    346345    assert list(e.walknode(xfind.css("*|li"))) == [e[0][0], e[0][1]] 
    347346    assert list(e.walknode(xfind.css("h|li", prefixes={"h": html}))) == [e[0][0], e[0][1]] 
    348347    assert list(e.walknode(xfind.css("h|li", prefixes={"h": specials}))) == [] 
     348 
     349    with xsc.Frag() as e: 
     350        +html.div("foo") 
     351        +xsc.Text("filler") 
     352        +html.p("foo") 
     353        +xsc.Text("filler") 
     354        +html.ul(html.li("foo")) 
     355 
     356    assert list(e.walknode(xfind.css("div + p"))) == [e[2]] 
     357    assert list(e.walknode(xfind.css("div + ul"))) == [] 
     358    assert list(e.walknode(xfind.css("ul + p"))) == [] 
     359    assert list(e.walknode(xfind.css("div ~ p"))) == [e[2]] 
     360    assert list(e.walknode(xfind.css("div ~ ul"))) == [e[4]] 
     361    assert list(e.walknode(xfind.css("p ~ div"))) == [] 
     362    assert list(e.walknode(xfind.css("div:first-child + p"))) == [e[2]] 
     363    assert list(e.walknode(xfind.css("*:first-child + p"))) == [e[2]]