| 1 | <!--! |
|---|
| 2 | changes - a list of diff items, each being a dict containing information about |
|---|
| 3 | changes for one file: |
|---|
| 4 | .href - link for the title (optional) |
|---|
| 5 | .title - tooltip for the title link (optional) |
|---|
| 6 | .comments - annotation for the change (optional) |
|---|
| 7 | .new and .old - information about the files being diffed |
|---|
| 8 | .path - path of the file |
|---|
| 9 | .rev - rev of the file (for 'sidebyside') |
|---|
| 10 | .shortrev - abbreviated form of rev of the file (for 'inline') |
|---|
| 11 | .href - link to the full file (optional) |
|---|
| 12 | .props - a list of property changes |
|---|
| 13 | .name - name of the property |
|---|
| 14 | .diff - rendered difference |
|---|
| 15 | .old - old value of the property |
|---|
| 16 | .new - new value for the property |
|---|
| 17 | (both .old and .new have .name, .value and .rendered properties) |
|---|
| 18 | .diffs - a sequence of list of blocks |
|---|
| 19 | |
|---|
| 20 | Each block being a dict: |
|---|
| 21 | .type - one of 'unmod', 'add', 'rem' or 'mod' |
|---|
| 22 | .base and .changed - information about lines from old and new content |
|---|
| 23 | .lines - the lines |
|---|
| 24 | .offset - position within the file |
|---|
| 25 | |
|---|
| 26 | .diffs_title - a sequence of titles for the list of blocks |
|---|
| 27 | Note: integrate this into .diffs for 0.12 or 0.13. |
|---|
| 28 | |
|---|
| 29 | diff - dict specifying diff style and options |
|---|
| 30 | .style - can be 'sidebyside' (4 columns) or 'inline' (3 columns) |
|---|
| 31 | .options - contexlines, various ignore... |
|---|
| 32 | |
|---|
| 33 | longcol - "long" column header; e.g. 'Revision' or 'File' or '' (for 'sidebyside') |
|---|
| 34 | shortcol - "short" column header: e.g. 'r' or '' (for 'inline') |
|---|
| 35 | no_id - skip generation of id attributes in h2 headings |
|---|
| 36 | |
|---|
| 37 | --> |
|---|
| 38 | <div xmlns="http://www.w3.org/1999/xhtml" |
|---|
| 39 | xmlns:py="http://genshi.edgewall.org/" |
|---|
| 40 | xmlns:xi="http://www.w3.org/2001/XInclude" |
|---|
| 41 | xmlns:i18n="http://genshi.edgewall.org/i18n" |
|---|
| 42 | class="diff"> |
|---|
| 43 | |
|---|
| 44 | <py:def function="add_comment(linenum, fileid)"> |
|---|
| 45 | <py:if test="review.status == 'closed' or not_allowed">${linenum or ' '}</py:if> |
|---|
| 46 | <a py:if="review.status != 'closed' and not not_allowed" href="javascript:addComment($linenum, $fileid, -1)">${linenum or ' '}</a> |
|---|
| 47 | </py:def> |
|---|
| 48 | |
|---|
| 49 | <ul py:if="any([item.diffs or item.props for item in changes])" class="entries"> |
|---|
| 50 | <py:for each="idx, item in enumerate(changes)" py:with="old = item.old; new = item.new"> |
|---|
| 51 | <li py:if="item and (item.diffs or item.props or 'comments' in item)" class="entry" |
|---|
| 52 | py:with="comments = item.get('comments')"> |
|---|
| 53 | <h2 id="${not no_id and 'file%s' % idx or None}" py:choose=""> |
|---|
| 54 | <a py:when="new.path" href="${item.get('href', new.get('href'))}" |
|---|
| 55 | title="${item.get('title', new.get('title'))}">$new.path</a> |
|---|
| 56 | <py:otherwise> </py:otherwise> |
|---|
| 57 | </h2> |
|---|
| 58 | <pre py:if="comments">$comments</pre> |
|---|
| 59 | <ul py:if="item.props" class="props"> |
|---|
| 60 | <py:def function="prop_name(name, attrs)"> |
|---|
| 61 | <strong py:attrs="attrs">$name</strong> |
|---|
| 62 | </py:def> |
|---|
| 63 | <py:def function="render_property(prop)"> |
|---|
| 64 | <py:choose> |
|---|
| 65 | <py:when test="prop.rendered">$prop.rendered.content</py:when> |
|---|
| 66 | <em py:when="istext(prop.value)"><tt>$prop.value</tt></em> |
|---|
| 67 | <py:otherwise>$prop.value</py:otherwise> |
|---|
| 68 | </py:choose> |
|---|
| 69 | </py:def> |
|---|
| 70 | <py:for each="prop in item.props" py:choose=""> |
|---|
| 71 | <py:when test="prop.diff">$prop.diff</py:when> |
|---|
| 72 | <py:with vars="one = prop.old or prop.new; |
|---|
| 73 | both = prop.old and prop.new; |
|---|
| 74 | name_attrs = one.rendered and one.rendered.name_attributes; |
|---|
| 75 | name = one.rendered and one.rendered.name or prop.name"> |
|---|
| 76 | <li py:when="one" py:choose=""> |
|---|
| 77 | <py:when test="both"><i18n:msg params="name, old, new"> |
|---|
| 78 | Property ${prop_name(name, name_attrs)} |
|---|
| 79 | changed from ${render_property(prop.old)} to ${render_property(prop.new)} |
|---|
| 80 | </i18n:msg></py:when> |
|---|
| 81 | <py:when test="not prop.old"><i18n:msg params="name, value"> |
|---|
| 82 | Property ${prop_name(name, name_attrs)} set to ${render_property(prop.new)} |
|---|
| 83 | </i18n:msg></py:when> |
|---|
| 84 | <py:otherwise><i18n:msg params="name"> |
|---|
| 85 | Property ${prop_name(name, name_attrs)} deleted |
|---|
| 86 | </i18n:msg></py:otherwise> |
|---|
| 87 | </li> |
|---|
| 88 | </py:with> |
|---|
| 89 | </py:for> |
|---|
| 90 | </ul> |
|---|
| 91 | <table py:if="item.diffs" class="trac-diff $diff.style" summary="Differences" cellspacing="0" |
|---|
| 92 | py:with="fromline = item.diffs[0][0].base.offset+1; |
|---|
| 93 | toline = item.diffs[0][0].changed.offset+1"> |
|---|
| 94 | <py:choose test="diff.style"> |
|---|
| 95 | <py:when test="'sidebyside'"> |
|---|
| 96 | <colgroup class="l"><col class="lineno" /><col class="content" /></colgroup> |
|---|
| 97 | <colgroup class="r"><col class="lineno" /><col class="content" /></colgroup> |
|---|
| 98 | <thead> |
|---|
| 99 | <tr> |
|---|
| 100 | <th colspan="2"> |
|---|
| 101 | <a title="${old.get('title')}" href="${old.get('href')}#L$fromline" |
|---|
| 102 | py:strip="'href' not in old">$longcol $old.rev</a> |
|---|
| 103 | </th> |
|---|
| 104 | <th colspan="2"> |
|---|
| 105 | <a title="${new.get('title')}" href="${new.get('href')}#L$toline" |
|---|
| 106 | py:strip="'href' not in new">$longcol $new.rev</a> |
|---|
| 107 | </th> |
|---|
| 108 | </tr> |
|---|
| 109 | </thead> |
|---|
| 110 | </py:when> |
|---|
| 111 | <py:when test="'inline'"> |
|---|
| 112 | <colgroup><col class="lineno" /><col class="lineno" /><col class="content" /></colgroup> |
|---|
| 113 | <thead> |
|---|
| 114 | <tr> |
|---|
| 115 | <th title="$longcol $old.rev"> |
|---|
| 116 | <a title="${old.get('title')}" href="${old.get('href')}#L$fromline" |
|---|
| 117 | py:strip="'href' not in old"> |
|---|
| 118 | $shortcol$old.shortrev</a> |
|---|
| 119 | </th> |
|---|
| 120 | <th title="$longcol $new.rev"> |
|---|
| 121 | <a title="${new.get('title')}" href="${new.get('href')}#L$toline" |
|---|
| 122 | py:strip="'href' not in new"> |
|---|
| 123 | $shortcol$new.shortrev</a> |
|---|
| 124 | </th> |
|---|
| 125 | <td><em py:if="'diffs_title' in item">${item.diffs_title[0]}</em> </td> |
|---|
| 126 | </tr> |
|---|
| 127 | </thead> |
|---|
| 128 | </py:when> |
|---|
| 129 | </py:choose> |
|---|
| 130 | <py:for each="idx, blocks in enumerate(item.diffs)"> |
|---|
| 131 | <tbody py:for="block in blocks" class="$block.type"> |
|---|
| 132 | <py:choose test="block.type"> |
|---|
| 133 | |
|---|
| 134 | <py:when test="'unmod'"> <!--! Show identical lines on both "sides" --> |
|---|
| 135 | <tr py:for="idx, line in enumerate(block.base.lines)"> |
|---|
| 136 | <py:with vars="from_n = block.base.offset+idx+1; to_n = block.changed.offset+idx+1; |
|---|
| 137 | clines = block.changed.lines"> |
|---|
| 138 | <py:choose test="diff.style"> |
|---|
| 139 | <py:when test="'sidebyside'"> |
|---|
| 140 | <th id="P$from_n">$from_n</th> |
|---|
| 141 | <td class="l"><span>$line</span> </td> |
|---|
| 142 | <th id="L$to_n">${add_comment(to_n, file_id)}</th> |
|---|
| 143 | <td class="r"><span>${idx < len(clines) and clines[idx] or ''}</span> </td> |
|---|
| 144 | </py:when> |
|---|
| 145 | <py:when test="'inline'"> |
|---|
| 146 | <th id="P$from_n">$from_n</th> |
|---|
| 147 | <th id="L$to_n">${add_comment(to_n, file_id)}</th> |
|---|
| 148 | <td class="l"><span>$line</span> </td> |
|---|
| 149 | </py:when> |
|---|
| 150 | </py:choose> |
|---|
| 151 | </py:with> |
|---|
| 152 | </tr> |
|---|
| 153 | </py:when> |
|---|
| 154 | |
|---|
| 155 | <py:when test="'add'"> <!--! Show only added lines, on the "right side" --> |
|---|
| 156 | <tr py:for="idx, line in enumerate(block.changed.lines)" |
|---|
| 157 | class="${diff.style == 'inline' and first_last(idx, block.changed.lines) or None}"> |
|---|
| 158 | <py:with vars="to_n = block.changed.offset+idx+1"> |
|---|
| 159 | <py:choose test="diff.style"> |
|---|
| 160 | <py:when test="'sidebyside'"> |
|---|
| 161 | <th> </th><td class="l"> </td> |
|---|
| 162 | <th id="L$to_n">${add_comment(to_n, file_id)}</th><td class="r"><ins>$line</ins> </td> |
|---|
| 163 | </py:when> |
|---|
| 164 | <py:when test="'inline'"> |
|---|
| 165 | <th> </th><th id="L$to_n">${add_comment(to_n, file_id)}</th><td class="r"><ins>$line</ins> </td> |
|---|
| 166 | </py:when> |
|---|
| 167 | </py:choose> |
|---|
| 168 | </py:with> |
|---|
| 169 | </tr> |
|---|
| 170 | </py:when> |
|---|
| 171 | |
|---|
| 172 | <py:when test="'rem'"> <!--! Show only deleted lines, on the "left side" --> |
|---|
| 173 | <tr py:for="idx, line in enumerate(block.base.lines)" |
|---|
| 174 | class="${diff.style == 'inline' and first_last(idx, block.base.lines) or None}"> |
|---|
| 175 | <py:with vars="from_n = block.base.offset+idx+1"> |
|---|
| 176 | <py:choose test="diff.style"> |
|---|
| 177 | <py:when test="'sidebyside'"> |
|---|
| 178 | <th id="P$from_n">$from_n</th><td class="l"><del>$line</del> </td> |
|---|
| 179 | <th> </th><td class="r"> </td> |
|---|
| 180 | </py:when> |
|---|
| 181 | <py:when test="'inline'"> |
|---|
| 182 | <th id="P$from_n">$from_n</th><th> </th><td class="l"><del>$line</del> </td> |
|---|
| 183 | </py:when> |
|---|
| 184 | </py:choose> |
|---|
| 185 | </py:with> |
|---|
| 186 | </tr> |
|---|
| 187 | </py:when> |
|---|
| 188 | |
|---|
| 189 | <py:when test="'mod'"> <!--! Show edited lines, on both "sides" --> |
|---|
| 190 | <py:choose test="diff.style"> |
|---|
| 191 | <py:when test="'sidebyside'"> |
|---|
| 192 | <py:choose> |
|---|
| 193 | <py:when test="len(block.base.lines) >= len(block.changed.lines)"> |
|---|
| 194 | <tr py:for="idx, line in enumerate(block.base.lines)"> |
|---|
| 195 | <th id="P${block.base.offset+idx+1}">${block.base.offset+idx+1}</th> |
|---|
| 196 | <td class="l"><span>$line</span> </td> |
|---|
| 197 | <py:with vars="within_change = idx < len(block.changed.lines)"> |
|---|
| 198 | <th id="L${within_change and block.changed.offset+idx+1 or '0'}"> |
|---|
| 199 | ${add_comment(within_change and block.changed.offset+idx+1 or 0, file_id)} |
|---|
| 200 | <!--!<a href="javascript:addComment(${}, $file_id, -1)"> |
|---|
| 201 | ${within_change and block.changed.offset+idx+1 or ' '}</a>--> |
|---|
| 202 | </th> |
|---|
| 203 | <td class="r"><span py:if="within_change">${block.changed.lines[idx]}</span> </td> |
|---|
| 204 | </py:with> |
|---|
| 205 | </tr> |
|---|
| 206 | </py:when> |
|---|
| 207 | <py:otherwise> <!--! there are more changed lines than original lines --> |
|---|
| 208 | <tr py:for="idx, line in enumerate(block.changed.lines)"> |
|---|
| 209 | <py:with vars="within_change = idx < len(block.base.lines)"> |
|---|
| 210 | <th id="P${within_change and block.base.offset+idx+1 or 0}">${within_change and block.base.offset+idx+1 or ' '}</th> |
|---|
| 211 | <td class="l"><span py:if="within_change">${block.base.lines[idx]}</span> </td> |
|---|
| 212 | </py:with> |
|---|
| 213 | <th id="L${block.changed.offset+idx+1}"> |
|---|
| 214 | ${add_comment(block.changed.offset+idx+1, file_id)} |
|---|
| 215 | </th> |
|---|
| 216 | <td class="r"><span>$line</span> </td> |
|---|
| 217 | </tr> |
|---|
| 218 | </py:otherwise> |
|---|
| 219 | </py:choose> |
|---|
| 220 | </py:when> |
|---|
| 221 | <py:when test="'inline'"> |
|---|
| 222 | <!--! First show the "old" lines --> |
|---|
| 223 | <tr py:for="idx, line in enumerate(block.base.lines)" |
|---|
| 224 | class="${idx == 0 and 'first' or None}"> |
|---|
| 225 | <th id="P${block.base.offset+idx+1}">${block.base.offset+idx+1}</th> |
|---|
| 226 | <th> </th> |
|---|
| 227 | <td class="l"><span>$line</span> </td> |
|---|
| 228 | </tr> |
|---|
| 229 | <!--! Then show the "new" lines --> |
|---|
| 230 | <tr py:for="idx, line in enumerate(block.changed.lines)" |
|---|
| 231 | class="${idx + 1 == len(block.changed.lines) and 'last' or None}"> |
|---|
| 232 | <th> </th> |
|---|
| 233 | <th id="L${block.changed.offset+idx+1}"> |
|---|
| 234 | ${add_comment(block.changed.offset+idx+1, file_id)} |
|---|
| 235 | </th> |
|---|
| 236 | <td class="r"><span>$line</span> </td> |
|---|
| 237 | </tr> |
|---|
| 238 | </py:when> |
|---|
| 239 | </py:choose> |
|---|
| 240 | </py:when> |
|---|
| 241 | |
|---|
| 242 | </py:choose> |
|---|
| 243 | </tbody> |
|---|
| 244 | <py:if test="idx < len(item.diffs) - 1"> |
|---|
| 245 | <tbody class="skipped" py:choose="diff.style" |
|---|
| 246 | py:with="fromline = item.diffs[idx+1][0].base.offset+1; |
|---|
| 247 | toline = item.diffs[idx+1][0].changed.offset+1"> |
|---|
| 248 | <tr py:when="'sidebyside'"> |
|---|
| 249 | <th><a href="$old.href#L$fromline">…</a></th><td> </td> |
|---|
| 250 | <th><a href="$new.href#L$toline">…</a></th><td> </td> |
|---|
| 251 | </tr> |
|---|
| 252 | <tr py:when="'inline'"> |
|---|
| 253 | <th><a href="$old.href#L$fromline">…</a></th> |
|---|
| 254 | <th><a href="$new.href#L$toline">…</a></th> |
|---|
| 255 | <td><em py:if="'diffs_title' in item">${item.diffs_title[idx+1]}</em> </td> |
|---|
| 256 | </tr> |
|---|
| 257 | </tbody> |
|---|
| 258 | </py:if> |
|---|
| 259 | </py:for> |
|---|
| 260 | </table> |
|---|
| 261 | </li> |
|---|
| 262 | </py:for> |
|---|
| 263 | </ul> |
|---|
| 264 | |
|---|
| 265 | </div> |
|---|