gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.app / org.gvsig.scripting.app.mainplugin / src / main / resources-plugin / scripting / lib / cssutils / css / cssstylerule.py @ 475
History | View | Annotate | Download (9 KB)
1 |
"""CSSStyleRule implements DOM Level 2 CSS CSSStyleRule."""
|
---|---|
2 |
__all__ = ['CSSStyleRule']
|
3 |
__docformat__ = 'restructuredtext'
|
4 |
__version__ = '$Id$'
|
5 |
|
6 |
from cssstyledeclaration import CSSStyleDeclaration |
7 |
from selectorlist import SelectorList |
8 |
import cssrule |
9 |
import cssutils |
10 |
import xml.dom |
11 |
|
12 |
class CSSStyleRule(cssrule.CSSRule): |
13 |
"""The CSSStyleRule object represents a ruleset specified (if any) in a CSS
|
14 |
style sheet. It provides access to a declaration block as well as to the
|
15 |
associated group of selectors.
|
16 |
|
17 |
Format::
|
18 |
|
19 |
: selector [ COMMA S* selector ]*
|
20 |
LBRACE S* declaration [ ';' S* declaration ]* '}' S*
|
21 |
;
|
22 |
"""
|
23 |
def __init__(self, selectorText=None, style=None, parentRule=None, |
24 |
parentStyleSheet=None, readonly=False): |
25 |
"""
|
26 |
:Parameters:
|
27 |
selectorText
|
28 |
string parsed into selectorList
|
29 |
style
|
30 |
string parsed into CSSStyleDeclaration for this CSSStyleRule
|
31 |
readonly
|
32 |
if True allows setting of properties in constructor only
|
33 |
"""
|
34 |
super(CSSStyleRule, self).__init__(parentRule=parentRule, |
35 |
parentStyleSheet=parentStyleSheet) |
36 |
|
37 |
self.selectorList = SelectorList()
|
38 |
if selectorText:
|
39 |
self.selectorText = selectorText
|
40 |
|
41 |
if style:
|
42 |
self.style = style
|
43 |
else:
|
44 |
self.style = CSSStyleDeclaration()
|
45 |
|
46 |
self._readonly = readonly
|
47 |
|
48 |
def __repr__(self): |
49 |
if self._namespaces: |
50 |
st = (self.selectorText, self._namespaces) |
51 |
else:
|
52 |
st = self.selectorText
|
53 |
return u"cssutils.css.%s(selectorText=%r, style=%r)" % ( |
54 |
self.__class__.__name__, st, self.style.cssText) |
55 |
|
56 |
def __str__(self): |
57 |
return u"<cssutils.css.%s object selectorText=%r style=%r _namespaces=%r "\ |
58 |
u"at 0x%x>" % (self.__class__.__name__, |
59 |
self.selectorText,
|
60 |
self.style.cssText,
|
61 |
self._namespaces,
|
62 |
id(self)) |
63 |
|
64 |
def _getCssText(self): |
65 |
"""Return serialized property cssText."""
|
66 |
return cssutils.ser.do_CSSStyleRule(self) |
67 |
|
68 |
def _setCssText(self, cssText): |
69 |
"""
|
70 |
:param cssText:
|
71 |
a parseable string or a tuple of (cssText, dict-of-namespaces)
|
72 |
:exceptions:
|
73 |
- :exc:`~xml.dom.NamespaceErr`:
|
74 |
Raised if the specified selector uses an unknown namespace
|
75 |
prefix.
|
76 |
- :exc:`~xml.dom.SyntaxErr`:
|
77 |
Raised if the specified CSS string value has a syntax error and
|
78 |
is unparsable.
|
79 |
- :exc:`~xml.dom.InvalidModificationErr`:
|
80 |
Raised if the specified CSS string value represents a different
|
81 |
type of rule than the current one.
|
82 |
- :exc:`~xml.dom.HierarchyRequestErr`:
|
83 |
Raised if the rule cannot be inserted at this point in the
|
84 |
style sheet.
|
85 |
- :exc:`~xml.dom.NoModificationAllowedErr`:
|
86 |
Raised if the rule is readonly.
|
87 |
"""
|
88 |
super(CSSStyleRule, self)._setCssText(cssText) |
89 |
|
90 |
# might be (cssText, namespaces)
|
91 |
cssText, namespaces = self._splitNamespacesOff(cssText)
|
92 |
try:
|
93 |
# use parent style sheet ones if available
|
94 |
namespaces = self.parentStyleSheet.namespaces
|
95 |
except AttributeError: |
96 |
pass
|
97 |
|
98 |
tokenizer = self._tokenize2(cssText)
|
99 |
selectortokens = self._tokensupto2(tokenizer, blockstartonly=True) |
100 |
styletokens = self._tokensupto2(tokenizer, blockendonly=True) |
101 |
trail = self._nexttoken(tokenizer)
|
102 |
if trail:
|
103 |
self._log.error(u'CSSStyleRule: Trailing content: %s' % |
104 |
self._valuestr(cssText), token=trail)
|
105 |
elif not selectortokens: |
106 |
self._log.error(u'CSSStyleRule: No selector found: %r' % |
107 |
self._valuestr(cssText))
|
108 |
elif self._tokenvalue(selectortokens[0]).startswith(u'@'): |
109 |
self._log.error(u'CSSStyleRule: No style rule: %r' % |
110 |
self._valuestr(cssText),
|
111 |
error=xml.dom.InvalidModificationErr) |
112 |
else:
|
113 |
newSelectorList = SelectorList(parentRule=self)
|
114 |
newStyle = CSSStyleDeclaration(parentRule=self)
|
115 |
ok = True
|
116 |
|
117 |
bracetoken = selectortokens.pop() |
118 |
if self._tokenvalue(bracetoken) != u'{': |
119 |
ok = False
|
120 |
self._log.error(
|
121 |
u'CSSStyleRule: No start { of style declaration found: %r' %
|
122 |
self._valuestr(cssText), bracetoken)
|
123 |
elif not selectortokens: |
124 |
ok = False
|
125 |
self._log.error(u'CSSStyleRule: No selector found: %r.' % |
126 |
self._valuestr(cssText), bracetoken)
|
127 |
# SET
|
128 |
newSelectorList.selectorText = (selectortokens, |
129 |
namespaces) |
130 |
|
131 |
if not styletokens: |
132 |
ok = False
|
133 |
self._log.error(
|
134 |
u'CSSStyleRule: No style declaration or "}" found: %r' %
|
135 |
self._valuestr(cssText))
|
136 |
else:
|
137 |
braceorEOFtoken = styletokens.pop() |
138 |
val, typ = self._tokenvalue(braceorEOFtoken),\
|
139 |
self._type(braceorEOFtoken)
|
140 |
if val != u'}' and typ != 'EOF': |
141 |
ok = False
|
142 |
self._log.error(u'CSSStyleRule: No "}" after style ' |
143 |
u'declaration found: %r'
|
144 |
% self._valuestr(cssText))
|
145 |
else:
|
146 |
if 'EOF' == typ: |
147 |
# add again as style needs it
|
148 |
styletokens.append(braceorEOFtoken) |
149 |
# SET, may raise:
|
150 |
newStyle.cssText = styletokens |
151 |
|
152 |
if ok:
|
153 |
self.selectorList = newSelectorList
|
154 |
self.style = newStyle
|
155 |
|
156 |
cssText = property(_getCssText, _setCssText,
|
157 |
doc=u"(DOM) The parsable textual representation of this "
|
158 |
u"rule.")
|
159 |
|
160 |
def __getNamespaces(self): |
161 |
"""Uses children namespaces if not attached to a sheet, else the sheet's
|
162 |
ones."""
|
163 |
try:
|
164 |
return self.parentStyleSheet.namespaces |
165 |
except AttributeError: |
166 |
return self.selectorList._namespaces |
167 |
|
168 |
_namespaces = property(__getNamespaces,
|
169 |
doc=u"If this Rule is attached to a CSSStyleSheet "
|
170 |
u"the namespaces of that sheet are mirrored "
|
171 |
u"here. While the Rule is not attached the "
|
172 |
u"namespaces of selectorList are used.""") |
173 |
|
174 |
def _setSelectorList(self, selectorList): |
175 |
"""
|
176 |
:param selectorList: A SelectorList which replaces the current
|
177 |
selectorList object
|
178 |
"""
|
179 |
self._checkReadonly()
|
180 |
selectorList._parentRule = self
|
181 |
self._selectorList = selectorList
|
182 |
|
183 |
_selectorList = None
|
184 |
selectorList = property(lambda self: self._selectorList, _setSelectorList, |
185 |
doc=u"The SelectorList of this rule.")
|
186 |
|
187 |
def _setSelectorText(self, selectorText): |
188 |
"""
|
189 |
wrapper for cssutils SelectorList object
|
190 |
|
191 |
:param selectorText:
|
192 |
of type string, might also be a comma separated list
|
193 |
of selectors
|
194 |
:exceptions:
|
195 |
- :exc:`~xml.dom.NamespaceErr`:
|
196 |
Raised if the specified selector uses an unknown namespace
|
197 |
prefix.
|
198 |
- :exc:`~xml.dom.SyntaxErr`:
|
199 |
Raised if the specified CSS string value has a syntax error
|
200 |
and is unparsable.
|
201 |
- :exc:`~xml.dom.NoModificationAllowedErr`:
|
202 |
Raised if this rule is readonly.
|
203 |
"""
|
204 |
self._checkReadonly()
|
205 |
|
206 |
sl = SelectorList(selectorText=selectorText, parentRule=self)
|
207 |
if sl.wellformed:
|
208 |
self._selectorList = sl
|
209 |
|
210 |
selectorText = property(lambda self: self._selectorList.selectorText, |
211 |
_setSelectorText, |
212 |
doc=u"(DOM) The textual representation of the "
|
213 |
u"selector for the rule set.")
|
214 |
|
215 |
def _setStyle(self, style): |
216 |
"""
|
217 |
:param style: A string or CSSStyleDeclaration which replaces the
|
218 |
current style object.
|
219 |
"""
|
220 |
self._checkReadonly()
|
221 |
if isinstance(style, basestring): |
222 |
self._style = CSSStyleDeclaration(cssText=style, parentRule=self) |
223 |
else:
|
224 |
style._parentRule = self
|
225 |
self._style = style
|
226 |
|
227 |
style = property(lambda self: self._style, _setStyle, |
228 |
doc=u"(DOM) The declaration-block of this rule set.")
|
229 |
|
230 |
type = property(lambda self: self.STYLE_RULE, |
231 |
doc=u"The type of this rule, as defined by a CSSRule "
|
232 |
"type constant.")
|
233 |
|
234 |
wellformed = property(lambda self: self.selectorList.wellformed) |