Package cssutils :: Package css :: Module csspagerule
[hide private]
[frames] | no frames]

Source Code for Module cssutils.css.csspagerule

  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   
15 -class CSSPageRule(cssrule.CSSRule):
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 # constant but needed: 49 wellformed = True 50
51 - def __init__(self, selectorText=None, style=None, parentRule=None, 52 parentStyleSheet=None, readonly=False):
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
79 - def __parseSelectorText(self, selectorText):
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 # for closures: must be a mutable 87 new = {'selector': None, 'wellformed': True} 88 89 def _char(expected, seq, token, tokenizer=None): 90 # pseudo_page, :left, :right or :first 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 # post conditions 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
135 - def _getCssText(self):
136 """ 137 returns serialized property cssText 138 """ 139 return cssutils.ser.do_CSSPageRule(self)
140
141 - def _setCssText(self, cssText):
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 # add again as style needs it 191 styletokens.append(braceorEOFtoken) 192 newstyle.cssText = styletokens 193 194 if wellformed: 195 self._selectorText = newselector # already parsed 196 self.style = newstyle 197 self._setSeq(newselectorseq) # contains upto style only
198 199 cssText = property(_getCssText, _setCssText, 200 doc="(DOM) The parsable textual representation of the rule.") 201
202 - def _getSelectorText(self):
203 """ 204 wrapper for cssutils Selector object 205 """ 206 return self._selectorText
207
208 - def _setSelectorText(self, selectorText):
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 # may raise SYNTAX_ERR 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
244 - def _getStyle(self):
245 246 return self._style
247
248 - def _setStyle(self, style):
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 # cssText would be serialized with optional preferences 259 # so use seq! 260 self._style.seq = style.seq
261 262 style = property(_getStyle, _setStyle, 263 doc="(DOM) The declaration-block of this rule set.") 264
265 - def __repr__(self):
266 return "cssutils.css.%s(selectorText=%r, style=%r)" % ( 267 self.__class__.__name__, self.selectorText, self.style.cssText)
268
269 - def __str__(self):
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