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