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