1 """CSSImportRule implements DOM Level 2 CSS CSSImportRule.
2
3 TODO:
4 - stylesheet: read and parse linked stylesheet
5 """
6 __all__ = ['CSSImportRule']
7 __docformat__ = 'restructuredtext'
8 __author__ = '$LastChangedBy: cthedot $'
9 __date__ = '$LastChangedDate: 2008-01-27 17:28:41 +0100 (So, 27 Jan 2008) $'
10 __version__ = '$LastChangedRevision: 950 $'
11
12 import xml.dom
13 import cssrule
14 import cssutils
15
17 """
18 Represents an @import rule within a CSS style sheet. The @import rule
19 is used to import style rules from other style sheets.
20
21 Properties
22 ==========
23 cssText: of type DOMString
24 The parsable textual representation of this rule
25 href: of type DOMString, (DOM readonly, cssutils also writable)
26 The location of the style sheet to be imported. The attribute will
27 not contain the url(...) specifier around the URI.
28 media: of type stylesheets::MediaList (DOM readonly)
29 A list of media types for this rule of type MediaList.
30 stylesheet: of type CSSStyleSheet (DOM readonly)
31 The style sheet referred to by this rule. The value of this
32 attribute is None if the style sheet has not yet been loaded or if
33 it will not be loaded (e.g. if the stylesheet is for a media type
34 not supported by the user agent).
35
36 Currently always None
37
38 cssutils only
39 -------------
40 atkeyword:
41 the literal keyword used
42 hreftype: 'uri' (serializer default) or 'string'
43 The original usage of href, not really relevant as it may be
44 configured in the serializer too
45
46 Inherits properties from CSSRule
47
48 Format
49 ======
50 import
51 : IMPORT_SYM S*
52 [STRING|URI] S* [ medium [ COMMA S* medium]* ]? ';' S*
53 ;
54 """
55 type = cssrule.CSSRule.IMPORT_RULE
56
57 - def __init__(self, href=None, mediaText=u'all', hreftype=None,
58 parentRule=None, parentStyleSheet=None, readonly=False):
88
91
93
94 for i, x in enumerate(self.seq):
95 if x == self._href:
96 self.seq[i] = href
97 break
98 else:
99 self.seq = [href]
100
101 self._href = href
102
103 href = property(_getHref, _setHref,
104 doc="Location of the style sheet to be imported.")
105
109
110 media = property(_getMedia,
111 doc=u"(DOM readonly) A list of media types for this rule of type\
112 MediaList")
113
115 """
116 returns a CSSStyleSheet or None
117 """
118 return self._styleSheet
119
120 styleSheet = property(_getStyleSheet,
121 doc="(readonly) The style sheet referred to by this rule.")
122
123 - def _getCssText(self):
124 """
125 returns serialized property cssText
126 """
127 return cssutils.ser.do_CSSImportRule(self)
128
129 - def _setCssText(self, cssText):
130 """
131 DOMException on setting
132
133 - HIERARCHY_REQUEST_ERR: (CSSStylesheet)
134 Raised if the rule cannot be inserted at this point in the
135 style sheet.
136 - INVALID_MODIFICATION_ERR: (self)
137 Raised if the specified CSS string value represents a different
138 type of rule than the current one.
139 - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
140 Raised if the rule is readonly.
141 - SYNTAX_ERR: (self)
142 Raised if the specified CSS string value has a syntax error and
143 is unparsable.
144 """
145 super(CSSImportRule, self)._setCssText(cssText)
146 tokenizer = self._tokenize2(cssText)
147 attoken = self._nexttoken(tokenizer, None)
148 if not attoken or self._type(attoken) != self._prods.IMPORT_SYM:
149 self._log.error(u'CSSImportRule: No CSSImportRule found: %s' %
150 self._valuestr(cssText),
151 error=xml.dom.InvalidModificationErr)
152 else:
153
154 new = {
155 'keyword': self._tokenvalue(attoken),
156 'href': None,
157 'hreftype': None,
158 'media': cssutils.stylesheets.MediaList(),
159 'wellformed': True
160 }
161
162 def _string(expected, seq, token, tokenizer=None):
163
164 if 'href' == expected:
165 new['hreftype'] = 'string'
166 new['href'] = self._tokenvalue(token)[1:-1]
167 seq.append(new['href'])
168 return 'media or ;'
169 else:
170 new['wellformed'] = False
171 self._log.error(
172 u'CSSImportRule: Unexpected string.', token)
173 return expected
174
175 def _uri(expected, seq, token, tokenizer=None):
176
177 if 'href' == expected:
178 new['hreftype'] = 'uri'
179 uri = self._tokenvalue(token)[4:-1].strip()
180 if uri[0] == uri[-1] == '"' or\
181 uri[0] == uri[-1] == "'":
182 uri = uri[1:-1]
183 new['href'] = uri
184 seq.append(new['href'])
185 return 'media or ;'
186 else:
187 new['wellformed'] = False
188 self._log.error(
189 u'CSSImportRule: Unexpected URI.', token)
190 return expected
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214 def _ident(expected, seq, token, tokenizer=None):
215
216 if expected.startswith('media'):
217 mediatokens = self._tokensupto2(
218 tokenizer, semicolon=True, keepEnd=True)
219 mediatokens.insert(0, token)
220
221 semicolonOrEOF = mediatokens.pop()
222 if self._tokenvalue(semicolonOrEOF) != u';' and\
223 self._type(semicolonOrEOF) != 'EOF':
224 new['wellformed'] = False
225 self._log.error(u'CSSImportRule: No ";" found: %s' %
226 self._valuestr(cssText), token=token)
227
228 media = cssutils.stylesheets.MediaList()
229 media.mediaText = mediatokens
230 if media.valid:
231 new['media'] = media
232 seq.append(media)
233 else:
234 new['wellformed'] = False
235 self._log.error(u'CSSImportRule: Invalid MediaList: %s' %
236 self._valuestr(cssText), token=token)
237 return 'EOF'
238 else:
239 new['wellformed'] = False
240 self._log.error(
241 u'CSSImportRule: Unexpected ident.', token)
242 return expected
243
244 def _char(expected, seq, token, tokenizer=None):
245
246 val = self._tokenvalue(token)
247 if expected.endswith(';') and u';' == val:
248 return 'EOF'
249 else:
250 new['wellformed'] = False
251 self._log.error(
252 u'CSSImportRule: Unexpected char.', token)
253 return expected
254
255
256
257 newseq = []
258 wellformed, expected = self._parse(expected='href',
259 seq=newseq, tokenizer=tokenizer,
260 productions={'STRING': _string,
261 'URI': _uri,
262
263 'IDENT': _ident,
264 'CHAR': _char})
265
266
267 wellformed = wellformed and new['wellformed']
268
269
270 if not new['href']:
271 wellformed = False
272 self._log.error(u'CSSImportRule: No href found: %s' %
273 self._valuestr(cssText))
274
275 if expected != 'EOF':
276 wellformed = False
277 self._log.error(u'CSSImportRule: No ";" found: %s' %
278 self._valuestr(cssText))
279
280
281 if wellformed:
282 self.valid = True
283 self.atkeyword = new['keyword']
284 self.href = new['href']
285 self.hreftype = new['hreftype']
286 self._media = new['media']
287 self.seq = newseq
288
289 cssText = property(fget=_getCssText, fset=_setCssText,
290 doc="(DOM attribute) The parsable textual representation.")
291
293 return "cssutils.css.%s(href=%r, mediaText=%r)" % (
294 self.__class__.__name__, self.href, self.media.mediaText)
295
297 return "<cssutils.css.%s object href=%r at 0x%x>" % (
298 self.__class__.__name__, self.href, id(self))
299