launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #16744
Re: [Merge] lp:~cprov/launchpad/ic-superseded-mps into lp:launchpad
Review: Approve code
Looks good, just a couple of inline comments.
Inline comments:
> --- lib/lp/app/javascript/comment.js 2014-04-04 05:23:48 +0000
> +++ lib/lp/app/javascript/comment.js 2014-05-15 03:58:24 +0000
> @@ -308,8 +308,6 @@
> initializer: function() {
> this.vote_input = Y.one('[id="field.vote"]');
> this.review_type = Y.one('[id="field.review_type"]');
> - this.publish_inline_comments = Y.one(
> - '[id="field.publish_inline_comments"]');
> this.in_reply_to = null;
> },
> /**
> @@ -334,6 +332,15 @@
> return selected.get('innerHTML');
> },
> /**
> + * Whether or not the review comment has inline comments to be published
> + *
> + * @method has_inline
> + */
> + has_inline: function() {
> + var inline_cb = Y.one('[id="field.publish_inline_comments"]');
> + return inline_cb !== null && inline_cb.get('checked')
> + },
Missing semicolon.
> + /**
> * Ensure that the widget's values are suitable for submission.
> *
> * This allows the vote to be submitted, even when no text is specified
> @@ -345,6 +352,9 @@
> if (this.get_vote() !== null) {
> return true;
> }
> + if (this.has_inline()) {
> + return true
> + }
> return namespace.Comment.prototype.validate.apply(this);
> },
> /**
> @@ -357,9 +367,6 @@
> namespace.Comment.prototype.set_disabled.call(this, disabled);
> this.vote_input.set('disabled', disabled);
> this.review_type.set('disabled', disabled);
> - if (this.publish_inline_comments) {
> - this.publish_inline_comments.set('disabled', disabled);
> - }
> },
> /**
> * Post the comment to the Launchpad API
> @@ -383,8 +390,8 @@
> if (this.in_reply_to !== null) {
> config.parameters.parent = this.in_reply_to.get('self_link');
> }
> - if (this.publish_inline_comments &&
> - this.publish_inline_comments.get('checked')) {
> +
> + if (this.has_inline()) {
> var ic = Y.lp.code.branchmergeproposal.inlinecomments;
> config.parameters.inline_comments = ic.inlinecomments;
> config.parameters.previewdiff_id = ic.current_previewdiff_id;
> @@ -451,9 +458,6 @@
> */
> reset_contents: function() {
> this.review_type.set('value', '');
> - if (this.publish_inline_comments) {
> - this.publish_inline_comments.set('value', '');
> - }
> this.vote_input.set('selectedIndex', 0);
> this.in_reply_to = null;
> namespace.Comment.prototype.reset_contents.apply(this);
> @@ -490,6 +494,11 @@
> this.review_type.on('keyup', this.syncUI, this);
> this.review_type.on('mouseup', this.syncUI, this);
> Y.all('a.menu-link-reply').on('click', this.reply_clicked, this);
> + Y.on('CodeReviewComment.SET_DISABLED', function(disabled) {
> + // this.set_disabled() unfortunately does too much for the
> + // current callsite (inlinecomment).
> + this.submit_button.set('disabled', disabled);
> + }, this);
> },
> /**
> * Implementation of Widget.syncUI: Update appearance according to state.
>
> === modified file 'lib/lp/code/browser/codereviewcomment.py'
> --- lib/lp/code/browser/codereviewcomment.py 2014-04-04 05:23:48 +0000
> +++ lib/lp/code/browser/codereviewcomment.py 2014-05-15 03:58:24 +0000
> @@ -292,18 +292,9 @@
> """Create the comment..."""
> vote = data.get('vote')
> review_type = data.get('review_type')
> - inline_comments = {}
> - previewdiff_id = None
> - if (getFeatureFlag('code.inline_diff_comments.enabled') and
> - data.get('publish_inline_comments')):
> - previewdiff_id = self.previewdiff.id
> - inline_comments = (
> - self.branch_merge_proposal.getDraftInlineComments(
> - previewdiff_id))
> self.branch_merge_proposal.createComment(
> self.user, subject=None, content=data['comment'],
> - parent=self.reply_to, vote=vote, review_type=review_type,
> - previewdiff_id=previewdiff_id, inline_comments=inline_comments)
> + parent=self.reply_to, vote=vote, review_type=review_type)
>
> @property
> def next_url(self):
>
> === modified file 'lib/lp/code/javascript/branchmergeproposal.inlinecomments.js'
> --- lib/lp/code/javascript/branchmergeproposal.inlinecomments.js 2014-05-07 06:16:12 +0000
> +++ lib/lp/code/javascript/branchmergeproposal.inlinecomments.js 2014-05-15 03:58:24 +0000
> @@ -62,6 +62,11 @@
> content_row.remove(true);
> }
> var config = {
> + on: {
> + success: function () {
> + Y.fire('inlinecomment.UPDATED');
> + }
> + },
> parameters: {
> previewdiff_id: namespace.current_previewdiff_id,
> comments: namespace.inlinecomments
> @@ -161,8 +166,8 @@
> namespace.cleanup_comments = function() {
> // Cleanup previous inline review comments.
> Y.all('.ict-header').each( function(line) {
> - line.next().remove();
> - line.remove();
> + line.next().remove(true);
> + line.remove(true);
> });
> };
>
> @@ -176,6 +181,7 @@
> comments.forEach( function (comment) {
> namespace.create_row(comment);
> });
> + Y.fire('inlinecomment.UPDATED');
> }
> },
> parameters: {
> @@ -203,6 +209,7 @@
> };
> namespace.create_row(comment);
> });
> + Y.fire('inlinecomment.UPDATED');
> }
> },
> parameters: {
> @@ -237,6 +244,68 @@
> };
>
>
> +var PublishDrafts = function () {
> + PublishDrafts.superclass.constructor.apply(this, arguments);
> +};
> +
> +Y.mix(PublishDrafts, {
> +
> + NAME: 'publishdrafts',
> +
> + ATTRS: {
> + }
> +
> +});
> +
> +Y.extend(PublishDrafts, Y.Widget, {
> +
> + /**
> + * syncUI implementation for PublishDrafts.
> + *
> + * Modifies the CodeReviewComment widget, by enable/disable it and
> + * adding/removing its 'publish_inline_comments' field according to
> + * the presence of draft inline comments to be published.
> + *
> + * @method syncUI
> + */
> + syncUI: function() {
> + this.get('srcNode').empty();
> + var n_drafts = Y.all('.draft').size();
>From http://yuilibrary.com/yui/docs/widget/, srcNode is used for progressive enhancement. It is given an existing non-JS widget which the JS should upgrade. There's no existing widget here, so I think srcNode should remain unused.
> + if (n_drafts == 0) {
> + Y.fire('CodeReviewComment.SET_DISABLED', true);
> + return;
> + }
> + var text = 'Publish ' + n_drafts + ' inline comment';
> + if (n_drafts > 1) text += 's';
> + var label = Y.Node.create('<a />')
> + .set('text', text);
> + var checkbox = Y.Node.create(
> + '<input id="field.publish_inline_comments"' +
> + 'name="field.publish_inline_comments"' +
> + 'type="checkbox" class="checkboxType"' +
> + 'checked=""></input>')
> + this.get('srcNode').append(checkbox);
> + this.get('srcNode').append(label);
> + Y.fire('CodeReviewComment.SET_DISABLED', false);
> + },
> +
> + /**
> + * bindUI implementation for PublishDrafts.
> + *
> + * Simply hook syncUI() to 'inlinecomment.UPDATE' events.
> + *
> + * @method bindUI
> + */
> + bindUI: function() {
> + Y.detach('inlinecomment.UPDATED');
> + Y.on('inlinecomment.UPDATED', this.syncUI, this);
> + }
> +
> +});
> +
> +namespace.PublishDrafts = PublishDrafts;
> +
> +
> var InlineCommentToggle = function () {
> InlineCommentToggle.superclass.constructor.apply(this, arguments);
> };
> @@ -383,7 +452,7 @@
> * @method cleanup_status
> */
> cleanup_status: function() {
> - this.get('srcNode').all('h2 img').remove();
> + this.get('srcNode').all('h2 img').remove(true);
> },
>
> /**
> @@ -395,6 +464,7 @@
> if (LP.cache.inline_diff_comments !== true) {
> return;
> }
> + namespace.cleanup_comments();
> namespace.populate_comments();
> this._connectScrollers();
> },
> @@ -408,10 +478,25 @@
> _connectScrollers: function() {
> var self = this;
> var rc = Y.lp.code.branchmergeproposal.reviewcomment;
> - Y.all('.inline-comment-scroller').each( function(node) {
> - rc.link_scroller(node, '#review-diff', function() {
> - self._showPreviewDiff(
> - node.getAttribute('data-previewdiff-id'));
> + Y.all('td[data-previewdiff-id]').each( function(td) {
> + // Comments from superseded MPs should be ignored.
> + if (td.getData('from-superseded') === 'True') {
> + return;
> + }
> + var previewdiff_id = td.getData('previewdiff-id');
> + var comment_id = td.getData('comment-id');
> + // We have to remove the old scrollers otherwise they will
> + // fire multiple 'click' handlers (and animations).
> + var scroller = td.one('.ic-scroller');
> + if (scroller !== null) {
> + scroller.remove(true);
> + }
> + scroller = Y.Node.create(
> + '<a href="" class="ic-scroller" style="float: right;">' +
> + 'View inline comments</a>');
> + td.append(scroller);
> + rc.link_scroller(scroller, '#review-diff', function() {
> + self._showPreviewDiff(previewdiff_id);
> });
> });
> },
> @@ -488,6 +573,14 @@
> self._updateDiff(preview_diff_uri);
> return;
> }
> +
> + var pub_drafts_container = Y.Node.create(
> + '<div class="publish_drafts_container">');
> + Y.one('[id="field.review_type"]').insert(
> + pub_drafts_container, 'after');
> + (new namespace.PublishDrafts(
> + {'srcNode': pub_drafts_container})).render();
> +
> var container = this.get('srcNode').one('.diff-navigator');
> container.empty();
> var preview_diffs_uri = LP.cache.context.preview_diffs_collection_link;
>
> === modified file 'lib/lp/code/javascript/tests/test_branchmergeproposal.inlinecomments.html'
> --- lib/lp/code/javascript/tests/test_branchmergeproposal.inlinecomments.html 2014-04-03 20:33:08 +0000
> +++ lib/lp/code/javascript/tests/test_branchmergeproposal.inlinecomments.html 2014-05-15 03:58:24 +0000
> @@ -72,11 +72,30 @@
> <li>lp.code.branchmergeproposal.inlinecomments.test</li>
> </ul>
>
> - <a id="scroll-one" class="inline-comment-scroller" href=""
> - data-previewdiff-id="101">Go to One</a>
> + <div>
> + <input id="field.review_type" type="text"></input>
> + <input id="field.actions.add" type="submit" value="Save"></input>
> + </div>
>
> - <a id="scroll-two" class="inline-comment-scroller" href=""
> - data-previewdiff-id="202">Go to Two</a>
> + <table class="conversation">
> + <tr>
> + <td data-previewdiff-id="102" data-from-superseded="True"
> + data-comment-id="10">
> + Comment from superseded </td>
> + </tr><tr>
> + <td data-previewdiff-id="101" data-from-superseded="False"
> + data-comment-id="1">
> + Comment One </td>
> + </tr><tr>
> + <td data-previewdiff-id="202" data-from-superseded="False"
> + data-comment-id="2">
> + Comment Two </td>
> + </tr><tr>
> + <td data-from-superseded="False"
> + data-comment-id="3">
> + No inlines </td>
> + </tr>
> + </table>
>
> <div id="review-diff">
>
>
> === modified file 'lib/lp/code/javascript/tests/test_branchmergeproposal.inlinecomments.js'
> --- lib/lp/code/javascript/tests/test_branchmergeproposal.inlinecomments.js 2014-05-07 06:16:12 +0000
> +++ lib/lp/code/javascript/tests/test_branchmergeproposal.inlinecomments.js 2014-05-15 03:58:24 +0000
> @@ -408,6 +408,31 @@
> 'table-row', Y.one('tr.ict-header').getStyle('display'));
> },
>
> + test_publish_drafts: function() {
> + // PublishDraft() widget modifies the add-comment form
> + // (adding/removing 'publish_inlines' checkbox) according
> + // to the existence of draft inline comments.
> + var container = Y.one('.publish_drafts_container')
> + Y.Assert.areEqual('', container.get('text'));
> + Y.Assert.isNull(container.one('[type=checkbox]'));
> + // A event is fired when the inlinecomments set changes.
> + Y.fire('inlinecomment.UPDATED');
> + Y.Assert.areEqual(
> + 'Publish 1 inline comment', container.get('text'));
> + Y.Assert.isNotNull(container.one('[type=checkbox]'));
> + // Adding another draft.
> + module.create_row({'line_number': '2', 'text': 'another'});
> + Y.fire('inlinecomment.UPDATED');
> + Y.Assert.areEqual(
> + 'Publish 2 inline comments', container.get('text'));
> + Y.Assert.isNotNull(container.one('[type=checkbox]'));
> + // Removing all drafts.
> + module.cleanup_comments();
> + Y.fire('inlinecomment.UPDATED');
> + Y.Assert.areEqual('', container.get('text'));
> + Y.Assert.isNull(container.one('[type=checkbox]'));
> + },
> +
> test_diff_nav_scrollers: function() {
> // The Diff Navigator review comment *scrollers* are connected
> // upon widget rendering and when clicked trigger the diff
> @@ -417,10 +442,26 @@
> this.reply_diffcontent();
> var mockio = this.diffnav.get('lp_client').io_provider;
> Y.Assert.areEqual(2, mockio.requests.length);
> + // The needed review-comment scrollers (View inline comments)
> + // are created. Only 'current' (non-superseded) comments
> + // associated with inline comments get a scroller.
> + var lines = []
> + Y.one('.conversation').get('text').split('\n').forEach(
> + function(line) { if (line.trim()) lines.push(line.trim()); }
> + );
> + Y.ArrayAssert.itemsAreEqual(
> + ['Comment from superseded',
> + 'Comment One View inline comments',
> + 'Comment Two View inline comments',
> + 'No inlines'],
> + lines);
> + // Scroller are identified as:
> + // 'ic-scroller-<previewdiff_id>-<comment_id>'.
> + var comment = Y.one('[data-comment-id="2"]');
> + var scroller = comment.one('.ic-scroller')
> // We need to re-instrument the scroller in other to
> // instantly fire the 'end' event (which runs the code
> // that matters to us).
> - scroller = Y.one('#scroll-two');
> scroller.on('click', function() {
> var rc = Y.lp.code.branchmergeproposal.reviewcomment;
> rc.window_scroll_anim.fire('end');
> @@ -446,20 +487,27 @@
> // hook new inline-comment scroller links.
> this.diffnav.set('navigator', Y.one('select'));
> // Let's create add a new scroller to the page.
> - var new_scroller = Y.Node.create(
> - '<a id="scroll-three" class="inline-comment-scroller" ' +
> - 'href="" data-previewdiff-id="202">Another scroller</a>');
> - Y.one('#scroll-two').insert(new_scroller, 'after');
> - // and instrument the inline-comment updated function.
> + var new_comment = Y.Node.create(
> + '<tr><td data-previewdiff-id="202" data-comment-id="3">' +
> + 'Comment Three</td></tr>');
> + Y.one('.conversation').append(new_comment);
> + // and instrument the inline-comment functions to remove
> + // and populate comments.
> + var cleaned = false;
> var populated = false;
> + module.cleanup_comments = function () {
> + cleaned = true;
> + };
> module.populate_comments = function () {
> populated = true;
> };
> - // Once called, update_on_new_comment() integrates the
> - // just-added scroller and updates the inline comments.
> + // Once called, update_on_new_comment() creates the scroller
> + // for the just-added comment and refreshes the inline comments.
> this.diffnav.update_on_new_comment();
> + var new_scroller = new_comment.one('.ic-scroller');
> Y.Assert.isTrue(new_scroller.hasClass('js-action'));
> Y.Assert.isTrue(populated);
> + Y.Assert.isTrue(cleaned);
> // Instrument the new scroller, so it will instantly fire
> // the diff navigator hook and register the requested diff.
> new_scroller.on('click', function() {
>
> === modified file 'lib/lp/code/stories/branches/xx-code-review-comments.txt'
> --- lib/lp/code/stories/branches/xx-code-review-comments.txt 2012-01-15 13:32:27 +0000
> +++ lib/lp/code/stories/branches/xx-code-review-comments.txt 2014-05-15 03:58:24 +0000
> @@ -189,3 +189,84 @@
> Testing commits in conversation
> 4. By ... on 2009-09-12
> and it works!
> +
> +
> +Inline Comments
> +---------------
> +
> +The code review inline comments support is entirely implemented in
> +Javascript. The current implementation relies on comments being
> +rendered with the following 'data-' attributes:
> +
> + # Created a new review comment with associated inline comments
> + # on the superseded and on the new MP.
> + >>> from lp.services.features.testing import FeatureFixture
> + >>> fixture = FeatureFixture(
> + ... {'code.inline_diff_comments.enabled': 'enabled'})
> +
> + >>> login('foo.bar@xxxxxxxxxxxxx')
> + >>> fixture.setUp()
> + >>> previewdiff = factory.makePreviewDiff(merge_proposal=merge_proposal)
> + >>> new_previewdiff = factory.makePreviewDiff(
> + ... merge_proposal=new_merge_proposal)
> + >>> transaction.commit()
> + >>> comment = merge_proposal.createComment(
> + ... eric, None, content='a_content',
> + ... previewdiff_id=previewdiff.id,
> + ... inline_comments={'1': 'No!'}
> + ... )
> + >>> transaction.commit()
> + >>> comment = new_merge_proposal.createComment(
> + ... eric, None, content='a_content',
> + ... previewdiff_id=new_previewdiff.id,
> + ... inline_comments={'1': 'Yes!'}
> + ... )
> + >>> fixture.cleanUp()
> + >>> logout()
> +
> + # helper for printing review comment 'data-' attributes.
> + >>> def print_comment_attributes(contents):
> + ... comments = find_tags_by_class(contents, 'boardCommentDetails')
> + ... print 'Text', 'Comment', 'Diff', 'Superseded'
> + ... for comment in comments:
> + ... tds = comment.findAll('td')
> + ... if len(tds) == 0:
> + ... continue
> + ... td = tds[0]
> + ... print ' '.join(
> + ... (extract_text(td),
> + ... td['data-comment-id'],
> + ... td.get('data-previewdiff-id', '-'),
> + ... td.get('data-from-superseded', '-')))
> +
> +The 'data-' attributes:
> +
> + * 'comment-id': The review comment ID, used to highlight related
> + * inline comments.
> + * 'previewdiff-id': used to load the corresponding `PreviewDiff`.
> + * 'from_superseded': 'True' or 'False' whether the context MP is
> + superseded by another. Used to supress context
> + handlers on superseded comments.
> +
> +They are always available in `BranchMergeProposal` pages.
> +
> + >>> anon_browser.open(merge_proposal_url)
> + >>> print_comment_attributes(anon_browser.contents)
> + Text Comment Diff Superseded
> + Eric... 1 - False
> + Eric... 2 - False
> + Eric... 3 - False
> + Eric... 4 1 False
> +
> +When visualized in the new merge proposal the comments from the original
> +merge proposal are marked as 'superseded' and there is a new and
> +non-superseded local comment.
> +
> + >>> anon_browser.open(new_merge_proposal_url)
> + >>> print_comment_attributes(anon_browser.contents)
> + Text Comment Diff Superseded
> + Eric... 1 - True
> + Eric... 2 - True
> + Eric... 3 - True
> + Eric... 4 1 True
> + Eric... 5 2 False
>
> === modified file 'lib/lp/code/templates/branchmergeproposal-index.pt'
> --- lib/lp/code/templates/branchmergeproposal-index.pt 2014-04-04 04:47:15 +0000
> +++ lib/lp/code/templates/branchmergeproposal-index.pt 2014-05-15 03:58:24 +0000
> @@ -144,7 +144,6 @@
> <div id="add-comment-review-fields">
> Review: <tal:review replace="structure comment_form/widgets/vote"/>
> Review type: <tal:review replace="structure comment_form/widgets/review_type"/>
> - <tal:publish_inline_comments condition="features/code.inline_diff_comments.enabled">Publish inline comments: <tal:review replace="structure comment_form/widgets/publish_inline_comments" tal:condition="features/code.inline_diff_comments.enabled"/></tal:publish_inline_comments>
> <div class="actions"
> tal:content="structure comment_form/actions/field.actions.add/render" />
> </div>
>
> === modified file 'lib/lp/code/templates/codereviewcomment-header.pt'
> --- lib/lp/code/templates/codereviewcomment-header.pt 2014-04-03 20:33:08 +0000
> +++ lib/lp/code/templates/codereviewcomment-header.pt 2014-05-15 03:58:24 +0000
> @@ -6,7 +6,9 @@
> <table>
> <tbody>
> <tr>
> - <td>
> + <td tal:attributes="data-previewdiff-id context/previewdiff_id;
> + data-from-superseded context/from_superseded;
> + data-comment-id context/id">
> <span
> itemprop="creator"
> tal:content="structure context/comment_author/fmt:link-display-name-id"/>
> @@ -26,11 +28,6 @@
> tal:attributes="href context/branch_merge_proposal/fmt:url">a
> previous version</a>
> of this proposal</span>
> - <span style="float: right;" tal:condition="context/previewdiff_id">
> - <a class="inline-comment-scroller" href=""
> - tal:attributes="data-previewdiff-id context/previewdiff_id"
> - >View inline comments</a>
> - </span>
> </td>
>
> <td class="bug-comment-index">
>
--
https://code.launchpad.net/~cprov/launchpad/ic-superseded-mps/+merge/219431
Your team Launchpad code reviewers is subscribed to branch lp:launchpad.
References