These tags are preserved by the Closure compiler and vulcanize in order to serve the license notices embedded in the outputs. In a standalone Gerrit server, these license are also covered in the LICENSES.txt served with the documentation. When serving PG assets from a CDN, it's less obvious what the corresponding LICENSES.txt file is, since the CDN is not directly linked to a running Gerrit server. Safer to embed the licenses in the assets themselves. Change-Id: Id1add1451fad1baa7916882a6bda02c326ccc988
		
			
				
	
	
		
			192 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			192 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/**
 | 
						|
 * @license
 | 
						|
 * Copyright (C) 2017 The Android Open Source Project
 | 
						|
 *
 | 
						|
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
 * you may not use this file except in compliance with the License.
 | 
						|
 * You may obtain a copy of the License at
 | 
						|
 *
 | 
						|
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 *
 | 
						|
 * Unless required by applicable law or agreed to in writing, software
 | 
						|
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
 * See the License for the specific language governing permissions and
 | 
						|
 * limitations under the License.
 | 
						|
 */
 | 
						|
(function() {
 | 
						|
  'use strict';
 | 
						|
 | 
						|
  Polymer({
 | 
						|
    is: 'gr-diff-comment-thread-group',
 | 
						|
 | 
						|
    properties: {
 | 
						|
      changeNum: String,
 | 
						|
      comments: {
 | 
						|
        type: Array,
 | 
						|
        value() { return []; },
 | 
						|
      },
 | 
						|
      projectName: String,
 | 
						|
      patchForNewThreads: String,
 | 
						|
      range: Object,
 | 
						|
      isOnParent: {
 | 
						|
        type: Boolean,
 | 
						|
        value: false,
 | 
						|
      },
 | 
						|
      parentIndex: {
 | 
						|
        type: Number,
 | 
						|
        value: null,
 | 
						|
      },
 | 
						|
      _threads: {
 | 
						|
        type: Array,
 | 
						|
        value() { return []; },
 | 
						|
      },
 | 
						|
    },
 | 
						|
 | 
						|
    observers: [
 | 
						|
      '_commentsChanged(comments.*)',
 | 
						|
    ],
 | 
						|
 | 
						|
    get threadEls() {
 | 
						|
      return Polymer.dom(this.root).querySelectorAll('gr-diff-comment-thread');
 | 
						|
    },
 | 
						|
 | 
						|
    /**
 | 
						|
     * Adds a new thread. Range is optional because a comment can be
 | 
						|
     * added to a line without a range selected.
 | 
						|
     *
 | 
						|
     * @param {!Object} opt_range
 | 
						|
     */
 | 
						|
    addNewThread(commentSide, opt_range) {
 | 
						|
      this.push('_threads', {
 | 
						|
        comments: [],
 | 
						|
        commentSide,
 | 
						|
        patchNum: this.patchForNewThreads,
 | 
						|
        range: opt_range,
 | 
						|
      });
 | 
						|
    },
 | 
						|
 | 
						|
    removeThread(rootId) {
 | 
						|
      for (let i = 0; i < this._threads.length; i++) {
 | 
						|
        if (this._threads[i].rootId === rootId) {
 | 
						|
          this.splice('_threads', i, 1);
 | 
						|
          return;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    },
 | 
						|
 | 
						|
    /**
 | 
						|
     * Fetch the thread group at the given range, or the range-less thread
 | 
						|
     * on the line if no range is provided, lineNum, and side.
 | 
						|
     *
 | 
						|
     * @param {string} side
 | 
						|
     * @param {!Object=} opt_range
 | 
						|
     * @return {!Object|undefined}
 | 
						|
     */
 | 
						|
    getThread(side, opt_range) {
 | 
						|
      const threads = [].filter.call(this.threadEls,
 | 
						|
          thread => this._rangesEqual(thread.range, opt_range))
 | 
						|
          .filter(thread => thread.commentSide === side);
 | 
						|
      if (threads.length === 1) {
 | 
						|
        return threads[0];
 | 
						|
      }
 | 
						|
    },
 | 
						|
 | 
						|
    _handleThreadDiscard(e) {
 | 
						|
      this.removeThread(e.detail.rootId);
 | 
						|
    },
 | 
						|
 | 
						|
    /**
 | 
						|
     * Compare two ranges. Either argument may be falsy, but will only return
 | 
						|
     * true if both are falsy or if neither are falsy and have the same position
 | 
						|
     * values.
 | 
						|
     *
 | 
						|
     * @param {Object=} a range 1
 | 
						|
     * @param {Object=} b range 2
 | 
						|
     * @return {boolean}
 | 
						|
     */
 | 
						|
    _rangesEqual(a, b) {
 | 
						|
      if (!a && !b) { return true; }
 | 
						|
      if (!a || !b) { return false; }
 | 
						|
      return a.startLine === b.startLine &&
 | 
						|
          a.startChar === b.startChar &&
 | 
						|
          a.endLine === b.endLine &&
 | 
						|
          a.endChar === b.endChar;
 | 
						|
    },
 | 
						|
 | 
						|
    _commentsChanged() {
 | 
						|
      this._threads = this._getThreads(this.comments);
 | 
						|
    },
 | 
						|
 | 
						|
    _sortByDate(threadGroups) {
 | 
						|
      if (!threadGroups.length) { return; }
 | 
						|
      return threadGroups.sort((a, b) => {
 | 
						|
        // If a comment is a draft, it doesn't have a start_datetime yet.
 | 
						|
        // Assume it is newer than the comment it is being compared to.
 | 
						|
        if (!a.start_datetime) {
 | 
						|
          return 1;
 | 
						|
        }
 | 
						|
        if (!b.start_datetime) {
 | 
						|
          return -1;
 | 
						|
        }
 | 
						|
        return util.parseDate(a.start_datetime) -
 | 
						|
            util.parseDate(b.start_datetime);
 | 
						|
      });
 | 
						|
    },
 | 
						|
 | 
						|
    _calculateLocationRange(range, comment) {
 | 
						|
      return 'range-' + range.start_line + '-' +
 | 
						|
          range.start_character + '-' +
 | 
						|
          range.end_line + '-' +
 | 
						|
          range.end_character + '-' +
 | 
						|
          comment.__commentSide;
 | 
						|
    },
 | 
						|
 | 
						|
    /**
 | 
						|
     * Determines what the patchNum of a thread should be. Use patchNum from
 | 
						|
     * comment if it exists, otherwise the property of the thread group.
 | 
						|
     * This is needed for switching between side-by-side and unified views when
 | 
						|
     * there are unsaved drafts.
 | 
						|
     */
 | 
						|
    _getPatchNum(comment) {
 | 
						|
      return comment.patch_set || this.patchForNewThreads;
 | 
						|
    },
 | 
						|
 | 
						|
    _getThreads(comments) {
 | 
						|
      const sortedComments = comments.slice(0).sort((a, b) => {
 | 
						|
        if (b.__draft && !a.__draft ) { return 0; }
 | 
						|
        if (a.__draft && !b.__draft ) { return 1; }
 | 
						|
        return util.parseDate(a.updated) - util.parseDate(b.updated);
 | 
						|
      });
 | 
						|
 | 
						|
      const threads = [];
 | 
						|
      for (const comment of sortedComments) {
 | 
						|
        // If the comment is in reply to another comment, find that comment's
 | 
						|
        // thread and append to it.
 | 
						|
        if (comment.in_reply_to) {
 | 
						|
          const thread = threads.find(thread =>
 | 
						|
              thread.comments.some(c => c.id === comment.in_reply_to));
 | 
						|
          if (thread) {
 | 
						|
            thread.comments.push(comment);
 | 
						|
            continue;
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
        // Otherwise, this comment starts its own thread.
 | 
						|
        const newThread = {
 | 
						|
          start_datetime: comment.updated,
 | 
						|
          comments: [comment],
 | 
						|
          commentSide: comment.__commentSide,
 | 
						|
          patchNum: this._getPatchNum(comment),
 | 
						|
          rootId: comment.id || comment.__draftID,
 | 
						|
        };
 | 
						|
        if (comment.range) {
 | 
						|
          newThread.range = Object.assign({}, comment.range);
 | 
						|
        }
 | 
						|
        threads.push(newThread);
 | 
						|
      }
 | 
						|
      return threads;
 | 
						|
    },
 | 
						|
  });
 | 
						|
})();
 |