
This is a behavior that we want gr-diff/gr-diff-cursor to support natively, not leave to users of gr-diff to do. Change-Id: Ifc9a18715f994d7049b2b6299bbca8c65e8a759a
445 lines
16 KiB
JavaScript
445 lines
16 KiB
JavaScript
/**
|
|
* @license
|
|
* Copyright (C) 2020 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.
|
|
*/
|
|
import {html} from '@polymer/polymer/lib/utils/html-tag.js';
|
|
|
|
export const htmlTemplate = html`
|
|
<style include="shared-styles">
|
|
:host {
|
|
display: block;
|
|
}
|
|
.row {
|
|
align-items: center;
|
|
border-top: 1px solid var(--border-color);
|
|
display: flex;
|
|
min-height: calc(var(--line-height-normal) + 2*var(--spacing-s));
|
|
padding: var(--spacing-xs) var(--spacing-l) var(--spacing-xs) calc(var(--spacing-l) - .35rem);
|
|
}
|
|
:host(.loading) .row {
|
|
opacity: .5;
|
|
};
|
|
:host(.editMode) .hideOnEdit {
|
|
display: none;
|
|
}
|
|
.showOnEdit {
|
|
display: none;
|
|
}
|
|
:host(.editMode) .showOnEdit {
|
|
display: initial;
|
|
}
|
|
.invisible {
|
|
visibility: hidden;
|
|
}
|
|
.header-row {
|
|
background-color: var(--background-color-secondary);
|
|
}
|
|
.controlRow {
|
|
align-items: center;
|
|
display: flex;
|
|
height: 2.25em;
|
|
justify-content: center;
|
|
}
|
|
.controlRow.invisible,
|
|
.show-hide.invisible {
|
|
display: none;
|
|
}
|
|
.reviewed,
|
|
.status {
|
|
align-items: center;
|
|
display: inline-flex;
|
|
}
|
|
.reviewed,
|
|
.status {
|
|
display: inline-block;
|
|
text-align: left;
|
|
width: 1.5em;
|
|
}
|
|
.file-row {
|
|
cursor: pointer;
|
|
}
|
|
.file-row.expanded {
|
|
border-bottom: 1px solid var(--border-color);
|
|
position: -webkit-sticky;
|
|
position: sticky;
|
|
top: 0;
|
|
/* Has to visible above the diff view, and by default has a lower
|
|
z-index. setting to 1 places it directly above. */
|
|
z-index: 1;
|
|
}
|
|
.file-row:hover {
|
|
background-color: var(--hover-background-color);
|
|
}
|
|
.file-row.selected {
|
|
background-color: var(--selection-background-color);
|
|
}
|
|
.file-row.expanded,
|
|
.file-row.expanded:hover {
|
|
background-color: var(--expanded-background-color);
|
|
}
|
|
.path {
|
|
cursor: pointer;
|
|
flex: 1;
|
|
/* Wrap it into multiple lines if too long. */
|
|
white-space: normal;
|
|
word-break: break-word;
|
|
}
|
|
.oldPath {
|
|
color: var(--deemphasized-text-color);
|
|
}
|
|
.header-stats {
|
|
text-align: center;
|
|
min-width: 7.5em;
|
|
}
|
|
.stats {
|
|
text-align: right;
|
|
min-width: 7.5em;
|
|
}
|
|
.comments {
|
|
padding-left: var(--spacing-l);
|
|
min-width: 7.5em;
|
|
}
|
|
.row:not(.header-row) .stats,
|
|
.total-stats {
|
|
font-family: var(--monospace-font-family);
|
|
font-size: var(--font-size-mono);
|
|
line-height: var(--line-height-mono);
|
|
display: flex;
|
|
}
|
|
.sizeBars {
|
|
margin-left: var(--spacing-m);
|
|
min-width: 7em;
|
|
text-align: center;
|
|
}
|
|
.sizeBars.hide {
|
|
display: none;
|
|
}
|
|
.added,
|
|
.removed {
|
|
display: inline-block;
|
|
min-width: 3.5em;
|
|
}
|
|
.added {
|
|
color: var(--vote-text-color-recommended);
|
|
}
|
|
.removed {
|
|
color: var(--vote-text-color-disliked);
|
|
text-align: left;
|
|
min-width: 4em;
|
|
padding-left: var(--spacing-s);
|
|
}
|
|
.drafts {
|
|
color: #C62828;
|
|
font-weight: var(--font-weight-bold);
|
|
}
|
|
.show-hide {
|
|
margin-left: var(--spacing-s);
|
|
width: 1.9em;
|
|
}
|
|
.fileListButton {
|
|
margin: var(--spacing-m);
|
|
}
|
|
.totalChanges {
|
|
justify-content: flex-end;
|
|
text-align: right;
|
|
}
|
|
.warning {
|
|
color: var(--deemphasized-text-color);
|
|
}
|
|
input.show-hide {
|
|
display: none;
|
|
}
|
|
label.show-hide {
|
|
cursor: pointer;
|
|
display: block;
|
|
min-width: 2em;
|
|
}
|
|
gr-diff {
|
|
display: block;
|
|
overflow-x: auto;
|
|
}
|
|
.truncatedFileName {
|
|
display: none;
|
|
}
|
|
.mobile {
|
|
display: none;
|
|
}
|
|
.reviewed {
|
|
margin-left: var(--spacing-xxl);
|
|
width: 15em;
|
|
}
|
|
.reviewed label {
|
|
color: var(--link-color);
|
|
opacity: 0;
|
|
justify-content: flex-end;
|
|
width: 100%;
|
|
}
|
|
.reviewed label:hover {
|
|
cursor: pointer;
|
|
opacity: 100;
|
|
}
|
|
.row:focus {
|
|
outline: none;
|
|
}
|
|
.row:hover .reviewed label,
|
|
.row:focus .reviewed label,
|
|
.row.expanded .reviewed label {
|
|
opacity: 100;
|
|
}
|
|
.reviewed input {
|
|
display: none;
|
|
}
|
|
.reviewedLabel {
|
|
color: var(--deemphasized-text-color);
|
|
margin-right: var(--spacing-l);
|
|
opacity: 0;
|
|
}
|
|
.reviewedLabel.isReviewed {
|
|
display: initial;
|
|
opacity: 100;
|
|
}
|
|
.editFileControls {
|
|
width: 7em;
|
|
}
|
|
.markReviewed,
|
|
.pathLink {
|
|
display: inline-block;
|
|
margin: -2px 0;
|
|
padding: var(--spacing-s) 0;
|
|
text-decoration: none;
|
|
}
|
|
.pathLink:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
/** copy on file path **/
|
|
.pathLink gr-copy-clipboard,
|
|
.oldPath gr-copy-clipboard {
|
|
display: inline-block;
|
|
visibility: hidden;
|
|
vertical-align: bottom;
|
|
text-decoration: none;
|
|
--gr-button: {
|
|
padding: 0px;
|
|
}
|
|
}
|
|
.pathLink:hover gr-copy-clipboard,
|
|
.oldPath:hover gr-copy-clipboard {
|
|
visibility: visible;
|
|
}
|
|
|
|
/** small screen breakpoint: 768px */
|
|
@media screen and (max-width: 55em) {
|
|
.desktop {
|
|
display: none;
|
|
}
|
|
.mobile {
|
|
display: block;
|
|
}
|
|
.row.selected {
|
|
background-color: var(--view-background-color);
|
|
}
|
|
.stats {
|
|
display: none;
|
|
}
|
|
.reviewed,
|
|
.status {
|
|
justify-content: flex-start;
|
|
}
|
|
.reviewed {
|
|
display: none;
|
|
}
|
|
.comments {
|
|
min-width: initial;
|
|
}
|
|
.expanded .fullFileName,
|
|
.truncatedFileName {
|
|
display: inline;
|
|
}
|
|
.expanded .truncatedFileName,
|
|
.fullFileName {
|
|
display: none;
|
|
}
|
|
}
|
|
</style>
|
|
<div id="container" on-click="_handleFileListClick">
|
|
<div class="header-row row">
|
|
<div class="status"></div>
|
|
<div class="path">File</div>
|
|
<div class="comments">Comments</div>
|
|
<div class="sizeBars">Size</div>
|
|
<div class="header-stats">Delta</div>
|
|
<template is="dom-if" if="[[_showDynamicColumns]]">
|
|
<template is="dom-repeat" items="[[_dynamicHeaderEndpoints]]" as="headerEndpoint">
|
|
<gr-endpoint-decorator name\$="[[headerEndpoint]]">
|
|
</gr-endpoint-decorator>
|
|
</template>
|
|
</template>
|
|
<!-- Empty div here exists to keep spacing in sync with file rows. -->
|
|
<div class="reviewed hideOnEdit" hidden\$="[[!_loggedIn]]"></div>
|
|
<div class="editFileControls showOnEdit"></div>
|
|
<div class="show-hide"></div>
|
|
</div>
|
|
|
|
<template is="dom-repeat" items="[[_shownFiles]]" id="files" as="file" initial-count="[[fileListIncrement]]" target-framerate="1">
|
|
[[_reportRenderedRow(index)]]
|
|
<div class="stickyArea">
|
|
<div class\$="file-row row [[_computePathClass(file.__path, _expandedFiles.*)]]" data-file\$="[[_computeFileData(file)]]" tabindex="-1">
|
|
<div class\$="[[_computeClass('status', file.__path)]]" tabindex="0" title\$="[[_computeFileStatusLabel(file.status)]]" aria-label\$="[[_computeFileStatusLabel(file.status)]]">
|
|
[[_computeFileStatus(file.status)]]
|
|
</div>
|
|
<!-- TODO: Remove data-url as it appears its not used -->
|
|
<span data-url="[[_computeDiffURL(change, patchRange, file.__path, editMode)]]" class="path">
|
|
<a class="pathLink" href\$="[[_computeDiffURL(change, patchRange, file.__path, editMode)]]">
|
|
<span title\$="[[computeDisplayPath(file.__path)]]" class="fullFileName">
|
|
[[computeDisplayPath(file.__path)]]
|
|
</span>
|
|
<span title\$="[[computeDisplayPath(file.__path)]]" class="truncatedFileName">
|
|
[[computeTruncatedPath(file.__path)]]
|
|
</span>
|
|
<gr-copy-clipboard hide-input="" text="[[file.__path]]"></gr-copy-clipboard>
|
|
</a>
|
|
<template is="dom-if" if="[[file.old_path]]">
|
|
<div class="oldPath" title\$="[[file.old_path]]">
|
|
[[file.old_path]]
|
|
<gr-copy-clipboard hide-input="" text="[[file.old_path]]"></gr-copy-clipboard>
|
|
</div>
|
|
</template>
|
|
</span>
|
|
<div class="comments desktop">
|
|
<span class="drafts">
|
|
[[_computeDraftsString(changeComments, patchRange, file.__path)]]
|
|
</span>
|
|
[[_computeCommentsString(changeComments, patchRange, file.__path)]]
|
|
</div>
|
|
<div class="comments mobile">
|
|
<span class="drafts">
|
|
[[_computeDraftsStringMobile(changeComments, patchRange,
|
|
file.__path)]]
|
|
</span>
|
|
[[_computeCommentsStringMobile(changeComments, patchRange,
|
|
file.__path)]]
|
|
</div>
|
|
<div class\$="[[_computeSizeBarsClass(_showSizeBars, file.__path)]]">
|
|
<svg width="61" height="8">
|
|
<rect x\$="[[_computeBarAdditionX(file, _sizeBarLayout)]]" y="0" height="8" fill="#388E3C" width\$="[[_computeBarAdditionWidth(file, _sizeBarLayout)]]"></rect>
|
|
<rect x\$="[[_computeBarDeletionX(_sizeBarLayout)]]" y="0" height="8" fill="#D32F2F" width\$="[[_computeBarDeletionWidth(file, _sizeBarLayout)]]"></rect>
|
|
</svg>
|
|
</div>
|
|
<div class\$="[[_computeClass('stats', file.__path)]]">
|
|
<span class="added" tabindex="0" aria-label\$="[[file.lines_inserted]] lines added" hidden\$="[[file.binary]]">
|
|
+[[file.lines_inserted]]
|
|
</span>
|
|
<span class="removed" tabindex="0" aria-label\$="[[file.lines_deleted]] lines removed" hidden\$="[[file.binary]]">
|
|
-[[file.lines_deleted]]
|
|
</span>
|
|
<span class\$="[[_computeBinaryClass(file.size_delta)]]" hidden\$="[[!file.binary]]">
|
|
[[_formatBytes(file.size_delta)]]
|
|
[[_formatPercentage(file.size, file.size_delta)]]
|
|
</span>
|
|
</div>
|
|
<template is="dom-if" if="[[_showDynamicColumns]]">
|
|
<template is="dom-repeat" items="[[_dynamicContentEndpoints]]" as="contentEndpoint">
|
|
<div class\$="[[_computeClass('', file.__path)]]">
|
|
<gr-endpoint-decorator name="[[contentEndpoint]]">
|
|
<gr-endpoint-param name="changeNum" value="[[changeNum]]">
|
|
</gr-endpoint-param>
|
|
<gr-endpoint-param name="patchRange" value="[[patchRange]]">
|
|
</gr-endpoint-param>
|
|
<gr-endpoint-param name="path" value="[[file.__path]]">
|
|
</gr-endpoint-param>
|
|
</gr-endpoint-decorator>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
<div class="reviewed hideOnEdit" hidden\$="[[!_loggedIn]]" hidden="">
|
|
<span class\$="reviewedLabel [[_computeReviewedClass(file.isReviewed)]]">Reviewed</span>
|
|
<label>
|
|
<input class="reviewed" type="checkbox" checked="[[file.isReviewed]]">
|
|
<span class="markReviewed" title\$="[[_reviewedTitle(file.isReviewed)]]">[[_computeReviewedText(file.isReviewed)]]</span>
|
|
</label>
|
|
</div>
|
|
<div class="editFileControls showOnEdit">
|
|
<template is="dom-if" if="[[editMode]]">
|
|
<gr-edit-file-controls class\$="[[_computeClass('', file.__path)]]" file-path="[[file.__path]]"></gr-edit-file-controls>
|
|
</template>
|
|
</div>
|
|
<div class="show-hide">
|
|
<label class="show-hide" data-path\$="[[file.__path]]" data-expand="true">
|
|
<input type="checkbox" class="show-hide" checked\$="[[_isFileExpanded(file.__path, _expandedFiles.*)]]" data-path\$="[[file.__path]]" data-expand="true">
|
|
<iron-icon id="icon" icon="[[_computeShowHideIcon(file.__path, _expandedFiles.*)]]">
|
|
</iron-icon>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<template is="dom-if" if="[[_isFileExpanded(file.__path, _expandedFiles.*)]]">
|
|
<gr-diff-host no-auto-render="" show-load-failure="" display-line="[[_displayLine]]" hidden="[[!_isFileExpanded(file.__path, _expandedFiles.*)]]" change-num="[[changeNum]]" patch-range="[[patchRange]]" path="[[file.__path]]" prefs="[[diffPrefs]]" project-name="[[change.project]]" no-render-on-prefs-change="" view-mode="[[diffViewMode]]"></gr-diff-host>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
<div class="row totalChanges" hidden\$="[[_hideChangeTotals]]">
|
|
<div class="total-stats">
|
|
<span class="added" tabindex="0" aria-label\$="[[_patchChange.inserted]] lines added">
|
|
+[[_patchChange.inserted]]
|
|
</span>
|
|
<span class="removed" tabindex="0" aria-label\$="[[_patchChange.deleted]] lines removed">
|
|
-[[_patchChange.deleted]]
|
|
</span>
|
|
</div>
|
|
<template is="dom-if" if="[[_showDynamicColumns]]">
|
|
<template is="dom-repeat" items="[[_dynamicSummaryEndpoints]]" as="summaryEndpoint">
|
|
<gr-endpoint-decorator name="[[summaryEndpoint]]">
|
|
</gr-endpoint-decorator>
|
|
</template>
|
|
</template>
|
|
<!-- Empty div here exists to keep spacing in sync with file rows. -->
|
|
<div class="reviewed hideOnEdit" hidden\$="[[!_loggedIn]]"></div>
|
|
<div class="editFileControls showOnEdit"></div>
|
|
<div class="show-hide"></div>
|
|
</div>
|
|
<div class="row totalChanges" hidden\$="[[_hideBinaryChangeTotals]]">
|
|
<div class="total-stats">
|
|
<span class="added" aria-label="Total lines added">
|
|
[[_formatBytes(_patchChange.size_delta_inserted)]]
|
|
[[_formatPercentage(_patchChange.total_size,
|
|
_patchChange.size_delta_inserted)]]
|
|
</span>
|
|
<span class="removed" aria-label="Total lines removed">
|
|
[[_formatBytes(_patchChange.size_delta_deleted)]]
|
|
[[_formatPercentage(_patchChange.total_size,
|
|
_patchChange.size_delta_deleted)]]
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class\$="row controlRow [[_computeFileListControlClass(numFilesShown, _files)]]">
|
|
<gr-button class="fileListButton" id="incrementButton" link="" on-click="_incrementNumFilesShown">
|
|
[[_computeIncrementText(numFilesShown, _files)]]
|
|
</gr-button>
|
|
<gr-tooltip-content has-tooltip="[[_computeWarnShowAll(_files)]]" show-icon="[[_computeWarnShowAll(_files)]]" title\$="[[_computeShowAllWarning(_files)]]">
|
|
<gr-button class="fileListButton" id="showAllButton" link="" on-click="_showAllFiles">
|
|
[[_computeShowAllText(_files)]]
|
|
</gr-button><!--
|
|
--></gr-tooltip-content>
|
|
</div>
|
|
<gr-diff-preferences-dialog id="diffPreferencesDialog" diff-prefs="{{diffPrefs}}" on-reload-diff-preference="_handleReloadingDiffPreference">
|
|
</gr-diff-preferences-dialog>
|
|
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
|
|
<gr-storage id="storage"></gr-storage>
|
|
<gr-diff-cursor id="diffCursor"></gr-diff-cursor>
|
|
<gr-cursor-manager id="fileCursor" scroll-behavior="keep-visible" focus-on-move="" cursor-target-class="selected"></gr-cursor-manager>
|
|
<gr-reporting id="reporting"></gr-reporting>
|
|
`;
|