2016-06-09 16:39:17 -07:00
|
|
|
// Copyright (C) 2016 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-selection',
|
|
|
|
|
|
|
|
properties: {
|
2016-09-08 14:09:11 -07:00
|
|
|
diff: Object,
|
2016-06-09 16:39:17 -07:00
|
|
|
_cachedDiffBuilder: Object,
|
2016-09-08 14:09:11 -07:00
|
|
|
_linesCache: {
|
|
|
|
type: Object,
|
|
|
|
value: function() { return {left: null, right: null}; },
|
|
|
|
},
|
2016-06-09 16:39:17 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
listeners: {
|
|
|
|
'copy': '_handleCopy',
|
|
|
|
'down': '_handleDown',
|
|
|
|
},
|
|
|
|
|
2016-08-10 11:29:17 -07:00
|
|
|
attached: function() {
|
|
|
|
this.classList.add('selected-right');
|
|
|
|
},
|
|
|
|
|
2016-06-09 16:39:17 -07:00
|
|
|
get diffBuilder() {
|
|
|
|
if (!this._cachedDiffBuilder) {
|
|
|
|
this._cachedDiffBuilder =
|
|
|
|
Polymer.dom(this).querySelector('gr-diff-builder');
|
|
|
|
}
|
|
|
|
return this._cachedDiffBuilder;
|
|
|
|
},
|
|
|
|
|
|
|
|
_handleDown: function(e) {
|
|
|
|
var lineEl = this.diffBuilder.getLineElByChild(e.target);
|
|
|
|
if (!lineEl) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var side = this.diffBuilder.getSideByLineEl(lineEl);
|
2016-08-10 11:29:17 -07:00
|
|
|
var targetClass = 'selected-' + side;
|
|
|
|
var alternateClass = 'selected-' + (side === 'left' ? 'right' : 'left');
|
|
|
|
|
|
|
|
if (this.classList.contains(alternateClass)) {
|
|
|
|
this.classList.remove(alternateClass);
|
|
|
|
}
|
|
|
|
if (!this.classList.contains(targetClass)) {
|
|
|
|
this.classList.add(targetClass);
|
|
|
|
}
|
2016-06-09 16:39:17 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
_handleCopy: function(e) {
|
2016-09-08 14:09:11 -07:00
|
|
|
var el = e.target;
|
|
|
|
while (!el.classList.contains('content')) {
|
|
|
|
if (!el.parentElement) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
el = el.parentElement;
|
2016-06-09 16:39:17 -07:00
|
|
|
}
|
|
|
|
var lineEl = this.diffBuilder.getLineElByChild(e.target);
|
|
|
|
if (!lineEl) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var side = this.diffBuilder.getSideByLineEl(lineEl);
|
|
|
|
var text = this._getSelectedText(side);
|
|
|
|
e.clipboardData.setData('Text', text);
|
|
|
|
e.preventDefault();
|
|
|
|
},
|
|
|
|
|
2016-08-24 14:44:21 -07:00
|
|
|
_getSelectedText: function(side) {
|
2016-06-09 16:39:17 -07:00
|
|
|
var sel = window.getSelection();
|
|
|
|
if (sel.rangeCount != 1) {
|
|
|
|
return; // No multi-select support yet.
|
|
|
|
}
|
|
|
|
var range = sel.getRangeAt(0);
|
2016-09-08 14:09:11 -07:00
|
|
|
var startLineEl = this.diffBuilder.getLineElByChild(range.startContainer);
|
|
|
|
var endLineEl = this.diffBuilder.getLineElByChild(range.endContainer);
|
|
|
|
var startLineNum = parseInt(startLineEl.getAttribute('data-value'), 10);
|
|
|
|
var endLineNum = parseInt(endLineEl.getAttribute('data-value'), 10);
|
|
|
|
|
|
|
|
return this._getRangeFromDiff(startLineNum, range.startOffset, endLineNum,
|
|
|
|
range.endOffset, side);
|
|
|
|
},
|
2016-08-24 14:44:21 -07:00
|
|
|
|
2016-09-08 14:09:11 -07:00
|
|
|
_getRangeFromDiff: function(startLineNum, startOffset, endLineNum,
|
|
|
|
endOffset, side) {
|
|
|
|
var lines = this._getDiffLines(side).slice(startLineNum - 1, endLineNum);
|
|
|
|
if (lines.length) {
|
|
|
|
lines[0] = lines[0].substring(startOffset);
|
|
|
|
lines[lines.length - 1] = lines[lines.length - 1]
|
|
|
|
.substring(0, endOffset);
|
2016-06-09 16:39:17 -07:00
|
|
|
}
|
2016-09-08 14:09:11 -07:00
|
|
|
return lines.join('\n');
|
|
|
|
},
|
2016-06-09 16:39:17 -07:00
|
|
|
|
2016-09-08 14:09:11 -07:00
|
|
|
_getDiffLines: function(side) {
|
|
|
|
if (this._linesCache[side]) {
|
|
|
|
return this._linesCache[side];
|
2016-06-09 16:39:17 -07:00
|
|
|
}
|
2016-09-08 14:09:11 -07:00
|
|
|
|
|
|
|
var lines = [];
|
|
|
|
var chunk;
|
|
|
|
var key = side === 'left' ? 'a' : 'b';
|
|
|
|
for (var chunkIndex = 0;
|
|
|
|
chunkIndex < this.diff.content.length;
|
|
|
|
chunkIndex++) {
|
|
|
|
chunk = this.diff.content[chunkIndex];
|
|
|
|
if (chunk.ab) {
|
|
|
|
lines = lines.concat(chunk.ab);
|
|
|
|
} else if (chunk[key]) {
|
|
|
|
lines = lines.concat(chunk[key]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this._linesCache[side] = lines;
|
|
|
|
return lines;
|
2016-06-09 16:39:17 -07:00
|
|
|
},
|
|
|
|
});
|
|
|
|
})();
|