1 """CSSStyleRule implements DOM Level 2 CSS CSSStyleRule.
2 """
3 __all__ = ['CSSStyleRule']
4 __docformat__ = 'restructuredtext'
5 __version__ = '$Id: cssstylerule.py 1284 2008-06-05 16:29:17Z cthedot $'
6
7 import xml.dom
8 import cssrule
9 import cssutils
10 from selectorlist import SelectorList
11 from cssstyledeclaration import CSSStyleDeclaration
12
14 """
15 The CSSStyleRule object represents a ruleset specified (if any) in a CSS
16 style sheet. It provides access to a declaration block as well as to the
17 associated group of selectors.
18
19 Properties
20 ==========
21 selectorList: of type SelectorList (cssutils only)
22 A list of all Selector elements for the rule set.
23 selectorText: of type DOMString
24 The textual representation of the selector for the rule set. The
25 implementation may have stripped out insignificant whitespace while
26 parsing the selector.
27 style: of type CSSStyleDeclaration, (DOM)
28 The declaration-block of this rule set.
29 type
30 the type of this rule, constant cssutils.CSSRule.STYLE_RULE
31
32 inherited properties:
33 - cssText
34 - parentRule
35 - parentStyleSheet
36
37 Format
38 ======
39 ruleset::
40
41 : selector [ COMMA S* selector ]*
42 LBRACE S* declaration [ ';' S* declaration ]* '}' S*
43 ;
44 """
45 type = property(lambda self: cssrule.CSSRule.STYLE_RULE)
46
47 - def __init__(self, selectorText=None, style=None, parentRule=None,
48 parentStyleSheet=None, readonly=False):
69
70
71 - def _getCssText(self):
72 """
73 returns serialized property cssText
74 """
75 return cssutils.ser.do_CSSStyleRule(self)
76
77 - def _setCssText(self, cssText):
78 """
79 :param cssText:
80 a parseable string or a tuple of (cssText, dict-of-namespaces)
81 :Exceptions:
82 - `NAMESPACE_ERR`: (Selector)
83 Raised if the specified selector uses an unknown namespace
84 prefix.
85 - `SYNTAX_ERR`: (self, StyleDeclaration, etc)
86 Raised if the specified CSS string value has a syntax error and
87 is unparsable.
88 - `INVALID_MODIFICATION_ERR`: (self)
89 Raised if the specified CSS string value represents a different
90 type of rule than the current one.
91 - `HIERARCHY_REQUEST_ERR`: (CSSStylesheet)
92 Raised if the rule cannot be inserted at this point in the
93 style sheet.
94 - `NO_MODIFICATION_ALLOWED_ERR`: (CSSRule)
95 Raised if the rule is readonly.
96 """
97 super(CSSStyleRule, self)._setCssText(cssText)
98
99
100 cssText, namespaces = self._splitNamespacesOff(cssText)
101 try:
102
103 namespaces = self.parentStyleSheet.namespaces
104 except AttributeError:
105 pass
106
107 tokenizer = self._tokenize2(cssText)
108 selectortokens = self._tokensupto2(tokenizer, blockstartonly=True)
109 styletokens = self._tokensupto2(tokenizer, blockendonly=True)
110 trail = self._nexttoken(tokenizer)
111 if trail:
112 self._log.error(u'CSSStyleRule: Trailing content: %s' %
113 self._valuestr(cssText), token=trail)
114 elif not selectortokens:
115 self._log.error(u'CSSStyleRule: No selector found: %r' %
116 self._valuestr(cssText))
117 elif self._tokenvalue(selectortokens[0]).startswith(u'@'):
118 self._log.error(u'CSSStyleRule: No style rule: %r' %
119 self._valuestr(cssText),
120 error=xml.dom.InvalidModificationErr)
121 else:
122 wellformed = True
123
124 bracetoken = selectortokens.pop()
125 if self._tokenvalue(bracetoken) != u'{':
126 wellformed = False
127 self._log.error(
128 u'CSSStyleRule: No start { of style declaration found: %r' %
129 self._valuestr(cssText), bracetoken)
130 elif not selectortokens:
131 wellformed = False
132 self._log.error(u'CSSStyleRule: No selector found: %r.' %
133 self._valuestr(cssText), bracetoken)
134 newselectorlist = SelectorList(selectorText=(selectortokens,
135 namespaces),
136 parentRule=self)
137
138 newstyle = CSSStyleDeclaration()
139 if not styletokens:
140 wellformed = False
141 self._log.error(
142 u'CSSStyleRule: No style declaration or "}" found: %r' %
143 self._valuestr(cssText))
144 else:
145 braceorEOFtoken = styletokens.pop()
146 val, typ = self._tokenvalue(braceorEOFtoken), self._type(braceorEOFtoken)
147 if val != u'}' and typ != 'EOF':
148 wellformed = False
149 self._log.error(
150 u'CSSStyleRule: No "}" after style declaration found: %r' %
151 self._valuestr(cssText))
152 else:
153 if 'EOF' == typ:
154
155 styletokens.append(braceorEOFtoken)
156 newstyle.cssText = styletokens
157
158 if wellformed:
159 self._selectorList = newselectorlist
160 self.style = newstyle
161
162 cssText = property(_getCssText, _setCssText,
163 doc="(DOM) The parsable textual representation of the rule.")
164
165
172
173 _namespaces = property(__getNamespaces, doc=u"""if this Rule is
174 attached to a CSSStyleSheet the namespaces of that sheet are mirrored
175 here. While the Rule is not attached the namespaces of selectorList
176 are used.""")
177
185
186 selectorList = property(lambda self: self._selectorList, _setSelectorList,
187 doc="The SelectorList of this rule.")
188
189 - def _setSelectorText(self, selectorText):
190 """
191 wrapper for cssutils SelectorList object
192
193 :param selectorText: of type string, might also be a comma separated list
194 of selectors
195 :Exceptions:
196 - `NAMESPACE_ERR`: (Selector)
197 Raised if the specified selector uses an unknown namespace
198 prefix.
199 - `SYNTAX_ERR`: (SelectorList, Selector)
200 Raised if the specified CSS string value has a syntax error
201 and is unparsable.
202 - `NO_MODIFICATION_ALLOWED_ERR`: (self)
203 Raised if this rule is readonly.
204 """
205 self._checkReadonly()
206 self._selectorList.selectorText = selectorText
207
208 selectorText = property(lambda self: self._selectorList.selectorText,
209 _setSelectorText,
210 doc="""(DOM) The textual representation of the selector for the
211 rule set.""")
212
214 """
215 :param style: CSSStyleDeclaration or string, only the cssText of a
216 declaration is used, not the actual object
217 """
218 self._checkReadonly()
219 if isinstance(style, basestring):
220 self._style.cssText = style
221 else:
222
223
224 self._style._seq = style._seq
225
226 style = property(lambda self: self._style, _setStyle,
227 doc="(DOM) The declaration-block of this rule set.")
228
229 wellformed = property(lambda self: self.selectorList.wellformed)
230
238
240 return "<cssutils.css.%s object selector=%r style=%r _namespaces=%r at 0x%x>" % (
241 self.__class__.__name__, self.selectorText, self.style.cssText,
242 self._namespaces, id(self))
243