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

# Source Code for Module cssutils.css.cssstylerule

      1  """CSSStyleRule implements DOM Level 2 CSS CSSStyleRule.
      2  """
      3  __all__ = ['CSSStyleRule']
      4  __docformat__ = 'restructuredtext'
      5  __author__ = '$LastChangedBy: cthedot $'
      6  __date__ = '$LastChangedDate: 2008-02-12 23:43:05 +0100 (Di, 12 Feb 2008) $'
      7  __version__ = '$LastChangedRevision: 1049 $'
      8
      9  import xml.dom
     10  import cssrule
     11  import cssutils
     12  from selectorlist import SelectorList
     13  from cssstyledeclaration import CSSStyleDeclaration
     14
     15 -class CSSStyleRule(cssrule.CSSRule):
     16      """
     17      The CSSStyleRule object represents a ruleset specified (if any) in a CSS
     18      style sheet. It provides access to a declaration block as well as to the
     19      associated group of selectors.
     20
     21      Properties
     22      ==========
     23      selectorList: of type SelectorList (cssutils only)
     24          A list of all Selector elements for the rule set.
     25      selectorText: of type DOMString
     26          The textual representation of the selector for the rule set. The
     27          implementation may have stripped out insignificant whitespace while
     28          parsing the selector.
     29      style: of type CSSStyleDeclaration, (DOM)
     30          The declaration-block of this rule set.
     31      type
     32          the type of this rule, constant cssutils.CSSRule.STYLE_RULE
     33
     34      inherited properties:
     35          - cssText
     36          - parentRule
     37          - parentStyleSheet
     38
     39      Format
     40      ======
     41      ruleset::
     42
     43          : selector [ COMMA S* selector ]*
     44          LBRACE S* declaration [ ';' S* declaration ]* '}' S*
     45          ;
     46      """
     47      type = cssrule.CSSRule.STYLE_RULE
     48
     49 -    def __init__(self, selectorText=None, style=None, parentRule=None,
     50                   parentStyleSheet=None, readonly=False):
     51          """
     52          :Parameters:
     53              selectorText
     54                  string parsed into selectorList
     55              style
     56                  string parsed into CSSStyleDeclaration for this CSSStyleRule
     57              readonly
     58                  if True allows setting of properties in constructor only
     59          """
     60          super(CSSStyleRule, self).__init__(parentRule=parentRule,
     61                                             parentStyleSheet=parentStyleSheet)
     62
     63          self._selectorList = SelectorList(parentRule=self)
     64          self._style = CSSStyleDeclaration(parentRule=self)
     65          if selectorText:
     66              self.selectorText = selectorText
     67          if style:
     68              self.style = style
     69
     70          self._readonly = readonly
     71
     72
     73 -    def _getCssText(self):
     74          """
     75          returns serialized property cssText
     76          """
     77          return cssutils.ser.do_CSSStyleRule(self)
     78
     79 -    def _setCssText(self, cssText):
     80          """
     81          :param cssText:
     82              a parseable string or a tuple of (cssText, dict-of-namespaces)
     83          :Exceptions:
     84              - `NAMESPACE_ERR`: (Selector)
     85                Raised if the specified selector uses an unknown namespace
     86                prefix.
     87              - `SYNTAX_ERR`: (self, StyleDeclaration, etc)
     88                Raised if the specified CSS string value has a syntax error and
     89                is unparsable.
     90              - `INVALID_MODIFICATION_ERR`: (self)
     91                Raised if the specified CSS string value represents a different
     92                type of rule than the current one.
     93              - `HIERARCHY_REQUEST_ERR`: (CSSStylesheet)
     94                Raised if the rule cannot be inserted at this point in the
     95                style sheet.
     96              - `NO_MODIFICATION_ALLOWED_ERR`: (CSSRule)
     97                Raised if the rule is readonly.
     98          """
     99          super(CSSStyleRule, self)._setCssText(cssText)
    100
    101          # might be (cssText, namespaces)
    102          cssText, namespaces = self._splitNamespacesOff(cssText)
    103          try:
    104              # use parent style sheet ones if available
    105              namespaces = self.parentStyleSheet.namespaces
    106          except AttributeError:
    107              pass
    108
    109          tokenizer = self._tokenize2(cssText)
    110          selectortokens = self._tokensupto2(tokenizer, blockstartonly=True)
    111          styletokens = self._tokensupto2(tokenizer, blockendonly=True)
    112          trail = self._nexttoken(tokenizer)
    113          if trail:
    114              self._log.error(u'CSSStyleRule: Trailing content: %s' %
    115                              self._valuestr(cssText), token=trail)
    116          elif not selectortokens:
    117              self._log.error(u'CSSStyleRule: No selector found: %r' %
    118                              self._valuestr(cssText))
    119          elif self._tokenvalue(selectortokens[0]).startswith(u'@'):
    120              self._log.error(u'CSSStyleRule: No style rule: %r' %
    121                              self._valuestr(cssText),
    122                              error=xml.dom.InvalidModificationErr)
    123          else:
    124              wellformed = True
    125
    126              bracetoken = selectortokens.pop()
    127              if self._tokenvalue(bracetoken) != u'{':
    128                  wellformed = False
    129                  self._log.error(
    130                      u'CSSStyleRule: No start { of style declaration found: %r' %
    131                      self._valuestr(cssText), bracetoken)
    132              elif not selectortokens:
    133                  wellformed = False
    134                  self._log.error(u'CSSStyleRule: No selector found: %r.' %
    135                              self._valuestr(cssText), bracetoken)
    136              newselectorlist = SelectorList(selectorText=(selectortokens,
    137                                                           namespaces),
    138                                             parentRule=self)
    139
    140              newstyle = CSSStyleDeclaration()
    141              if not styletokens:
    142                  wellformed = False
    143                  self._log.error(
    144                      u'CSSStyleRule: No style declaration or "}" found: %r' %
    145                      self._valuestr(cssText))
    146              else:
    147                  braceorEOFtoken = styletokens.pop()
    148                  val, typ = self._tokenvalue(braceorEOFtoken), self._type(braceorEOFtoken)
    149                  if val != u'}' and typ != 'EOF':
    150                      wellformed = False
    151                      self._log.error(
    152                          u'CSSStyleRule: No "}" after style declaration found: %r' %
    153                          self._valuestr(cssText))
    154                  else:
    155                      if 'EOF' == typ:
    156                          # add again as style needs it
    157                          styletokens.append(braceorEOFtoken)
    158                      newstyle.cssText = styletokens
    159
    160              if wellformed:
    161                  self._selectorList = newselectorlist
    162                  self.style = newstyle
    163
    164      cssText = property(_getCssText, _setCssText,
    165          doc="(DOM) The parsable textual representation of the rule.")
    166
    167
    168 -    def __getNamespaces(self):
    169          "uses children namespaces if not attached to a sheet, else the sheet's ones"
    170          try:
    171              return self.parentStyleSheet.namespaces
    172          except AttributeError:
    173              return self.selectorList._namespaces
    174
    175      _namespaces = property(__getNamespaces, doc=u"""if this Rule is
    176          attached to a CSSStyleSheet the namespaces of that sheet are mirrored
    177          here. While the Rule is not attached the namespaces of selectorList
    178          are used.""")
    179
    180 -    def _setSelectorList(self, selectorList):
    181          """
    182          :param selectorList: selectorList, only content is used, not the actual
    183              object
    184          """
    185          self._checkReadonly()
    186          self.selectorText = selectorList.selectorText
    187
    188      selectorList = property(lambda self: self._selectorList, _setSelectorList,
    189          doc="The SelectorList of this rule.")
    190
    191 -    def _setSelectorText(self, selectorText):
    192          """
    193          wrapper for cssutils SelectorList object
    194
    195          :param selectorText: of type string, might also be a comma separated list
    196              of selectors
    197          :Exceptions:
    198              - `NAMESPACE_ERR`: (Selector)
    199                Raised if the specified selector uses an unknown namespace
    200                prefix.
    201              - `SYNTAX_ERR`: (SelectorList, Selector)
    202                Raised if the specified CSS string value has a syntax error
    203                and is unparsable.
    204              - `NO_MODIFICATION_ALLOWED_ERR`: (self)
    205                Raised if this rule is readonly.
    206          """
    207          self._checkReadonly()
    208          self._selectorList.selectorText = selectorText
    209
    210      selectorText = property(lambda self: self._selectorList.selectorText,
    211                              _setSelectorText,
    212          doc="""(DOM) The textual representation of the selector for the
    213              rule set.""")
    214
    215 -    def _setStyle(self, style):
    216          """
    217          :param style: CSSStyleDeclaration or string, only the cssText of a
    218              declaration is used, not the actual object
    219          """
    220          self._checkReadonly()
    221          if isinstance(style, basestring):
    222              self._style.cssText = style
    223          else:
    224              # cssText would be serialized with optional preferences
    225              # so use seq!
    226              self._style.seq = style.seq
    227
    228      style = property(lambda self: self._style, _setStyle,
    229          doc="(DOM) The declaration-block of this rule set.")
    230
    231      wellformed = property(lambda self: self.selectorList.wellformed)
    232
    233 -    def __repr__(self):
    234          if self._namespaces:
    235              st = (self.selectorText, self._namespaces)
    236          else:
    237              st = self.selectorText
    238          return "cssutils.css.%s(selectorText=%r, style=%r)" % (
    239                  self.__class__.__name__, st, self.style.cssText)
    240
    241 -    def __str__(self):
    242          return "<cssutils.css.%s object selector=%r style=%r _namespaces=%r at 0x%x>" % (
    243                  self.__class__.__name__, self.selectorText, self.style.cssText,
    244                  self._namespaces, id(self))
    245