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