Merge lp:~cprov/launchpad/ic-show-hide into lp:launchpad

Proposed by Celso Providelo
Status: Merged
Merged at revision: 16992
Proposed branch: lp:~cprov/launchpad/ic-show-hide
Merge into: lp:launchpad
Diff against target: 286 lines (+135/-26)
2 files modified
lib/lp/code/javascript/branchmergeproposal.inlinecomments.js (+76/-14)
lib/lp/code/javascript/tests/test_branchmergeproposal.inlinecomments.js (+59/-12)
To merge this branch: bzr merge lp:~cprov/launchpad/ic-show-hide
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+215691@code.launchpad.net

Description of the change

Implements another auxiliary widget to show/hide rendered inline comments.

Fixes presentation order of draft and published inline comments. Drafts are always presented after chronologically-ordered (serve-side) published comments for the context diff line.

As a code refactoring/cleanup, removes DiffNav._showPreviewDiff() 'force' argument, since it's not used (or needed).

To post a comment you must log in.
Revision history for this message
William Grant (wgrant) wrote :

The whole previous().previous().previous().previous()... business is a trainwreck, but it should work for now.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/code/javascript/branchmergeproposal.inlinecomments.js'
2--- lib/lp/code/javascript/branchmergeproposal.inlinecomments.js 2014-04-04 05:23:48 +0000
3+++ lib/lp/code/javascript/branchmergeproposal.inlinecomments.js 2014-04-24 11:02:44 +0000
4@@ -84,19 +84,20 @@
5 namespace.create_row = function(comment) {
6 var ident = comment.line_number + '-draft';
7 var headerrow = Y.Node.create(
8- '<tr><td colspan="2"></td></tr>').addClass('ict-header');
9+ '<tr><td class="line-no"></td><td></td></tr>').addClass('ict-header');
10 var headerspan;
11 var newrow;
12 if (Y.Lang.isUndefined(comment.person)) {
13 // Creates a draft inline comment area.
14 headerspan = Y.Node.create('<span></span>').set(
15- 'text', 'Draft comment.');
16+ 'text', 'Draft comment');
17 headerrow.set('id', 'ict-' + ident + '-header');
18- newrow = Y.Node.create('<tr><td></td><td><div>' +
19+ newrow = Y.Node.create('<tr><td class="line-no"></td><td><div>' +
20 '<span class="yui3-editable_text-text"></span>' +
21 '<div class="yui3-editable_text-trigger"></div>' +
22 '</div></td></tr>').set('id', 'ict-' + ident);
23 newrow.one('td>div').set('id', 'inlinecomment-' + ident);
24+ newrow.addClass('draft');
25 if (!Y.Lang.isUndefined(comment.text)) {
26 namespace.inlinecomments[comment.line_number] = comment.text;
27 newrow.one('span').set('text', comment.text);
28@@ -123,19 +124,29 @@
29 var fmt_date = 'on ' + Y.Date.format(
30 new Date(comment.date), {format: '%Y-%m-%d'});
31 headerspan.one('span').set('text', fmt_date);
32- newrow = Y.Node.create('<tr><td></td><td><span></span></td></tr>');
33+ newrow = Y.Node.create(
34+ '<tr><td class="line-no"></td><td><span></span></td></tr>');
35 newrow.one('span').set('text', comment.text);
36 }
37- headerrow.one('td').appendChild(headerspan);
38+ headerrow.one('td:last-child').appendChild(headerspan);
39
40 // We want to have the comments in order after the line.
41- var tr = Y.one('#diff-line-' + (parseInt(comment.line_number, 10) + 1));
42- if (tr !== null) {
43- tr.insert(headerrow, 'before');
44+ var base_line = Y.one(
45+ '#diff-line-' + (parseInt(comment.line_number, 10) + 1));
46+ if (base_line !== null) {
47+ // If there are drafts, they should remain at the bottom.
48+ if (base_line.previous().hasClass('draft')) {
49+ base_line = base_line.previous().previous();
50+ }
51+ base_line.insert(headerrow, 'before');
52 } else {
53 // If this is the last row, grab the last child.
54- tr = Y.one('.diff>tbody>tr:last-child');
55- tr.insert(headerrow, 'after');
56+ base_line = Y.one('.diff>tbody>tr:last-child');
57+ // If there are drafts, they should remain at the bottom.
58+ if (base_line.hasClass('draft')) {
59+ base_line = base_line.previous().previous();
60+ }
61+ base_line.insert(headerrow, 'after');
62 }
63 headerrow.insert(newrow, 'after');
64
65@@ -207,6 +218,56 @@
66 };
67
68
69+var InlineCommentToggle = function () {
70+ InlineCommentToggle.superclass.constructor.apply(this, arguments);
71+};
72+
73+Y.mix(InlineCommentToggle, {
74+
75+ NAME: 'inlinecommenttoggle',
76+
77+ ATTRS: {
78+ }
79+
80+});
81+
82+Y.extend(InlineCommentToggle, Y.Widget, {
83+
84+ renderUI: function() {
85+ var ui = Y.Node.create('<li><label>' +
86+ '<input type="checkbox" checked="checked" id="show-ic"/>' +
87+ '&nbsp;Show inline comments</label></li>');
88+ var ul = Y.one('#review-diff div div ul.horizontal');
89+ if (ul) {
90+ ul.appendChild(ui);
91+ }
92+ },
93+
94+ bindUI: function() {
95+ var cb = Y.one('#show-ic');
96+ if (cb === null) {
97+ return;
98+ }
99+ var self = this;
100+ cb.on('click', function() {
101+ self.showIC(cb.get('checked'));
102+ });
103+ },
104+
105+ showIC: function(display) {
106+ var css_display = 'none';
107+ if (display) {
108+ css_display = 'table-row';
109+ }
110+ Y.all('.ict-header').each( function() {
111+ this.setStyle('display', css_display);
112+ this.next().setStyle('display', css_display);
113+ });
114+ }
115+});
116+
117+namespace.InlineCommentToggle = InlineCommentToggle;
118+
119
120 function DiffNav(config) {
121 DiffNav.superclass.constructor.apply(this, arguments);
122@@ -239,10 +300,10 @@
123 container.append(navigator);
124 var self = this;
125 navigator.on('change', function() {
126- self._showPreviewDiff(this.get('value'), false);
127+ self._showPreviewDiff(this.get('value'));
128 });
129 this._connectScrollers();
130- this._showPreviewDiff(navigator.get('value'), true);
131+ this._showPreviewDiff(navigator.get('value'));
132 }
133 }
134
135@@ -288,6 +349,7 @@
136 set_status_updated: function() {
137 var rc = Y.lp.code.branchmergeproposal.reviewcomment;
138 (new rc.NumberToggle()).render();
139+ (new namespace.InlineCommentToggle()).render();
140 if (this.get('previewdiff_id')) {
141 namespace.setup_inline_comments(this.get('previewdiff_id'));
142 }
143@@ -327,7 +389,7 @@
144 Y.all('.inline-comment-scroller').each( function(node) {
145 rc.link_scroller(node, '#review-diff', function() {
146 self._showPreviewDiff(
147- node.getAttribute('data-previewdiff-id'), false);
148+ node.getAttribute('data-previewdiff-id'));
149 });
150 });
151 },
152@@ -374,7 +436,7 @@
153 *
154 * @method _showPreviewDiff
155 */
156- _showPreviewDiff: function(previewdiff_id, force) {
157+ _showPreviewDiff: function(previewdiff_id) {
158 var navigator = this.get('navigator');
159 if (!Y.Lang.isValue(navigator)) {
160 // DiffNav was not properly initialised.
161
162=== modified file 'lib/lp/code/javascript/tests/test_branchmergeproposal.inlinecomments.js'
163--- lib/lp/code/javascript/tests/test_branchmergeproposal.inlinecomments.js 2014-04-04 05:23:48 +0000
164+++ lib/lp/code/javascript/tests/test_branchmergeproposal.inlinecomments.js 2014-04-24 11:02:44 +0000
165@@ -55,7 +55,7 @@
166 Y.Assert.areSame(
167 "ws.op=getDraftInlineComments&previewdiff_id=1",
168 mockio.requests[1].config.data);
169- draft_comments = {'3': 'Zoing!'};
170+ draft_comments = {'2': 'Boing!', '3': 'Zoing!'};
171 mockio.success({
172 responseText: Y.JSON.stringify(draft_comments),
173 responseHeaders: {'Content-Type': 'application/json'}});
174@@ -88,9 +88,16 @@
175 var text = header.next();
176 Y.Assert.areEqual('This is preloaded.', text.get('text'));
177
178- // Draft comment is displayed.
179+ // Draft comment for line 2 is displayed after all published
180+ // comments.
181+ header = text.next()
182+ Y.Assert.areEqual('Draft comment', header.get('text'));
183+ var text = header.next();
184+ Y.Assert.areEqual('Boing!', text.get('text'));
185+
186+ // Draft comment for line 3 is displayed.
187 header = Y.one('#diff-line-3').next();
188- Y.Assert.areEqual('Draft comment.', header.get('text'));
189+ Y.Assert.areEqual('Draft comment', header.get('text'));
190 text = header.next();
191 Y.Assert.areEqual('Zoing!', text.get('text'));
192 },
193@@ -117,7 +124,7 @@
194 // LP was hit and a comment was created.
195 Y.Assert.areEqual(1, mockio.requests.length);
196 Y.Assert.areEqual(
197- 'Draft comment.', Y.one('#ict-1-draft-header').get('text'));
198+ 'Draft comment', Y.one('#ict-1-draft-header').get('text'));
199 Y.Assert.areEqual(
200 'Go!', ic_area.one('.yui3-editable_text-text').get('text'));
201
202@@ -283,12 +290,11 @@
203 // The local (fake) setup_inline_comments function
204 // was called with the selected diff_id value.
205 Y.Assert.areEqual(101, this.inline_comments_requested_id);
206- // NumberToggle widget is rendered
207- Y.Assert.isNotNull(Y.one('.diff-content').one('#show-no'));
208 // Diff content is rendered/updated.
209+ var comment = Y.one(
210+ '.diff-content table tbody tr td').next()
211 Y.Assert.areSame(
212- "foo bar",
213- Y.one('.diff-content table tbody tr td').next().get('text'));
214+ "foo bar", comment.get('text'));
215 // The option corresponding to the current 'preview_diff'
216 // is selected and contains the expected text (title and
217 // formatted date_created).
218@@ -321,6 +327,50 @@
219 Y.Assert.areEqual(202, this.inline_comments_requested_id);
220 },
221
222+ test_diff_lineno_show_hide: function() {
223+ // NumberToggle widget is rendered as a checked checkbox.
224+ // Checking/Unchecking it show or hide the diff
225+ // line-numbers cells.
226+ var line_no_check = Y.one('.diff-content').one('#show-no');
227+ Y.Assert.isTrue(line_no_check.get('checked'));
228+ Y.Assert.areEqual(
229+ 'table-cell', Y.one('td.line-no').getStyle('display'));
230+ line_no_check.set('checked', false);
231+ line_no_check.simulate('change');
232+ // XXX cprov 20140414: a tiny/empty wait seems to be
233+ // required for the DOM changes become accessible.
234+ this.wait(function() {}, 1);
235+ Y.Assert.areEqual(
236+ 'none', Y.one('td.line-no').getStyle('display'));
237+ line_no_check.set('checked', true);
238+ line_no_check.simulate('change');
239+ this.wait(function() {}, 1);
240+ Y.Assert.areEqual(
241+ 'block', Y.one('td.line-no').getStyle('display'));
242+ },
243+
244+ test_diff_inline_show_hide: function() {
245+ // InlineCommentToggle widget is rendered as a checked
246+ // checkbox. Checking/Unchecking it show or hide all
247+ // rendered inline comments.
248+ var ic_check = Y.one('.diff-content').one('#show-ic');
249+ Y.Assert.isTrue(ic_check.get('checked'));
250+ // Render a draft comment for tests.
251+ module.create_row({'line_number': '1', 'text': 'inline'});
252+ Y.Assert.areEqual(
253+ 'table-row', Y.one('tr.ict-header').getStyle('display'));
254+ ic_check.set('checked', false);
255+ ic_check.simulate('change');
256+ this.wait(function() {}, 1);
257+ Y.Assert.areEqual(
258+ 'none', Y.one('tr.ict-header').getStyle('display'));
259+ ic_check.set('checked', true);
260+ ic_check.simulate('change');
261+ this.wait(function() {}, 1);
262+ Y.Assert.areEqual(
263+ 'table-row', Y.one('tr.ict-header').getStyle('display'));
264+ },
265+
266 test_diff_nav_scrollers: function() {
267 // The Diff Navigator review comment *scrollers* are connected
268 // upon widget rendering and when clicked trigger the diff
269@@ -380,16 +430,13 @@
270 rc.window_scroll_anim.fire('end');
271 });
272 var called_pd_id = null;
273- var called_force = null;
274- this.diffnav._showPreviewDiff = function (pd_id, force) {
275+ this.diffnav._showPreviewDiff = function (pd_id) {
276 called_pd_id = pd_id;
277- called_force = force;
278 };
279 // the new scroller works, it has requested and diff update
280 // to the encoded data-previewdiff-id.
281 new_scroller.simulate('click');
282 Y.Assert.areEqual(202, called_pd_id);
283- Y.Assert.isFalse(called_force);
284 },
285
286 test_diff_nav_failed_diff_content: function() {