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

# Source Code for Module cssutils.css.cssimportrule

      1  """CSSImportRule implements DOM Level 2 CSS CSSImportRule.
      2
      3  TODO:
      4      - stylesheet: read and parse linked stylesheet
      5  """
      6  __all__ = ['CSSImportRule']
      7  __docformat__ = 'restructuredtext'
      8  __author__ = '$LastChangedBy: cthedot $'
      9  __date__ = '$LastChangedDate: 2007-10-20 20:06:16 +0200 (Sa, 20 Okt 2007) $'
     10  __version__ = '$LastChangedRevision: 542 $'
     11
     12  import xml.dom
     13  import cssrule
     14  import cssutils
     15
     16 -class CSSImportRule(cssrule.CSSRule):
     17      """
     18      Represents an @import rule within a CSS style sheet.  The @import rule
     19      is used to import style rules from other style sheets.
     20
     21      Properties
     22      ==========
     23      cssText: of type DOMString
     24          The parsable textual representation of this rule
     25      href: of type DOMString, (DOM readonly, cssutils also writable)
     26          The location of the style sheet to be imported. The attribute will
     27          not contain the url(...) specifier around the URI.
     28      media: of type stylesheets::MediaList (DOM readonly)
     29          A list of media types for this rule of type MediaList.
     30      stylesheet: of type CSSStyleSheet (DOM readonly)
     31          The style sheet referred to by this rule. The value of this
     32          attribute is None if the style sheet has not yet been loaded or if
     33          it will not be loaded (e.g. if the stylesheet is for a media type
     34          not supported by the user agent).
     35
     36          Currently always None
     37
     38      cssutils only
     39      -------------
     40      atkeyword:
     41          the literal keyword used
     42      hreftype: 'uri' (serializer default) or 'string'
     43          The original usage of href, not really relevant as it may be
     44          configured in the serializer too
     45
     46      Inherits properties from CSSRule
     47
     48      Format
     49      ======
     50      import
     51        : IMPORT_SYM S*
     52        [STRING|URI] S* [ medium [ COMMA S* medium]* ]? ';' S*
     53        ;
     54      """
     55      type = cssrule.CSSRule.IMPORT_RULE
     56
     57 -    def __init__(self, href=None, mediaText=u'all', hreftype=None,
     58                   readonly=False):
     59          """
     60          if readonly allows setting of properties in constructor only
     61
     62          Do not use as positional but as keyword attributes only!
     63
     64          href
     65              location of the style sheet to be imported.
     66          mediaText
     67              A list of media types for which this style sheet may be used
     68              as a string
     69          hreftype
     70              'uri' (default) or 'string'
     71          """
     72          super(CSSImportRule, self).__init__()
     73
     74          self.atkeyword = u'@import'
     75          self.href = href
     76          self.hreftype = hreftype
     77          self._media = cssutils.stylesheets.MediaList(
     78              mediaText, readonly=readonly)
     79          if not self.media.valid:
     80              self._media = cssutils.stylesheets.MediaList()
     81          self.seq = [self.href, self.media]
     82
     83          # TODO: load stylesheet from href automatically?
     84          self._styleSheet = None
     85
     86          self._readonly = readonly
     87
     88
     89 -    def _getHref(self):
     90          return self._href
     91
     92 -    def _setHref(self, href):
     93          # update seq
     94          for i, x in enumerate(self.seq):
     95              if x == self._href:
     96                  self.seq[i] = href
     97                  break
     98          else:
     99              self.seq = [href]
    100          # set new href
    101          self._href = href
    102
    103      href = property(_getHref, _setHref,
    104          doc="Location of the style sheet to be imported.")
    105
    106 -    def _getMedia(self):
    107          "returns MediaList"
    108          return self._media
    109
    110      media = property(_getMedia,
    111          doc=u"(DOM readonly) A list of media types for this rule of type\
    112              MediaList")
    113
    114 -    def _getStyleSheet(self):
    115          """
    116          returns a CSSStyleSheet or None
    117          """
    118          return self._styleSheet
    119
    120      styleSheet = property(_getStyleSheet,
    121          doc="(readonly) The style sheet referred to by this rule.")
    122
    123 -    def _getCssText(self):
    124          """
    125          returns serialized property cssText
    126          """
    127          return cssutils.ser.do_CSSImportRule(self)
    128
    129 -    def _setCssText(self, cssText):
    130          """
    131          DOMException on setting
    132
    133          - HIERARCHY_REQUEST_ERR: (CSSStylesheet)
    134            Raised if the rule cannot be inserted at this point in the
    135            style sheet.
    136          - INVALID_MODIFICATION_ERR: (self)
    137            Raised if the specified CSS string value represents a different
    138            type of rule than the current one.
    139          - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
    140            Raised if the rule is readonly.
    141          - SYNTAX_ERR: (self)
    142            Raised if the specified CSS string value has a syntax error and
    143            is unparsable.
    144          """
    145          super(CSSImportRule, self)._setCssText(cssText)
    146          tokenizer = self._tokenize2(cssText)
    147          attoken = self._nexttoken(tokenizer, None)
    148          if not attoken or self._type(attoken) != self._prods.IMPORT_SYM:
    149              self._log.error(u'CSSImportRule: No CSSImportRule found: %s' %
    150                  self._valuestr(cssText),
    151                  error=xml.dom.InvalidModificationErr)
    152          else:
    153              # for closures: must be a mutable
    154              new = {
    155                     'keyword': self._tokenvalue(attoken),
    156                     'href': None,
    157                     'hreftype': None,
    158                     'media': cssutils.stylesheets.MediaList(),
    159                     'wellformed': True
    160                     }
    161
    162              def _string(expected, seq, token, tokenizer=None):
    163                  # href
    164                  if 'href' == expected:
    165                      new['hreftype'] = 'string'
    166                      new['href'] = self._tokenvalue(token)[1:-1] # "uri" or 'uri'
    167                      seq.append(new['href'])
    168                      return 'media or ;'
    169                  else:
    170                      new['wellformed'] = False
    171                      self._log.error(
    172                          u'CSSImportRule: Unexpected string.', token)
    173                      return expected
    174
    175              def _uri(expected, seq, token, tokenizer=None):
    176                  # href
    177                  if 'href' == expected:
    178                      new['hreftype'] = 'uri'
    179                      uri = self._tokenvalue(token)[4:-1].strip() # url(uri)
    180                      if uri[0] == uri[-1] == '"' or\
    181                         uri[0] == uri[-1] == "'":
    182                          uri = uri[1:-1]
    183                      new['href'] = uri
    184                      seq.append(new['href'])
    185                      return 'media or ;'
    186                  else:
    187                      new['wellformed'] = False
    188                      self._log.error(
    189                          u'CSSImportRule: Unexpected URI.', token)
    190                      return expected
    191
    192  #            def _function(expected, seq, token, tokenizer=None):
    193  #                # FUNCTION may be an incomplete URI, else an error
    194  #                val = self._tokenvalue(token, normalize=True)
    195  #                if 'href' == expected and val.startswith(u'url('):
    196  #                    new['hreftype'] = 'uri'
    197  #                    # TODO
    198  #                    uri = 'TODO'
    199  #
    200  ##                    uri = self._tokenvalue(token)[4:].strip() # url(uri INCOMPLETE!
    201  ##                    if uri and (
    202  ##                       uri[0] == uri[-1] == '"' or
    203  ##                       uri[0] == uri[-1] == "'"):
    204  ##                        uri = uri[1:-1]
    205  #                    new['href'] = uri
    206  #                    seq.append(new['href'])
    207  #                    return 'EOF'
    208  #                else:
    209  #                    new['wellformed'] = False
    210  #                    self._log.error(
    211  #                        u'CSSImportRule: Unexpected FUNCTION.', token)
    212  #                    return expected
    213
    214              def _ident(expected, seq, token, tokenizer=None):
    215                  # medialist ending with ; which is checked upon too
    216                  if expected.startswith('media'):
    217                      mediatokens = self._tokensupto2(
    218                          tokenizer, semicolon=True, keepEnd=True)
    219                      mediatokens.insert(0, token) # push found token
    220
    221                      semicolonOrEOF = mediatokens.pop() # retrieve ;
    222                      if self._tokenvalue(semicolonOrEOF) != u';' and\
    223                         self._type(semicolonOrEOF) != 'EOF':
    224                          new['wellformed'] = False
    225                          self._log.error(u'CSSImportRule: No ";" found: %s' %
    226                                          self._valuestr(cssText), token=token)
    227
    228                      media = cssutils.stylesheets.MediaList()
    229                      media.mediaText = mediatokens
    230                      if media.valid:
    231                          new['media'] = media
    232                          seq.append(media)
    233                      else:
    234                          new['wellformed'] = False
    235                          self._log.error(u'CSSImportRule: Invalid MediaList: %s' %
    236                                          self._valuestr(cssText), token=token)
    237                      return 'EOF' # ';' is found already
    238                  else:
    239                      new['wellformed'] = False
    240                      self._log.error(
    241                          u'CSSImportRule: Unexpected ident.', token)
    242                      return expected
    243
    244              def _char(expected, seq, token, tokenizer=None):
    245                  # final ;
    246                  val = self._tokenvalue(token)
    247                  if expected.endswith(';') and u';' == val:
    248                      return 'EOF'
    249                  else:
    250                      new['wellformed'] = False
    251                      self._log.error(
    252                          u'CSSImportRule: Unexpected char.', token)
    253                      return expected
    254
    255              # import : IMPORT_SYM S* [STRING|URI]
    256              #            S* [ medium [ ',' S* medium]* ]? ';' S*  ;
    257              newseq = []
    258              wellformed, expected = self._parse(expected='href',
    259                  seq=newseq, tokenizer=tokenizer,
    260                  productions={'STRING': _string,
    261                               'URI': _uri,
    262                               #'FUNCTION': _function,
    263                               'IDENT': _ident,
    264                               'CHAR': _char})
    265
    266              # wellformed set by parse
    267              wellformed = wellformed and new['wellformed']
    268
    269              # post conditions
    270              if not new['href']:
    271                  wellformed = False
    272                  self._log.error(u'CSSImportRule: No href found: %s' %
    273                      self._valuestr(cssText))
    274
    275              if expected != 'EOF':
    276                  wellformed = False
    277                  self._log.error(u'CSSImportRule: No ";" found: %s' %
    278                      self._valuestr(cssText))
    279
    280              # set all
    281              if wellformed:
    282                  self.valid = True
    283                  self.atkeyword = new['keyword']
    284                  self.href = new['href']
    285                  self.hreftype = new['hreftype']
    286                  self._media = new['media']
    287                  self.seq = newseq
    288
    289      cssText = property(fget=_getCssText, fset=_setCssText,
    290          doc="(DOM attribute) The parsable textual representation.")
    291
    292 -    def __repr__(self):
    293          return "cssutils.css.%s(href=%r, mediaText=%r)" % (
    294                  self.__class__.__name__, self.href, self.media.mediaText)
    295
    296 -    def __str__(self):
    297          return "<cssutils.css.%s object href=%r at 0x%x>" % (
    298                  self.__class__.__name__, self.href, id(self))
    299