Commits

Anonymous committed a4ceefe

Many fixes for markup validation errors. Should close #1927.

Comments (0)

Files changed (14)

htdocs/css/browser.css

 #chglist td.change { 
  white-space: nowrap; 
 }
-#chglist td.change div { 
+#chglist td.change span { 
  border: 1px solid #999;
+ display: block;
  margin: .2em .5em 0 0;
  width: .8em; height: .8em;
 }

htdocs/css/trac.css

  color: inherit;
 }
 
-.ext-link { background: url(../extlink.gif) no-repeat 0 58%; padding-left: 16px }
-* html .ext-link { background-position: 0 .35em } /* IE hack, see #937 */
+@media screen {
+ a.ext-link {
+  background: url(../extlink.gif) no-repeat 0 58%;
+  padding-left: 16px;
+ }
+ * html a.ext-link { background-position: 0 .35em } /* IE hack, see #937 */
+}
 
 /* Forms */
 input, textarea, select { margin: 2px }
    <label>and back to <input type="text" id="stop_rev" name="stop_rev" value="<?cs
     var:log.stop_rev ?>" size="5" /></label>
    <br />
-   <div class="choice" ?>
+   <div class="choice">
     <fieldset>
      <legend>Mode:</legend>
      <label for="stop_on_copy">
     <tr class="<?cs if:name(item) % #2 ?>even<?cs else ?>odd<?cs /if ?>">
      <td class="change" style="padding-left:<?cs var:indent ?>em">
       <a title="View log starting at this revision" href="<?cs var:item.log_href ?>">
-       <div class="<?cs var:item.change ?>"></div>
+       <span class="<?cs var:item.change ?>"></span>
        <span class="comment">(<?cs var:item.change ?>)</span>
       </a>
      </td>

templates/macros.cs

 /def ?><?cs 
 
 def:sortable_th(order, desc, class, title, href) ?>
- <th class="<?cs var:class ?><?cs if:order == class ?> <?cs if:desc ?>desc<?cs else ?>asc<?cs /if ?><?cs /if ?>">
-  <a title="Sort by <?cs var:class ?><?cs if:order == class && !desc ?> (descending)<?cs /if ?>"
-     href="<?cs var:href ?>&order=<?cs var:class ?><?cs if:order == class && !desc ?>&desc=1<?cs /if ?>"><?cs var:title ?></a>
+ <th class="<?cs var:class ?><?cs if:order == class ?> <?cs
+   if:desc ?>desc<?cs else ?>asc<?cs /if ?><?cs /if ?>">
+  <a title="Sort by <?cs var:class ?><?cs
+    if:order == class && !desc ?> (descending)<?cs /if ?>" href="<?cs
+    var:href ?>&amp;order=<?cs var:class ?><?cs
+    if:order == class && !desc ?>&amp;desc=1<?cs /if ?>"><?cs var:title ?></a>
  </th><?cs
 /def ?>

templates/milestone.cs

     /if ?><?cs
    /with ?>
   </div>
-  <form id="stats" method="get">
+  <form id="stats" action="" method="get">
    <fieldset><?cs
     if:milestone.id_param ?>
      <input type="hidden" name="id" value="<?cs var:milestone.name ?>" /><?cs
       <tr>
        <th scope="row"><a href="<?cs
          var:group.queries.all_tickets ?>"><?cs var:group.name ?></a></th>
-       <td nowrap=nowrap><?cs if:#group.total_tickets ?>
+       <td style="white-space: nowrap"><?cs if:#group.total_tickets ?>
         <div class="progress" style="width: <?cs
           var:#group.percent_total * #80 / #milestone.stats.max_percent_total ?>%">
          <a class="closed" href="<?cs

templates/newticket.cs

          var:option ?></label> <?cs set:optidx = optidx + 1 ?><?cs
        /each ?><?cs
       /if ?></td><?cs
