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