Files
gerrit/polygerrit-ui/app/elements/gr-diff-view.html
Andrew Bonventre ba69835964 Add the skeleton of a new UI based on Polymer, PolyGerrit
This is the beginnings of an experimental new non-GWT web UI developed
using a modern JS web framework, http://www.polymer-project.org/. It
will coexist alongside the GWT UI until it is feature-complete.

The functionality of this change is light years from complete, with
a full laundry list of things that don't work. This change is simply
meant to get the starting work in and continue iteration afterward.

The contents of the polygerrit-ui directory started as the full tree of
https://github.com/andybons/polygerrit at 219f531, plus a few more
local changes since review started. In the future this directory will
be pruned, rearranged, and integrated with the Buck build.

Change-Id: Ifb6f5429e8031ee049225cdafa244ad1c21bf5b5
2015-11-09 22:01:28 +00:00

274 lines
8.8 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
Copyright (C) 2015 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.
-->
<link rel="import" href="../bower_components/polymer/polymer.html">
<dom-module id="gr-diff-view">
<template>
<style>
:host {
display: block;
}
.diffContainer {
display: flex;
font-family: 'Source Code Pro', monospace;
white-space: pre;
}
.diffNumbers {
border-right: 1px solid #eee;
color: #aaa;
padding: 0 10px;
text-align: right;
}
.diffContent {
padding-left: 2px;
}
.lineNum {
cursor: pointer;
}
.lineNum:hover {
text-decoration: underline;
}
.lightRed {
background-color: #fee;
}
.darkRed,
.delete span {
background-color: #faa;
}
.lightGreen {
background-color: #efe;
}
.darkGreen,
.insert span {
background-color: #9f9;
}
</style>
<iron-ajax id="changeDetailXHR"
auto
url="[[_computeChangeDetailPath(_changeNum)]]"
params="[[_computeChangeDetailQueryParams()]]"
json-prefix=")]}'"
last-response="{{_change}}"
debounce-duration="300"></iron-ajax>
<iron-ajax
id="diffXHR"
url="[[_computeDiffPath(_changeNum, _patchNum, _path)]]"
json-prefix=")]}'"
on-response="_handleDiffResponse"
debounce-duration="300"></iron-ajax>
<div class="diffContainer" id="diffContainer">
<div class="diffNumbers" id="leftDiffNumbers"></div>
<div class="diffContent" id="leftDiffContent"></div>
<div class="diffNumbers" id="rightDiffNumbers"></div>
<div class="diffContent" id="rightDiffContent"></div>
</div>
</template>
<script>
(function() {
'use strict';
Polymer({
is: 'gr-diff-view',
properties: {
/**
* URL params passed from the router.
*/
params: {
type: Object,
observer: '_paramsChanged',
},
_change: Object,
_changeNum: String,
_basePatchNum: String,
_patchNum: String,
_path: String,
},
_paramsChanged: function(value) {
console.log(value)
this._changeNum = value.changeNum;
this._patchNum = value.patchNum;
this._basePatchNum = value.basePatchNum;
this._path = value.path;
console.log(this._basePatchNum);
if (!this._changeNum) {
this._change = null;
this._basePatchNum = null;
this._patchNum = null;
this._path = null;
return;
}
// Assign the params here since a computed binding relying on
// `_basePatchNum` wont fire in the case where its not defined.
this.$.diffXHR.params = this._diffQueryParams();
this.$.diffXHR.generateRequest();
},
_computeChangeDetailPath: function(changeNum) {
return '/changes/' + changeNum + '/detail';
},
_computeChangeDetailQueryParams: function() {
var options = Changes.listChangesOptionsToHex(
Changes.ListChangesOption.ALL_REVISIONS
);
return { O: options };
},
_computeDiffPath: function(changeNum, patchNum, path) {
return '/changes/' + changeNum + '/revisions/' + patchNum + '/files/' +
encodeURIComponent(path) + '/diff';
},
_diffQueryParams: function(basePatchNum) {
var params = {
context: 'ALL',
intraline: null
};
if (!!basePatchNum) {
params.base = basePatchNum;
}
return params;
},
_handleDiffResponse: function(e, req) {
var diff = e.detail.response;
this._constructDOM(diff);
},
_constructDOM: function(diff) {
if (!diff.content) { return; }
var leftLineNum = 0 + (diff.content.skip || 0);
var rightLineNum = leftLineNum;
for (var i = 0; i < diff.content.length; i++) {
var diffChunk = diff.content[i];
if (diffChunk.ab) {
for (var j = 0; j < diffChunk.ab.length; j++) {
this._addRow(++leftLineNum, ++rightLineNum, diffChunk.ab[j],
diffChunk.ab[j]);
}
continue;
}
if (diffChunk.a || diffChunk.b) {
var aLen = (diffChunk.a && diffChunk.a.length) || 0;
var bLen = (diffChunk.b && diffChunk.b.length) || 0;
var maxLen = Math.max(aLen, bLen);
for (var j = 0; j < maxLen; j++) {
var leftContent;
if (diffChunk.a && j < diffChunk.a.length) {
leftContent = diffChunk.a[j];
leftLineNum++;
}
var rightContent;
if (diffChunk.b && j < diffChunk.b.length) {
rightContent = diffChunk.b[j];
rightLineNum++;
}
var leftHighlight;
if (diffChunk.edit_a && j < diffChunk.edit_a.length) {
leftHighlight = diffChunk.edit_a[j];
}
var rightHighlight;
if (diffChunk.edit_b && j < diffChunk.edit_b.length) {
rightHighlight = diffChunk.edit_b[j];
}
this._addRow(leftLineNum,
rightLineNum,
leftContent,
rightContent,
leftHighlight,
rightHighlight);
}
}
}
},
_addRow: function(leftLineNum,
rightLineNum,
leftContent,
rightContent,
leftHighlight,
rightHighlight) {
var leftLineNumEl = document.createElement('div');
var rightLineNumEl = document.createElement('div');
var leftColEl = document.createElement('div');
// These classes are added to account for Polymers polyfill behavior.
// In order to guarantee sufficient specificity within the CSS rules,
// these are added to every element. Since the Polymer DOM utility
// functions (which would do this automatically) are not being used for
// performance reasons, this is done manually.
leftColEl.className = 'style-scope gr-diff-view';
var rightColEl = document.createElement('div');
rightColEl.className = 'style-scope gr-diff-view';
leftLineNumEl.className = 'style-scope gr-diff-view lineNum';
rightLineNumEl.className = 'style-scope gr-diff-view lineNum';
// Ensure that all elements have content so they render at the correct
// height.
leftLineNumEl.textContent =
leftContent != undefined ? leftLineNum : '\n';
rightLineNumEl.textContent =
rightContent != undefined ? rightLineNum : '\n';
leftContent = leftContent || '\n';
rightContent = rightContent || '\n';
var leftHTML;
var rightHTML;
if (leftContent == rightContent) {
leftHTML = leftContent;
rightHTML = rightContent;
} else {
leftHTML = this._highlightedHTML(leftContent, leftHighlight);
rightHTML = this._highlightedHTML(rightContent, rightHighlight);
}
// If the html is just the text then it didn't get highlighted.
// Use textContent which is faster than innerHTML.
if (leftContent == leftHTML) {
leftColEl.textContent = leftContent;
} else {
leftColEl.innerHTML = leftHTML;
}
if (rightContent == rightHTML) {
rightColEl.textContent = rightContent;
} else {
rightColEl.innerHTML = rightHTML;
}
if (leftContent != rightContent) {
leftColEl.classList.add('delete');
rightColEl.classList.add('insert');
leftColEl.classList.add(leftHighlight ? 'lightRed' : 'darkRed');
rightColEl.classList.add(rightHighlight ? 'lightGreen' : 'darkGreen');
}
this.$.leftDiffNumbers.appendChild(leftLineNumEl);
this.$.leftDiffContent.appendChild(leftColEl);
this.$.rightDiffNumbers.appendChild(rightLineNumEl);
this.$.rightDiffContent.appendChild(rightColEl);
},
_highlightedHTML: function(content, range) {
return content;
},
});
})();
</script>
</dom-module>