-     if:idx % 2 || fullrow ?></tr><tr><?cs 
+     if:idx % 2 || fullrow ?><?cs
+      if:idx < num_fields - 1 ?></tr><tr><?cs
+      /if ?><?cs 
      elif:idx == num_fields - 1 ?><th class="col2"></th><td></td><?cs
      /if ?><?cs set:idx = idx + #fullrow + 1 ?><?cs
     /if ?><?cs

templates/report.cs

 
 <div id="ctxtnav" class="nav">
  <h2>Report Navigation</h2>
- <ul>
-  <li class="first"><?cs
+ <ul><?cs
    if:chrome.links.up.0.href ?><li class="first"><a href="<?cs
     var:chrome.links.up.0.href ?>">Available Reports</a><?cs
    else ?>Available Reports<?cs
   /if ?></li><?cs
   if:report.query_href ?><li class="last"><a href="<?cs
    var:report.query_href ?>">Custom Query</a></li><?cs
-  /if ?>
- </ul>
+  /if ?></ul>
 </div>
 
 <div id="content" class="report">

templates/search.cs

-<?cs include "header.cs"?>
+<?cs include:"header.cs"?>
 <script type="text/javascript">
 addEvent(window, 'load', function() { document.getElementById('q').focus()}); 
 </script>
-<div id="ctxtnav" class="nav">
+<div id="ctxtnav" class="nav"><?cs
+ with:links = chrome.links ?><?cs
+  if:len(links.prev) || len(links.next) ?><ul><?cs
+   if:len(links.prev) ?>
+    <li class="first<?cs if:!len(links.up) && !len(links.next) ?> last<?cs /if ?>">
+     &larr; <a href="<?cs var:links.prev.0.href ?>"><?cs
+       var:links.prev.0.title ?></a>
+    </li><?cs
+   /if ?><?cs
+   if:len(links.next) ?>
+    <li class="<?cs if:!len(links.prev) && !len(links.up) ?>first <?cs /if ?>last">
+     <a href="<?cs var:links.next.0.href ?>"><?cs
+       var:links.next.0.title ?></a> &rarr;
+    </li><?cs
+   /if ?></ul><?cs
+  /if ?><?cs
+ /with ?>
 </div>
 
 <div id="content" class="search">
   </dl>
   <hr />
  </div><?cs 
-if search.n_pages > 1 ?>
- <div id="paging">
- Pages: <?cs
- if len(chrome.links.prev) ?>
-   <a href="<?cs var:chrome.links.prev.0.href ?>" title="<?cs
-      var:chrome.links.prev.0.title ?>">prev</a> <?cs
+ if search.n_pages > 1 ?>
+  <div id="paging"><?cs
+  if len(chrome.links.prev) ?>
+    <a href="<?cs var:chrome.links.prev.0.href ?>" title="<?cs
+       var:chrome.links.prev.0.title ?>">&larr;</a> <?cs
+  /if ?><?cs
+  loop:p = 1, search.n_pages ?><?cs
+    if p == search.page ?><?cs var:p ?><?cs
+    else ?><a href="<?cs var:search.page_href + "&amp;page=" + p?>"><?cs
+     var:p ?></a><?cs
+    /if ?> <?cs
+  /loop ?><?cs
+  if len(chrome.links.next) ?>
+    <a href="<?cs var:chrome.links.next.0.href ?>" title="<?cs
+       var:chrome.links.next.0.title ?>">&rarr;</a><?cs
+  /if ?>
+  </div><?cs
  /if ?><?cs
- loop:p = 1, search.n_pages ?><?cs
-   if p == search.page ?><?cs var:p ?><?cs
-   else ?><a href="<?cs var:search.page_href + "&page=" + p?>"><?cs var:p ?></a><?cs
-   /if ?> <?cs
- /loop ?><?cs
- if len(chrome.links.next) ?>
-   <a href="<?cs var:chrome.links.next.0.href ?>" title="<?cs
-      var:chrome.links.next.0.title ?>">next</a><?cs
- /if ?>
- </div>
-<?cs
+
+elif:search.q ?>
+ <div id="notfound">No matches found.</div><?cs
 /if ?>
 
