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