Package cssutils :: Package stylesheets :: Module medialist |
[hide private]
[frames] | no frames]

# Source Code for Module cssutils.stylesheets.medialist

      1  """
      2  MediaList implements DOM Level 2 Style Sheets MediaList.
      3
      4  TODO:
      5      delete: maybe if deleting from all, replace *all* with all others?
      6      is unknown media an exception?
      7  """
      8  __all__ = ['MediaList']
      9  __docformat__ = 'restructuredtext'
     10  __author__ = '$LastChangedBy: cthedot $'
     11  __date__ = '$LastChangedDate: 2007-10-27 19:28:26 +0200 (Sa, 27 Okt 2007) $'
     12  __version__ = '$LastChangedRevision: 576 $'
     13
     14  import xml.dom
     15  import cssutils
     16  from cssutils.css import csscomment
     17  from mediaquery import MediaQuery
     18
     19 -class MediaList(cssutils.util.Base, list):
     20      """
     21      Provides the abstraction of an ordered collection of media,
     22      without defining or constraining how this collection is
     23      implemented.
     24
     25      A media is always an instance of MediaQuery.
     26
     27      An empty list is the same as a list that contains the medium "all".
     28
     29      Properties
     30      ==========
     31      length:
     32          The number of MediaQuery objects in the list.
     33      mediaText: of type DOMString
     34          The parsable textual representation of this MediaList
     35      self: a list (cssutils)
     36          All MediaQueries in this MediaList
     37      valid:
     38          if this list is valid
     39
     40      Format
     41      ======
     42      ::
     43
     44          medium [ COMMA S* medium ]*
     45
     46      New::
     47
     48          <media_query> [, <media_query> ]*
     49      """
     50 -    def __init__(self, mediaText=None, readonly=False):
     51          """
     52          mediaText
     53              unicodestring of parsable comma separared media
     54              or a list of media
     55          """
     56          super(MediaList, self).__init__()
     57          self.valid = True
     58
     59          if isinstance(mediaText, list):
     60              mediaText = u','.join(mediaText)
     61
     62          if mediaText:
     63              self.mediaText = mediaText
     64
     65          self._readonly = readonly
     66
     67 -    def _getLength(self):
     68          """
     69          returns count of media in this list which is not the same as
     70          len(MediaListInstance) which also contains CSSComments
     71          """
     72          return len(self)
     73
     74      length = property(_getLength,
     75          doc="(DOM readonly) The number of media in the list.")
     76
     77 -    def _getMediaText(self):
     78          """
     79          returns serialized property mediaText
     80          """
     81          return cssutils.ser.do_stylesheets_medialist(self)
     82
     83 -    def _setMediaText(self, mediaText):
     84          """
     85          mediaText
     86              simple value or comma-separated list of media
     87
     88          DOMException
     89
     90          - SYNTAX_ERR: (MediaQuery)
     91            Raised if the specified string value has a syntax error and is
     92            unparsable.
     93          - NO_MODIFICATION_ALLOWED_ERR: (self)
     94            Raised if this media list is readonly.
     95          """
     96          self._checkReadonly()
     97          valid = True
     98          tokenizer = self._tokenize2(mediaText)
     99          newseq = []
    100
    101          expected = None
    102          while True:
    103              # find all upto and including next ",", EOF or nothing
    104              mqtokens = self._tokensupto2(tokenizer, listseponly=True)
    105              if mqtokens:
    106                  if self._tokenvalue(mqtokens[-1]) == ',':
    107                      expected = mqtokens.pop()
    108                  else:
    109                      expected = None
    110
    111                  mq = MediaQuery(mqtokens)
    112                  if mq.valid:
    113                      newseq.append(mq)
    114                  else:
    115                      valid = False
    116                      self._log.error(u'MediaList: Invalid MediaQuery: %s' %
    117                                      self._valuestr(mqtokens))
    118              else:
    119                  break
    120
    121          # post condition
    122          if expected:
    123              valid = False
    124              self._log.error(u'MediaList: Cannot end with ",".')
    125
    126          if valid:
    127              del self[:]
    128              for mq in newseq:
    129                  self.appendMedium(mq)
    130
    131      mediaText = property(_getMediaText, _setMediaText,
    132          doc="""(DOM) The parsable textual representation of the media list.
    133              This is a comma-separated list of media.""")
    134
    135 -    def appendMedium(self, newMedium):
    136          """
    137          (DOM)
    138          Adds the medium newMedium to the end of the list. If the newMedium
    139          is already used, it is first removed.
    140
    141          newMedium
    142              a string or a MediaQuery object
    143
    144          returns if newMedium is valid
    145
    146          DOMException
    147
    148          - INVALID_CHARACTER_ERR: (self)
    149            If the medium contains characters that are invalid in the
    150            underlying style language.
    151          - NO_MODIFICATION_ALLOWED_ERR: (self)
    152            Raised if this list is readonly.
    153          """
    154          self._checkReadonly()
    155
    156          if not isinstance(newMedium, MediaQuery):
    157              newMedium = MediaQuery(newMedium)
    158
    159          if newMedium.valid:
    160
    161              mts = [self._normalize(mq.mediaType) for mq in self]
    162              newmt = self._normalize(newMedium.mediaType)
    163
    164              if newmt in mts:
    165                  self.deleteMedium(newmt)
    166                  self.append(newMedium)
    167              elif u'all' == newmt:
    168                  # remove all except handheld (Opera)
    169                  h = None
    170                  for mq in self:
    171                      if mq.mediaType == u'handheld':
    172                          h = mq
    173                  del self[:]
    174                  self.append(newMedium)
    175                  if h:
    176                      self.append(h)
    177              elif u'all' in mts:
    178                  if u'handheld' == newmt:
    179                      self.append(newMedium)
    180              else:
    181                  self.append(newMedium)
    182
    183              return True
    184
    185          else:
    186              return False
    187
    188 -    def deleteMedium(self, oldMedium):
    189          """
    190          (DOM)
    191          Deletes the medium indicated by oldMedium from the list.
    192
    193          DOMException
    194
    195          - NO_MODIFICATION_ALLOWED_ERR: (self)
    196            Raised if this list is readonly.
    197          - NOT_FOUND_ERR: (self)
    198            Raised if oldMedium is not in the list.
    199          """
    200          self._checkReadonly()
    201          oldMedium = self._normalize(oldMedium)
    202
    203          for i, mq in enumerate(self):
    204              if self._normalize(mq.mediaType) == oldMedium:
    205                  del self[i]
    206                  break
    207          else:
    208              raise xml.dom.NotFoundErr(
    209                  u'"%s" not in this MediaList' % oldMedium)
    210
    211 -    def item(self, index):
    212          """
    213          (DOM)
    214          Returns the mediaType of the index'th element in the list.
    215          If index is greater than or equal to the number of media in the
    216          list, returns None.
    217          """
    218          try:
    219              return self[index].mediaType
    220          except IndexError:
    221              return None
    222
    223 -    def __repr__(self):
    224          return "cssutils.stylesheets.%s(mediaText=%r)" % (
    225                  self.__class__.__name__, self.mediaText)
    226
    227 -    def __str__(self):
    228          return "<cssutils.stylesheets.%s object mediaText=%r at 0x%x>" % (
    229                  self.__class__.__name__, self.mediaText, id(self))
    230