1 """SelectorList is a list of CSS Selector objects.
2
3 TODO
4 - ??? CSS2 gives a special meaning to the comma (,) in selectors.
5 However, since it is not known if the comma may acquire other
6 meanings in future versions of CSS, the whole statement should be
7 ignored if there is an error anywhere in the selector, even though
8 the rest of the selector may look reasonable in CSS2.
9
10 Illegal example(s):
11
12 For example, since the "&" is not a valid token in a CSS2 selector,
13 a CSS2 user agent must ignore the whole second line, and not set
14 the color of H3 to red:
15 """
16 __all__ = ['SelectorList']
17 __docformat__ = 'restructuredtext'
18 __author__ = '$LastChangedBy: cthedot $'
19 __date__ = '$LastChangedDate: 2008-01-06 01:14:26 +0100 (So, 06 Jan 2008) $'
20 __version__ = '$LastChangedRevision: 820 $'
21
22 import xml.dom
23 import cssutils
24 from selector import Selector
25
26 -class SelectorList(cssutils.util.Base, cssutils.util.ListSeq):
27 """
28 (cssutils) a list of Selectors of a CSSStyleRule
29
30 Properties
31 ==========
32 length: of type unsigned long, readonly
33 The number of Selector elements in the list.
34 namespaces
35 **TODO:**
36 a dict of {prefix: namespaceURI} mapping, may also be a
37 CSSStyleSheet in which case the namespaces defined there
38 are used. If None cssutils tries to get the namespaces as
39 defined in a possible parent CSSStyleSheet.
40 parentRule: of type CSSRule, readonly
41 The CSS rule that contains this declaration block or None if this
42 CSSStyleDeclaration is not attached to a CSSRule.
43 selectorText: of type DOMString
44 The textual representation of the selector for the rule set. The
45 implementation may have stripped out insignificant whitespace while
46 parsing the selector.
47 seq:
48 A list of interwoven Selector objects and u','
49 wellformed
50 if this selectorlist is wellformed regarding the Selector spec
51 """
52 - def __init__(self, selectorText=None, namespaces=None,
53 parentRule=None, readonly=False):
67
69
70 self._checkReadonly()
71
72 if not isinstance(newSelector, Selector):
73 newSelector = Selector(newSelector, namespaces=self.namespaces)
74
75 if newSelector.wellformed:
76 newSelector.parentRule = self
77 return newSelector
78
80 """
81 overwrites ListSeq.__setitem__
82
83 Any duplicate Selectors are **not** removed.
84 """
85 newSelector = self.__prepareset(newSelector)
86 if newSelector:
87 self.seq[index] = newSelector
88
89
91 """
92 Append newSelector (is a string will be converted to a new
93 Selector. A duplicate Selector is removed.
94
95 Returns new Selector or None if newSelector is no wellformed
96 Selector.
97
98 DOMException on setting
99
100 - SYNTAX_ERR: (self)
101 Raised if the specified CSS string value has a syntax error
102 and is unparsable.
103 - NO_MODIFICATION_ALLOWED_ERR: (self)
104 Raised if this rule is readonly.
105 """
106 newSelector = self.__prepareset(newSelector)
107 if newSelector:
108 self.wellformed = True
109 seq = self.seq[:]
110 del self.seq[:]
111 for s in seq:
112 if s.selectorText != newSelector.selectorText:
113 self.seq.append(s)
114 self.seq.append(newSelector)
115 return newSelector
116
117 - def append(self, newSelector):
120
121 length = property(lambda self: len(self),
122 doc="The number of Selector elements in the list.")
123
125 "returns serialized format"
126 return cssutils.ser.do_css_SelectorList(self)
127
128 - def _setSelectorText(self, selectorText):
129 """
130 selectortext
131 comma-separated list of selectors
132
133 DOMException on setting
134
135 - SYNTAX_ERR: (self)
136 Raised if the specified CSS string value has a syntax error
137 and is unparsable.
138 - NO_MODIFICATION_ALLOWED_ERR: (self)
139 Raised if this rule is readonly.
140 """
141 self._checkReadonly()
142 wellformed = True
143 tokenizer = self._tokenize2(selectorText)
144 newseq = []
145
146 expected = True
147 while True:
148
149 selectortokens = self._tokensupto2(tokenizer, listseponly=True)
150 if selectortokens:
151 if self._tokenvalue(selectortokens[-1]) == ',':
152 expected = selectortokens.pop()
153 else:
154 expected = None
155
156 selector = Selector(selectortokens, namespaces=self.namespaces)
157 if selector.wellformed:
158 selector.parentRule = self.parentRule
159 newseq.append(selector)
160 else:
161 wellformed = False
162 self._log.error(u'SelectorList: Invalid Selector: %s' %
163 self._valuestr(selectortokens))
164 else:
165 break
166
167
168 if u',' == expected:
169 wellformed = False
170 self._log.error(u'SelectorList: Cannot end with ",": %r' %
171 self._valuestr(selectorText))
172 elif expected:
173 wellformed = False
174 self._log.error(u'SelectorList: Unknown Syntax: %r' %
175 self._valuestr(selectorText))
176 if wellformed:
177 self.wellformed = wellformed
178 self.seq = newseq
179
180
181
183 return self._parentRule
184
189
190 parentRule = property(_getParentRule, _setParentRule,
191 doc="(DOM) The CSS rule that contains this SelectorList or\
192 None if this SelectorList is not attached to a CSSRule.")
193
194 selectorText = property(_getSelectorText, _setSelectorText,
195 doc="""(cssutils) The textual representation of the selector for
196 a rule set.""")
197
199 return "cssutils.css.%s(selectorText=%r)" % (
200 self.__class__.__name__, self.selectorText)
201
203 return "<cssutils.css.%s object selectorText=%r at 0x%x>" % (
204 self.__class__.__name__, self.selectorText, id(self))
205