diff --git a/trac/htdocs/css/ticket.css b/trac/htdocs/css/ticket.css
|
a
|
b
|
div.comment ol { list-style: decimal } |
| 123 | 123 | font-size: 100%; |
| 124 | 124 | font-weight: normal; |
| 125 | 125 | } |
| | 126 | .trac-loading { |
| | 127 | background: url(../loading.gif) 0 50% no-repeat; |
| | 128 | margin: 0 1em; |
| | 129 | padding-left: 20px; |
| | 130 | display: none; |
| | 131 | } |
| 126 | 132 | .threading, #changelog .inlinebuttons { float: right; margin-left: 0.2em } |
| 127 | 133 | .threading { font-size: 85%; } |
| 128 | 134 | .threading :link, .threading :visited { border-bottom: 0 } |
| … |
… |
div.comment ol { list-style: decimal } |
| 134 | 140 | #changelog .trac-lastedit :link, #changelog .trac-lastedit :visited { color: inherit } |
| 135 | 141 | |
| 136 | 142 | #changelog .changes, #ticketchange .changes { list-style: square; margin-left: 2em; padding: 0 } |
| | 143 | .trac-conflict { border-left: .3em solid #e44; padding-left: .3em; } |
| 137 | 144 | #changelog .comment, #ticketchange .comment { margin-left: 2em } |
| 138 | 145 | |
| 139 | 146 | form .field { margin-top: .75em; width: 100% } |
diff --git a/trac/htdocs/js/auto_preview.js b/trac/htdocs/js/auto_preview.js
|
a
|
b
|
|
| 12 | 12 | // - `args`: additional form data to be passed with the XHR. |
| 13 | 13 | // - `update`: the function that is called with the submission reply. It |
| 14 | 14 | // is called with the request data and the reply. |
| 15 | | $.fn.autoSubmit = function(args, update) { |
| | 15 | // - `busy`: an object or jQuery selector to be shown while requesting an |
| | 16 | // update. |
| | 17 | $.fn.autoSubmit = function(args, update, busy) { |
| 16 | 18 | if (this.length == 0 || auto_preview_timeout <= 0) |
| 17 | 19 | return this; |
| 18 | 20 | if (this[0].nodeName == 'FORM') { |
| … |
… |
|
| 46 | 48 | if (values_changed(new_values)) { |
| 47 | 49 | values = new_values; |
| 48 | 50 | updating = true; |
| | 51 | if (busy != undefined) |
| | 52 | $(busy).show(); |
| 49 | 53 | |
| 50 | 54 | // Construct request data |
| 51 | 55 | var data = values.slice(0); |
| … |
… |
|
| 60 | 64 | timer = setTimeout(request, timeout); |
| 61 | 65 | updating = false; |
| 62 | 66 | queued = false; |
| | 67 | if (busy != undefined) |
| | 68 | $(busy).hide(); |
| 63 | 69 | update(data, reply); |
| 64 | 70 | }, |
| 65 | 71 | error: function(req, err, exc) { |
| 66 | 72 | updating = false; |
| 67 | 73 | queued = false; |
| | 74 | if (busy != undefined) |
| | 75 | $(busy).hide(); |
| 68 | 76 | }, |
| 69 | 77 | }); |
| 70 | 78 | } |
diff --git a/trac/ticket/templates/ticket.html b/trac/ticket/templates/ticket.html
|
a
|
b
|
|
| 60 | 60 | // Collapse property form if comment editor has focus |
| 61 | 61 | if (show_preview && comment_focused) |
| 62 | 62 | $("#modify").parent().addClass("collapsed"); |
| 63 | | }); |
| | 63 | }, "#ticketchange .trac-loading"); |
| 64 | 64 | $("#trac-comment-editor").autoSubmit({preview_comment: '1'}, function(data, reply) { |
| 65 | 65 | var comment = $("#trac-comment-editor").next("div.comment").html(reply); |
| 66 | 66 | comment.toggle(comment.children().length != 0); |
| 67 | | }); |
| | 67 | }, "#changelog .trac-loading"); |
| 68 | 68 | /*]]>*/ |
| 69 | 69 | <py:if test="preview_mode"> |
| 70 | 70 | $("#attachments").toggleClass("collapsed"); |
| … |
… |
|
| 74 | 74 | <py:otherwise> |
| 75 | 75 | $("#propertyform").autoSubmit({preview: '1'}, function(data, reply) { |
| 76 | 76 | $('#ticket').replaceWith(reply); |
| 77 | | }); |
| | 77 | }, "#ticket .trac-loading"); |
| 78 | 78 | <py:if test="not preview_mode"> |
| 79 | 79 | $("#field-summary").focus(); |
| 80 | 80 | </py:if> |
| … |
… |
|
| 167 | 167 | <div id="trac-edit-warning" class="warning system-message" |
| 168 | 168 | style="${'display: none' if start_time == ticket['changetime'] else None}"> |
| 169 | 169 | This ticket has been modified since you started editing. You should review the |
| 170 | | <em class="trac-new">other modifications</em> which have been appended above. |
| | 170 | <em class="trac-new">other modifications</em> which have been appended above, |
| | 171 | and any <em class="trac-conflict">conflicts</em> shown in the preview below. |
| 171 | 172 | You can nevertheless proceed and submit your changes if you wish so. |
| 172 | 173 | </div> |
| 173 | 174 | <!--! Comment field --> |
| … |
… |
|
| 317 | 318 | <div py:if="ticket.exists and can_append" id="ticketchange" class="ticketdraft" |
| 318 | 319 | style="${'display: none' if not (change_preview.fields or change_preview.comment) |
| 319 | 320 | or cnum_edit is not None else None}"> |
| 320 | | <xi:include href="ticket_change.html" py:with="change = change_preview"/> |
| | 321 | <xi:include href="ticket_change.html" py:with="change = change_preview; preview = True"/> |
| 321 | 322 | </div> |
| 322 | 323 | |
| 323 | 324 | <!--! Author or Reporter --> |
diff --git a/trac/ticket/templates/ticket_box.html b/trac/ticket/templates/ticket_box.html
|
a
|
b
|
Arguments: |
| 18 | 18 | <div class="date"> |
| 19 | 19 | <p i18n:msg="created" py:if="ticket.exists">Opened ${pretty_dateinfo(ticket.time)}</p> |
| 20 | 20 | <p i18n:msg="modified" py:if="ticket.changetime != ticket.time">Last modified ${pretty_dateinfo(ticket.changetime)}</p> |
| 21 | | <p py:if="not ticket.exists"><i>(ticket not yet created)</i></p> |
| | 21 | <p py:if="not ticket.exists"><span class="trac-loading"/><i>(ticket not yet created)</i></p> |
| 22 | 22 | </div> |
| 23 | 23 | <!--! use a placeholder if it's a new ticket --> |
| 24 | 24 | <h2 class="summary searchable">$ticket.summary</h2> |
diff --git a/trac/ticket/templates/ticket_change.html b/trac/ticket/templates/ticket_change.html
|
a
|
b
|
Arguments: |
| 9 | 9 | - cnum_hist=None: the comment number for which to show a historical content |
| 10 | 10 | - can_append=False: True if the user is allowed to append to tickets |
| 11 | 11 | - has_edit_comment=False: True if the user is allowed to edit all comments |
| | 12 | - preview=False: True if rendering a change preview |
| 12 | 13 | --> |
| 13 | 14 | <html xmlns="http://www.w3.org/1999/xhtml" |
| 14 | 15 | xmlns:py="http://genshi.edgewall.org/" |
| … |
… |
Arguments: |
| 17 | 18 | py:with="cnum = change.get('cnum'); hide_buttons = value_of('hide_buttons', False); |
| 18 | 19 | cnum_edit = value_of('cnum_edit'); cnum_hist = value_of('cnum_hist'); |
| 19 | 20 | can_append = value_of('can_append', False); has_edit_comment = value_of('has_edit_comment', False); |
| | 21 | preview = value_of('preview', False); |
| 20 | 22 | can_edit_comment = has_edit_comment or (authname and authname != 'anonymous' |
| 21 | 23 | and authname == change.author); |
| 22 | 24 | show_editor = can_edit_comment and str(cnum) == cnum_edit; |
| … |
… |
Arguments: |
| 54 | 56 | <i18n:msg params="author">Changed by ${authorinfo(change.author)}</i18n:msg> |
| 55 | 57 | </py:otherwise> |
| 56 | 58 | </py:choose> |
| | 59 | <span py:if="preview or show_editor" class="trac-loading"/> |
| 57 | 60 | </h3> |
| 58 | 61 | <div py:if="show_buttons" class="trac-ticket-buttons"> |
| 59 | 62 | <form py:if="'cnum' in change and can_edit_comment" method="get" action="#comment:${cnum}"> |
| … |
… |
Arguments: |
| 71 | 74 | </form> |
| 72 | 75 | </div> |
| 73 | 76 | <ul py:if="change.fields" class="changes"> |
| 74 | | <li py:for="field_name, field in sorted(change.fields.iteritems(), key=lambda item: item[1].label.lower())"> |
| | 77 | <li py:for="field_name, field in sorted(change.fields.iteritems(), key=lambda item: item[1].label.lower())" |
| | 78 | class="${'trac-conflict' if preview and field_name in conflicts else None}"> |
| 75 | 79 | <strong>${field.label}</strong> |
| 76 | 80 | <py:choose> |
| 77 | 81 | <py:when test="field_name == 'attachment'"><i18n:msg params="name"> |
diff --git a/trac/ticket/templates/ticket_preview.html b/trac/ticket/templates/ticket_preview.html
|
a
|
b
|
Render data relevant to automatic ticket |
| 18 | 18 | </div> |
| 19 | 19 | <input type="hidden" name="view_time" value="${to_utimestamp(ticket['changetime'])}"/> |
| 20 | 20 | <div id="preview"><xi:include py:if="change_preview.fields or change_preview.comment" |
| 21 | | href="ticket_change.html" py:with="change = change_preview"/></div> |
| | 21 | href="ticket_change.html" py:with="change = change_preview; preview = True"/></div> |
| 22 | 22 | </html> |
diff --git a/trac/ticket/web_ui.py b/trac/ticket/web_ui.py
|
a
|
b
|
class TicketModule(Component): |
| 1480 | 1480 | changes = [] |
| 1481 | 1481 | cnum = 0 |
| 1482 | 1482 | skip = False |
| | 1483 | start_time = data.get('start_time') |
| | 1484 | conflicts = set() |
| 1483 | 1485 | for change in self.rendered_changelog_entries(req, ticket): |
| 1484 | 1486 | # change['permanent'] is false for attachment changes; true for |
| 1485 | 1487 | # other changes. |
| … |
… |
class TicketModule(Component): |
| 1506 | 1508 | values[k] = v['new'] |
| 1507 | 1509 | if 'description' in change['fields']: |
| 1508 | 1510 | data['description_change'] = change |
| | 1511 | if start_time is not None and change['date'] > start_time: |
| | 1512 | conflicts.update(change['fields']) |
| 1509 | 1513 | if not skip: |
| 1510 | 1514 | changes.append(change) |
| 1511 | 1515 | |
| … |
… |
class TicketModule(Component): |
| 1566 | 1570 | data['%s_link' % user] = self._query_link(req, user, |
| 1567 | 1571 | ticket[user]) |
| 1568 | 1572 | data.update({ |
| 1569 | | 'context': context, |
| | 1573 | 'context': context, 'conflicts': conflicts, |
| 1570 | 1574 | 'fields': fields, 'changes': changes, 'replies': replies, |
| 1571 | 1575 | 'attachments': AttachmentModule(self.env).attachment_data(context), |
| 1572 | 1576 | 'action_controls': action_controls, 'action': selected_action, |