-<?cs elif $search.q ?>
- <div id="notfound">No matches found.</div>
-<?cs /if ?>
-
- <div id="help">
-  <strong>Note:</strong> See <a href="<?cs var:$trac.href.wiki ?>/TracSearch">TracSearch</a>  for help on searching.
- </div>
+<div id="help">
+ <strong>Note:</strong> See <a href="<?cs
+   var:trac.href.wiki ?>/TracSearch">TracSearch</a>  for help on searching.
+</div>
 
 </div>
-<?cs include "footer.cs"?>
+<?cs include:"footer.cs"?>

templates/ticket.cs

 
 <div id="ctxtnav" class="nav">
  <h2>Ticket Navigation</h2><?cs
- with:links = chrome.links ?>
-  <ul><?cs
+ with:links = chrome.links ?><?cs
+  if:len(links.prev) || len(links.up) || len(links.next) ?><ul><?cs
    if:len(links.prev) ?>
     <li class="first<?cs if:!len(links.up) && !len(links.next) ?> last<?cs /if ?>">
      &larr; <a href="<?cs var:links.prev.0.href ?>" title="<?cs
      <a href="<?cs var:links.next.0.href ?>" title="<?cs
        var:links.next.0.title ?>">Next Ticket</a> &rarr;
     </li><?cs
-   /if ?>
-  </ul><?cs
+   /if ?></ul><?cs
+  /if ?><?cs
  /with ?>
 </div>
 
 
 <?cs if:trac.acl.TICKET_CHGPROP || trac.acl.TICKET_APPEND ?>
 <form action="<?cs var:ticket.href ?>#preview" method="post">
- <input type="hidden" name="ts" value="<?cs var:ticket.ts ?>"/>
  <hr />
  <h3><a name="edit" onfocus="document.getElementById('comment').focus()">Add/Change #<?cs
    var:ticket.id ?> (<?cs var:ticket.summary ?>)</a></h3>
   <table><tr>
    <th><label for="summary">Summary:</label></th>
    <td class="fullrow" colspan="3"><input type="text" id="summary" name="summary" value="<?cs
-     var:ticket.summary ?>" size="70" />
+     var:ticket.summary ?>" size="70" /></td>
    </tr><?cs
    if:len(ticket.fields.type.options) ?>
    <tr>
          var:option ?></label> <?cs set:optidx = optidx + 1 ?><?cs
         /each ?><?cs
       /if ?></td><?cs
-     if:idx % 2 || fullrow ?></tr><tr><?cs 
+     if:idx % 2 || fullrow ?><?cs
+      if:idx < num_fields - 1 ?></tr><tr><?cs
+      /if ?><?cs 
      elif:idx == num_fields - 1 ?><th class="col2"></th><td></td><?cs
      /if ?><?cs set:idx = idx + #fullrow + 1 ?><?cs
     /if ?><?cs
    var:chrome.href ?>/common/js/wikitoolbar.js"></script>
 
  <div class="buttons">
+  <input type="hidden" name="ts" value="<?cs var:ticket.ts ?>" />
   <input type="submit" name="preview" value="Preview" />&nbsp;
   <input type="submit" value="Submit changes" />
  </div>

trac/Milestone.py

         tickets = get_tickets_for_milestone(self.env, db, milestone.name, by)
         stats = calc_ticket_stats(tickets)
         req.hdf['milestone.stats'] = stats
-        queries = get_query_links(self.env, milestone.name)
-        req.hdf['milestone.queries'] = queries
+        for key, value in get_query_links(self.env, milestone.name).items():
+            req.hdf['milestone.queries.' + key] = escape(value)
 
         groups = _get_groups(self.env, db, by)
         group_no = 0
             req.hdf['%s.percent_total' % prefix] = percent_total * 100
             stats = calc_ticket_stats(group_tickets)
             req.hdf[prefix] = stats
