1 """CSSPageRule implements DOM Level 2 CSS CSSPageRule.
2 """
3 __all__ = ['CSSPageRule']
4 __docformat__ = 'restructuredtext'
5 __author__ = '$LastChangedBy: cthedot $'
6 __date__ = '$LastChangedDate: 2008-02-19 22:56:27 +0100 (Di, 19 Feb 2008) $'
7 __version__ = '$LastChangedRevision: 1068 $'
8
9 import xml.dom
10 import cssrule
11 import cssutils
12 from selectorlist import SelectorList
13 from cssstyledeclaration import CSSStyleDeclaration
14
16 """
17 The CSSPageRule interface represents a @page rule within a CSS style
18 sheet. The @page rule is used to specify the dimensions, orientation,
19 margins, etc. of a page box for paged media.
20
21 Properties
22 ==========
23 atkeyword (cssutils only)
24 the literal keyword used
25 cssText: of type DOMString
26 The parsable textual representation of this rule
27 selectorText: of type DOMString
28 The parsable textual representation of the page selector for the rule.
29 style: of type CSSStyleDeclaration
30 The declaration-block of this rule.
31
32 Inherits properties from CSSRule
33
34 Format
35 ======
36 ::
37
38 page
39 : PAGE_SYM S* pseudo_page? S*
40 LBRACE S* declaration [ ';' S* declaration ]* '}' S*
41 ;
42 pseudo_page
43 : ':' IDENT # :first, :left, :right in CSS 2.1
44 ;
45
46 """
47 type = cssrule.CSSRule.PAGE_RULE
48
49 wellformed = True
50
53 """
54 if readonly allows setting of properties in constructor only
55
56 selectorText
57 type string
58 style
59 CSSStyleDeclaration for this CSSStyleRule
60 """
61 super(CSSPageRule, self).__init__(parentRule=parentRule,
62 parentStyleSheet=parentStyleSheet)
63 self.atkeyword = u'@page'
64 tempseq = self._tempSeq()
65 if selectorText:
66 self.selectorText = selectorText
67 tempseq.append(self.selectorText, 'selectorText')
68 else:
69 self._selectorText = u''
70 if style:
71 self.style = style
72 tempseq.append(self.style, 'style')
73 else:
74 self._style = CSSStyleDeclaration(parentRule=self)
75 self._setSeq(tempseq)
76
77 self._readonly = readonly
78
80 """
81 parses selectorText which may also be a list of tokens
82 and returns (selectorText, seq)
83
84 see _setSelectorText for details
85 """
86
87 new = {'selector': None, 'wellformed': True}
88
89 def _char(expected, seq, token, tokenizer=None):
90
91 val = self._tokenvalue(token)
92 if ':' == expected and u':' == val:
93 try:
94 identtoken = tokenizer.next()
95 except StopIteration:
96 self._log.error(
97 u'CSSPageRule selectorText: No IDENT found.', token)
98 else:
99 ival, ityp = self._tokenvalue(identtoken), self._type(identtoken)
100 if self._prods.IDENT != ityp:
101 self._log.error(
102 u'CSSPageRule selectorText: Expected IDENT but found: %r' %
103 ival, token)
104 else:
105 new['selector'] = val + ival
106 seq.append(new['selector'], 'selector')
107 return 'EOF'
108 return expected
109 else:
110 new['wellformed'] = False
111 self._log.error(
112 u'CSSPageRule selectorText: Unexpected CHAR: %r' % val, token)
113 return expected
114
115 newseq = self._tempSeq()
116 wellformed, expected = self._parse(expected=':',
117 seq=newseq, tokenizer=self._tokenize2(selectorText),
118 productions={'CHAR': _char},
119 new=new)
120 wellformed = wellformed and new['wellformed']
121 newselector = new['selector']
122
123
124 if expected == 'ident':
125 self._log.error(
126 u'CSSPageRule selectorText: No valid selector: %r' %
127 self._valuestr(selectorText))
128
129 if not newselector in (None, u':first', u':left', u':right'):
130 self._log.warn(u'CSSPageRule: Unknown CSS 2.1 @page selector: %r' %
131 newselector, neverraise=True)
132
133 return newselector, newseq
134
136 """
137 returns serialized property cssText
138 """
139 return cssutils.ser.do_CSSPageRule(self)
140
142 """
143 DOMException on setting
144
145 - SYNTAX_ERR: (self, StyleDeclaration)
146 Raised if the specified CSS string value has a syntax error and
147 is unparsable.
148 - INVALID_MODIFICATION_ERR: (self)
149 Raised if the specified CSS string value represents a different
150 type of rule than the current one.
151 - HIERARCHY_REQUEST_ERR: (CSSStylesheet)
152 Raised if the rule cannot be inserted at this point in the
153 style sheet.
154 - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
155 Raised if the rule is readonly.
156 """
157 super(CSSPageRule, self)._setCssText(cssText)
158
159 tokenizer = self._tokenize2(cssText)
160 if self._type(self._nexttoken(tokenizer)) != self._prods.PAGE_SYM:
161 self._log.error(u'CSSPageRule: No CSSPageRule found: %s' %
162 self._valuestr(cssText),
163 error=xml.dom.InvalidModificationErr)
164 else:
165 wellformed = True
166 selectortokens, startbrace = self._tokensupto2(tokenizer,
167 blockstartonly=True,
168 separateEnd=True)
169 styletokens, braceorEOFtoken = self._tokensupto2(tokenizer,
170 blockendonly=True,
171 separateEnd=True)
172
173 if self._tokenvalue(startbrace) != u'{':
174 wellformed = False
175 self._log.error(
176 u'CSSPageRule: No start { of style declaration found: %r' %
177 self._valuestr(cssText), startbrace)
178
179 newselector, newselectorseq = self.__parseSelectorText(selectortokens)
180
181 newstyle = CSSStyleDeclaration()
182 val, typ = self._tokenvalue(braceorEOFtoken), self._type(braceorEOFtoken)
183 if val != u'}' and typ != 'EOF':
184 wellformed = False
185 self._log.error(
186 u'CSSPageRule: No "}" after style declaration found: %r' %
187 self._valuestr(cssText))
188 else:
189 if 'EOF' == typ:
190
191 styletokens.append(braceorEOFtoken)
192 newstyle.cssText = styletokens
193
194 if wellformed:
195 self._selectorText = newselector
196 self.style = newstyle
197 self._setSeq(newselectorseq)
198
199 cssText = property(_getCssText, _setCssText,
200 doc="(DOM) The parsable textual representation of the rule.")
201
203 """
204 wrapper for cssutils Selector object
205 """
206 return self._selectorText
207
209 """
210 wrapper for cssutils Selector object
211
212 selector: DOM String
213 in CSS 2.1 one of
214 - :first
215 - :left
216 - :right
217 - empty
218
219 If WS or Comments are included they are ignored here! Only
220 way to add a comment is via setting ``cssText``
221
222 DOMException on setting
223
224 - SYNTAX_ERR:
225 Raised if the specified CSS string value has a syntax error
226 and is unparsable.
227 - NO_MODIFICATION_ALLOWED_ERR: (self)
228 Raised if this rule is readonly.
229 """
230 self._checkReadonly()
231
232
233 newselectortext, newseq = self.__parseSelectorText(selectorText)
234
235 if newselectortext:
236 for i, x in enumerate(self.seq):
237 if x == self._selectorText:
238 self.seq[i] = newselectortext
239 self._selectorText = newselectortext
240
241 selectorText = property(_getSelectorText, _setSelectorText,
242 doc="""(DOM) The parsable textual representation of the page selector for the rule.""")
243
245
246 return self._style
247
249 """
250 style
251 StyleDeclaration or string
252 """
253 self._checkReadonly()
254
255 if isinstance(style, basestring):
256 self._style.cssText = style
257 else:
258
259
260 self._style.seq = style.seq
261
262 style = property(_getStyle, _setStyle,
263 doc="(DOM) The declaration-block of this rule set.")
264
266 return "cssutils.css.%s(selectorText=%r, style=%r)" % (
267 self.__class__.__name__, self.selectorText, self.style.cssText)
268
270 return "<cssutils.css.%s object selectorText=%r style=%r at 0x%x>" % (
271 self.__class__.__name__, self.selectorText, self.style.cssText,
272 id(self))
273