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-08-20 22:07:12 +0200 (Mo, 20 Aug 2007) $'
     10  __version__ = '$LastChangedRevision: 257 $'
     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          """ returns href as a string """
     91          return self._href
     92
     93 -    def _setHref(self, href):
     94          """
     95          TODO:
     96              parse properly
     97
     98          DOMException on setting
     99
    100          - SYNTAX_ERR: (not checked here)
    101            Raised if the specified CSS string value has a syntax error and
    102            is unparsable.
    103          - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
    104            Raised if this rule is readonly.
    105          """
    106          self._checkReadonly()
    107
    108          # update seq
    109          for i, x in enumerate(self.seq):
    110              if x == self._href:
    111                  self.seq[i] = href
    112                  break
    113          else:
    114              self.seq = [href]
    115          # set new href
    116          self._href = href
    117
    118      href = property(_getHref, _setHref,
    119          doc="Location of the style sheet to be imported.")
    120
    121
    122 -    def _getMedia(self):
    123          "returns MediaList"
    124          return self._media
    125
    126      media = property(_getMedia,
    127          doc=u"(DOM readonly) A list of media types for this rule of type\
    128              MediaList")
    129
    130
    131 -    def _getStyleSheet(self):
    132          """
    133          returns a CSSStyleSheet or None
    134          """
    135          return self._styleSheet
    136
    137      styleSheet = property(_getStyleSheet,
    138          doc="(readonly) The style sheet referred to by this rule.")
    139
    140
    141 -    def _getCssText(self):
    142          """
    143          returns serialized property cssText
    144          """
    145          return cssutils.ser.do_CSSImportRule(self)
    146
    147 -    def _setCssText(self, cssText):
    148          """
    149          DOMException on setting
    150
    151          - HIERARCHY_REQUEST_ERR: (CSSStylesheet)
    152            Raised if the rule cannot be inserted at this point in the
    153            style sheet.
    154          - INVALID_MODIFICATION_ERR: (self)
    155            Raised if the specified CSS string value represents a different
    156            type of rule than the current one.
    157          - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
    158            Raised if the rule is readonly.
    159          - SYNTAX_ERR: (self)
    160            Raised if the specified CSS string value has a syntax error and
    161            is unparsable.
    162          """
    163          super(CSSImportRule, self)._setCssText(cssText)
    164          valid = True
    165
    166          tokens = self._tokenize(cssText)
    167
    168          # check if right type
    169          if not tokens or tokens and tokens[0].type != self._ttypes.IMPORT_SYM:
    170              self._log.error(u'CSSImportRule: No CSSImportRule found: %s' %
    171                        self._valuestr(cssText),
    172                        error=xml.dom.InvalidModificationErr)
    173              return
    174          else:
    175              newatkeyword = tokens[0].value
    176
    177          newseq = []
    178          newhref = None
    179          newhreftype = None
    180          newmedia = cssutils.stylesheets.MediaList()
    181
    182          mediatokens = []
    183          expected = 'href' # href medialist end
    184          for i in range(1, len(tokens)):
    185              t = tokens[i]
    186
    187              if self._ttypes.EOF == t.type:
    188                  expected = 'EOF'
    189
    190              elif self._ttypes.S == t.type: # ignore
    191                  pass
    192
    193              elif self._ttypes.COMMENT == t.type:
    194                  if 'href' == expected: # before href
    195                      newseq.append(cssutils.css.CSSComment(t))
    196                  else: # after href
    197                      mediatokens.append(t)
    198
    199              elif 'href' == expected and \
    200                   t.type in (self._ttypes.URI, self._ttypes.STRING):
    201                  if t.type == self._ttypes.URI:
    202                      newhref = t.value[4:-1].strip() # url(href)
    203                      newhreftype = 'uri'
    204                  else:
    205                      newhref = t.value[1:-1].strip() # "href" or 'href'
    206                      newhreftype = 'string'
    207                  newseq.append(newhref)
    208                  expected = 'medialist'
    209
    210              elif self._ttypes.SEMICOLON == t.type:
    211                  if 'medialist' != expected: # normal end
    212                      valid = False
    213                      self._log.error(
    214                          u'CSSImportRule: Syntax Error, no href found.', t)
    215                  expected = None
    216                  break
    217
    218              elif 'medialist' == expected:
    219                  mediatokens.append(t)
    220
    221              else:
    222                  valid = False
    223                  self._log.error(u'CSSImportRule: Syntax Error.', t)
    224
    225          if expected and expected != 'EOF':
    226              valid = False
    227              self._log.error(u'CSSImportRule: Syntax Error, no ";" found: %s' %
    228                        self._valuestr(cssText))
    229              return
    230
    231          if mediatokens:
    232              newmedia.mediaText = mediatokens
    233              if not newmedia.valid:
    234                  valid = False
    235              newseq.append(newmedia)
    236
    237          if valid:
    238              self.atkeyword = newatkeyword
    239              self.href = newhref
    240              self.hreftype = newhreftype
    241              self._media = newmedia
    242              self.seq = newseq
    243
    244      cssText = property(fget=_getCssText, fset=_setCssText,
    245          doc="(DOM attribute) The parsable textual representation.")
    246
    247 -    def __repr__(self):
    248          return "cssutils.css.%s(href=%r, mediaText=%r)" % (
    249                  self.__class__.__name__, self.href, self.media.mediaText)
    250
    251 -    def __str__(self):
    252          return "<cssutils.css.%s object href=%r at 0x%x>" % (
    253                  self.__class__.__name__, self.href, id(self))
    254
    255  if __name__ == '__main__':
    256      c = CSSImportRule(href='"1.css"', mediaText='handheld, all, tv')
    257      print c.seq#, c.media.seq
    258      print c.cssText
    259      c.cssText = '@import'
    260