1 | #! /usr/bin/env python |
---|
2 | # -*- coding: iso-8859-1 -*- |
---|
3 | |
---|
4 | ## Copyright 1999-2006 by LivingLogic AG, Bayreuth/Germany. |
---|
5 | ## Copyright 1999-2006 by Walter Dörwald |
---|
6 | ## |
---|
7 | ## All Rights Reserved |
---|
8 | ## |
---|
9 | ## See xist/__init__.py for the license |
---|
10 | |
---|
11 | """ |
---|
12 | <par>An &xist; module that contains a collection of useful elements for |
---|
13 | generating &html;.</par> |
---|
14 | """ |
---|
15 | |
---|
16 | __version__ = "$Revision$".split()[1] |
---|
17 | # $Source$ |
---|
18 | |
---|
19 | import sys, types, time as time_, string, warnings |
---|
20 | |
---|
21 | from ll.xist import xsc, parsers, sims |
---|
22 | from ll.xist.ns import ihtml, html, meta, specials |
---|
23 | |
---|
24 | |
---|
25 | class plaintable(html.table): |
---|
26 | """ |
---|
27 | <par>a &html; table where the values of the attributes <lit>cellpadding</lit>, |
---|
28 | <lit>cellspacing</lit> and <lit>border</lit> default to <lit>0</lit>.</par> |
---|
29 | """ |
---|
30 | class Attrs(html.table.Attrs): |
---|
31 | class cellpadding(html.table.Attrs.cellpadding): |
---|
32 | default = 0 |
---|
33 | class cellspacing(html.table.Attrs.cellspacing): |
---|
34 | default = 0 |
---|
35 | class border(html.table.Attrs.border): |
---|
36 | default = 0 |
---|
37 | |
---|
38 | def convert(self, converter): |
---|
39 | e = html.table(self.content, self.attrs) |
---|
40 | return e.convert(converter) |
---|
41 | |
---|
42 | |
---|
43 | class plainbody(html.body): |
---|
44 | """ |
---|
45 | <par>a &html; body where the attributes <lit>leftmargin</lit>, <lit>topmargin</lit>, |
---|
46 | <lit>marginheight</lit> and <lit>marginwidth</lit> default to <lit>0</lit>.</par> |
---|
47 | """ |
---|
48 | class Attrs(html.body.Attrs): |
---|
49 | class leftmargin(html.body.Attrs.leftmargin): |
---|
50 | default = 0 |
---|
51 | class topmargin(html.body.Attrs.topmargin): |
---|
52 | default = 0 |
---|
53 | class marginheight(html.body.Attrs.marginheight): |
---|
54 | default = 0 |
---|
55 | class marginwidth(html.body.Attrs.marginwidth): |
---|
56 | default = 0 |
---|
57 | |
---|
58 | def convert(self, converter): |
---|
59 | e = html.body(self.content, self.attrs) |
---|
60 | return e.convert(converter) |
---|
61 | |
---|
62 | |
---|
63 | class _pixelbase(html.img): |
---|
64 | class Attrs(html.img.Attrs): |
---|
65 | class color(xsc.TextAttr): |
---|
66 | """ |
---|
67 | The pixel color as a three digit hex value or <lit>spc</lit> to |
---|
68 | get a transparent pixel. |
---|
69 | """ |
---|
70 | default = u"spc" |
---|
71 | |
---|
72 | def checkvalid(self): |
---|
73 | if len(self) and not self.isfancy(): |
---|
74 | content = unicode(self) |
---|
75 | if content != u"spc": |
---|
76 | if len(content) == 3: |
---|
77 | for c in content: |
---|
78 | if c not in u"0369cf": |
---|
79 | warnings.warn(xsc.IllegalAttrValueWarning(self)) |
---|
80 | else: |
---|
81 | warnings.warn(xsc.IllegalAttrValueWarning(self)) |
---|
82 | |
---|
83 | class alt(html.img.Attrs.alt): |
---|
84 | default = "" |
---|
85 | |
---|
86 | |
---|
87 | class pixel(_pixelbase): |
---|
88 | """ |
---|
89 | <par>element for single pixel images.</par> |
---|
90 | |
---|
91 | <par>The default is the image <filename>root:px/0.gif</filename>, but |
---|
92 | you can specify the color as a three digit hex string, which will be |
---|
93 | used as the filename, i.e. <markup><pixel color="000"/></markup> |
---|
94 | results in <markup><img src="root:px/000.gif"></markup>.</par> |
---|
95 | |
---|
96 | <par>In addition to that you can specify width and height attributes |
---|
97 | (and every other allowed attribute for the <class>img</class> element) |
---|
98 | as usual.</par> |
---|
99 | """ |
---|
100 | |
---|
101 | class Attrs(_pixelbase.Attrs): |
---|
102 | class width(_pixelbase.Attrs.width): |
---|
103 | default = 1 |
---|
104 | class height(_pixelbase.Attrs.height): |
---|
105 | default = 1 |
---|
106 | src = None # remove source attribute |
---|
107 | |
---|
108 | def convert(self, converter): |
---|
109 | self.attrs.checkvalid() |
---|
110 | e = converter.target.img( |
---|
111 | self.attrs.without([u"color"]), |
---|
112 | src=(u"root:px/", self[u"color"], u".gif") |
---|
113 | ) |
---|
114 | return e.convert(converter) |
---|
115 | |
---|
116 | |
---|
117 | class autoimg(html.img): |
---|
118 | """ |
---|
119 | <par>An image were width and height attributes are automatically generated.</par> |
---|
120 | |
---|
121 | <par>If the attributes are already there, they won't be modified.</par> |
---|
122 | """ |
---|
123 | def convert(self, converter): |
---|
124 | target = converter.target |
---|
125 | if issubclass(target, (ihtml, html)): |
---|
126 | e = target.img(self.attrs.convert(converter)) |
---|
127 | else: |
---|
128 | raise ValueError("unknown conversion target %r" % target) |
---|
129 | src = self[u"src"].convert(converter).forInput(converter.root) |
---|
130 | e._addimagesizeattributes(src, u"width", u"height") |
---|
131 | return e |
---|
132 | |
---|
133 | |
---|
134 | class autopixel(_pixelbase): |
---|
135 | """ |
---|
136 | <par>A pixel image were width and height attributes are automatically generated.</par> |
---|
137 | |
---|
138 | <par>This works like <pyref class="pixel"><class>pixel</class></pyref> but the |
---|
139 | size is <z>inherited</z> from the image specified via the <lit>src</lit> attribute.</par> |
---|
140 | """ |
---|
141 | |
---|
142 | def convert(self, converter): |
---|
143 | target = converter.target |
---|
144 | if not issubclass(target, (ihtml, html)): |
---|
145 | raise ValueError("unknown conversion target %r" % target) |
---|
146 | self.attrs.checkvalid() |
---|
147 | e = target.img(self.attrs.without([u"color"])) |
---|
148 | src = self[u"src"].convert(converter).forInput(converter.root) |
---|
149 | e._addimagesizeattributes(src, u"width", u"height") |
---|
150 | e[u"src"] = (u"root:px/", self[u"color"], u".gif") |
---|
151 | return e |
---|
152 | |
---|
153 | |
---|
154 | class autoinput(html.input): |
---|
155 | """ |
---|
156 | <par>Extends <pyref module="ll.xist.ns.html" class="input"><class>input</class></pyref> |
---|
157 | with the ability to automatically set the size, if this element |
---|
158 | has <lit>type=="image"</lit>.</par> |
---|
159 | """ |
---|
160 | def convert(self, converter): |
---|
161 | target = converter.target |
---|
162 | e = target.input(self.content, self.attrs) |
---|
163 | if u"type" in self.attrs and unicode(self[u"type"].convert(converter)) == u"image": |
---|
164 | src = self[u"src"].convert(converter).forInput(converter.root) |
---|
165 | e._addimagesizeattributes(src, u"size", None) # no height |
---|
166 | return e.convert(converter) |
---|
167 | |
---|
168 | |
---|
169 | class redirectpage(xsc.Element): |
---|
170 | model = sims.Empty() |
---|
171 | class Attrs(xsc.Element.Attrs): |
---|
172 | class href(xsc.URLAttr): required = True |
---|
173 | |
---|
174 | langs = { |
---|
175 | "en": (u"Redirection to ", u"Your browser doesn't understand redirects. This page has been redirected to "), |
---|
176 | "de": (u"Weiterleitung auf ", u"Ihr Browser unterstützt keine Weiterleitung. Diese Seite wurde weitergeleitet auf ") |
---|
177 | } |
---|
178 | |
---|
179 | def convert(self, converter): |
---|
180 | target = converter.target |
---|
181 | (title, text) = self.langs.get(converter.lang, self.langs[u"en"]) |
---|
182 | url = self[u"href"] |
---|
183 | e = target.html( |
---|
184 | target.head( |
---|
185 | meta.contenttype(), |
---|
186 | target.title(title, url) |
---|
187 | ), |
---|
188 | target.body( |
---|
189 | text, target.a(url, href=url) |
---|
190 | ) |
---|
191 | ) |
---|
192 | return e.convert(converter) |
---|
193 | |
---|
194 | |
---|
195 | class javascript(html.script): |
---|
196 | """ |
---|
197 | <par>can be used for javascript.</par> |
---|
198 | """ |
---|
199 | class Attrs(html.script.Attrs): |
---|
200 | language = None |
---|
201 | type = None |
---|
202 | |
---|
203 | def convert(self, converter): |
---|
204 | target = converter.target |
---|
205 | e = target.script(self.content, self.attrs, language=u"javascript", type=u"text/javascript") |
---|
206 | return e.convert(converter) |
---|
207 | |
---|
208 | |
---|
209 | class flash(xsc.Element): |
---|
210 | model = sims.Empty() |
---|
211 | class Attrs(xsc.Element.Attrs): |
---|
212 | class src(xsc.URLAttr): required = True |
---|
213 | class width(xsc.IntAttr): required = True |
---|
214 | class height(xsc.IntAttr): required = True |
---|
215 | class quality(xsc.TextAttr): default = u"high" |
---|
216 | class bgcolor(xsc.ColorAttr): pass |
---|
217 | |
---|
218 | def convert(self, converter): |
---|
219 | target = converter.target |
---|
220 | e = target.object( |
---|
221 | target.param(name=u"movie", value=self[u"src"]), |
---|
222 | target.embed( |
---|
223 | src=self[u"src"], |
---|
224 | quality=self[u"quality"], |
---|
225 | bgcolor=self[u"bgcolor"], |
---|
226 | width=self[u"width"], |
---|
227 | height=self[u"height"], |
---|
228 | type=u"application/x-shockwave-flash", |
---|
229 | pluginspage=u"http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" |
---|
230 | ), |
---|
231 | classid=u"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", |
---|
232 | codebase=u"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0", |
---|
233 | width=self[u"width"], |
---|
234 | height=self[u"height"] |
---|
235 | ) |
---|
236 | |
---|
237 | # copy optional attributes |
---|
238 | for attrname in (u"quality", u"bgcolor"): |
---|
239 | if attrname in self.attrs: |
---|
240 | e.insert(0, target.param(name=attrname, value=self[attrname])) |
---|
241 | |
---|
242 | return e.convert(converter) |
---|
243 | |
---|
244 | |
---|
245 | class quicktime(xsc.Element): |
---|
246 | model = sims.Empty() |
---|
247 | class Attrs(xsc.Element.Attrs): |
---|
248 | class src(xsc.URLAttr): required = True |
---|
249 | class href(xsc.URLAttr): pass |
---|
250 | class target(xsc.TextAttr): pass |
---|
251 | class width(xsc.IntAttr): required = True |
---|
252 | class height(xsc.IntAttr): required = True |
---|
253 | class bgcolor(xsc.ColorAttr): pass |
---|
254 | class controller(xsc.ColorAttr): values = (u"true", u"false") |
---|
255 | class autoplay(xsc.ColorAttr): values = (u"true", u"false") |
---|
256 | class border(xsc.IntAttr): pass |
---|
257 | |
---|
258 | def convert(self, converter): |
---|
259 | target = converter.target |
---|
260 | e = target.object( |
---|
261 | target.param(name=u"src", value=self[u"src"]), |
---|
262 | target.param(name=u"type", value=u"video/quicktime"), |
---|
263 | target.param(name=u"pluginspage", value=u"http://www.apple.com/quicktime/download/indext.html"), |
---|
264 | target.embed( |
---|
265 | src=self[u"src"], |
---|
266 | href=self[u"href"], |
---|
267 | target=self[u"target"], |
---|
268 | bgcolor=self[u"bgcolor"], |
---|
269 | width=self[u"width"], |
---|
270 | height=self[u"height"], |
---|
271 | type=u"video/quicktime", |
---|
272 | border=self[u"border"], |
---|
273 | pluginspage=u"http://www.apple.com/quicktime/download/indext.html" |
---|
274 | ), |
---|
275 | classid=u"clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B", |
---|
276 | codebase=u"http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0", |
---|
277 | width=self[u"width"], |
---|
278 | height=self[u"height"] |
---|
279 | ) |
---|
280 | |
---|
281 | # copy optional attributes |
---|
282 | for attrname in (u"href", u"target", u"bgcolor", u"controller", u"autoplay"): |
---|
283 | if attrname in self.attrs: |
---|
284 | e.insert(0, target.param(name=attrname, value=self[attrname])) |
---|
285 | |
---|
286 | return e.convert(converter) |
---|
287 | |
---|
288 | |
---|
289 | class ImgAttrDecorator(specials.AttrDecorator): |
---|
290 | class Attrs(html.img.Attrs): |
---|
291 | pass |
---|
292 | idecoratable = (html.img,) |
---|
293 | |
---|
294 | |
---|
295 | class InputAttrDecorator(specials.AttrDecorator): |
---|
296 | class Attrs(html.input.Attrs): |
---|
297 | pass |
---|
298 | decoratable = (html.input,) |
---|
299 | |
---|
300 | |
---|
301 | class FormAttrDecorator(specials.AttrDecorator): |
---|
302 | class Attrs(html.form.Attrs): |
---|
303 | pass |
---|
304 | decoratable = (html.form,) |
---|
305 | |
---|
306 | |
---|
307 | class TextAreaAttrDecorator(specials.AttrDecorator): |
---|
308 | class Attrs(html.textarea.Attrs): |
---|
309 | pass |
---|
310 | decoratable = (html.textarea,) |
---|
311 | |
---|
312 | |
---|
313 | class __ns__(xsc.Namespace): |
---|
314 | xmlname = "htmlspecials" |
---|
315 | xmlurl = "http://xmlns.livinglogic.de/xist/ns/htmlspecials" |
---|
316 | __ns__.makemod(vars()) |
---|