1 """CSSCharsetRule implements DOM Level 2 CSS CSSCharsetRule.
2
3 TODO:
4 - check specific allowed syntaxes
5 - check encoding syntax and not codecs.lookup?
6 """
7 __all__ = ['CSSCharsetRule']
8 __docformat__ = 'restructuredtext'
9 __author__ = '$LastChangedBy: cthedot $'
10 __date__ = '$LastChangedDate: 2008-01-27 17:28:41 +0100 (So, 27 Jan 2008) $'
11 __version__ = '$LastChangedRevision: 950 $'
12
13 import codecs
14 import xml.dom
15 import cssrule
16 import cssutils
17
19 """
20 The CSSCharsetRule interface represents an @charset rule in a CSS style
21 sheet. The value of the encoding attribute does not affect the encoding
22 of text data in the DOM objects; this encoding is always UTF-16
23 (also in Python?). After a stylesheet is loaded, the value of the
24 encoding attribute is the value found in the @charset rule. If there
25 was no @charset in the original document, then no CSSCharsetRule is
26 created. The value of the encoding attribute may also be used as a hint
27 for the encoding used on serialization of the style sheet.
28
29 The value of the @charset rule (and therefore of the CSSCharsetRule)
30 may not correspond to the encoding the document actually came in;
31 character encoding information e.g. in an HTTP header, has priority
32 (see CSS document representation) but this is not reflected in the
33 CSSCharsetRule.
34
35 Properties
36 ==========
37 cssText: of type DOMString
38 The parsable textual representation of this rule
39 encoding: of type DOMString
40 The encoding information used in this @charset rule.
41
42 Inherits properties from CSSRule
43
44 Format
45 ======
46 charsetrule:
47 CHARSET_SYM S* STRING S* ';'
48
49 BUT: Only valid format is:
50 @charset "ENCODING";
51 """
52 type = cssrule.CSSRule.CHARSET_RULE
53
54 - def __init__(self, encoding=None, parentRule=None,
55 parentStyleSheet=None, readonly=False):
71
73 """ returns encoding as a string """
74 return self._encoding
75
77 """
78 DOMException on setting
79
80 - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
81 Raised if this encoding rule is readonly.
82 - SYNTAX_ERR: (self)
83 Raised if the specified encoding value has a syntax error and
84 is unparsable.
85 Currently only valid Python encodings are allowed.
86 """
87 self._checkReadonly()
88 tokenizer = self._tokenize2(encoding)
89 encodingtoken = self._nexttoken(tokenizer)
90 unexpected = self._nexttoken(tokenizer)
91
92 valid = True
93 if not encodingtoken or unexpected or\
94 self._prods.IDENT != self._type(encodingtoken):
95 valid = False
96 self._log.error(
97 'CSSCharsetRule: Syntax Error in encoding value %r.' %
98 encoding)
99 else:
100 try:
101 codecs.lookup(encoding)
102 except LookupError:
103 valid = False
104 self._log.error('CSSCharsetRule: Unknown (Python) encoding %r.' %
105 encoding)
106 else:
107 self._encoding = encoding.lower()
108 self.valid = valid
109
110 encoding = property(_getEncoding, _setEncoding,
111 doc="(DOM)The encoding information used in this @charset rule.")
112
113
114 - def _getCssText(self):
115 """returns serialized property cssText"""
116 return cssutils.ser.do_CSSCharsetRule(self)
117
118 - def _setCssText(self, cssText):
119 """
120 DOMException on setting
121
122 - SYNTAX_ERR: (self)
123 Raised if the specified CSS string value has a syntax error and
124 is unparsable.
125 - INVALID_MODIFICATION_ERR: (self)
126 Raised if the specified CSS string value represents a different
127 type of rule than the current one.
128 - HIERARCHY_REQUEST_ERR: (CSSStylesheet)
129 Raised if the rule cannot be inserted at this point in the
130 style sheet.
131 - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
132 Raised if the rule is readonly.
133 """
134 super(CSSCharsetRule, self)._setCssText(cssText)
135
136 valid = True
137 tokenizer = self._tokenize2(cssText)
138
139 atkeyword = self._tokenvalue(self._nexttoken(tokenizer))
140 if u'@charset ' != atkeyword:
141 valid = False
142 self._log.error(u'CSSCharsetRule must start with "@charset "',
143 error=xml.dom.InvalidModificationErr)
144
145 encodingtoken = self._nexttoken(tokenizer)
146 encodingtype, encoding = self._type(encodingtoken), self._tokenvalue(
147 encodingtoken)
148 if 'STRING' != encodingtype or len(encoding) < 3:
149 valid = False
150 self._log.error(u'CSSCharsetRule: no encoding found.')
151 else:
152 encoding = encoding[1:-1]
153
154 semicolon = self._tokenvalue(self._nexttoken(tokenizer))
155 EOFtype = self._type(self._nexttoken(tokenizer))
156 if u';' != semicolon or (EOFtype and 'EOF' != EOFtype):
157 valid = False
158 self._log.error(u'CSSCharsetRule: Syntax Error: %r.' %
159 self._valuestr(cssText))
160
161 self.valid = valid
162 if valid:
163 self.encoding = encoding
164
165 cssText = property(fget=_getCssText, fset=_setCssText,
166 doc="(DOM) The parsable textual representation.")
167
169 return "cssutils.css.%s(encoding=%r)" % (
170 self.__class__.__name__, self.encoding)
171
173 return "<cssutils.css.%s object encoding=%r at 0x%x>" % (
174 self.__class__.__name__, self.encoding, id(self))
175