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: 2007-08-20 22:07:12 +0200 (Mo, 20 Aug 2007) $'
10 __version__ = '$LastChangedRevision: 257 $'
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 readonly=False):
59 """
60 if readonly allows setting of properties in constructor only
61
62 Do not use as positional but as keyword attributes only!
63
64 href
65 location of the style sheet to be imported.
66 mediaText
67 A list of media types for which this style sheet may be used
68 as a string
69 hreftype
70 'uri' (default) or 'string'
71 """
72 super(CSSImportRule, self).__init__()
73
74 self.atkeyword = u'@import'
75 self.href = href
76 self.hreftype = hreftype
77 self._media = cssutils.stylesheets.MediaList(
78 mediaText, readonly=readonly)
79 if not self.media.valid:
80 self._media = cssutils.stylesheets.MediaList()
81 self.seq = [self.href, self.media]
82
83
84 self._styleSheet = None
85
86 self._readonly = readonly
87
88
90 """ returns href as a string """
91 return self._href
92
94 """
95 TODO:
96 parse properly
97
98 DOMException on setting
99
100 - SYNTAX_ERR: (not checked here)
101 Raised if the specified CSS string value has a syntax error and
102 is unparsable.
103 - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
104 Raised if this rule is readonly.
105 """
106 self._checkReadonly()
107
108
109 for i, x in enumerate(self.seq):
110 if x == self._href:
111 self.seq[i] = href
112 break
113 else:
114 self.seq = [href]
115
116 self._href = href
117
118 href = property(_getHref, _setHref,
119 doc="Location of the style sheet to be imported.")
120
121
125
126 media = property(_getMedia,
127 doc=u"(DOM readonly) A list of media types for this rule of type\
128 MediaList")
129
130
132 """
133 returns a CSSStyleSheet or None
134 """
135 return self._styleSheet
136
137 styleSheet = property(_getStyleSheet,
138 doc="(readonly) The style sheet referred to by this rule.")
139
140
141 - def _getCssText(self):
142 """
143 returns serialized property cssText
144 """
145 return cssutils.ser.do_CSSImportRule(self)
146
147 - def _setCssText(self, cssText):
148 """
149 DOMException on setting
150
151 - HIERARCHY_REQUEST_ERR: (CSSStylesheet)
152 Raised if the rule cannot be inserted at this point in the
153 style sheet.
154 - INVALID_MODIFICATION_ERR: (self)
155 Raised if the specified CSS string value represents a different
156 type of rule than the current one.
157 - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
158 Raised if the rule is readonly.
159 - SYNTAX_ERR: (self)
160 Raised if the specified CSS string value has a syntax error and
161 is unparsable.
162 """
163 super(CSSImportRule, self)._setCssText(cssText)
164 valid = True
165
166 tokens = self._tokenize(cssText)
167
168
169 if not tokens or tokens and tokens[0].type != self._ttypes.IMPORT_SYM:
170 self._log.error(u'CSSImportRule: No CSSImportRule found: %s' %
171 self._valuestr(cssText),
172 error=xml.dom.InvalidModificationErr)
173 return
174 else:
175 newatkeyword = tokens[0].value
176
177 newseq = []
178 newhref = None
179 newhreftype = None
180 newmedia = cssutils.stylesheets.MediaList()
181
182 mediatokens = []
183 expected = 'href'
184 for i in range(1, len(tokens)):
185 t = tokens[i]
186
187 if self._ttypes.EOF == t.type:
188 expected = 'EOF'
189
190 elif self._ttypes.S == t.type:
191 pass
192
193 elif self._ttypes.COMMENT == t.type:
194 if 'href' == expected:
195 newseq.append(cssutils.css.CSSComment(t))
196 else:
197 mediatokens.append(t)
198
199 elif 'href' == expected and \
200 t.type in (self._ttypes.URI, self._ttypes.STRING):
201 if t.type == self._ttypes.URI:
202 newhref = t.value[4:-1].strip()
203 newhreftype = 'uri'
204 else:
205 newhref = t.value[1:-1].strip()
206 newhreftype = 'string'
207 newseq.append(newhref)
208 expected = 'medialist'
209
210 elif self._ttypes.SEMICOLON == t.type:
211 if 'medialist' != expected:
212 valid = False
213 self._log.error(
214 u'CSSImportRule: Syntax Error, no href found.', t)
215 expected = None
216 break
217
218 elif 'medialist' == expected:
219 mediatokens.append(t)
220
221 else:
222 valid = False
223 self._log.error(u'CSSImportRule: Syntax Error.', t)
224
225 if expected and expected != 'EOF':
226 valid = False
227 self._log.error(u'CSSImportRule: Syntax Error, no ";" found: %s' %
228 self._valuestr(cssText))
229 return
230
231 if mediatokens:
232 newmedia.mediaText = mediatokens
233 if not newmedia.valid:
234 valid = False
235 newseq.append(newmedia)
236
237 if valid:
238 self.atkeyword = newatkeyword
239 self.href = newhref
240 self.hreftype = newhreftype
241 self._media = newmedia
242 self.seq = newseq
243
244 cssText = property(fget=_getCssText, fset=_setCssText,
245 doc="(DOM attribute) The parsable textual representation.")
246
248 return "cssutils.css.%s(href=%r, mediaText=%r)" % (
249 self.__class__.__name__, self.href, self.media.mediaText)
250
252 return "<cssutils.css.%s object href=%r at 0x%x>" % (
253 self.__class__.__name__, self.href, id(self))
254
255 if __name__ == '__main__':
256 c = CSSImportRule(href='"1.css"', mediaText='handheld, all, tv')
257 print c.seq
258 print c.cssText
259 c.cssText = '@import'
260