-            queries = get_query_links(self.env, milestone.name, by, group)
-            req.hdf['%s.queries' % prefix] = queries
+            for key, value in get_query_links(self.env, milestone.name,
+                                              by, group).items():
+                req.hdf['%s.queries.%s' % (prefix, key)] = escape(value)
             group_no += 1
         req.hdf['milestone.stats.max_percent_total'] = max_percent_total * 100
 
 import re
 from time import localtime, strftime, time
 
-from trac import Milestone, __version__
+from trac import __version__
 from trac.core import *
+from trac.Milestone import Milestone, calc_ticket_stats, get_query_links, \
+                           get_tickets_for_milestone, milestone_to_hdf
 from trac.perm import IPermissionRequestor
 from trac.util import enum, escape, pretty_timedelta, CRLF
 from trac.ticket import Ticket
 
         db = self.env.get_db_cnx()
         milestones = []
-        for idx,milestone in enum(Milestone.Milestone.select(self.env, showall)):
-            hdf = Milestone.milestone_to_hdf(self.env, db, req, milestone)
+        for idx, milestone in enum(Milestone.select(self.env, showall)):
+            hdf = milestone_to_hdf(self.env, db, req, milestone)
             milestones.append(hdf)
         req.hdf['roadmap.milestones'] = milestones
 
         for idx,milestone in enum(milestones):
-            tickets = Milestone.get_tickets_for_milestone(self.env, db,
-                                                          milestone['name'],
-                                                          'owner')
-            stats = Milestone.calc_ticket_stats(tickets)
-            req.hdf['roadmap.milestones.%s.stats' % idx] = stats
-            queries = Milestone.get_query_links(self.env, milestone['name'])
-            req.hdf['roadmap.milestones.%s.queries' % idx] = queries
+            prefix = 'roadmap.milestones.%d.' % idx
+            tickets = get_tickets_for_milestone(self.env, db, milestone['name'],
+                                                'owner')
+            req.hdf[prefix + 'stats'] = calc_ticket_stats(tickets)
+            for k, v in get_query_links(self.env, milestone['name']).items():
+                req.hdf[prefix + 'queries.' + k] = escape(v)
             milestone['tickets'] = tickets # for the iCalendar view
 
         if req.args.get('format') == 'ics':
             req.hdf['search.n_pages'] = n_pages
             req.hdf['search.page_size'] = page_size
             if page < n_pages:
-                req.hdf['chrome.links.next'] = [
-                    {'title': 'Next Page',
-                     'href': self.env.href.search(zip(filters,
-                                                      ['on'] * len(filters)),
-                                                  q=query, page=page+1)
-                    }]
+                next_href = self.env.href.search(zip(filters,
+                                                     ['on'] * len(filters)),
+                                                 q=query, page=page + 1)
+                add_link(req, 'next', next_href, 'Next Page')
             if page > 1:
-                req.hdf['chrome.links.prev'] = [
-                    {'title': 'Previous Page',
-                     'href': self.env.href.search(zip(filters,
-                                                      ['on'] * len(filters)),
-                                                  q=query, page=page-1)
-                    }]
-            req.hdf['search.page_href'] = \
-                 self.env.href.search(zip(filters,
-                                          ['on'] * len(filters)), q=query)
+                prev_href = self.env.href.search(zip(filters,
+                                                     ['on'] * len(filters)),
+                                                 q=query, page=page - 1)
+                add_link(req, 'prev', prev_href, 'Previous Page')
+            req.hdf['search.page_href'] = escape(
+                self.env.href.search(zip(filters, ['on'] * len(filters)),
+                                     q=query))
             req.hdf['search.result'] = [
-                { 'href': result[0],
+                { 'href': escape(result[0]),
                   'title': result[1],
                   'date': time.strftime('%c', time.localtime(result[2])),
-                  'author': result[3],
+                  'author': escape(result[3]),
                   'excerpt': result[4]
                 } for result in results]
 

trac/versioncontrol/web_ui/browser.py

             'props': dict([(util.escape(name), util.escape(value))
                            for name, value in node.get_properties().items()
                            if not name in hidden_properties]),
-            'href': self.env.href.browser(path,rev=rev or repos.youngest_rev),
-            'log_href': self.env.href.log(path)
+            'href': util.escape(self.env.href.browser(path, rev=rev or
+                                                      repos.youngest_rev)),
+            'log_href': util.escape(self.env.href.log(path))
         }
 
         path_links = get_path_links(self.env.href, path, rev)
                 'size': util.pretty_size(entry.content_length),
                 'rev': entry.rev,
                 'permission': 1, # FIXME
