1 """CSSUnknownRule implements DOM Level 2 CSS CSSUnknownRule.
2 """
3 __all__ = ['CSSUnknownRule']
4 __docformat__ = 'restructuredtext'
5 __version__ = '$Id: cssunknownrule.py 1170 2008-03-20 17:42:07Z cthedot $'
6
7 import xml.dom
8 import cssrule
9 import cssutils
10
12 """
13 represents an at-rule not supported by this user agent.
14
15 Properties
16 ==========
17 inherited from CSSRule
18 - cssText
19 - type
20
21 cssutils only
22 -------------
23 atkeyword
24 the literal keyword used
25 seq
26 All parts of this rule excluding @KEYWORD but including CSSComments
27 wellformed
28 if this Rule is wellformed, for Unknown rules if an atkeyword is set
29 at all
30
31 Format
32 ======
33 unknownrule:
34 @xxx until ';' or block {...}
35 """
36 type = property(lambda self: cssrule.CSSRule.UNKNOWN_RULE)
37
38 - def __init__(self, cssText=u'', parentRule=None,
39 parentStyleSheet=None, readonly=False):
51
52 - def _getCssText(self):
53 """ returns serialized property cssText """
54 return cssutils.ser.do_CSSUnknownRule(self)
55
56 - def _setCssText(self, cssText):
57 """
58 DOMException on setting
59
60 - SYNTAX_ERR:
61 Raised if the specified CSS string value has a syntax error and
62 is unparsable.
63 - INVALID_MODIFICATION_ERR:
64 Raised if the specified CSS string value represents a different
65 type of rule than the current one.
66 - HIERARCHY_REQUEST_ERR: (never raised)
67 Raised if the rule cannot be inserted at this point in the
68 style sheet.
69 - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
70 Raised if the rule is readonly.
71 """
72 super(CSSUnknownRule, self)._setCssText(cssText)
73 tokenizer = self._tokenize2(cssText)
74 attoken = self._nexttoken(tokenizer, None)
75 if not attoken or self._type(attoken) != self._prods.ATKEYWORD:
76 self._log.error(u'CSSUnknownRule: No CSSUnknownRule found: %s' %
77 self._valuestr(cssText),
78 error=xml.dom.InvalidModificationErr)
79 else:
80
81 new = {'nesting': [],
82 'wellformed': True
83 }
84
85 def CHAR(expected, seq, token, tokenizer=None):
86 type_, val, line, col = token
87 if expected != 'EOF':
88 if val in u'{[(':
89 new['nesting'].append(val)
90 elif val in u'}])':
91 opening = {u'}': u'{', u']': u'[', u')': u'('}[val]
92 try:
93 if new['nesting'][-1] == opening:
94 new['nesting'].pop()
95 else:
96 raise IndexError()
97 except IndexError:
98 new['wellformed'] = False
99 self._log.error(u'CSSUnknownRule: Wrong nesting of {, [ or (.',
100 token=token)
101
102 if val in u'};' and not new['nesting']:
103 expected = 'EOF'
104
105 seq.append(val, type_, line=line, col=col)
106 return expected
107 else:
108 new['wellformed'] = False
109 self._log.error(u'CSSUnknownRule: Expected end of rule.',
110 token=token)
111 return expected
112
113 def EOF(expected, seq, token, tokenizer=None):
114 "close all blocks and return 'EOF'"
115 for x in reversed(new['nesting']):
116 closing = {u'{': u'}', u'[': u']', u'(': u')'}[x]
117 seq.append(closing, closing)
118 new['nesting'] = []
119 return 'EOF'
120
121 def INVALID(expected, seq, token, tokenizer=None):
122
123 self._log.error(u'CSSUnknownRule: Bad syntax.',
124 token=token, error=xml.dom.SyntaxErr)
125 new['wellformed'] = False
126 return expected
127
128 def STRING(expected, seq, token, tokenizer=None):
129 type_, val, line, col = token
130 val = self._stringtokenvalue(token)
131 if expected != 'EOF':
132 seq.append(val, type_, line=line, col=col)
133 return expected
134 else:
135 new['wellformed'] = False
136 self._log.error(u'CSSUnknownRule: Expected end of rule.',
137 token=token)
138 return expected
139
140 def URI(expected, seq, token, tokenizer=None):
141 type_, val, line, col = token
142 val = self._uritokenvalue(token)
143 if expected != 'EOF':
144 seq.append(val, type_, line=line, col=col)
145 return expected
146 else:
147 new['wellformed'] = False
148 self._log.error(u'CSSUnknownRule: Expected end of rule.',
149 token=token)
150 return expected
151
152 def default(expected, seq, token, tokenizer=None):
153 type_, val, line, col = token
154 if expected != 'EOF':
155 seq.append(val, type_, line=line, col=col)
156 return expected
157 else:
158 new['wellformed'] = False
159 self._log.error(u'CSSUnknownRule: Expected end of rule.',
160 token=token)
161 return expected
162
163
164 newseq = self._tempSeq()
165 wellformed, expected = self._parse(expected=None,
166 seq=newseq, tokenizer=tokenizer,
167 productions={'CHAR': CHAR,
168 'EOF': EOF,
169 'INVALID': INVALID,
170 'STRING': STRING,
171 'URI': URI,
172 'S': default
173 },
174 default=default,
175 new=new)
176
177
178 wellformed = wellformed and new['wellformed']
179
180
181 if expected != 'EOF':
182 wellformed = False
183 self._log.error(
184 u'CSSUnknownRule: No ending ";" or "}" found: %r' %
185 self._valuestr(cssText))
186 elif new['nesting']:
187 wellformed = False
188 self._log.error(
189 u'CSSUnknownRule: Unclosed "{", "[" or "(": %r' %
190 self._valuestr(cssText))
191
192
193 if wellformed:
194 self.atkeyword = self._tokenvalue(attoken)
195 self._setSeq(newseq)
196
197 cssText = property(fget=_getCssText, fset=_setCssText,
198 doc="(DOM) The parsable textual representation.")
199
200 wellformed = property(lambda self: bool(self.atkeyword))
201
203 return "cssutils.css.%s(cssText=%r)" % (
204 self.__class__.__name__, self.cssText)
205
207 return "<cssutils.css.%s object cssText=%r at 0x%x>" % (
208 self.__class__.__name__, self.cssText, id(self))
209