<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[271] sites/trunk/wordpress.org/public_html/style/trac/wp-trac.js: Trac JS cleanup: Reorganize this file to make it a bit more maintainable.</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://meta.trac.wordpress.org/changeset/271">271</a></dd>
<dt>Author</dt> <dd>nacin</dd>
<dt>Date</dt> <dd>2014-01-11 20:06:28 +0000 (Sat, 11 Jan 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Trac JS cleanup: Reorganize this file to make it a bit more maintainable.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#sitestrunkwordpressorgpublic_htmlstyletracwptracjs">sites/trunk/wordpress.org/public_html/style/trac/wp-trac.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="sitestrunkwordpressorgpublic_htmlstyletracwptracjs"></a>
<div class="modfile"><h4>Modified: sites/trunk/wordpress.org/public_html/style/trac/wp-trac.js (270 => 271)</h4>
<pre class="diff"><span>
<span class="info">--- sites/trunk/wordpress.org/public_html/style/trac/wp-trac.js 2014-01-11 19:22:00 UTC (rev 270)
+++ sites/trunk/wordpress.org/public_html/style/trac/wp-trac.js 2014-01-11 20:06:28 UTC (rev 271)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-var vnpTrac, coreKeywordList, gardenerKeywordList;
</del><ins>+var wpTrac, coreKeywordList, gardenerKeywordList;
</ins><span class="cx">
</span><span class="cx"> (function($){
</span><span class="cx">
</span><span class="lines">@@ -30,23 +30,20 @@
</span><span class="cx">
</span><span class="cx"> wpTrac = {
</span><span class="cx">
</span><del>- keywords : {},
- originalKeywords : {},
- field : {},
</del><span class="cx"> gardener : typeof wpBugGardener !== 'undefined',
</span><span class="cx">
</span><span class="cx"> init : function() {
</span><ins>+ wpTrac.hacks();
+ wpTrac.workflow.init();
+ wpTrac.nonGardeners();
+ },
+
+ hacks: function() {
</ins><span class="cx"> // Change 'Comments' and 'Stars' columns to dashicons glyphs to save space
</span><span class="cx"> $('th a[href*="sort=Comments"]').html('<div class="dashicons dashicons-admin-comments"></div>');
</span><span class="cx"> $('th a[href*="sort=Stars"]').html('<div class="dashicons dashicons-star-empty"></div>');
</span><span class="cx">
</span><del>- // Bring back 'Delete' comment buttons, if any.
- $('div.change').children('.trac-ticket-buttons').each( function() {
- var el = $(this);
- el.children().appendTo( el.prev().children('.trac-ticket-buttons') ).end().end().remove();
- });
-
- // Automatically preview images
</del><ins>+ // Automatically preview images.
</ins><span class="cx"> $('li.trac-field-attachment').each( function() {
</span><span class="cx"> var href, el, image, li = $(this);
</span><span class="cx"> el = $(this).find('.trac-rawlink');
</span><span class="lines">@@ -69,26 +66,21 @@
</span><span class="cx"> };
</span><span class="cx"> });
</span><span class="cx">
</span><del>- // 'User Interface' preferences tab => 'Help Links' (and removes icons-only setting)
- var uitab = $('#tab_userinterface');
- if ( uitab.length ) {
- if ( uitab.hasClass('active') ) {
- uitab.text('Help Links');
- $('input[name="ui.use_symbols"]').closest('div.field').remove();
- } else {
- uitab.find('a').text('Help Links');
- }
- }
</del><ins>+ // Restore the 'Delete' comment buttons, if any. The Trac plugin places them in a location we don't want.
+ // See https://meta.trac.wordpress.org/changeset/204.
+ $('div.change').children('.trac-ticket-buttons').each( function() {
+ var el = $(this);
+ el.children().appendTo( el.prev().children('.trac-ticket-buttons') ).end().end().remove();
+ });
</ins><span class="cx">
</span><span class="cx"> // Add After the Deadline (only add it if it loaded)
</span><span class="cx"> if ( $.isFunction( $.fn.addProofreader ) ) {
</span><span class="cx"> $('textarea').addProofreader();
</span><ins>+ $('.AtD_proofread_button').each(function() {
+ $(this).parent().appendTo( $(this).parents('fieldset').find('.wikitoolbar') );
+ });
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- $('.AtD_proofread_button').each(function() {
- $(this).parent().appendTo( $(this).parents('fieldset').find('.wikitoolbar') );
- });
-
</del><span class="cx"> // Force 'Attachments' and 'Modify Ticket' to be shown
</span><span class="cx"> $('#attachments').removeClass('collapsed');
</span><span class="cx"> $("#modify").parent().removeClass('collapsed');
</span><span class="lines">@@ -102,6 +94,7 @@
</span><span class="cx"> var action, hadClass,
</span><span class="cx"> form = $('#propertyform'),
</span><span class="cx"> modify = $('#modify').parent();
</span><ins>+
</ins><span class="cx"> if ( ! form.length ) {
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="lines">@@ -144,12 +137,12 @@
</span><span class="cx"> });
</span><span class="cx">
</span><span class="cx"> // Clear the milestone on wontfix, duplicate, worksforme, invalid
</span><del>- wpTrac.field.milestone = $('#field-milestone');
- if ( ! wpTrac.field.milestone.prop('disabled') ) {
</del><ins>+ var milestone = $('#field-milestone');
+ if ( ! milestone.prop('disabled') ) {
</ins><span class="cx"> $('#propertyform').submit( function() {
</span><span class="cx"> var action = $('input[name=action]:checked').val();
</span><span class="cx"> if ( 'duplicate' === action || ( 'resolve' === action && 'fixed' !== $('#action_resolve_resolve_resolution').val() ) ) {
</span><del>- wpTrac.field.milestone.val('');
</del><ins>+ milestone.val('');
</ins><span class="cx"> }
</span><span class="cx"> });
</span><span class="cx"> }
</span><span class="lines">@@ -176,249 +169,252 @@
</span><span class="cx"> .show();
</span><span class="cx"> });
</span><span class="cx">
</span><del>- // Start of Keywords manipulation.
- wpTrac.hiddenEl = $('#field-keywords');
- if ( ! wpTrac.hiddenEl.length )
- return;
</del><ins>+ // 'User Interface' preferences tab => 'Help Links' (and removes icons-only setting)
+ var uitab = $('#tab_userinterface');
+ if ( uitab.length ) {
+ if ( uitab.hasClass('active') ) {
+ uitab.text('Help Links');
+ $('input[name="ui.use_symbols"]').closest('div.field').remove();
+ } else {
+ uitab.find('a').text('Help Links');
+ }
+ }
+ },
</ins><span class="cx">
</span><del>- // Designed so the list could have come from another file.
- if ( typeof coreKeywordList === 'undefined' )
</del><ins>+ // If we're not dealing with a trusted bug gardener:
+ nonGardeners: function() {
+ if ( wpTrac.gardener ) {
</ins><span class="cx"> return;
</span><ins>+ }
</ins><span class="cx">
</span><del>- // If we're not a gardener and we're on /newticket (field-owner check), declutter.
- if ( ! wpTrac.gardener && $('#field-owner').length ) {
</del><ins>+ var version,
+ elements = {},
+ remove = true;
+
+ // If we're on /newticket (based on the field-owner check), declutter.
+ if ( $('#field-owner').length ) {
</ins><span class="cx"> $('#field-priority, #field-severity, #field-milestone, #field-cc, #field-keywords').parents('td').hide().prev().hide();
</span><span class="cx"> }
</span><del>-
- // Generate the workflow template.
- wpTrac.template();
</del><span class="cx">
</span><del>- wpTrac.field.add = $('#keyword-add');
</del><ins>+ elements.type = $('#field-type');
+ elements.version = $('#field-version');
+ version = elements.version.val();
</ins><span class="cx">
</span><del>- // Load up the initial keywords and the dropdown.
- wpTrac.populate();
</del><ins>+ // Remove task (blessed), or make a task ticket read only.
+ if ( 'task (blessed)' === elements.type.val() ) {
+ elements.type.after('<input type="hidden" name="field_type" value="task (blessed)" /> task (blessed)')
+ .parent().css('vertical-align', 'middle').end()
+ .remove();
+ } else {
+ elements.type.find('option[value="task (blessed)"]').remove();
+ }
</ins><span class="cx">
</span><del>- // Save these for later.
- wpTrac.originalKeywords = $.merge([], wpTrac.keywords);
</del><ins>+ // Once a Version is set, remove newer versions.
+ if ( version ) {
+ elements.version.find('option').each( function() {
+ var value = $(this).val();
+ if ( version === value )
+ remove = false;
+ else if ( remove && value )
+ $(this).remove();
+ });
+ }
+ },
</ins><span class="cx">
</span><del>- // Catch the submit to see if keywords were simply reordered.
- wpTrac.hiddenEl.parents('form').submit( wpTrac.submit );
</del><ins>+ workflow: (function() {
+ var keywords = {},
+ originalKeywords = {},
+ elements = {};
</ins><span class="cx">
</span><del>- // Keyword removal.
- $('#keyword-bin').delegate('a', 'click', function(e) {
- e.preventDefault();
- wpTrac.removeKeyword( $(this).parent() );
- });
</del><ins>+ return {
+ init: function() {
+ elements.hiddenEl = $('#field-keywords');
+ if ( ! elements.hiddenEl.length ) {
+ return;
+ }
</ins><span class="cx">
</span><del>- // Keyword adds.
- $('#keyword-add').bind('change keypress', function(e) {
- if ( e.type === 'keypress' ) {
- if ( e.which === 13 ) {
- e.stopPropagation();
- e.preventDefault();
- } else {
</del><ins>+ // Designed so the list could have come from another file.
+ if ( typeof coreKeywordList === 'undefined' ) {
</ins><span class="cx"> return;
</span><span class="cx"> }
</span><del>- }
- wpTrac.addKeyword( $(this).val() );
- $(this).val('');
- });
</del><span class="cx">
</span><del>- // Manual link.
- $('#edit-keywords').click( function() {
- wpTrac.hiddenEl.show().focus();
- $(this).hide();
- wpTrac.hiddenEl.change( wpTrac.populate );
- });
</del><ins>+ // Generate the workflow template.
+ wpTrac.workflow.template();
</ins><span class="cx">
</span><del>- // If we're not dealing with a trusted bug gardener:
- if ( ! wpTrac.gardener ) {
- var remove = true, version;
- wpTrac.field.type = $('#field-type');
- wpTrac.field.version = $('#field-version');
- version = wpTrac.field.version.val();
</del><ins>+ elements.add = $('#keyword-add');
</ins><span class="cx">
</span><del>- // Remove task (blessed), or make a task ticket read only.
- if ( 'task (blessed)' === wpTrac.field.type.val() ) {
- wpTrac.field.type.after('<input type="hidden" name="field_type" value="task (blessed)" /> task (blessed)')
- .parent().css('vertical-align', 'middle').end()
- .remove();
- } else {
- wpTrac.field.type.find('option[value="task (blessed)"]').remove();
- }
</del><ins>+ // Load up the initial keywords and the dropdown.
+ wpTrac.workflow.populate();
</ins><span class="cx">
</span><del>- // Once a Version is set, remove newer versions.
- if ( version ) {
- wpTrac.field.version.find('option').each( function() {
- var value = $(this).val();
- if ( version === value )
- remove = false;
- else if ( remove && value )
- $(this).remove();
- });
- }
- }
- },
</del><ins>+ // Save these for later.
+ originalKeywords = $.merge([], keywords);
</ins><span class="cx">
</span><del>- // Generates the workflow template.
- template : function() {
- var container = wpTrac.hiddenEl.parent(), html, labelWidth;
</del><ins>+ // Catch the submit to see if keywords were simply reordered.
+ elements.hiddenEl.parents('form').submit( wpTrac.workflow.submit );
</ins><span class="cx">
</span><del>- // Necessary to keep everything in line. The + 4 is a careful CSS balance.
- labelWidth = container.prev().width() + 4;
</del><ins>+ // Keyword removal.
+ elements.bin.on( 'click', 'a', function(e) {
+ e.preventDefault();
+ wpTrac.workflow.removeKeyword( $(this).parent() );
+ });
</ins><span class="cx">
</span><del>- // Rearrange the table to suit our needs.
- container.prev().detach().end()
- .attr('colspan', '2').addClass('has-js')
- .parents('table').css('table-layout', 'fixed');
</del><ins>+ // Keyword adds.
+ $('#keyword-add').bind('change keypress', function(e) {
+ if ( e.type === 'keypress' ) {
+ if ( e.which === 13 ) {
+ e.stopPropagation();
+ e.preventDefault();
+ } else {
+ return;
+ }
+ }
+ wpTrac.workflow.addKeyword( $(this).val() );
+ $(this).val('');
+ });
</ins><span class="cx">
</span><del>- // If the owner field exists, then we're on /newticket. Remove it.
- $('#field-owner').parents('tr').remove();
</del><ins>+ // Manual link.
+ $('#edit-keywords').click( function() {
+ elements.hiddenEl.show().focus();
+ $(this).hide();
+ elements.hiddenEl.change( wpTrac.workflow.populate );
+ });
+ },
</ins><span class="cx">
</span><del>- html = '<a id="edit-keywords">manual</a>';
- html += '<div><label id="keyword-label" for="keyword-add" style="width:' + labelWidth + 'px">Workflow Keywords:</label>';
- html += '<select id="keyword-add"><option value=""> - Add - </option></select></div>';
- html += '<div id="keyword-bin"></div>';
- container.prepend( html );
</del><ins>+ // Generates the workflow template.
+ template : function() {
+ var container = elements.hiddenEl.parent(), html, labelWidth;
</ins><span class="cx">
</span><del>- // Walk in the footsteps of Firefox autocomplete's trail of destruction,
- // tidying the radio buttons in its wake. See WP#17051.
- if ( $.browser.mozilla ) {
- $('#action input:radio').each( function() {
- this.checked = this.defaultChecked;
- });
- }
- },
</del><ins>+ // Necessary to keep everything in line. The + 4 is a careful CSS balance.
+ labelWidth = container.prev().width() + 4;
</ins><span class="cx">
</span><del>- // Populates the keywords and dropdown.
- populate : function() {
- var bin = $('#keyword-bin');
</del><ins>+ // Rearrange the table to suit our needs.
+ container.prev().detach().end()
+ .attr('colspan', '2').addClass('has-js')
+ .parents('table').css('table-layout', 'fixed');
</ins><span class="cx">
</span><del>- // For repopulation. Starting over.
- if ( bin.find('span').length )
- bin.empty();
</del><ins>+ // If the owner field exists, then we're on /newticket. Remove it.
+ $('#field-owner').parents('tr').remove();
</ins><span class="cx">
</span><del>- // Replace commas, collapse spaces, trim, then split by space.
- wpTrac.keywords = $.trim( wpTrac.hiddenEl.val().replace(',', ' ').replace(/ +/g, ' ') ).split(' ');
</del><ins>+ html = '<a id="edit-keywords">manual</a>';
+ html += '<div><label id="keyword-label" for="keyword-add" style="width:' + labelWidth + 'px">Workflow Keywords:</label>';
+ html += '<select id="keyword-add"><option value=""> - Add - </option></select></div>';
+ html += '<div id="keyword-bin"></div>';
+ container.prepend( html );
+ elements.bin = $('#keyword-bin');
</ins><span class="cx">
</span><del>- // Put our cleaned up version back into the hidden field.
- wpTrac.hiddenEl.val( wpTrac.keywords.join(' ') );
</del><ins>+ // Walk in the footsteps of Firefox autocomplete's trail of destruction,
+ // tidying the radio buttons in its wake. See #WP17051.
+ if ( $.browser.mozilla ) {
+ $('#action input:radio').each( function() {
+ this.checked = this.defaultChecked;
+ });
+ }
+ },
</ins><span class="cx">
</span><del>- // If we have a non-empty keyword, let's go through the process of adding the spans.
- if ( 1 !== wpTrac.keywords.length || wpTrac.keywords[0] !== '' ) {
- $.each( wpTrac.keywords, function( k, v ) {
- var html = $('<span />').text(v).attr('data-keyword', v).prepend('<a href="#" />');
- if ( v in coreKeywordList )
- html.attr('title', coreKeywordList[v]);
- html.appendTo( bin );
- });
- }
</del><ins>+ // Populates the keywords and dropdown.
+ populate : function() {
+ // For repopulation. Starting over.
+ if ( elements.bin.find('span').length )
+ elements.bin.empty();
</ins><span class="cx">
</span><del>- // Populate the dropdown.
- $.each( coreKeywordList, function( k, v ) {
- // Don't show special (permission-based) ones.
- if ( ! wpTrac.gardener && -1 !== $.inArray( k, gardenerKeywordList ) )
- return;
- wpTrac.field.add.append( '<option value="' + k + ( -1 !== $.inArray( k, wpTrac.keywords ) ? '" disabled="disabled">* ' : '">' ) + k + '</option>' );
- });
- },
</del><ins>+ // Replace commas, collapse spaces, trim, then split by space.
+ keywords = $.trim( elements.hiddenEl.val().replace(',', ' ').replace(/ +/g, ' ') ).split(' ');
</ins><span class="cx">
</span><del>- // Add a keyword. Takes a sanitized string.
- addKeyword : function( keyword ) {
- if ( ! keyword )
- return;
- var html, title = '';
- // Don't add it again.
- if ( -1 !== $.inArray( keyword, wpTrac.keywords ) )
- return;
- wpTrac.keywords.push( keyword );
</del><ins>+ // Put our cleaned up version back into the hidden field.
+ elements.hiddenEl.val( keywords.join(' ') );
</ins><span class="cx">
</span><del>- // Update the dropdown. Core keywords also get a title attribute with their description.
- if ( keyword in coreKeywordList ) {
- wpTrac.field.add.find('option[value=' + keyword + ']').prop('disabled', true).text('* ' + keyword);
- title = coreKeywordList[keyword];
- }
</del><ins>+ // If we have a non-empty keyword, let's go through the process of adding the spans.
+ if ( 1 !== keywords.length || keywords[0] !== '' ) {
+ $.each( keywords, function( k, v ) {
+ var html = $('<span />').text(v).attr('data-keyword', v).prepend('<a href="#" />');
+ if ( v in coreKeywordList )
+ html.attr('title', coreKeywordList[v]);
+ html.appendTo( elements.bin );
+ });
+ }
</ins><span class="cx">
</span><del>- if ( 'has-patch' === keyword )
- wpTrac.removeKeyword( 'needs-patch' );
- else if ( 'needs-patch' === keyword )
- wpTrac.removeKeyword( 'has-patch' );
</del><ins>+ // Populate the dropdown.
+ $.each( coreKeywordList, function( k, v ) {
+ // Don't show special (permission-based) ones.
+ if ( ! wpTrac.gardener && -1 !== $.inArray( k, gardenerKeywordList ) )
+ return;
+ elements.add.append( '<option value="' + k + ( -1 !== $.inArray( k, keywords ) ? '" disabled="disabled">* ' : '">' ) + k + '</option>' );
+ });
+ },
</ins><span class="cx">
</span><del>- // Add it to the bin, and refresh the hidden input.
- html = $('<span />').text(keyword).attr('data-keyword', keyword).prepend('<a href="#" />');
- if ( title )
- html.attr('title', title);
- html.appendTo( $('#keyword-bin') );
- wpTrac.hiddenEl.val( wpTrac.keywords.join(' ') );
- },
</del><ins>+ // Add a keyword. Takes a sanitized string.
+ addKeyword : function( keyword ) {
+ if ( ! keyword )
+ return;
+ var html, title = '';
+ // Don't add it again.
+ if ( -1 !== $.inArray( keyword, keywords ) )
+ return;
+ keywords.push( keyword );
</ins><span class="cx">
</span><del>- // Remove a keyword. Takes a jQuery object of a keyword in the bin, or a sanitized keyword as a string.
- removeKeyword : function( object ) {
- var keyword;
- if ( typeof object === 'string' ) {
- keyword = object;
- object = $('#keyword-bin').find('span[data-keyword="' + keyword + '"]');
- if ( ! object.length )
- return;
- } else {
- keyword = object.text();
- }
</del><ins>+ // Update the dropdown. Core keywords also get a title attribute with their description.
+ if ( keyword in coreKeywordList ) {
+ elements.add.find('option[value=' + keyword + ']').prop('disabled', true).text('* ' + keyword);
+ title = coreKeywordList[keyword];
+ }
</ins><span class="cx">
</span><del>- wpTrac.keywords = $.grep(wpTrac.keywords, function(v) {
- return v != keyword;
- });
- // Update the core keyword dropdown.
- if ( keyword in coreKeywordList )
- wpTrac.field.add.find('option[value=' + keyword + ']').prop('disabled', false).text( keyword );
- wpTrac.hiddenEl.val( wpTrac.keywords.join(' ') );
- object.remove();
- },
</del><ins>+ if ( 'has-patch' === keyword ) {
+ wpTrac.workflow.removeKeyword( 'needs-patch' );
+ } else if ( 'needs-patch' === keyword ) {
+ wpTrac.workflow.removeKeyword( 'has-patch' );
+ }
</ins><span class="cx">
</span><del>- // Check on submit that we're not just re-ordering keywords.
- // Otherwise, Trac flips out and adds a useless 'Keywords changed from X to X' marker.
- submit : function(e) {
- if ( wpTrac.keywords.length !== wpTrac.originalKeywords.length )
- return;
- var testKeywords = $.grep(wpTrac.keywords, function(v) {
- return -1 === $.inArray( v, wpTrac.originalKeywords );
- });
- // If the difference has no length, then restore to the original keyword order.
- if ( ! testKeywords.length )
- wpTrac.hiddenEl.val( wpTrac.originalKeywords.join(' ') );
- },
</del><ins>+ // Add it to the bin, and refresh the hidden input.
+ html = $('<span />').text(keyword).attr('data-keyword', keyword).prepend('<a href="#" />');
+ if ( title )
+ html.attr('title', title);
+ html.appendTo( elements.bin );
+ elements.hiddenEl.val( keywords.join(' ') );
+ },
</ins><span class="cx">
</span><del>- hide_cc_field: function() {
- var content = $( '#content' );
- if ( content.hasClass( 'query' ) ) {
- $( 'table.trac-clause tr.actions option[value="cc"]' ).remove();
- $( '#columns' ).find( 'input[type="checkbox"][name="col"][value="cc"]' ).parent().remove();
- }
- if ( content.hasClass( 'ticket' ) ) {
- $( '#changelog div.change' ).has( 'li.trac-field-cc' ).each( function() {
- var change = $(this), changes = change.children( 'ul.changes' );
- /* Three possibilities:
- The comment is just a single CC (hide the whole comment)
- The comment is a CC plus a comment (hide the CC line)
- The comment contains multiple property changes (hide only the CC line)
- */
- if ( changes.children( 'li' ).length === 1 ) {
- if ( change.children( 'div.comment' ).length === 0 ) {
- change.hide();
- } else {
- changes.hide();
- }
</del><ins>+ // Remove a keyword. Takes a jQuery object of a keyword in the bin, or a sanitized keyword as a string.
+ removeKeyword : function( object ) {
+ var keyword;
+ if ( typeof object === 'string' ) {
+ keyword = object;
+ object = elements.bin.find('span[data-keyword="' + keyword + '"]');
+ if ( ! object.length )
+ return;
</ins><span class="cx"> } else {
</span><del>- changes.children( 'li.trac-field-cc' ).hide();
</del><ins>+ keyword = object.text();
</ins><span class="cx"> }
</span><del>- });
</del><ins>+
+ keywords = $.grep( keywords, function(v) {
+ return v != keyword;
+ });
+
+ // Update the core keyword dropdown.
+ if ( keyword in coreKeywordList )
+ elements.add.find('option[value=' + keyword + ']').prop('disabled', false).text( keyword );
+ elements.hiddenEl.val( keywords.join(' ') );
+ object.remove();
+ },
+
+ // Check on submit that we're not just re-ordering keywords.
+ // Otherwise, Trac flips out and adds a useless 'Keywords changed from X to X' marker.
+ submit : function(e) {
+ if ( keywords.length !== originalKeywords.length )
+ return;
+ var testKeywords = $.grep( keywords, function(v) {
+ return -1 === $.inArray( v, originalKeywords );
+ });
+ // If the difference has no length, then restore to the original keyword order.
+ if ( ! testKeywords.length )
+ elements.hiddenEl.val( originalKeywords.join(' ') );
+ }
</ins><span class="cx"> }
</span><del>- },
</del><ins>+ }()),
</ins><span class="cx">
</span><span class="cx"> notifications: (function() {
</span><span class="cx"> var notifications, endpoint, _ticket;
</span><span class="cx">
</span><span class="cx"> function init( settings ) {
</span><del>- $( wpTrac.hide_cc_field );
</del><ins>+ $( hide_cc_field );
</ins><span class="cx"> if ( ! settings.authenticated ) {
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="lines">@@ -427,9 +423,36 @@
</span><span class="cx"> _ticket = settings.ticket;
</span><span class="cx"> ticketInit( _ticket );
</span><span class="cx"> }
</span><del>- $( reportInit() );
</del><ins>+ $( reportInit );
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+ function hide_cc_field() {
+ var content = $( '#content' );
+ if ( content.hasClass( 'query' ) ) {
+ $( 'table.trac-clause tr.actions option[value="cc"]' ).remove();
+ $( '#columns' ).find( 'input[type="checkbox"][name="col"][value="cc"]' ).parent().remove();
+ }
+ if ( content.hasClass( 'ticket' ) ) {
+ $( '#changelog div.change' ).has( 'li.trac-field-cc' ).each( function() {
+ var change = $(this), changes = change.children( 'ul.changes' );
+ /* Three possibilities:
+ The comment is just a single CC (hide the whole comment)
+ The comment is a CC plus a comment (hide the CC line)
+ The comment contains multiple property changes (hide only the CC line)
+ */
+ if ( changes.children( 'li' ).length === 1 ) {
+ if ( change.children( 'div.comment' ).length === 0 ) {
+ change.hide();
+ } else {
+ changes.hide();
+ }
+ } else {
+ changes.children( 'li.trac-field-cc' ).hide();
+ }
+ });
+ }
+ }
+
</ins><span class="cx"> function ticketInit( ticket ) {
</span><span class="cx"> $.ajax({
</span><span class="cx"> url: endpoint + '?trac-notifications=' + ticket,
</span></span></pre>
</div>
</div>
</body>
</html>