/usr/lib/python2.7/dist-packages/cssutils/stylesheets/medialist.py is in python-cssutils 1.0.2-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | """MediaList implements DOM Level 2 Style Sheets MediaList.
TODO:
- delete: maybe if deleting from all, replace *all* with all others?
- is unknown media an exception?
"""
__all__ = ['MediaList']
__docformat__ = 'restructuredtext'
__version__ = '$Id$'
from cssutils.prodparser import *
from cssutils.helper import normalize, pushtoken
from cssutils.css import csscomment
from mediaquery import MediaQuery
import cssutils
import xml.dom
#class MediaList(cssutils.util.Base, cssutils.util.ListSeq):
class MediaList(cssutils.util._NewListBase):
"""Provides the abstraction of an ordered collection of media,
without defining or constraining how this collection is
implemented.
A single media in the list is an instance of :class:`MediaQuery`.
An empty list is the same as a list that contains the medium "all".
New format with :class:`MediaQuery`::
: S* [media_query [ ',' S* media_query ]* ]?
"""
def __init__(self, mediaText=None, parentRule=None, readonly=False):
"""
:param mediaText:
Unicodestring of parsable comma separared media
or a (Python) list of media.
:param parentRule:
CSSRule this medialist is used in, e.g. an @import or @media.
:param readonly:
Not used yet.
"""
super(MediaList, self).__init__()
self._wellformed = False
if isinstance(mediaText, list):
mediaText = u','.join(mediaText)
self._parentRule = parentRule
if mediaText:
self.mediaText = mediaText
self._readonly = readonly
def __repr__(self):
return "cssutils.stylesheets.%s(mediaText=%r)" % (self.__class__.__name__, self.mediaText)
def __str__(self):
return "<cssutils.stylesheets.%s object mediaText=%r at 0x%x>" % (self.__class__.__name__, self.mediaText, id(self))
def __iter__(self):
for item in self._seq:
if item.type == 'MediaQuery':
yield item
length = property(lambda self: len(list(self)),
doc="The number of media in the list (DOM readonly).")
def _getMediaText(self):
return cssutils.ser.do_stylesheets_medialist(self)
def _setMediaText(self, mediaText):
"""
:param mediaText:
simple value or comma-separated list of media
:exceptions:
- - :exc:`~xml.dom.SyntaxErr`:
Raised if the specified string value has a syntax error and is
unparsable.
- - :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if this media list is readonly.
"""
self._checkReadonly()
mediaquery = lambda: Prod(name='MediaQueryStart',
match=lambda t, v: t == 'IDENT' or v == u'(',
toSeq=lambda t, tokens: ('MediaQuery',
MediaQuery(pushtoken(t, tokens),
_partof=True))
)
prods = Sequence(Sequence(PreDef.comment(parent=self),
minmax=lambda: (0, None)
),
mediaquery(),
Sequence(PreDef.comma(toSeq=False),
mediaquery(),
minmax=lambda: (0, None))
)
# parse
ok, seq, store, unused = ProdParser().parse(mediaText,
u'MediaList',
prods, debug="ml")
# each mq must be valid
atleastone = False
for item in seq:
v = item.value
if isinstance(v, MediaQuery):
if not v.wellformed:
ok = False
break
else:
atleastone = True
# must be at least one value!
if not atleastone:
ok = False
self._wellformed = ok
self._log.error(u'MediaQuery: No content.',
error=xml.dom.SyntaxErr)
self._wellformed = ok
if ok:
mediaTypes = []
finalseq = cssutils.util.Seq(readonly=False)
commentseqonly = cssutils.util.Seq(readonly=False)
for item in seq:
# filter for doubles?
if item.type == 'MediaQuery':
mediaType = item.value.mediaType
if mediaType:
if mediaType == u'all':
# remove anthing else and keep all+comments(!) only
finalseq = commentseqonly
finalseq.append(item)
break
elif mediaType in mediaTypes:
continue
else:
mediaTypes.append(mediaType)
elif isinstance(item.value, cssutils.css.csscomment.CSSComment):
commentseqonly.append(item)
finalseq.append(item)
self._setSeq(finalseq)
mediaText = property(_getMediaText, _setMediaText,
doc="The parsable textual representation of the media list.")
def __prepareset(self, newMedium):
# used by appendSelector and __setitem__
self._checkReadonly()
if not isinstance(newMedium, MediaQuery):
newMedium = MediaQuery(newMedium)
if newMedium.wellformed:
return newMedium
def __setitem__(self, index, newMedium):
"""Overwriting ListSeq.__setitem__
Any duplicate items are **not yet** removed.
"""
# TODO: remove duplicates?
newMedium = self.__prepareset(newMedium)
if newMedium:
self._seq[index] = (newMedium, 'MediaQuery', None, None)
def appendMedium(self, newMedium):
"""Add the `newMedium` to the end of the list.
If the `newMedium` is already used, it is first removed.
:param newMedium:
a string or a :class:`~cssutils.stylesheets.MediaQuery`
:returns: Wellformedness of `newMedium`.
:exceptions:
- :exc:`~xml.dom.InvalidCharacterErr`:
If the medium contains characters that are invalid in the
underlying style language.
- :exc:`~xml.dom.InvalidModificationErr`:
If mediaText is "all" and a new medium is tried to be added.
Exception is "handheld" which is set in any case (Opera does handle
"all, handheld" special, this special case might be removed in the
future).
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if this list is readonly.
"""
newMedium = self.__prepareset(newMedium)
if newMedium:
mts = [normalize(item.value.mediaType) for item in self]
newmt = normalize(newMedium.mediaType)
self._seq._readonly = False
if u'all' in mts:
self._log.info(u'MediaList: Ignoring new medium %r as already specified "all" (set ``mediaText`` instead).' % newMedium, error=xml.dom.InvalidModificationErr)
elif newmt and newmt in mts:
# might be empty
self.deleteMedium(newmt)
self._seq.append(newMedium, 'MediaQuery')
else:
if u'all' == newmt:
self._clearSeq()
self._seq.append(newMedium, 'MediaQuery')
self._seq._readonly = True
return True
else:
return False
def append(self, newMedium):
"Same as :meth:`appendMedium`."
self.appendMedium(newMedium)
def deleteMedium(self, oldMedium):
"""Delete a medium from the list.
:param oldMedium:
delete this medium from the list.
:exceptions:
- :exc:`~xml.dom.NotFoundErr`:
Raised if `oldMedium` is not in the list.
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if this list is readonly.
"""
self._checkReadonly()
oldMedium = normalize(oldMedium)
for i, mq in enumerate(self):
if normalize(mq.value.mediaType) == oldMedium:
del self[i]
break
else:
self._log.error(u'"%s" not in this MediaList' % oldMedium,
error=xml.dom.NotFoundErr)
def item(self, index):
"""Return the mediaType of the `index`'th element in the list.
If `index` is greater than or equal to the number of media in the
list, returns ``None``.
"""
try:
return self[index].mediaType
except IndexError:
return None
parentRule = property(lambda self: self._parentRule,
doc=u"The CSSRule (e.g. an @media or @import rule "
u"this list is part of or None")
wellformed = property(lambda self: self._wellformed)
|