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  TODO
      4  - parentRule?
      5  - parentStyleSheet?
      6  """
      7  __all__ = ['CSSStyleRule']
      8  __docformat__ = 'restructuredtext'
      9  __author__ = '$LastChangedBy: cthedot $'
     10  __date__ = '$LastChangedDate: 2007-08-20 22:07:12 +0200 (Mo, 20 Aug 2007) $'
     11  __version__ = '$LastChangedRevision: 257 $'
     12
     13  import xml.dom
     14  import cssrule
     15  import cssstyledeclaration
     16  import cssutils
     17  from selector import Selector
     18  from selectorlist import SelectorList
     19
     20 -class CSSStyleRule(cssrule.CSSRule):
     21      """
     22      represents a single rule set in a CSS style sheet.
     23
     24      Properties
     25      ==========
     26      cssText: of type DOMString
     27          The parsable textual representation of this rule
     28      selectorText: of type DOMString
     29          The textual representation of the selector for the rule set. The
     30          implementation may have stripped out insignificant whitespace while
     31          parsing the selector.
     32      style: of type CSSStyleDeclaration, (DOM)
     33          The declaration-block of this rule set.
     34
     35      cssutils only
     36      -------------
     37      selectorList: of type SelectorList (cssutils only)
     38          A list of all Selector elements for the rule set.
     39
     40      Inherits properties from CSSRule
     41
     42      Format
     43      ======
     44      ruleset
     45        : selector [ COMMA S* selector ]*
     46        LBRACE S* declaration [ ';' S* declaration ]* '}' S*
     47        ;
     48      """
     49      type = cssrule.CSSRule.STYLE_RULE
     50
     51 -    def __init__(self, selectorText=None, style=None, readonly=False):
     52          """
     53          if readonly allows setting of properties in constructor only
     54
     55          selectorText
     56              type string
     57          style
     58              CSSStyleDeclaration for this CSSStyleRule
     59          """
     60          super(CSSStyleRule, self).__init__()
     61
     62          if selectorText:
     63              self.selectorText = selectorText
     64              self.seq.append(self.selectorText)
     65          else:
     66              self._selectorList = SelectorList()
     67          if style:
     68              self.style = style
     69              self.seq.append(self.style)
     70          else:
     71              self._style = cssstyledeclaration.CSSStyleDeclaration(
     72                  parentRule=self)
     73
     74          self._readonly = readonly
     75
     76 -    def _getCssText(self):
     77          """
     78          returns serialized property cssText
     79          """
     80          return cssutils.ser.do_CSSStyleRule(self)
     81
     82 -    def _setCssText(self, cssText):
     83          """
     84          DOMException on setting
     85
     86          - SYNTAX_ERR: (self, StyleDeclaration)
     87            Raised if the specified CSS string value has a syntax error and
     88            is unparsable.
     89          - INVALID_MODIFICATION_ERR: (self)
     90            Raised if the specified CSS string value represents a different
     91            type of rule than the current one.
     92          - HIERARCHY_REQUEST_ERR: (CSSStylesheet)
     93            Raised if the rule cannot be inserted at this point in the
     94            style sheet.
     95          - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
     96            Raised if the rule is readonly.
     97          """
     98          super(CSSStyleRule, self)._setCssText(cssText)
     99          tokens = self._tokenize(cssText)
    100          valid = True
    101
    102          # check if right token
    103          if not tokens or tokens[0].value.startswith(u'@'):
    104              self._log.error(u'CSSStyleRule: No CSSStyleRule found: %s' %
    105                        self._valuestr(cssText),
    106                        error=xml.dom.InvalidModificationErr)
    107              return
    108
    109          # init
    110          newselectorList = SelectorList()
    111          newstyle = cssstyledeclaration.CSSStyleDeclaration(parentRule=self)
    112          newseq = []
    113
    114          # get selector (must be one, see above)
    115          selectortokens, endi = self._tokensupto(tokens,
    116                                                      blockstartonly=True)
    117          expected = '{' # or None (end)
    118          if selectortokens[-1].value != expected:
    119              self._log.error(u'CSSStyleRule: No StyleDeclaration found.',
    120                  selectortokens[-1])
    121              return
    122          newselectorList.selectorText = selectortokens[:-1]
    123          newseq.append(newselectorList)
    124
    125          # get rest (StyleDeclaration and Comments)
    126          i, imax = endi, len(tokens)
    127          while i < imax:
    128              t = tokens[i]
    129              if self._ttypes.EOF == t.type:
    130                  expected = 'EOF'
    131
    132              elif self._ttypes.S == t.type: # ignore
    133                  pass
    134
    135              elif self._ttypes.COMMENT == t.type: # just add
    136                  newseq.append(cssutils.css.CSSComment(t))
    137
    138              elif self._ttypes.LBRACE == t.type:
    139                  foundtokens, endi = self._tokensupto(
    140                      tokens[i:], blockendonly=True)
    141                  i += endi
    142                  if len(foundtokens) < 2:
    143                      self._log.error(u'CSSStyleRule: Syntax Error.', t)
    144                      return
    145                  else:
    146                      styletokens = foundtokens[1:-1] # without { and }
    147                      newstyle = cssstyledeclaration.CSSStyleDeclaration(
    148                          parentRule=self)
    149                      newstyle.cssText = styletokens
    150                      newseq.append(newstyle)
    151                      expected = '}'
    152                  continue
    153
    154              elif '}' == expected and self._ttypes.RBRACE == t.type:
    155                  expected = None
    156
    157              else:
    158                  self._log.error(u'CSSStyleRule: Unexpected token.', t)
    159                  return
    160
    161              i += 1
    162
    163          if expected == '{':
    164              self._log.error(u'CSSStyleRule: No StyleDeclaration found: %s' %
    165                        self._valuestr(cssText))
    166              return
    167          elif expected and expected == 'EOF':
    168              self._log.error(u'CSSStyleRule: Trailing text after ending "}" or no end of StyleDeclaration found: %s' %
    169                        self._valuestr(cssText))
    170              return
    171          else:
    172              # everything ok
    173              self.selectorList = newselectorList
    174              self.style = newstyle
    175              self.seq = newseq
    176
    177      cssText = property(_getCssText, _setCssText,
    178          doc="(DOM) The parsable textual representation of the rule.")
    179
    180 -    def _setSelectorList(self, selectorList):
    181          """
    182          (cssutils)
    183          set the SelectorList of this rule
    184
    185          selectorList
    186              instance of SelectorList
    187
    188          DOMException on setting
    189
    190          - NO_MODIFICATION_ALLOWED_ERR:
    191            Raised if this rule is readonly.
    192          """
    193          self._checkReadonly()
    194          self._selectorList = selectorList
    195
    196 -    def _getSelectorList(self):
    197          """
    198          (cssutils)
    199          returns the SelectorList of this rule
    200          see selectorText for a textual representation
    201          """
    202          return self._selectorList
    203
    204      selectorList = property(_getSelectorList, _setSelectorList,
    205          doc="The SelectorList of this rule.")
    206
    207 -    def _getSelectorText(self):
    208          """
    209          wrapper for cssutils Selector object
    210          """
    211          return self._selectorList.selectorText
    212
    213 -    def _setSelectorText(self, selectorText):
    214          """
    215          wrapper for cssutils Selector object
    216
    217          selector
    218              of type string, might also be a comma separated list of
    219              selectors
    220
    221          DOMException on setting
    222
    223          - SYNTAX_ERR:
    224            Raised if the specified CSS string value has a syntax error
    225            and is unparsable.
    226          - NO_MODIFICATION_ALLOWED_ERR: (self)
    227            Raised if this rule is readonly.
    228          """
    229          self._checkReadonly()
    230          self._selectorList = SelectorList(selectorText)
    231
    232      selectorText = property(_getSelectorText, _setSelectorText,
    233          doc="""(DOM) The textual representation of the selector for the
    234              rule set.""")
    235
    236 -    def _getStyle(self):
    237          return self._style
    238
    239 -    def _setStyle(self, style):
    240          """
    241          style
    242              StyleDeclaration or string
    243          """
    244          self._checkReadonly()
    245          if isinstance(style, basestring):
    246              # may raise Exception!
    247              temp = cssstyledeclaration.CSSStyleDeclaration(parentRule=self)
    248              temp.cssText = style
    249              self._style = temp
    250          else:
    251              self._style = style
    252              style.parentRule = self
    253
    254      style = property(_getStyle, _setStyle,
    255          doc="(DOM) The declaration-block of this rule set.")
    256
    257 -    def __repr__(self):
    258          return "cssutils.css.%s(selectorText=%r)" % (
    259                  self.__class__.__name__, self.selectorText)
    260
    261 -    def __str__(self):
    262          return "<cssutils.css.%s object selector=%r at 0x%x>" % (
    263                  self.__class__.__name__, self.selectorText, id(self))
    264
    265
    266  if __name__ == '__main__':
    267      cssutils.css.cssstylerule.Selector = Selector # for main test
    268      r = CSSStyleRule()
    269      r.cssText = 'a {}a'
    270      r.selectorText = u'b + a'
    271      print r.cssText
    272