-                'log_href': self.env.href.log(entry.path, rev=rev),
-                'browser_href': self.env.href.browser(entry.path, rev=rev)
+                'log_href': util.escape(self.env.href.log(entry.path, rev=rev)),
+                'browser_href': util.escape(self.env.href.browser(entry.path,
+                                                                  rev=rev))
             })
         changes = get_changes(self.env, repos, [i['rev'] for i in info])
 
         changeset = repos.get_changeset(node.rev)  
         req.hdf['file'] = {  
             'rev': node.rev,  
-            'changeset_href': self.env.href.changeset(node.rev),  
-            'date': time.strftime('%x %X', time.localtime(changeset.date)),  
-            'age': util.pretty_timedelta(changeset.date),  
-            'author': changeset.author or 'anonymous',  
-            'message': wiki_to_html(changeset.message or '--', self.env, req,  
-                                    escape_newlines=True)  
+            'changeset_href': util.escape(self.env.href.changeset(node.rev)),
+            'date': time.strftime('%x %X', time.localtime(changeset.date)),
+            'age': util.pretty_timedelta(changeset.date),
+            'author': changeset.author or 'anonymous',
+            'message': wiki_to_html(changeset.message or '--', self.env, req,
+                                    escape_newlines=True)
         } 
         mime_type = node.content_type
         if not mime_type or mime_type == 'application/octet-stream':
 
             raw_href = self.env.href.browser(node.path, rev=rev and node.rev,
                                              format='raw')
-            req.hdf['file.raw_href'] = raw_href
+            req.hdf['file.raw_href'] = util.escape(raw_href)
             add_link(req, 'alternate', raw_href, 'Original Format', mime_type)
 
             add_stylesheet(req, 'common/css/code.css')
         path, rev = get_path_rev(path)
         label = urllib.unquote(label)
         return '<a class="source" href="%s">%s</a>' \
-               % (formatter.href.browser(path, rev=rev), label)
+               % (util.escape(formatter.href.browser(path, rev=rev)), label)
 

trac/versioncontrol/web_ui/util.py

 import urllib
 
 from trac import util
+from trac.util import escape, pretty_timedelta, shorten_line
 from trac.wiki import wiki_to_html, wiki_to_oneliner
 
 __all__ = [ 'get_changes', 'get_path_links', 'get_path_rev' ]
     for rev in revs:
         changeset = repos.get_changeset(rev)
         message = changeset.message
-        shortlog = util.shorten_line(message)        
+        shortlog = shorten_line(message)        
         files = None
         if format == 'changelog':
             files = [change[0] for change in changeset.get_changes()]
         changes[rev] = {
             'date_seconds': changeset.date,
             'date': time.strftime('%x %X', time.localtime(changeset.date)),
-            'age': util.pretty_timedelta(changeset.date),
+            'age': pretty_timedelta(changeset.date),
             'author': changeset.author or 'anonymous',
             'shortlog': shortlog,
             'message': message,
         path = path + part + '/'
         links.append({
             'name': part or 'root',
-            'href': href.browser(path, rev=rev)
+            'href': escape(href.browser(path, rev=rev))
         })
     return links