Contents
Details
- Applies to
- moin-1.6
- Purpose
have moin output valid XHTML 1.0 output, as described in FeatureRequests/ValidXHTMLOutput
- Description
- Summary of changes:
the following elements with EMPTY content model, while properly generated starting from user markup, where generated without the closing tag in some place in the code. They are now correctly generated as empty XML elements (e.g. <foo />).
- hr
- img
- input
- link
- meta
- param
- the 'disabled' attribute must have a value when outputting xml. Now it is properly generated as 'disabled="disabled"' as required by the XHTML specifications.
escaped '&' characters in verbatim javascript snippets and hyperlink endpoints
do not rely on browsers for automatically closing <p> tags generated from wiki markup
- change DOCTYPE string on sent document to be XHTML 1.0, changed bottom page link label claiming the page is valid XHTML 1.0
Note: applying this patch will not make Moin output always valid XHTML 1.0, but it will fix a lot of common issues. I (StefanoZacchiroli) am working on testing the whole legacy Moin installation so that all pages in the distribution are output as valid XHTML 1.0, but I'm not there yet. I will keep this patch updated. Help is more than welcome.
Patch
1 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/action/AttachFile.py moin-dev/MoinMoin/action/AttachFile.py
2 --- moin-dev.orig/MoinMoin/action/AttachFile.py 2006-06-21 10:25:45.000000000 +0200
3 +++ moin-dev/MoinMoin/action/AttachFile.py 2006-06-16 16:02:42.000000000 +0200
4 @@ -371,7 +371,7 @@
5 scriptName, pagename_quoted,
6 action_name, wikiutil.url_quote_plus(file))
7
8 - request.write(u'<link rel="Appendix" title="%s" href="%s">\n' % (
9 + request.write(u'<link rel="Appendix" title="%s" href="%s" />\n' % (
10 wikiutil.escape(file), wikiutil.escape(url)))
11
12
13 @@ -402,15 +402,15 @@
14 request.write('<h2>' + _("Edit drawing") + '</h2>')
15 request.write("""
16 <p>
17 -<img src="%(pngpath)s%(timestamp)s">
18 +<img src="%(pngpath)s%(timestamp)s" />
19 <applet code="CH.ifa.draw.twiki.TWikiDraw.class"
20 - archive="%(pubpath)s/twikidraw.jar" width="640" height="480">
21 -<param name="drawpath" value="%(drawpath)s">
22 -<param name="pngpath" value="%(pngpath)s">
23 -<param name="savepath" value="%(savelink)s">
24 -<param name="basename" value="%(basename)s">
25 -<param name="viewpath" value="%(pagelink)s">
26 -<param name="helppath" value="%(helplink)s">
27 + archive="%(pubpath)s/twikidraw.jar" width="640" height="480" />
28 +<param name="drawpath" value="%(drawpath)s" />
29 +<param name="pngpath" value="%(pngpath)s" />
30 +<param name="savepath" value="%(savelink)s" />
31 +<param name="basename" value="%(basename)s" />
32 +<param name="viewpath" value="%(pagelink)s" />
33 +<param name="helppath" value="%(helplink)s" />
34 <strong>NOTE:</strong> You need a Java enabled browser to edit the drawing example.
35 </applet>
36 </p>""" % {
37 @@ -450,14 +450,14 @@
38 <form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data">
39 <dl>
40 <dt>%(upload_label_file)s</dt>
41 -<dd><input type="file" name="file" size="50"></dd>
42 +<dd><input type="file" name="file" size="50" /></dd>
43 <dt>%(upload_label_rename)s</dt>
44 -<dd><input type="text" name="rename" size="50" value="%(rename)s"></dd>
45 +<dd><input type="text" name="rename" size="50" value="%(rename)s" /></dd>
46 </dl>
47 <p>
48 -<input type="hidden" name="action" value="%(action_name)s">
49 -<input type="hidden" name="do" value="upload">
50 -<input type="submit" value="%(upload_button)s">
51 +<input type="hidden" name="action" value="%(action_name)s" />
52 +<input type="hidden" name="do" value="upload" />
53 +<input type="submit" value="%(upload_button)s" />
54 </p>
55 </form>
56 """ % {
57 @@ -471,7 +471,7 @@
58 })
59
60 #<dt>%(upload_label_mime)s</dt>
61 -#<dd><input type="text" name="mime" size="50"></dd>
62 +#<dd><input type="text" name="mime" size="50" /></dd>
63 # 'upload_label_mime': _('MIME Type (optional)'),
64
65
66 @@ -780,7 +780,7 @@
67 mt = wikiutil.MimeType(filename=filename)
68 if mt.major == 'image':
69 timestamp = htdocs_access(request) and "?%s" % time.time() or ''
70 - request.write('<img src="%s%s" alt="%s">' % (
71 + request.write('<img src="%s%s" alt="%s" />' % (
72 getAttachUrl(pagename, filename, request, escaped=1), timestamp, wikiutil.escape(filename, 1)))
73 return
74 elif mt.major == 'text':
75 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/action/backup.py moin-dev/MoinMoin/action/backup.py
76 --- moin-dev.orig/MoinMoin/action/backup.py 2006-06-21 10:25:45.000000000 +0200
77 +++ moin-dev/MoinMoin/action/backup.py 2006-06-16 16:02:42.000000000 +0200
78 @@ -92,15 +92,15 @@
79
80 request.write("""
81 <form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data">
82 -<input type="hidden" name="action" value="backup">
83 -<input type="hidden" name="do" value="backup">
84 -<input type="submit" value="%(backup_button)s">
85 +<input type="hidden" name="action" value="backup" />
86 +<input type="hidden" name="do" value="backup" />
87 +<input type="submit" value="%(backup_button)s" />
88 </form>
89
90 <form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data">
91 -<input type="hidden" name="action" value="backup">
92 -<input type="hidden" name="do" value="restore">
93 -<input type="submit" value="%(restore_button)s">
94 +<input type="hidden" name="action" value="backup" />
95 +<input type="hidden" name="do" value="restore" />
96 +<input type="submit" value="%(restore_button)s" />
97 </form>
98 """ % {
99 'baseurl': request.getScriptname(),
100 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/action/DeletePage.py moin-dev/MoinMoin/action/DeletePage.py
101 --- moin-dev.orig/MoinMoin/action/DeletePage.py 2006-06-21 10:25:45.000000000 +0200
102 +++ moin-dev/MoinMoin/action/DeletePage.py 2006-06-16 16:02:42.000000000 +0200
103 @@ -61,7 +61,7 @@
104 <tr>
105 <td class="label"><label>%(comment_label)s</label></td>
106 <td class="content">
107 - <input type="text" name="comment" maxlength="80">
108 + <input type="text" name="comment" maxlength="80" />
109 </td>
110 </tr>
111 <tr>
112 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/action/Despam.py moin-dev/MoinMoin/action/Despam.py
113 --- moin-dev.orig/MoinMoin/action/Despam.py 2006-06-21 10:25:45.000000000 +0200
114 +++ moin-dev/MoinMoin/action/Despam.py 2006-06-16 16:02:42.000000000 +0200
115 @@ -84,9 +84,9 @@
116 </table>
117 <p>
118 <form method="post" action="%s/%s">
119 -<input type="hidden" name="action" value="Despam">
120 -<input type="hidden" name="editor" value="%s">
121 -<input type="submit" name="ok" value="%s">
122 +<input type="hidden" name="action" value="Despam" />
123 +<input type="hidden" name="editor" value="%s" />
124 +<input type="submit" name="ok" value="%s" />
125 </form>
126 </p>
127 ''' % (request.getScriptname(), wikiutil.quoteWikinameURL(pagename),
128 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/action/fckdialog.py moin-dev/MoinMoin/action/fckdialog.py
129 --- moin-dev.orig/MoinMoin/action/fckdialog.py 2006-06-21 10:25:45.000000000 +0200
130 +++ moin-dev/MoinMoin/action/fckdialog.py 2006-06-16 16:12:57.000000000 +0200
131 @@ -21,8 +21,8 @@
132 <html>
133 <head>
134 <title>Insert Macro</title>
135 - <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
136 - <meta content="noindex,nofollow" name="robots">
137 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
138 + <meta content="noindex,nofollow" name="robots" />
139 <script src="%s/applets/FCKeditor/editor/dialog/common/fck_dialog_common.js" type="text/javascript"></script>
140 <script language="javascript">
141
142 @@ -178,8 +178,8 @@
143 <html>
144 <head>
145 <title>Insert Page Link</title>
146 - <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
147 - <meta content="noindex,nofollow" name="robots">
148 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
149 + <meta content="noindex,nofollow" name="robots" />
150 </head>
151 <body scroll="no" style="OVERFLOW: hidden">
152 <table height="100%%" cellSpacing="0" cellPadding="0" width="100%%" border="0">
153 @@ -273,8 +273,8 @@
154 * Frederico Caldeira Knabben (fredck@fckeditor.net)
155 -->
156 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
157 -<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
158 -<meta name="robots" content="index,nofollow">
159 +<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
160 +<meta name="robots" content="index,nofollow" />
161 <html>
162 <head>
163 <title>Link Properties</title>
164 @@ -299,17 +299,17 @@
165 <tr>
166 <td>
167 <form action=%(action)s method="GET">
168 - <input type="hidden" name="action" value="fckdialog">
169 - <input type="hidden" name="dialog" value="link">
170 - <input type="hidden" id="basepage" name="basepage" value="%(basepage)s">
171 + <input type="hidden" name="action" value="fckdialog" />
172 + <input type="hidden" name="dialog" value="link" />
173 + <input type="hidden" id="basepage" name="basepage" value="%(basepage)s" />
174 <table cellSpacing="0" cellPadding="0" align="center" border="0">
175 <tr>
176 <td>
177 <span fckLang="PageDlgName">Page Name</span><br>
178 - <input id="txtPagename" name="pagename" size="30" value="%(name)s">
179 + <input id="txtPagename" name="pagename" size="30" value="%(name)s" />
180 </td>
181 <td valign="bottom">
182 - <input id=btnSearchpage type="submit" value="Search">
183 + <input id=btnSearchpage type="submit" value="Search" />
184 </td>
185 </tr>
186 %(page_list)s
187 @@ -330,7 +330,7 @@
188 <select id="sctInterwiki" size="1">
189 %(interwiki)s
190 </select>:
191 - <input id="txtInterwikipagename"></input>
192 + <input id="txtInterwikipagename" />
193 </td>
194 </tr>
195 </table>
196 @@ -426,8 +426,8 @@
197 * Frederico Caldeira Knabben (fredck@fckeditor.net)
198 -->
199 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
200 -<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
201 -<meta name="robots" content="index,nofollow">
202 +<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
203 +<meta name="robots" content="index,nofollow" />
204 <html>
205 <head>
206 <title>Attachment Properties</title>
207 @@ -444,13 +444,13 @@
208 <tr>
209 <td>
210 <form action=%(action)s method="GET">
211 - <input type="hidden" name="action" value="fckdialog">
212 - <input type="hidden" name="dialog" value="attachment">
213 + <input type="hidden" name="action" value="fckdialog" />
214 + <input type="hidden" name="dialog" value="attachment" />
215 <table cellSpacing="0" cellPadding="0" align="center" border="0">
216 <tr>
217 <td>
218 <span fckLang="AttachmentDlgName">Attachment Name</span><br>
219 - <input id="txtAttachmentname" name="pagename" size="30" value="%(name)s">
220 + <input id="txtAttachmentname" name="pagename" size="30" value="%(name)s" />
221 </td>
222 </tr>
223 </table>
224 @@ -518,7 +518,7 @@
225 <tr>
226 <td colspan=2>
227 <div id="divChkLink">
228 - <input id="chkLink" type="checkbox"> Link to
229 + <input id="chkLink" type="checkbox" /> Link to
230 </div>
231 </td>
232 </table>
233 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/action/__init__.py moin-dev/MoinMoin/action/__init__.py
234 --- moin-dev.orig/MoinMoin/action/__init__.py 2006-06-21 10:25:45.000000000 +0200
235 +++ moin-dev/MoinMoin/action/__init__.py 2006-06-16 16:02:42.000000000 +0200
236 @@ -115,11 +115,11 @@
237 buttons = self.make_buttons()
238 buttons_html = []
239 for button in buttons:
240 - buttons_html.append('<input type="submit" name="%s" value="%s">' % button)
241 + buttons_html.append('<input type="submit" name="%s" value="%s" />' % button)
242 buttons_html = "".join(buttons_html)
243
244 if self.use_ticket:
245 - ticket_html = '<input type="hidden" name="ticket" value="%s">' % wikiutil.createTicket()
246 + ticket_html = '<input type="hidden" name="ticket" value="%s" />' % wikiutil.createTicket()
247 else:
248 ticket_html = ''
249
250 @@ -134,7 +134,7 @@
251 form_html = '''
252 %(error_html)s
253 <form method="post" action="">
254 -<input type="hidden" name="action" value="%(actionname)s">
255 +<input type="hidden" name="action" value="%(actionname)s" />
256 %(ticket_html)s
257 %(user_html)s
258 </form>''' % d
259 @@ -599,7 +599,7 @@
260 request.write('<pre>')
261 for line in lines:
262 if line[0] == "@":
263 - request.write('<hr>')
264 + request.write('<hr />')
265 request.write(wikiutil.escape(line)+'\n')
266 request.write('</pre>')
267
268 @@ -669,7 +669,7 @@
269 Column('rev', label='#', align='right'),
270 Column('mtime', label=_('Date'), align='right'),
271 Column('size', label=_('Size'), align='right'),
272 - Column('diff', label='<input type="submit" value="%s">' % (_("Diff"))),
273 + Column('diff', label='<input type="submit" value="%s" />' % (_("Diff"))),
274 Column('editor', label=_('Editor'), hidden=not request.cfg.show_names),
275 Column('comment', label=_('Comment')),
276 Column('action', label=_('Action')),
277 @@ -721,7 +721,7 @@
278 rchecked = ''
279 else:
280 lchecked = rchecked = ''
281 - diff = '<input type="radio" name="rev1" value="%d"%s><input type="radio" name="rev2" value="%d"%s>' % (rev,lchecked,rev,rchecked)
282 + diff = '<input type="radio" name="rev1" value="%d"%s /><input type="radio" name="rev2" value="%d"%s />' % (rev,lchecked,rev,rchecked)
283 comment = line.comment
284 if not comment and line.action.find('/REVERT') != -1:
285 comment = _("Revert to revision %(rev)d.") % {'rev': int(line.extra)}
286 @@ -785,7 +785,7 @@
287 # into the page view itself, and not in this form.
288 request.write('<form method="GET" action="">\n')
289 request.write('<div id="page-history">\n')
290 - request.write('<input type="hidden" name="action" value="diff">\n')
291 + request.write('<input type="hidden" name="action" value="diff" />\n')
292
293 history_table = DataBrowserWidget(request)
294 history_table.setData(history)
295 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/action/PackagePages.py moin-dev/MoinMoin/action/PackagePages.py
296 --- moin-dev.orig/MoinMoin/action/PackagePages.py 2006-06-21 10:25:45.000000000 +0200
297 +++ moin-dev/MoinMoin/action/PackagePages.py 2006-06-16 16:02:42.000000000 +0200
298 @@ -141,25 +141,25 @@
299 form = '''
300 %(error)s
301 <form method="post" action="">
302 -<input type="hidden" name="action" value="%(action)s">
303 +<input type="hidden" name="action" value="%(action)s" />
304 <table>
305 <tr>
306 <td class="label"><label>%(newname_label)s</label></td>
307 <td class="content">
308 - <input type="text" name="packagename" value="package.zip">
309 + <input type="text" name="packagename" value="package.zip" />
310 </td>
311 </tr>
312 <tr>
313 <td class="label"><label>%(list_label)s</label></td>
314 <td class="content">
315 - <input type="text" name="pagelist" maxlength="80">
316 + <input type="text" name="pagelist" maxlength="80" />
317 </td>
318 </tr>
319 <tr>
320 <td></td>
321 <td class="buttons">
322 - <input type="submit" name="submit" value="%(package)s">
323 - <input type="submit" name="cancel" value="%(cancel)s">
324 + <input type="submit" name="submit" value="%(package)s" />
325 + <input type="submit" name="cancel" value="%(cancel)s" />
326 </td>
327 </tr>
328 </table>
329 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/action/RenamePage.py moin-dev/MoinMoin/action/RenamePage.py
330 --- moin-dev.orig/MoinMoin/action/RenamePage.py 2006-06-21 10:25:45.000000000 +0200
331 +++ moin-dev/MoinMoin/action/RenamePage.py 2006-06-16 16:02:42.000000000 +0200
332 @@ -73,13 +73,13 @@
333 <tr>
334 <td class="label"><label>%(newname_label)s</label></td>
335 <td class="content">
336 - <input type="text" name="newpagename" value="%(pagename)s">
337 + <input type="text" name="newpagename" value="%(pagename)s" />
338 </td>
339 </tr>
340 <tr>
341 <td class="label"><label>%(comment_label)s</label></td>
342 <td class="content">
343 - <input type="text" name="comment" maxlength="80">
344 + <input type="text" name="comment" maxlength="80" />
345 </td>
346 </tr>
347 <tr>
348 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/action/SpellCheck.py moin-dev/MoinMoin/action/SpellCheck.py
349 --- moin-dev.orig/MoinMoin/action/SpellCheck.py 2006-06-21 10:25:45.000000000 +0200
350 +++ moin-dev/MoinMoin/action/SpellCheck.py 2006-06-16 16:02:42.000000000 +0200
351 @@ -191,12 +191,12 @@
352 # add a form containing the bad words
353 if own_form:
354 msg = msg + ('<form method="post" action="">\n'
355 - '<input type="hidden" name="action" value="%s">\n') % action_name
356 + '<input type="hidden" name="action" value="%s" />\n') % action_name
357
358 - checkbox = '<input type="checkbox" name="newwords" value="%(word)s">%(word)s '
359 + checkbox = '<input type="checkbox" name="newwords" value="%(word)s" />%(word)s '
360 msg = msg + (
361 " ".join(map(lambda w, cb=checkbox: cb % {'word': wikiutil.escape(w),}, badwords)) +
362 - '<p><input type="submit" name="button_newwords" value="%s"></p>' %
363 + '<p><input type="submit" name="button_newwords" value="%s" /></p>' %
364 _('Add checked words to dictionary')
365 )
366 if own_form:
367 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/action/SubscribeUser.py moin-dev/MoinMoin/action/SubscribeUser.py
368 --- moin-dev.orig/MoinMoin/action/SubscribeUser.py 2006-06-21 10:25:45.000000000 +0200
369 +++ moin-dev/MoinMoin/action/SubscribeUser.py 2006-06-16 16:02:42.000000000 +0200
370 @@ -22,9 +22,9 @@
371
372 request.write("""
373 <form action="" method="POST" enctype="multipart/form-data">
374 -<input type="hidden" name="action" value="SubscribeUser">
375 -Enter user names (comma separated): <input type="text" name="users" size="50">
376 -<input type="submit" value="Subscribe">
377 +<input type="hidden" name="action" value="SubscribeUser" />
378 +Enter user names (comma separated): <input type="text" name="users" size="50" />
379 +<input type="submit" value="Subscribe" />
380 </form>
381 """)
382 request.theme.send_footer(pagename)
383 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/formatter/text_html.py moin-dev/MoinMoin/formatter/text_html.py
384 --- moin-dev.orig/MoinMoin/formatter/text_html.py 2006-06-21 10:25:45.000000000 +0200
385 +++ moin-dev/MoinMoin/formatter/text_html.py 2006-06-16 18:01:13.000000000 +0200
386 @@ -29,9 +29,6 @@
387 _self_closing_tags = Set(['area', 'base', 'br', 'col', 'frame', 'hr', 'img', 'input',
388 'isindex', 'link', 'meta', 'param'])
389
390 -# We only open those tags and let the browser auto-close them:
391 -_auto_closing_tags = Set(['p'])
392 -
393 # These are the elements which generally should cause an increase in the
394 # indention level in the html souce code.
395 _indenting_tags = Set(['ol', 'ul', 'dl', 'li', 'dt', 'dd', 'tr', 'td'])
396 @@ -372,7 +369,7 @@
397 @rtype: string
398 @return: closing tag as a string
399 """
400 - if tag in _self_closing_tags or tag in _auto_closing_tags:
401 + if tag in _self_closing_tags:
402 # This tag was already closed
403 tagstr = ''
404 elif tag in _blocks:
405 @@ -633,7 +630,7 @@
406 linktext = _('Upload new attachment "%(filename)s"')
407 return wikiutil.link_tag(
408 self.request,
409 - ('%s?action=AttachFile&rename=%s' %
410 + ('%s?action=AttachFile&rename=%s' %
411 (wikiutil.quoteWikinameURL(pagename),
412 wikiutil.url_quote_plus(fname))),
413 linktext % {'filename': self.text(fname)})
414 @@ -651,7 +648,7 @@
415 linktext = _('Upload new attachment "%(filename)s"')
416 return wikiutil.link_tag(
417 self.request,
418 - ('%s?action=AttachFile&rename=%s' %
419 + ('%s?action=AttachFile&rename=%s' %
420 (wikiutil.quoteWikinameURL(pagename),
421 wikiutil.url_quote_plus(fname))),
422 linktext % {'filename': self.text(fname)})
423 @@ -681,14 +678,14 @@
424 linktext = _('Create new drawing "%(filename)s"')
425 return wikiutil.link_tag(
426 self.request,
427 - ('%s?action=AttachFile&rename=%s%s' %
428 + ('%s?action=AttachFile&rename=%s%s' %
429 (wikiutil.quoteWikinameURL(pagename),
430 wikiutil.url_quote_plus(fname),
431 - drawing and ('&drawing=%s' % wikiutil.url_quote(drawing)) or '')),
432 + drawing and ('&drawing=%s' % wikiutil.url_quote(drawing)) or '')),
433 linktext % {'filename': self.text(fname)})
434
435 mappath = AttachFile.getFilename(self.request, pagename, drawing + u'.map')
436 - edit_link = ('%s?action=AttachFile&rename=%s&drawing=%s' % (
437 + edit_link = ('%s?action=AttachFile&rename=%s&drawing=%s' % (
438 wikiutil.quoteWikinameURL(pagename),
439 wikiutil.url_quote_plus(fname),
440 wikiutil.url_quote(drawing)))
441 @@ -710,8 +707,8 @@
442 map = re.sub('href\s*=\s*"((?!%TWIKIDRAW%).+?)"', r'href="\1" alt="\1" title="\1"', map)
443 # add in edit links plus alt and title attributes
444 map = map.replace('%TWIKIDRAW%"', edit_link + '" alt="' + _('Edit drawing %(filename)s') % {'filename': self.text(fname)} + '" title="' + _('Edit drawing %(filename)s') % {'filename': self.text(fname)} + '"')
445 - # unxml, because 4.01 concrete will not validate />
446 - map = map.replace('/>', '>')
447 + # ensure at least 1 space exists, backward compatibility with html
448 + map = map.replace('/>', ' />')
449 return (map + self.image(
450 alt=drawing,
451 src=AttachFile.getAttachUrl(
452 @@ -871,6 +868,7 @@
453 # Use by code area
454 _toggleLineNumbersScript = """
455 <script type="text/javascript">
456 +<![CDATA[
457 function isnumbered(obj) {
458 return obj.childNodes.length && obj.firstChild.childNodes.length && obj.firstChild.firstChild.className == 'LineNumber';
459 }
460 @@ -918,6 +916,7 @@
461 }
462 return false;
463 }
464 +]]
465 </script>
466 """
467
468 @@ -957,8 +956,10 @@
469 if self._code_area_state[1] >= 0:
470 toggleLineNumbersLink = r'''
471 <script type="text/javascript">
472 +<![CDATA[
473 document.write('<a href="#" onclick="return togglenumber(\'%s\', %d, %d);" \
474 class="codenumbers">%s<\/a>');
475 +]]>
476 </script>
477 ''' % (self._code_area_state[0], self._code_area_state[2], self._code_area_state[3],
478 _("Toggle line numbers"))
479 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/macro/__init__.py moin-dev/MoinMoin/macro/__init__.py
480 --- moin-dev.orig/MoinMoin/macro/__init__.py 2006-06-21 10:25:46.000000000 +0200
481 +++ moin-dev/MoinMoin/macro/__init__.py 2006-06-16 16:02:42.000000000 +0200
482 @@ -170,10 +170,10 @@
483 if type == "fullsearch":
484 boxes = [
485 u'<br>',
486 - u'<input type="checkbox" name="context" value="160" checked="checked">',
487 + u'<input type="checkbox" name="context" value="160" checked="checked" />',
488 _('Display context of search results'),
489 u'<br>',
490 - u'<input type="checkbox" name="case" value="1">',
491 + u'<input type="checkbox" name="case" value="1" />',
492 _('Case-sensitive searching'),
493 ]
494 boxes = u'\n'.join(boxes)
495 @@ -184,10 +184,10 @@
496 html = [
497 u'<form method="get" action="">',
498 u'<div>',
499 - u'<input type="hidden" name="action" value="fullsearch">',
500 - u'<input type="hidden" name="titlesearch" value="%i">' % type,
501 - u'<input type="text" name="value" size="30" value="%s">' % default,
502 - u'<input type="submit" value="%s">' % button,
503 + u'<input type="hidden" name="action" value="fullsearch" />',
504 + u'<input type="hidden" name="titlesearch" value="%i" />' % type,
505 + u'<input type="text" name="value" size="30" value="%s" />' % default,
506 + u'<input type="submit" value="%s" />' % button,
507 boxes,
508 u'</div>',
509 u'</form>',
510 @@ -206,9 +206,9 @@
511 html = [
512 u'<form method="get" action="">',
513 u'<div>',
514 - u'<input type="hidden" name="action" value="goto">',
515 - u'<input type="text" name="target" size="30">',
516 - u'<input type="submit" value="%s">' % _("Go To Page"),
517 + u'<input type="hidden" name="action" value="goto" />',
518 + u'<input type="text" name="target" size="30" />',
519 + u'<input type="submit" value="%s" />' % _("Go To Page"),
520 u'</div>',
521 u'</form>',
522 ]
523 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/macro/NewPage.py moin-dev/MoinMoin/macro/NewPage.py
524 --- moin-dev.orig/MoinMoin/macro/NewPage.py 2006-06-21 10:25:46.000000000 +0200
525 +++ moin-dev/MoinMoin/macro/NewPage.py 2006-06-16 16:02:42.000000000 +0200
526 @@ -87,18 +87,18 @@
527 # TODO: better abstract this using the formatter
528 html = [
529 u'<form class="macro" method="get" action=""><div>',
530 - u'<input type="hidden" name="action" value="newpage">',
531 - u'<input type="hidden" name="parent" value="%s">' % wikiutil.escape(parent, 1),
532 - u'<input type="hidden" name="template" value="%s">' % wikiutil.escape(template, 1),
533 - u'<input type="hidden" name="nametemplate" value="%s">' % wikiutil.escape(nametemplate,1),
534 + u'<input type="hidden" name="action" value="newpage" />',
535 + u'<input type="hidden" name="parent" value="%s" />' % wikiutil.escape(parent, 1),
536 + u'<input type="hidden" name="template" value="%s" />' % wikiutil.escape(template, 1),
537 + u'<input type="hidden" name="nametemplate" value="%s" />' % wikiutil.escape(nametemplate,1),
538 ]
539
540 if requires_input:
541 html += [
542 - u'<input type="text" name="pagename" size="30">',
543 + u'<input type="text" name="pagename" size="30" />',
544 ]
545 html += [
546 - u'<input type="submit" value="%s">' % wikiutil.escape(label, 1),
547 + u'<input type="submit" value="%s" />' % wikiutil.escape(label, 1),
548 u'</div></form>',
549 ]
550 return self.formatter.rawHTML('\n'.join(html))
551 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/macro/TeudView.py moin-dev/MoinMoin/macro/TeudView.py
552 --- moin-dev.orig/MoinMoin/macro/TeudView.py 2006-06-21 10:25:46.000000000 +0200
553 +++ moin-dev/MoinMoin/macro/TeudView.py 2006-06-16 16:02:42.000000000 +0200
554 @@ -53,7 +53,7 @@
555 pagename, path, modparts[pathidx])
556 if pathidx < pathlen:
557 navigation = navigation + '.'
558 - navigation = navigation + '<hr size="1">'
559 + navigation = navigation + '<hr size="1" />'
560 else:
561 # generate index
562 xmlstr = xmldoc.xml.document(None, encoding=config.charset)
563 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/multiconfig.py moin-dev/MoinMoin/multiconfig.py
564 --- moin-dev.orig/MoinMoin/multiconfig.py 2006-06-21 10:25:46.000000000 +0200
565 +++ moin-dev/MoinMoin/multiconfig.py 2006-06-20 14:30:09.000000000 +0200
566 @@ -260,10 +260,10 @@
567 hosts_deny = []
568
569 html_head = ''
570 - html_head_queries = '''<meta name="robots" content="noindex,nofollow">\n'''
571 - html_head_posts = '''<meta name="robots" content="noindex,nofollow">\n'''
572 - html_head_index = '''<meta name="robots" content="index,follow">\n'''
573 - html_head_normal = '''<meta name="robots" content="index,nofollow">\n'''
574 + html_head_queries = '''<meta name="robots" content="noindex,nofollow" />\n'''
575 + html_head_posts = '''<meta name="robots" content="noindex,nofollow" />\n'''
576 + html_head_index = '''<meta name="robots" content="index,follow" />\n'''
577 + html_head_normal = '''<meta name="robots" content="index,nofollow" />\n'''
578 html_pagetitle = None
579
580 interwiki_preferred = [] # list of wiki names to show at top of interwiki list
581 @@ -293,7 +293,7 @@
582 page_credits = [
583 '<a href="http://moinmoin.wikiwikiweb.de/">MoinMoin Powered</a>',
584 '<a href="http://www.python.org/">Python Powered</a>',
585 - '<a href="http://validator.w3.org/check?uri=referer">Valid HTML 4.01</a>',
586 + '<a href="http://validator.w3.org/check/referer">Valid XHTML 1.0</a>',
587 ]
588 page_footer1 = ''
589 page_footer2 = ''
590 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/PageEditor.py moin-dev/MoinMoin/PageEditor.py
591 --- moin-dev.orig/MoinMoin/PageEditor.py 2006-06-21 10:25:45.000000000 +0200
592 +++ moin-dev/MoinMoin/PageEditor.py 2006-06-16 16:02:42.000000000 +0200
593 @@ -299,7 +299,7 @@
594 self.request.write(unicode(html.INPUT(type="hidden", name="action", value="edit")))
595
596 # Send revision of the page our edit is based on
597 - self.request.write('<input type="hidden" name="rev" value="%d">' % (rev,))
598 + self.request.write('<input type="hidden" name="rev" value="%d" />' % (rev,))
599
600 # Save backto in a hidden input
601 backto = form.get('backto', [None])[0]
602 @@ -308,7 +308,7 @@
603
604 # button bar
605 button_spellcheck = (SpellCheck and
606 - '<input class="button" type="submit" name="button_spellcheck" value="%s" onClick="flgChange = false;">'
607 + '<input class="button" type="submit" name="button_spellcheck" value="%s" onClick="flgChange = false;" />'
608 % _('Check Spelling')) or ''
609
610 save_button_text = _('Save Changes')
611 @@ -325,19 +325,19 @@
612
613
614 self.request.write('''
615 -<input class="button" type="submit" name="button_save" value="%s" onClick="flgChange = false;">
616 -<input class="button" type="submit" name="button_preview" value="%s" onClick="flgChange = false;">
617 +<input class="button" type="submit" name="button_save" value="%s" onClick="flgChange = false;" />
618 +<input class="button" type="submit" name="button_preview" value="%s" onClick="flgChange = false;" />
619 ''' % (save_button_text, _('Preview'),))
620
621 if not (self.request.cfg.editor_force and self.request.cfg.editor_default == 'text'):
622 self.request.write('''
623 -<input id="switch2gui" style="display: none;" class="button" type="submit" name="button_switch" value="%s">
624 +<input id="switch2gui" style="display: none;" class="button" type="submit" name="button_switch" value="%s" />
625 ''' % (_('GUI Mode'),))
626
627 self.request.write('''
628 %s
629 -<input class="button" type="submit" name="button_cancel" value="%s">
630 -<input type="hidden" name="editor" value="text">
631 +<input class="button" type="submit" name="button_cancel" value="%s" />
632 +<input type="hidden" name="editor" value="text" />
633 ''' % (button_spellcheck, cancel_button_text,))
634
635 # Add textarea with page text
636 @@ -364,7 +364,7 @@
637 self.request.write("<p>")
638 self.request.write(_("Comment:"),
639 ' <input id="editor-comment" type="text" name="comment" value="%s" maxlength="80"'
640 - ' onChange="flgChange = true;" onKeyPress="flgChange = true;">' % (
641 + ' onChange="flgChange = true;" onKeyPress="flgChange = true;" />' % (
642 wikiutil.escape(kw.get('comment', ''), 1), ))
643 self.request.write("</p>")
644
645 @@ -382,7 +382,7 @@
646 if self.cfg.mail_enabled:
647 self.request.write('''
648
649 -<input type="checkbox" name="trivial" id="chktrivial" value="1" %(checked)s>
650 +<input type="checkbox" name="trivial" id="chktrivial" value="1" %(checked)s />
651 <label for="chktrivial">%(label)s</label> ''' % {
652 'checked': ('', 'checked')[form.get('trivial',['0'])[0] == '1'],
653 'label': _("Trivial change"),
654 @@ -390,7 +390,7 @@
655
656 self.request.write('''
657
658 -<input type="checkbox" name="rstrip" id="chkrstrip" value="1" %(checked)s>
659 +<input type="checkbox" name="rstrip" id="chkrstrip" value="1" %(checked)s />
660 <label for="chkrstrip">%(label)s</label>
661 ''' % {
662 'checked': ('', 'checked')[form.get('rstrip',['0'])[0] == '1'],
663 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/PageGraphicalEditor.py moin-dev/MoinMoin/PageGraphicalEditor.py
664 --- moin-dev.orig/MoinMoin/PageGraphicalEditor.py 2006-06-21 10:25:45.000000000 +0200
665 +++ moin-dev/MoinMoin/PageGraphicalEditor.py 2006-06-16 16:02:42.000000000 +0200
666 @@ -206,7 +206,7 @@
667 self.request.write(unicode(html.INPUT(type="hidden", name="action", value="edit")))
668
669 # Send revision of the page our edit is based on
670 - self.request.write('<input type="hidden" name="rev" value="%d">' % (rev,))
671 + self.request.write('<input type="hidden" name="rev" value="%d" />' % (rev,))
672
673 # Save backto in a hidden input
674 backto = form.get('backto', [None])[0]
675 @@ -215,7 +215,7 @@
676
677 # button bar
678 button_spellcheck = (SpellCheck and
679 - '<input class="button" type="submit" name="button_spellcheck" value="%s">'
680 + '<input class="button" type="submit" name="button_spellcheck" value="%s" />'
681 % _('Check Spelling')) or ''
682
683 save_button_text = _('Save Changes')
684 @@ -231,12 +231,12 @@
685 }, '</em></p>')
686
687 self.request.write('''
688 -<input class="button" type="submit" name="button_save" value="%s">
689 -<input class="button" type="submit" name="button_preview" value="%s">
690 -<input class="button" type="submit" name="button_switch" value="%s">
691 +<input class="button" type="submit" name="button_save" value="%s" />
692 +<input class="button" type="submit" name="button_preview" value="%s" />
693 +<input class="button" type="submit" name="button_switch" value="%s" />
694 %s
695 -<input class="button" type="submit" name="button_cancel" value="%s">
696 -<input type="hidden" name="editor" value="gui">
697 +<input class="button" type="submit" name="button_cancel" value="%s" />
698 +<input type="hidden" name="editor" value="gui" />
699 ''' % (save_button_text, _('Preview'), _('Text mode'), button_spellcheck, cancel_button_text,))
700
701 self.sendconfirmleaving() # TODO update state of flgChange to make this work, see PageEditor
702 @@ -295,7 +295,7 @@
703 """)
704 self.request.write("<p>")
705 self.request.write(_("Comment:"),
706 - ' <input id="editor-comment" type="text" name="comment" value="%s" maxlength="80">' % (
707 + ' <input id="editor-comment" type="text" name="comment" value="%s" maxlength="80" />' % (
708 wikiutil.escape(kw.get('comment', ''), 1), ))
709 self.request.write("</p>")
710
711 @@ -312,7 +312,7 @@
712 if self.cfg.mail_enabled:
713 self.request.write('''
714
715 -<input type="checkbox" name="trivial" id="chktrivial" value="1" %(checked)s>
716 +<input type="checkbox" name="trivial" id="chktrivial" value="1" %(checked)s />
717 <label for="chktrivial">%(label)s</label> ''' % {
718 'checked': ('', 'checked')[form.get('trivial',['0'])[0] == '1'],
719 'label': _("Trivial change"),
720 @@ -320,7 +320,7 @@
721
722 self.request.write('''
723
724 -<input type="checkbox" name="rstrip" id="chkrstrip" value="1" %(checked)s>
725 +<input type="checkbox" name="rstrip" id="chkrstrip" value="1" %(checked)s />
726 <label for="chkrstrip">%(label)s</label>
727 </p> ''' % {
728 'checked': ('', 'checked')[form.get('rstrip',['0'])[0] == '1'],
729 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/Page.py moin-dev/MoinMoin/Page.py
730 --- moin-dev.orig/MoinMoin/Page.py 2006-06-21 10:25:45.000000000 +0200
731 +++ moin-dev/MoinMoin/Page.py 2006-06-16 16:02:42.000000000 +0200
732 @@ -1226,7 +1226,7 @@
733 # user-defined form preview?
734 # TODO: check if this is also an RTL form - then add ui_lang_attr
735 if pi_formtext:
736 - pi_formtext.append('<input type="hidden" name="fieldlist" value="%s">\n' %
737 + pi_formtext.append('<input type="hidden" name="fieldlist" value="%s" />\n' %
738 "|".join(pi_formfields))
739 pi_formtext.append('</form></table>\n')
740 pi_formtext.append(_(
741 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/script/export/dump.py moin-dev/MoinMoin/script/export/dump.py
742 --- moin-dev.orig/MoinMoin/script/export/dump.py 2006-06-21 10:25:46.000000000 +0200
743 +++ moin-dev/MoinMoin/script/export/dump.py 2006-06-16 16:12:36.000000000 +0200
744 @@ -18,17 +18,17 @@
745 from MoinMoin.action import AttachFile
746
747 url_prefix = "."
748 -logo_html = '<img src="logo.png">'
749 +logo_html = '<img src="logo.png" />'
750 HTML_SUFFIX = ".html"
751
752 -page_template = u'''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
753 -<html>
754 +page_template = u'''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
755 +<html xmlns="http://www.w3.org/1999/xhtml">
756 <head>
757 -<meta http-equiv="content-type" content="text/html; charset=%(charset)s">
758 +<meta http-equiv="content-type" content="text/html; charset=%(charset)s" />
759 <title>%(pagename)s</title>
760 -<link rel="stylesheet" type="text/css" media="all" charset="utf-8" href="%(theme)s/css/common.css">
761 -<link rel="stylesheet" type="text/css" media="screen" charset="utf-8" href="%(theme)s/css/screen.css">
762 -<link rel="stylesheet" type="text/css" media="print" charset="utf-8" href="%(theme)s/css/print.css">
763 +<link rel="stylesheet" type="text/css" media="all" charset="utf-8" href="%(theme)s/css/common.css" />
764 +<link rel="stylesheet" type="text/css" media="screen" charset="utf-8" href="%(theme)s/css/screen.css" />
765 +<link rel="stylesheet" type="text/css" media="print" charset="utf-8" href="%(theme)s/css/print.css" />
766 </head>
767 <body>
768 <table>
769 @@ -41,12 +41,12 @@
770 </td>
771 </tr>
772 </table>
773 -<hr>
774 +<hr />
775 <div id="page">
776 <h1 id="title">%(pagename)s</h1>
777 %(pagehtml)s
778 </div>
779 -<hr>
780 +<hr />
781 %(timestamp)s
782 </body>
783 </html>
784 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/stats/hitcounts.py moin-dev/MoinMoin/stats/hitcounts.py
785 --- moin-dev.orig/MoinMoin/stats/hitcounts.py 2006-06-21 10:25:48.000000000 +0200
786 +++ moin-dev/MoinMoin/stats/hitcounts.py 2006-06-16 16:02:42.000000000 +0200
787 @@ -41,7 +41,7 @@
788 data = {'url': page.url(request, querystr, escape=0)}
789 data.update(request.cfg.chart_options)
790 result = ('<img src="%(url)s" width="%(width)d" height="%(height)d"'
791 - ' alt="hitcounts chart">') % data
792 + ' alt="hitcounts chart" />') % data
793
794 return result
795
796 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/stats/pagesize.py moin-dev/MoinMoin/stats/pagesize.py
797 --- moin-dev.orig/MoinMoin/stats/pagesize.py 2006-06-21 10:25:48.000000000 +0200
798 +++ moin-dev/MoinMoin/stats/pagesize.py 2006-06-16 16:02:42.000000000 +0200
799 @@ -38,7 +38,7 @@
800 data = {'url': page.url(request, querystr, escape=0)}
801 data.update(request.cfg.chart_options)
802 result = ('<img src="%(url)s" width="%(width)d" height="%(height)d"'
803 - ' alt="pagesize chart">') % data
804 + ' alt="pagesize chart" />') % data
805 return result
806
807
808 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/stats/useragents.py moin-dev/MoinMoin/stats/useragents.py
809 --- moin-dev.orig/MoinMoin/stats/useragents.py 2006-06-21 10:25:48.000000000 +0200
810 +++ moin-dev/MoinMoin/stats/useragents.py 2006-06-16 16:02:42.000000000 +0200
811 @@ -39,7 +39,7 @@
812 data = {'url': page.url(request, querystr, escape=0)}
813 data.update(request.cfg.chart_options)
814 result = ('<img src="%(url)s" width="%(width)d" height="%(height)d"'
815 - ' alt="useragents chart">') % data
816 + ' alt="useragents chart" />') % data
817
818 return result
819
820 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/_tests/broken/test_converter_text_html_text_moin_wiki.py moin-dev/MoinMoin/_tests/broken/test_converter_text_html_text_moin_wiki.py
821 --- moin-dev.orig/MoinMoin/_tests/broken/test_converter_text_html_text_moin_wiki.py 2006-06-21 10:25:45.000000000 +0200
822 +++ moin-dev/MoinMoin/_tests/broken/test_converter_text_html_text_moin_wiki.py 2006-06-16 16:02:42.000000000 +0200
823 @@ -1050,7 +1050,7 @@
824
825 def testSmiley01(self):
826 test = ur":-)"
827 - output = ur"""<img src="/wiki/modern/img/smile.png" alt=":-)" height="15" width="15">"""
828 + output = ur"""<img src="/wiki/modern/img/smile.png" alt=":-)" height="15" width="15" />"""
829 self.do(test, output)
830
831 class StripTests(unittest.TestCase):
832 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/theme/__init__.py moin-dev/MoinMoin/theme/__init__.py
833 --- moin-dev.orig/MoinMoin/theme/__init__.py 2006-06-21 10:25:48.000000000 +0200
834 +++ moin-dev/MoinMoin/theme/__init__.py 2006-06-16 16:11:51.000000000 +0200
835 @@ -487,7 +487,7 @@
836 try:
837 tag = self.request.formatter.image(src=img, alt=alt, width=w, height=h)
838 except AttributeError: # XXX FIXME if we have no formatter or no request
839 - tag = '<img src="%s" alt="%s" width="%s" height="%s">' % (
840 + tag = '<img src="%s" alt="%s" width="%s" height="%s" />' % (
841 img, alt, w, h)
842 import warnings
843 warnings.warn("calling themes without correct request", DeprecationWarning)
844 @@ -580,7 +580,7 @@
845 @rtype: string
846 @return: stylesheets links
847 """
848 - link = '<link rel="stylesheet" type="text/css" charset="%s" media="%s" href="%s">'
849 + link = '<link rel="stylesheet" type="text/css" charset="%s" media="%s" href="%s" />'
850
851 # Check mode
852 if d.get('print_mode'):
853 @@ -695,16 +695,16 @@
854 html = u'''
855 <form id="searchform" method="get" action="">
856 <div>
857 -<input type="hidden" name="action" value="fullsearch">
858 -<input type="hidden" name="context" value="180">
859 +<input type="hidden" name="action" value="fullsearch" />
860 +<input type="hidden" name="context" value="180" />
861 <label for="searchinput">%(search_label)s</label>
862 <input id="searchinput" type="text" name="value" value="%(search_value)s" size="20"
863 onfocus="searchFocus(this)" onblur="searchBlur(this)"
864 - onkeyup="searchChange(this)" onchange="searchChange(this)" alt="Search">
865 + onkeyup="searchChange(this)" onchange="searchChange(this)" alt="Search" />
866 <input id="titlesearch" name="titlesearch" type="submit"
867 - value="%(search_title_label)s" alt="Search Titles">
868 + value="%(search_title_label)s" alt="Search Titles" />
869 <input id="fullsearch" name="fullsearch" type="submit"
870 - value="%(search_full_label)s" alt="Search Full Text">
871 + value="%(search_full_label)s" alt="Search Full Text" />
872 </div>
873 </form>
874 <script type="text/javascript">
875 @@ -859,7 +859,7 @@
876 link = u''
877 if self.shouldUseRSS():
878 link = (u'<link rel="alternate" title="%s Recent Changes" '
879 - u'href="%s" type="application/rss+xml">') % (
880 + u'href="%s" type="application/rss+xml" />') % (
881 self.cfg.sitename,
882 self.rsshref() )
883 return link
884 @@ -963,7 +963,7 @@
885 # class="disabled" is a workaround for browsers that ignore
886 # "disabled", e.g IE, Safari
887 # for XHTML: data['disabled'] = ' disabled="disabled"'
888 - disabled = ' disabled class="disabled"'
889 + disabled = ' disabled="disabled" class="disabled"'
890
891 # Format standard actions
892 available = request.getAvailableActions(page)
893 @@ -1018,14 +1018,14 @@
894 <div>
895 <label>%(label)s</label>
896 <select name="action"
897 - onchange="if ((this.selectedIndex != 0) &&
898 + onchange="if ((this.selectedIndex != 0) &&
899 (this.options[this.selectedIndex].disabled == false)) {
900 this.form.submit();
901 }
902 this.selectedIndex = 0;">
903 %(options)s
904 </select>
905 - <input type="submit" value="%(do_button)s">
906 + <input type="submit" value="%(do_button)s" />
907 </div>
908 <script type="text/javascript">
909 <!--// Init menu
910 @@ -1160,7 +1160,7 @@
911 _ = self.request.getText
912 return """\
913 <script type="text/javascript">
914 -var gui_editor_link_href = "%(url)s?action=edit&editor=gui";
915 +var gui_editor_link_href = "%(url)s?action=edit&editor=gui";
916 var gui_editor_link_text = "%(text)s";
917 </script>
918 """ % {'url': page.url(self.request),
919 @@ -1466,14 +1466,14 @@
920
921 # include charset information - needed for moin_dump or any other case
922 # when reading the html without a web server
923 - user_head.append('''<meta http-equiv="Content-Type" content="%s;charset=%s">\n''' % (page.output_mimetype, page.output_charset))
924 + user_head.append('''<meta http-equiv="Content-Type" content="%s;charset=%s" />\n''' % (page.output_mimetype, page.output_charset))
925
926 meta_keywords = request.getPragma('keywords')
927 meta_desc = request.getPragma('description')
928 if meta_keywords:
929 - user_head.append('<meta name="keywords" content="%s">\n' % escape(meta_keywords, 1))
930 + user_head.append('<meta name="keywords" content="%s" />\n' % escape(meta_keywords, 1))
931 if meta_desc:
932 - user_head.append('<meta name="description" content="%s">\n' % escape(meta_desc, 1))
933 + user_head.append('<meta name="description" content="%s" />\n' % escape(meta_desc, 1))
934
935 # search engine precautions / optimization:
936 # if it is an action or edit/search, send query headers (noindex,nofollow):
937 @@ -1496,14 +1496,13 @@
938 user_head.append(request.cfg.html_head_normal)
939
940 if keywords.has_key('pi_refresh') and keywords['pi_refresh']:
941 - user_head.append('<meta http-equiv="refresh" content="%(delay)d;URL=%(url)s">' % keywords['pi_refresh'])
942 + user_head.append('<meta http-equiv="refresh" content="%(delay)d;URL=%(url)s" />' % keywords['pi_refresh'])
943
944 # output buffering increases latency but increases throughput as well
945 output = []
946 - # later: <html xmlns=\"http://www.w3.org/1999/xhtml\">
947 output.append("""\
948 -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
949 -<html>
950 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
951 +<html xmlns="http://www.w3.org/1999/xhtml">
952 <head>
953 %s
954 %s
955 @@ -1521,11 +1520,11 @@
956 ))
957
958 # Links
959 - output.append('<link rel="Start" href="%s/%s">\n' % (scriptname, wikiutil.quoteWikinameURL(page_front_page)))
960 + output.append('<link rel="Start" href="%s/%s" />\n' % (scriptname, wikiutil.quoteWikinameURL(page_front_page)))
961 if pagename:
962 - output.append('<link rel="Alternate" title="%s" href="%s/%s?action=raw">\n' % (
963 + output.append('<link rel="Alternate" title="%s" href="%s/%s?action=raw" />\n' % (
964 _('Wiki Markup'), scriptname, pagename_quoted,))
965 - output.append('<link rel="Alternate" media="print" title="%s" href="%s/%s?action=print">\n' % (
966 + output.append('<link rel="Alternate" media="print" title="%s" href="%s/%s?action=print" />\n' % (
967 _('Print View'), scriptname, pagename_quoted,))
968
969 # !!! currently disabled due to Mozilla link prefetching, see
970 @@ -1538,15 +1537,15 @@
971 #~ # this shopuld never happend in theory, but let's be sure
972 #~ pass
973 #~ else:
974 - #~ request.write('<link rel="First" href="%s/%s">\n' % (request.getScriptname(), quoteWikinameURL(all_pages[0]))
975 + #~ request.write('<link rel="First" href="%s/%s" />\n' % (request.getScriptname(), quoteWikinameURL(all_pages[0]))
976 #~ if pos > 0:
977 - #~ request.write('<link rel="Previous" href="%s/%s">\n' % (request.getScriptname(), quoteWikinameURL(all_pages[pos-1])))
978 + #~ request.write('<link rel="Previous" href="%s/%s" />\n' % (request.getScriptname(), quoteWikinameURL(all_pages[pos-1])))
979 #~ if pos+1 < len(all_pages):
980 - #~ request.write('<link rel="Next" href="%s/%s">\n' % (request.getScriptname(), quoteWikinameURL(all_pages[pos+1])))
981 - #~ request.write('<link rel="Last" href="%s/%s">\n' % (request.getScriptname(), quoteWikinameURL(all_pages[-1])))
982 + #~ request.write('<link rel="Next" href="%s/%s" />\n' % (request.getScriptname(), quoteWikinameURL(all_pages[pos+1])))
983 + #~ request.write('<link rel="Last" href="%s/%s" />\n' % (request.getScriptname(), quoteWikinameURL(all_pages[-1])))
984
985 if page_parent_page:
986 - output.append('<link rel="Up" href="%s/%s">\n' % (scriptname, wikiutil.quoteWikinameURL(page_parent_page)))
987 + output.append('<link rel="Up" href="%s/%s" />\n' % (scriptname, wikiutil.quoteWikinameURL(page_parent_page)))
988
989 # write buffer because we call AttachFile
990 request.write(''.join(output))
991 @@ -1557,10 +1556,10 @@
992 AttachFile.send_link_rel(request, pagename)
993
994 output.extend([
995 - '<link rel="Search" href="%s/%s">\n' % (scriptname, wikiutil.quoteWikinameURL(page_find_page)),
996 - '<link rel="Index" href="%s/%s">\n' % (scriptname, wikiutil.quoteWikinameURL(page_title_index)),
997 - '<link rel="Glossary" href="%s/%s">\n' % (scriptname, wikiutil.quoteWikinameURL(page_word_index)),
998 - '<link rel="Help" href="%s/%s">\n' % (scriptname, wikiutil.quoteWikinameURL(page_help_formatting)),
999 + '<link rel="Search" href="%s/%s" />\n' % (scriptname, wikiutil.quoteWikinameURL(page_find_page)),
1000 + '<link rel="Index" href="%s/%s" />\n' % (scriptname, wikiutil.quoteWikinameURL(page_title_index)),
1001 + '<link rel="Glossary" href="%s/%s" />\n' % (scriptname, wikiutil.quoteWikinameURL(page_word_index)),
1002 + '<link rel="Help" href="%s/%s" />\n' % (scriptname, wikiutil.quoteWikinameURL(page_help_formatting)),
1003 ])
1004
1005 output.append("</head>\n")
1006 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/MoinMoin/theme/modern.py moin-dev/MoinMoin/theme/modern.py
1007 --- moin-dev.orig/MoinMoin/theme/modern.py 2006-06-21 10:25:48.000000000 +0200
1008 +++ moin-dev/MoinMoin/theme/modern.py 2006-06-16 16:02:42.000000000 +0200
1009 @@ -35,7 +35,7 @@
1010 self.trail(d),
1011 self.navibar(d),
1012 #u'<hr id="pageline">',
1013 - u'<div id="pageline"><hr style="display:none;"></div>',
1014 + u'<div id="pageline"><hr style="display:none;" /></div>',
1015 self.msg(d),
1016 self.editbar(d),
1017 u'</div>',
1018 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/wiki/config/wikiconfig.py moin-dev/wiki/config/wikiconfig.py
1019 --- moin-dev.orig/wiki/config/wikiconfig.py 2006-06-21 10:25:49.000000000 +0200
1020 +++ moin-dev/wiki/config/wikiconfig.py 2006-06-16 16:02:42.000000000 +0200
1021 @@ -38,7 +38,7 @@
1022 # Wiki logo. You can use an image, text or both. [Unicode]
1023 # For no logo or text, use '' - the default is to show the sitename.
1024 # See also url_prefix setting below!
1025 - logo_string = u'<img src="/wiki/common/moinmoin.png" alt="MoinMoin Logo">'
1026 + logo_string = u'<img src="/wiki/common/moinmoin.png" alt="MoinMoin Logo" />'
1027
1028 # name of entry page / front page [Unicode], choose one of those:
1029
1030 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/wiki/htdocs/applets/FCKeditor/_samples/py/sample01.py moin-dev/wiki/htdocs/applets/FCKeditor/_samples/py/sample01.py
1031 --- moin-dev.orig/wiki/htdocs/applets/FCKeditor/_samples/py/sample01.py 2006-06-21 10:25:49.000000000 +0200
1032 +++ moin-dev/wiki/htdocs/applets/FCKeditor/_samples/py/sample01.py 2006-06-16 16:02:42.000000000 +0200
1033 @@ -34,15 +34,15 @@
1034 <html>
1035 <head>
1036 <title>FCKeditor - Sample</title>
1037 - <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
1038 - <meta name="robots" content="noindex, nofollow">
1039 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1040 + <meta name="robots" content="noindex, nofollow" />
1041 <link href="../sample.css" rel="stylesheet" type="text/css" />
1042 </head>
1043 <body>
1044 <h1>FCKeditor - Python - Sample 1</h1>
1045 This sample displays a normal HTML form with an FCKeditor with full features
1046 enabled.
1047 - <hr>
1048 + <hr />
1049 <form action="sampleposteddata.py" method="post" target="_blank">
1050 """
1051
1052 @@ -64,10 +64,10 @@
1053 """
1054
1055 # For testing your environments
1056 -print "<hr>"
1057 +print "<hr />"
1058 for key in os.environ.keys():
1059 print "%s: %s<br>" % (key, os.environ.get(key, ""))
1060 -print "<hr>"
1061 +print "<hr />"
1062
1063 # Document footer
1064 print """
1065 diff -Naur -x .hg -x '*.pyc' -r moin-dev.orig/wiki/htdocs/applets/FCKeditor/_samples/py/sampleposteddata.py moin-dev/wiki/htdocs/applets/FCKeditor/_samples/py/sampleposteddata.py
1066 --- moin-dev.orig/wiki/htdocs/applets/FCKeditor/_samples/py/sampleposteddata.py 2006-06-21 10:25:49.000000000 +0200
1067 +++ moin-dev/wiki/htdocs/applets/FCKeditor/_samples/py/sampleposteddata.py 2006-06-16 16:02:42.000000000 +0200
1068 @@ -37,8 +37,8 @@
1069 <html>
1070 <head>
1071 <title>FCKeditor - Samples - Posted Data</title>
1072 - <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
1073 - <meta name="robots" content="noindex, nofollow">
1074 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1075 + <meta name="robots" content="noindex, nofollow" />
1076 <link href="../sample.css" rel="stylesheet" type="text/css" />
1077 </head>
1078 <body>
1079 @@ -48,7 +48,7 @@
1080 print """
1081 <h1>FCKeditor - Samples - Posted Data</h1>
1082 This page lists all data posted by the form.
1083 - <hr>
1084 + <hr />
1085 <table width="100%" border="1" cellspacing="0" bordercolor="#999999">
1086 <tr style="FONT-WEIGHT: bold; COLOR: #dddddd; BACKGROUND-COLOR: #999999">
1087 <td nowrap>Field Name </td>
1088 @@ -69,10 +69,10 @@
1089 print "</table>"
1090
1091 # For testing your environments
1092 -print "<hr>"
1093 +print "<hr />"
1094 for key in os.environ.keys():
1095 print "%s: %s<br>" % (key, os.environ.get(key, ""))
1096 -print "<hr>"
1097 +print "<hr />"
1098
1099 # Document footer
1100 print """
Comments
it would have been easier to review if this were split into moin_only_adding_slashes.diff and moin_xhtml.diff. Adding slashes is lots of work, but no big problem (we had patches for this since years). But the other changes needed are more problematic (and this is the reason moin is not xhtml - not the missing slashes). (ThomasWaldmann)
got it, I will split the patch in pieces: slashes, fck, xhtml (e.g. disabled="disabled" attributes) (StefanoZacchiroli)
stuff under wiki/htdocs/applets/FCKeditor needs to be a separate patch (and go to FCKeditor author, too) (ThomasWaldmann)
the <p> stuff has to get checked thoroughly as it ever breaks when touched. (ThomasWaldmann)
what do you mean? (StefanoZacchiroli)
you changed <p> handling (auto_closing stuff iirc) (ThomasWaldmann)
yes, I did, and it worked for me. I fail to see how it can be such a fragile piece of code, it just a matter of outputting or not </p>. But maybe I'm being too naive ... If you have any particolar suggestion about what to test I can do that. (StefanoZacchiroli)
maybe look at mercurial (hg) (ThomasWaldmann)
I'm using mercurial, but on a repository which is available only via ssh. Do you like to have it accessible via http://? Does that substitute or complement making patches available here? (StefanoZacchiroli)
maybe we can use it when merging your stuff. that comment was rather meant for your work being more comfortable to you. if you just have commented, clean changesets (either with trivial stuff ONLY, like the slashes stuff, or with only serious stuff, like the rest for moin, and with some changesets with FCKeditor only stuff, it will be easy to handle) (ThomasWaldmann)
Right now the aspect of mercurial which puzzles me most is that it's hard to get plain patches out of it. I found 'ht export', but if I want to merge several commit to obtain a single patch I have to manually list the changes. Do you know if there is a way to pack several commits in a single one (other than the stupid way I'm using of cloning again from scratch and commit several changesets at once). I will setup a public version of my repo. (StefanoZacchiroli)
TODO
Known Issues
Testing is missing. Right now I don't have the time to integrate my patch in the testing framework of Moin (mainly because I don't know its detail). Help is welcome on this subject. (StefanoZacchiroli)
You can safely ignore most stuff that is already there testing html output (most stuff is broken because it is too restrictive). If you can really reach xhtml output, you maybe can use an x(ht)ml parsing framework for the tests. Setting up such a framework did not make sense yet, as we had no x(ht)ml. (ThomasWaldmann)
Table markup may generated non well formed XML, I'll work on that. (StefanoZacchiroli)
Ordered lists (<ol>) in XHTML does not have the "start" and "type" attributes. While the latter has a direct mapping to css, the former hasn't. "start" can be emulated using css counters, but that requires re-defining the css rendering of <li> items from scratch. Is that ok or is better to drop the support for "start" in Moin lists? Regarding "type" is it preferred to change a global moin "css" ot to output "style" attributes on affected list elements? (The latter probably requires also some reworking of some Moin sanitization passes ...) (StefanoZacchiroli)
Discussion
Thanks a lot for your work on this. Especially the more complex things on the todo might be critical as there is no such thing as 99% xhtml. -- ThomasWaldmann 2006-06-21 10:37:11
I added a (proof of concept) TODO list Regarding 99% xhtml: as a matter of fact it is not possible to achieve 100% xhtml as long as markup permits to output arbitrary HTML. Still, this patch fixes oddities Moin is better without, IMHO of course. Any plan about committing it to the main development branch even if we are 99% xhtml? (StefanoZacchiroli)
What standard wiki markup permits arbitrary html? In case you talk of HTML macro: this is not included in moin and we don't recommend it. So I hope there is no means to insert user defined html in the output. (ThomasWaldmann)
Yep, I was thinking at that. Non issue then. (StefanoZacchiroli)
It is known that some parts of moin just output html fragments (esp. the theme, but also other stuff), but this can be fixed in the code. (ThomasWaldmann)
What do you prefer for that? Invoking the formatter instead of having html hard coded or patch the hard coded html? (I did the latter right now). (StefanoZacchiroli)
About committing to main: it will rather get committed to a testing branch first. We need to test against multiple browsers first and see if they are happy with our output. E.g.: what happens if we claim it is xhtml in the header and there is something in the output (that 1% ), that isn't valid xhtml? What does a browser do in that case? (ThomasWaldmann)
I agree on that. Still, I'm not willing to do the test since I only have linux/firefox at hand. Regarding commit I really don't care about commiting to test vs main. I care about having it committed to a place where main development is merged often. Of course I understand if you're not willing to do that. After all that's the dirty work of patch contributors Stay tuned for the split patches ... (StefanoZacchiroli)
Please only output CDATA sections if you're outputting application/xhtml+xml ... which I suspect/hope you're not yet, because that requires 100% XHTML. CDATA will break in text/html, even if syntactically it is perfectly XHTML. Otherwise thanks for doing a lot of the tedious gruntwork. -- -- DeronMeranda 2006-06-21 15:10:44
Plan
- Priority:
- Assigned to:
- Status: