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 1116 2008-03-05 13:52:23Z 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 = cssrule.CSSRule.CHARSET_RULE
50
51 - def __init__(self, encoding=None, parentRule=None,
52 parentStyleSheet=None, readonly=False):
68
69 - def _getCssText(self):
70 """returns serialized property cssText"""
71 return cssutils.ser.do_CSSCharsetRule(self)
72
73 - def _setCssText(self, cssText):
74 """
75 DOMException on setting
76
77 - SYNTAX_ERR: (self)
78 Raised if the specified CSS string value has a syntax error and
79 is unparsable.
80 - INVALID_MODIFICATION_ERR: (self)
81 Raised if the specified CSS string value represents a different
82 type of rule than the current one.
83 - HIERARCHY_REQUEST_ERR: (CSSStylesheet)
84 Raised if the rule cannot be inserted at this point in the
85 style sheet.
86 - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
87 Raised if the rule is readonly.
88 """
89 super(CSSCharsetRule, self)._setCssText(cssText)
90
91 wellformed = True
92 tokenizer = self._tokenize2(cssText)
93
94 if self._type(self._nexttoken(tokenizer)) != self._prods.CHARSET_SYM:
95 wellformed = False
96 self._log.error(u'CSSCharsetRule must start with "@charset "',
97 error=xml.dom.InvalidModificationErr)
98
99 encodingtoken = self._nexttoken(tokenizer)
100 encodingtype = self._type(encodingtoken)
101 encoding = self._stringtokenvalue(encodingtoken)
102 if self._prods.STRING != encodingtype or not encoding:
103 wellformed = False
104 self._log.error(u'CSSCharsetRule: no encoding found; %r.' %
105 self._valuestr(cssText))
106
107 semicolon = self._tokenvalue(self._nexttoken(tokenizer))
108 EOFtype = self._type(self._nexttoken(tokenizer))
109 if u';' != semicolon or EOFtype not in ('EOF', None):
110 wellformed = False
111 self._log.error(u'CSSCharsetRule: Syntax Error: %r.' %
112 self._valuestr(cssText))
113
114 if wellformed:
115 self.encoding = encoding
116
117 cssText = property(fget=_getCssText, fset=_setCssText,
118 doc="(DOM) The parsable textual representation.")
119
121 """
122 DOMException on setting
123
124 - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
125 Raised if this encoding rule is readonly.
126 - SYNTAX_ERR: (self)
127 Raised if the specified encoding value has a syntax error and
128 is unparsable.
129 Currently only valid Python encodings are allowed.
130 """
131 self._checkReadonly()
132 tokenizer = self._tokenize2(encoding)
133 encodingtoken = self._nexttoken(tokenizer)
134 unexpected = self._nexttoken(tokenizer)
135
136 valid = True
137 if not encodingtoken or unexpected or\
138 self._prods.IDENT != self._type(encodingtoken):
139 valid = False
140 self._log.error(
141 'CSSCharsetRule: Syntax Error in encoding value %r.' %
142 encoding)
143 else:
144 try:
145 codecs.lookup(encoding)
146 except LookupError:
147 valid = False
148 self._log.error('CSSCharsetRule: Unknown (Python) encoding %r.' %
149 encoding)
150 else:
151 self._encoding = encoding.lower()
152
153 encoding = property(lambda self: self._encoding, _setEncoding,
154 doc="(DOM)The encoding information used in this @charset rule.")
155
156 wellformed = property(lambda self: bool(self.encoding))
157
159 return "cssutils.css.%s(encoding=%r)" % (
160 self.__class__.__name__, self.encoding)
161
163 return "<cssutils.css.%s object encoding=%r at 0x%x>" % (
164 self.__class__.__name__, self.encoding, id(self))
165