Fix 2772. Skipping line marker when applying attribs to a range
parent
92798f21e8
commit
330d2b079d
|
@ -55,14 +55,71 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
|
||||||
Sets attributes on a range
|
Sets attributes on a range
|
||||||
@param start [row, col] tuple pointing to the start of the range
|
@param start [row, col] tuple pointing to the start of the range
|
||||||
@param end [row, col] tuple pointing to the end of the range
|
@param end [row, col] tuple pointing to the end of the range
|
||||||
@param attribute: an array of attributes
|
@param attribs: an array of attributes
|
||||||
*/
|
*/
|
||||||
setAttributesOnRange: function(start, end, attribs)
|
setAttributesOnRange: function(start, end, attribs)
|
||||||
|
{
|
||||||
|
// instead of applying the attributes to the whole range at once, we need to apply them
|
||||||
|
// line by line, to be able to disregard the "*" used as line marker. For more details,
|
||||||
|
// see https://github.com/ether/etherpad-lite/issues/2772
|
||||||
|
var allChangesets;
|
||||||
|
for(var row = start[0]; row <= end[0]; row++) {
|
||||||
|
var rowRange = this._findRowRange(row, start, end);
|
||||||
|
var startCol = rowRange[0];
|
||||||
|
var endCol = rowRange[1];
|
||||||
|
|
||||||
|
var rowChangeset = this._setAttributesOnRangeByLine(row, startCol, endCol, attribs);
|
||||||
|
|
||||||
|
// compose changesets of all rows into a single changeset, as the range might not be continuous
|
||||||
|
// due to the presence of line markers on the rows
|
||||||
|
if (allChangesets) {
|
||||||
|
allChangesets = Changeset.compose(allChangesets.toString(), rowChangeset.toString(), this.rep.apool);
|
||||||
|
} else {
|
||||||
|
allChangesets = rowChangeset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.applyChangeset(allChangesets);
|
||||||
|
},
|
||||||
|
|
||||||
|
_findRowRange: function(row, start, end)
|
||||||
|
{
|
||||||
|
var startCol, endCol;
|
||||||
|
|
||||||
|
var startLineOffset = this.rep.lines.offsetOfIndex(row);
|
||||||
|
var endLineOffset = this.rep.lines.offsetOfIndex(row+1);
|
||||||
|
var lineLength = endLineOffset - startLineOffset;
|
||||||
|
|
||||||
|
// find column where range on this row starts
|
||||||
|
if (row === start[0]) { // are we on the first row of range?
|
||||||
|
startCol = start[1];
|
||||||
|
} else {
|
||||||
|
startCol = this.lineHasMarker(row) ? 1 : 0; // remove "*" used as line marker
|
||||||
|
}
|
||||||
|
|
||||||
|
// find column where range on this row ends
|
||||||
|
if (row === end[0]) { // are we on the last row of range?
|
||||||
|
endCol = end[1]; // if so, get the end of range, not end of row
|
||||||
|
} else {
|
||||||
|
endCol = lineLength - 1; // remove "\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
return [startCol, endCol];
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
Sets attributes on a range, by line
|
||||||
|
@param row the row where range is
|
||||||
|
@param startCol column where range starts
|
||||||
|
@param endCol column where range ends
|
||||||
|
@param attribs: an array of attributes
|
||||||
|
*/
|
||||||
|
_setAttributesOnRangeByLine: function(row, startCol, endCol, attribs)
|
||||||
{
|
{
|
||||||
var builder = Changeset.builder(this.rep.lines.totalWidth());
|
var builder = Changeset.builder(this.rep.lines.totalWidth());
|
||||||
ChangesetUtils.buildKeepToStartOfRange(this.rep, builder, start);
|
ChangesetUtils.buildKeepToStartOfRange(this.rep, builder, [row, startCol]);
|
||||||
ChangesetUtils.buildKeepRange(this.rep, builder, start, end, attribs, this.rep.apool);
|
ChangesetUtils.buildKeepRange(this.rep, builder, [row, startCol], [row, endCol], attribs, this.rep.apool);
|
||||||
return this.applyChangeset(builder);
|
return builder;
|
||||||
},
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -2423,6 +2423,9 @@ function Ace2Inner(){
|
||||||
var opIter = Changeset.opIterator(rep.alines[n]);
|
var opIter = Changeset.opIterator(rep.alines[n]);
|
||||||
var indexIntoLine = 0;
|
var indexIntoLine = 0;
|
||||||
var selectionStartInLine = 0;
|
var selectionStartInLine = 0;
|
||||||
|
if (documentAttributeManager.lineHasMarker(n)) {
|
||||||
|
selectionStartInLine = 1; // ignore "*" used as line marker
|
||||||
|
}
|
||||||
var selectionEndInLine = rep.lines.atIndex(n).text.length; // exclude newline
|
var selectionEndInLine = rep.lines.atIndex(n).text.length; // exclude newline
|
||||||
if (n == selStartLine)
|
if (n == selStartLine)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue