gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.app / org.gvsig.scripting.app.mainplugin / src / main / resources-plugin / scripting / lib / cssutils / stylesheets / mediaquery.py @ 475
History | View | Annotate | Download (8 KB)
1 |
"""Implements a DOM for MediaQuery, see
|
---|---|
2 |
http://www.w3.org/TR/css3-mediaqueries/.
|
3 |
|
4 |
A cssutils implementation, not defined in official DOM.
|
5 |
"""
|
6 |
__all__ = ['MediaQuery']
|
7 |
__docformat__ = 'restructuredtext'
|
8 |
__version__ = '$Id$'
|
9 |
|
10 |
from cssutils.prodparser import * |
11 |
from cssutils.helper import normalize, pushtoken |
12 |
import cssutils |
13 |
import re |
14 |
import xml.dom |
15 |
|
16 |
class MediaQuery(cssutils.util._NewBase):#cssutils.util.Base): |
17 |
"""
|
18 |
A Media Query consists of one of :const:`MediaQuery.MEDIA_TYPES`
|
19 |
and one or more expressions involving media features.
|
20 |
|
21 |
Format::
|
22 |
|
23 |
media_query
|
24 |
: [ONLY | NOT]? S* media_type S* [ AND S* expression ]*
|
25 |
| expression [ AND S* expression ]*
|
26 |
;
|
27 |
media_type
|
28 |
: IDENT
|
29 |
;
|
30 |
expression
|
31 |
: '(' S* media_feature S* [ ':' S* expr ]? ')' S*
|
32 |
;
|
33 |
media_feature
|
34 |
: IDENT
|
35 |
;
|
36 |
|
37 |
"""
|
38 |
MEDIA_TYPES = ['all', 'braille', 'handheld', 'print', 'projection', |
39 |
'speech', 'screen', 'tty', 'tv', 'embossed'] |
40 |
|
41 |
|
42 |
def __init__(self, mediaText=None, readonly=False, _partof=False): |
43 |
"""
|
44 |
:param mediaText:
|
45 |
unicodestring of parsable media
|
46 |
|
47 |
# _standalone: True if new from ML parser
|
48 |
"""
|
49 |
super(MediaQuery, self).__init__() |
50 |
|
51 |
self._wellformed = False |
52 |
self._mediaType = u'' |
53 |
self._partof = _partof
|
54 |
if mediaText:
|
55 |
self.mediaText = mediaText # sets self._mediaType too |
56 |
self._partof = False |
57 |
|
58 |
self._readonly = readonly
|
59 |
|
60 |
def __repr__(self): |
61 |
return "cssutils.stylesheets.%s(mediaText=%r)" % ( |
62 |
self.__class__.__name__, self.mediaText) |
63 |
|
64 |
def __str__(self): |
65 |
return "<cssutils.stylesheets.%s object mediaText=%r at 0x%x>" % ( |
66 |
self.__class__.__name__, self.mediaText, id(self)) |
67 |
|
68 |
def _getMediaText(self): |
69 |
return cssutils.ser.do_stylesheets_mediaquery(self) |
70 |
|
71 |
def _setMediaText(self, mediaText): |
72 |
"""
|
73 |
:param mediaText:
|
74 |
a single media query string, e.g. ``print and (min-width: 25cm)``
|
75 |
|
76 |
:exceptions:
|
77 |
- :exc:`~xml.dom.SyntaxErr`:
|
78 |
Raised if the specified string value has a syntax error and is
|
79 |
unparsable.
|
80 |
- :exc:`~xml.dom.InvalidCharacterErr`:
|
81 |
Raised if the given mediaType is unknown.
|
82 |
- :exc:`~xml.dom.NoModificationAllowedErr`:
|
83 |
Raised if this media query is readonly.
|
84 |
|
85 |
media_query
|
86 |
: [ONLY | NOT]? S* media_type S* [ AND S* expression ]*
|
87 |
| expression [ AND S* expression ]*
|
88 |
;
|
89 |
media_type
|
90 |
: IDENT
|
91 |
;
|
92 |
expression
|
93 |
: '(' S* media_feature S* [ ':' S* expr ]? ')' S*
|
94 |
;
|
95 |
media_feature
|
96 |
: IDENT
|
97 |
;
|
98 |
|
99 |
"""
|
100 |
self._checkReadonly()
|
101 |
|
102 |
expression = lambda: Sequence(PreDef.char(name='expression', char=u'('), |
103 |
Prod(name=u'media_feature',
|
104 |
match=lambda t, v: t == PreDef.types.IDENT
|
105 |
), |
106 |
Sequence(PreDef.char(name='colon', char=u':'), |
107 |
cssutils.css.value.MediaQueryValueProd(self),
|
108 |
minmax=lambda: (0, 1) # optional |
109 |
), |
110 |
PreDef.char(name='expression END', char=u')', |
111 |
stopIfNoMoreMatch=self._partof
|
112 |
) |
113 |
) |
114 |
|
115 |
prods = Choice(Sequence(Prod(name=u'ONLY|NOT', # media_query |
116 |
match=lambda t, v: t == PreDef.types.IDENT and |
117 |
normalize(v) in (u'only', u'not'), |
118 |
optional=True,
|
119 |
toStore='not simple'
|
120 |
), |
121 |
Prod(name=u'media_type',
|
122 |
match=lambda t, v: t == PreDef.types.IDENT and |
123 |
normalize(v) in self.MEDIA_TYPES, |
124 |
stopIfNoMoreMatch=True,
|
125 |
toStore='media_type'
|
126 |
), |
127 |
Sequence(Prod(name=u'AND',
|
128 |
match=lambda t, v: t == PreDef.types.IDENT and |
129 |
normalize(v) == 'and',
|
130 |
toStore='not simple'
|
131 |
), |
132 |
expression(), |
133 |
minmax=lambda: (0, None) |
134 |
) |
135 |
), |
136 |
Sequence(expression(), |
137 |
Sequence(Prod(name=u'AND',
|
138 |
match=lambda t, v: t == PreDef.types.IDENT and |
139 |
normalize(v) == 'and'
|
140 |
), |
141 |
expression(), |
142 |
minmax=lambda: (0, None) |
143 |
) |
144 |
) |
145 |
) |
146 |
|
147 |
# parse
|
148 |
ok, seq, store, unused = ProdParser().parse(mediaText, |
149 |
u'MediaQuery',
|
150 |
prods) |
151 |
self._wellformed = ok
|
152 |
if ok:
|
153 |
try:
|
154 |
media_type = store['media_type']
|
155 |
except KeyError, e: |
156 |
pass
|
157 |
else:
|
158 |
if 'not simple' not in store: |
159 |
self.mediaType = media_type.value
|
160 |
|
161 |
# TODO: filter doubles!
|
162 |
self._setSeq(seq)
|
163 |
|
164 |
mediaText = property(_getMediaText, _setMediaText,
|
165 |
doc="The parsable textual representation of the media list.")
|
166 |
|
167 |
def _setMediaType(self, mediaType): |
168 |
"""
|
169 |
:param mediaType:
|
170 |
one of :attr:`MEDIA_TYPES`
|
171 |
|
172 |
:exceptions:
|
173 |
- :exc:`~xml.dom.SyntaxErr`:
|
174 |
Raised if the specified string value has a syntax error and is
|
175 |
unparsable.
|
176 |
- :exc:`~xml.dom.InvalidCharacterErr`:
|
177 |
Raised if the given mediaType is unknown.
|
178 |
- :exc:`~xml.dom.NoModificationAllowedErr`:
|
179 |
Raised if this media query is readonly.
|
180 |
"""
|
181 |
self._checkReadonly()
|
182 |
nmediaType = normalize(mediaType) |
183 |
|
184 |
if nmediaType not in self.MEDIA_TYPES: |
185 |
self._log.error(
|
186 |
u'MediaQuery: Syntax Error in media type "%s".' % mediaType,
|
187 |
error=xml.dom.SyntaxErr) |
188 |
else:
|
189 |
# set
|
190 |
self._mediaType = mediaType
|
191 |
|
192 |
# update seq
|
193 |
for i, x in enumerate(self._seq): |
194 |
if isinstance(x.value, basestring): |
195 |
if normalize(x.value) in (u'only', u'not'): |
196 |
continue
|
197 |
else:
|
198 |
# TODO: simplify!
|
199 |
self._seq[i] = (mediaType, 'IDENT', None, None) |
200 |
break
|
201 |
else:
|
202 |
self._seq.insert(0, mediaType, 'IDENT') |
203 |
|
204 |
mediaType = property(lambda self: self._mediaType, _setMediaType, |
205 |
doc="The media type of this MediaQuery (one of "
|
206 |
":attr:`MEDIA_TYPES`) but only if it is a simple MediaType!")
|
207 |
|
208 |
wellformed = property(lambda self: self._wellformed) |