1 """CSSNamespaceRule currently implements
2 http://dev.w3.org/csswg/css3-namespace/
3
4 (until 0.9.5a2: http://www.w3.org/TR/2006/WD-css3-namespace-20060828/)
5 """
6 __all__ = ['CSSNamespaceRule']
7 __docformat__ = 'restructuredtext'
8 __author__ = '$LastChangedBy: cthedot $'
9 __date__ = '$LastChangedDate: 2008-02-22 19:03:20 +0100 (Fr, 22 Feb 2008) $'
10 __version__ = '$LastChangedRevision: 1070 $'
11
12 import xml.dom
13 import cssrule
14 import cssutils
15 from cssutils.util import Deprecated
16
18 """
19 Represents an @namespace rule within a CSS style sheet.
20
21 The @namespace at-rule declares a namespace prefix and associates
22 it with a given namespace (a string). This namespace prefix can then be
23 used in namespace-qualified names such as those described in the
24 Selectors Module [SELECT] or the Values and Units module [CSS3VAL].
25
26 Properties
27 ==========
28 atkeyword (cssutils only)
29 the literal keyword used
30 cssText: of type DOMString
31 The parsable textual representation of this rule
32 namespaceURI: of type DOMString
33 The namespace URI (a simple string!) which is bound to the given
34 prefix. If no prefix is set (``CSSNamespaceRule.prefix==''``)
35 the namespace defined by ``namespaceURI`` is set as the default
36 namespace.
37 prefix: of type DOMString
38 The prefix used in the stylesheet for the given
39 ``CSSNamespaceRule.nsuri``. If prefix is empty namespaceURI sets a
40 default namespace for the stylesheet.
41
42 Inherits properties from CSSRule
43
44 Format
45 ======
46 namespace
47 : NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S*
48 ;
49 namespace_prefix
50 : IDENT
51 ;
52 """
53 type = cssrule.CSSRule.NAMESPACE_RULE
54
55 - def __init__(self, namespaceURI=None, prefix=None, cssText=None,
56 parentRule=None, parentStyleSheet=None, readonly=False):
57 """
58 :Parameters:
59 namespaceURI
60 The namespace URI (a simple string!) which is bound to the
61 given prefix. If no prefix is set
62 (``CSSNamespaceRule.prefix==''``) the namespace defined by
63 namespaceURI is set as the default namespace
64 prefix
65 The prefix used in the stylesheet for the given
66 ``CSSNamespaceRule.uri``.
67 cssText
68 if no namespaceURI is given cssText must be given to set
69 a namespaceURI as this is readonly later on
70 parentStyleSheet
71 sheet where this rule belongs to
72
73 Do not use as positional but as keyword parameters only!
74
75 If readonly allows setting of properties in constructor only
76
77 format namespace::
78
79 namespace
80 : NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S*
81 ;
82 namespace_prefix
83 : IDENT
84 ;
85 """
86 super(CSSNamespaceRule, self).__init__(parentRule=parentRule,
87 parentStyleSheet=parentStyleSheet)
88 self.atkeyword = u'@namespace'
89 self._prefix = u''
90 self._namespaceURI = None
91
92 if namespaceURI:
93 self.namespaceURI = namespaceURI
94 self.prefix = prefix
95 tempseq = self._tempSeq()
96 tempseq.append(self.prefix, 'prefix')
97 tempseq.append(self.namespaceURI, 'namespaceURI')
98 self._setSeq(tempseq)
99 elif cssText is not None:
100 self.cssText = cssText
101
102 if parentStyleSheet:
103 self._parentStyleSheet = parentStyleSheet
104
105 self._readonly = readonly
106
107 - def _getCssText(self):
108 """
109 returns serialized property cssText
110 """
111 return cssutils.ser.do_CSSNamespaceRule(self)
112
113 - def _setCssText(self, cssText):
114 """
115 DOMException on setting
116
117 :param cssText: initial value for this rules cssText which is parsed
118 :Exceptions:
119 - `HIERARCHY_REQUEST_ERR`: (CSSStylesheet)
120 Raised if the rule cannot be inserted at this point in the
121 style sheet.
122 - `INVALID_MODIFICATION_ERR`: (self)
123 Raised if the specified CSS string value represents a different
124 type of rule than the current one.
125 - `NO_MODIFICATION_ALLOWED_ERR`: (CSSRule)
126 Raised if the rule is readonly.
127 - `SYNTAX_ERR`: (self)
128 Raised if the specified CSS string value has a syntax error and
129 is unparsable.
130 """
131 super(CSSNamespaceRule, self)._setCssText(cssText)
132 tokenizer = self._tokenize2(cssText)
133 attoken = self._nexttoken(tokenizer, None)
134 if self._type(attoken) != self._prods.NAMESPACE_SYM:
135 self._log.error(u'CSSNamespaceRule: No CSSNamespaceRule found: %s' %
136 self._valuestr(cssText),
137 error=xml.dom.InvalidModificationErr)
138 else:
139
140 new = {'keyword': self._tokenvalue(attoken),
141 'prefix': u'',
142 'uri': None,
143 'wellformed': True
144 }
145
146 def _ident(expected, seq, token, tokenizer=None):
147
148 if 'prefix or uri' == expected:
149 new['prefix'] = self._tokenvalue(token)
150 seq.append(new['prefix'], 'prefix')
151 return 'uri'
152 else:
153 new['wellformed'] = False
154 self._log.error(
155 u'CSSNamespaceRule: Unexpected ident.', token)
156 return expected
157
158 def _string(expected, seq, token, tokenizer=None):
159
160 if expected.endswith('uri'):
161 new['uri'] = self._stringtokenvalue(token)
162 seq.append(new['uri'], 'namespaceURI')
163 return ';'
164
165 else:
166 new['wellformed'] = False
167 self._log.error(
168 u'CSSNamespaceRule: Unexpected string.', token)
169 return expected
170
171 def _uri(expected, seq, token, tokenizer=None):
172
173 if expected.endswith('uri'):
174 uri = self._uritokenvalue(token)
175 new['uri'] = uri
176 seq.append(new['uri'], 'namespaceURI')
177 return ';'
178 else:
179 new['wellformed'] = False
180 self._log.error(
181 u'CSSNamespaceRule: Unexpected URI.', token)
182 return expected
183
184 def _char(expected, seq, token, tokenizer=None):
185
186 val = self._tokenvalue(token)
187 if ';' == expected and u';' == val:
188 return 'EOF'
189 else:
190 new['wellformed'] = False
191 self._log.error(
192 u'CSSNamespaceRule: Unexpected char.', token)
193 return expected
194
195
196 newseq = self._tempSeq()
197 wellformed, expected = self._parse(expected='prefix or uri',
198 seq=newseq, tokenizer=tokenizer,
199 productions={'IDENT': _ident,
200 'STRING': _string,
201 'URI': _uri,
202 'CHAR': _char})
203
204
205 wellformed = wellformed and new['wellformed']
206
207
208 if new['uri'] is None:
209 wellformed = False
210 self._log.error(u'CSSNamespaceRule: No namespace URI found: %s' %
211 self._valuestr(cssText))
212
213 if expected != 'EOF':
214 wellformed = False
215 self._log.error(u'CSSNamespaceRule: No ";" found: %s' %
216 self._valuestr(cssText))
217
218
219 if wellformed:
220 self.atkeyword = new['keyword']
221 self._prefix = new['prefix']
222 self.namespaceURI = new['uri']
223 self._setSeq(newseq)
224
225 cssText = property(fget=_getCssText, fset=_setCssText,
226 doc="(DOM attribute) The parsable textual representation.")
227
229 """
230 DOMException on setting
231
232 :param namespaceURI: the initial value for this rules namespaceURI
233 :Exceptions:
234 - `NO_MODIFICATION_ALLOWED_ERR`:
235 (CSSRule) Raised if this rule is readonly or a namespaceURI is
236 already set in this rule.
237 """
238 self._checkReadonly()
239 if not self._namespaceURI:
240
241 self._namespaceURI = namespaceURI
242 tempseq = self._tempSeq()
243 tempseq.append(namespaceURI, 'namespaceURI')
244 self._setSeq(tempseq)
245 elif self._namespaceURI != namespaceURI:
246 self._log.error(u'CSSNamespaceRule: namespaceURI is readonly.',
247 error=xml.dom.NoModificationAllowedErr)
248
249 namespaceURI = property(lambda self: self._namespaceURI, _setNamespaceURI,
250 doc="URI (string!) of the defined namespace.")
251
253 """
254 DOMException on setting
255
256 :param prefix: the new prefix
257 :Exceptions:
258 - `SYNTAX_ERR`: (TODO)
259 Raised if the specified CSS string value has a syntax error and
260 is unparsable.
261 - `NO_MODIFICATION_ALLOWED_ERR`: CSSRule)
262 Raised if this rule is readonly.
263 """
264 self._checkReadonly()
265 if not prefix:
266 prefix = u''
267 else:
268 tokenizer = self._tokenize2(prefix)
269 prefixtoken = self._nexttoken(tokenizer, None)
270 if not prefixtoken or self._type(prefixtoken) != self._prods.IDENT:
271 self._log.error(u'CSSNamespaceRule: No valid prefix "%s".' %
272 self._valuestr(prefix),
273 error=xml.dom.SyntaxErr)
274 return
275 else:
276 prefix = self._tokenvalue(prefixtoken)
277
278 for i, x in enumerate(self._seq):
279 if x == self._prefix:
280 self._seq[i] = (prefix, 'prefix', None, None)
281 break
282 else:
283
284 self._seq[0] = (prefix, 'prefix', None, None)
285
286
287 self._prefix = prefix
288
289 prefix = property(lambda self: self._prefix, _setPrefix,
290 doc="Prefix used for the defined namespace.")
291
294
295 parentStyleSheet = property(lambda self: self._parentStyleSheet,
296 _setParentStyleSheet,
297 doc=u"Containing CSSStyleSheet.")
298
299 wellformed = property(lambda self: self.namespaceURI is not None)
300
302 return "cssutils.css.%s(namespaceURI=%r, prefix=%r)" % (
303 self.__class__.__name__, self.namespaceURI, self.prefix)
304
306 return "<cssutils.css.%s object namespaceURI=%r prefix=%r at 0x%x>" % (
307 self.__class__.__name__, self.namespaceURI, self.prefix, id(self))
308