1 """CSSStyleRule implements DOM Level 2 CSS CSSStyleRule.
2
3 TODO
4 - parentRule?
5 - parentStyleSheet?
6 """
7 __all__ = ['CSSStyleRule']
8 __docformat__ = 'restructuredtext'
9 __author__ = '$LastChangedBy: doerwalter $'
10 __date__ = '$LastChangedDate: 2007-08-03 13:52:32 +0200 (Fr, 03 Aug 2007) $'
11 __version__ = '0.9.2a2 $LastChangedRevision: 161 $'
12
13 import xml.dom
14
15 import cssrule
16 import cssstyledeclaration
17 import cssutils
18
19 from selector import Selector
20 from selectorlist import SelectorList
21
22
24 """
25 represents a single rule set in a CSS style sheet.
26
27 Properties
28 ==========
29 cssText: of type DOMString
30 The parsable textual representation of this rule
31 selectorText: of type DOMString
32 The textual representation of the selector for the rule set. The
33 implementation may have stripped out insignificant whitespace while
34 parsing the selector.
35 style: of type CSSStyleDeclaration, (DOM)
36 The declaration-block of this rule set.
37
38 cssutils only
39 -------------
40 selectorList: of type SelectorList (cssutils only)
41 A list of all Selector elements for the rule set.
42
43 Inherits properties from CSSRule
44
45 Format
46 ======
47 ruleset
48 : selector [ COMMA S* selector ]*
49 LBRACE S* declaration [ ';' S* declaration ]* '}' S*
50 ;
51 """
52 type = cssrule.CSSRule.STYLE_RULE
53
54 - def __init__(self, selectorText=None, style=None, readonly=False):
78
79
80 - def _getCssText(self):
81 """
82 returns serialized property cssText
83 """
84 return cssutils.ser.do_CSSStyleRule(self)
85
86 - def _setCssText(self, cssText):
87 """
88 DOMException on setting
89
90 - SYNTAX_ERR: (self, StyleDeclaration)
91 Raised if the specified CSS string value has a syntax error and
92 is unparsable.
93 - INVALID_MODIFICATION_ERR: (self)
94 Raised if the specified CSS string value represents a different
95 type of rule than the current one.
96 - HIERARCHY_REQUEST_ERR: (CSSStylesheet)
97 Raised if the rule cannot be inserted at this point in the
98 style sheet.
99 - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
100 Raised if the rule is readonly.
101 """
102 super(CSSStyleRule, self)._setCssText(cssText)
103 tokens = self._tokenize(cssText)
104 valid = True
105
106
107 if not tokens or tokens[0].value.startswith(u'@'):
108 self._log.error(u'CSSStyleRule: No CSSStyleRule found: %s' %
109 self._valuestr(cssText),
110 error=xml.dom.InvalidModificationErr)
111 return
112
113
114 newselectorList = SelectorList()
115 newstyle = cssstyledeclaration.CSSStyleDeclaration(parentRule=self)
116 newseq = []
117
118
119 selectortokens, endi = self._tokensupto(tokens,
120 blockstartonly=True)
121 expected = '{'
122 if selectortokens[-1].value != expected:
123 self._log.error(u'CSSStyleRule: No StyleDeclaration found.',
124 selectortokens[-1])
125 return
126 newselectorList.selectorText = selectortokens[:-1]
127 newseq.append(newselectorList)
128
129
130 i, imax = endi, len(tokens)
131 while i < imax:
132 t = tokens[i]
133 if self._ttypes.EOF == t.type:
134 expected = 'EOF'
135
136 elif self._ttypes.S == t.type:
137 pass
138
139 elif self._ttypes.COMMENT == t.type:
140 newseq.append(cssutils.css.CSSComment(t))
141
142 elif self._ttypes.LBRACE == t.type:
143 foundtokens, endi = self._tokensupto(
144 tokens[i:], blockendonly=True)
145 i += endi
146 if len(foundtokens) < 2:
147 self._log.error(u'CSSStyleRule: Syntax Error.', t)
148 return
149 else:
150 styletokens = foundtokens[1:-1]
151 newstyle = cssstyledeclaration.CSSStyleDeclaration(
152 parentRule=self)
153 newstyle.cssText = styletokens
154 newseq.append(newstyle)
155 expected = '}'
156 continue
157
158 elif '}' == expected and self._ttypes.RBRACE == t.type:
159 expected = None
160
161 else:
162 self._log.error(u'CSSStyleRule: Unexpected token.', t)
163 return
164
165 i += 1
166
167 if expected == '{':
168 self._log.error(u'CSSStyleRule: No StyleDeclaration found: %s' %
169 self._valuestr(cssText))
170 return
171 elif expected and expected == 'EOF':
172 self._log.error(u'CSSStyleRule: Trailing text after ending "}" or no end of StyleDeclaration found: %s' %
173 self._valuestr(cssText))
174 return
175 else:
176
177 self.selectorList = newselectorList
178 self.style = newstyle
179 self.seq = newseq
180
181 cssText = property(_getCssText, _setCssText,
182 doc="(DOM) The parsable textual representation of the rule.")
183
184
186 """
187 (cssutils)
188 set the SelectorList of this rule
189
190 selectorList
191 instance of SelectorList
192
193 DOMException on setting
194
195 - NO_MODIFICATION_ALLOWED_ERR:
196 Raised if this rule is readonly.
197 """
198 self._checkReadonly()
199 self._selectorList = selectorList
200
202 """
203 (cssutils)
204 returns the SelectorList of this rule
205 see selectorText for a textual representation
206 """
207 return self._selectorList
208
209 selectorList = property(_getSelectorList, _setSelectorList,
210 doc="The SelectorList of this rule.")
211
212
214 """
215 wrapper for cssutils Selector object
216 """
217 return self._selectorList.selectorText
218
219 - def _setSelectorText(self, selectorText):
220 """
221 wrapper for cssutils Selector object
222
223 selector
224 of type string, might also be a comma separated list of
225 selectors
226
227 DOMException on setting
228
229 - SYNTAX_ERR:
230 Raised if the specified CSS string value has a syntax error
231 and is unparsable.
232 - NO_MODIFICATION_ALLOWED_ERR: (self)
233 Raised if this rule is readonly.
234 """
235 self._checkReadonly()
236 self._selectorList = SelectorList(selectorText)
237
238 selectorText = property(_getSelectorText, _setSelectorText,
239 doc="""(DOM) The textual representation of the selector for the
240 rule set.""")
241
242
245
260
261 style = property(_getStyle, _setStyle,
262 doc="(DOM) The declaration-block of this rule set.")
263
265 return "<%s.%s object selector=%r at 0x%x>" % (self.__class__.__module__, self.__class__.__name__, self.selectorText, id(self))
266
267
268 if __name__ == '__main__':
269 cssutils.css.cssstylerule.Selector = Selector
270 r = CSSStyleRule()
271 r.cssText = 'a {}a'
272 r.selectorText = u'b + a'
273 print r.cssText
274