//
List<Edit> edits = new ArrayList<Edit>(this.edits.size() + 1);
edits.addAll(this.edits);
edits.add(new Edit(src.size(), src.size()));
SafeHtmlBuilder buf = new SafeHtmlBuilder();
int curIdx = 0;
Edit curEdit = edits.get(curIdx);
ReplaceEdit lastReplace = null;
List<Edit> charEdits = null;
int lastPos = 0;
int lastIdx = 0;
for (int index = src.first(); index < src.size(); index = src.next(index)) {
int cmp = compare(index, curEdit);
while (0 < cmp) {
// The index is after the edit. Skip to the next edit.
//
curEdit = edits.get(curIdx++);
cmp = compare(index, curEdit);
}
if (cmp < 0) {
// index occurs before the edit. This is a line of context.
//
appendShowBareCR(buf, src.get(index), true);
buf.append('\n');
continue;
}
// index occurs within the edit. The line is a modification.
//
if (curEdit instanceof ReplaceEdit) {
if (lastReplace != curEdit) {
lastReplace = (ReplaceEdit) curEdit;
charEdits = lastReplace.getInternalEdits();
lastPos = 0;
lastIdx = 0;
}
String line = src.get(index) + "\n";
for (int c = 0; c < line.length();) {
if (charEdits.size() <= lastIdx) {
appendShowBareCR(buf, line.substring(c), false);
break;
}
final Edit edit = charEdits.get(lastIdx);
final int b = side.getBegin(edit) - lastPos;
final int e = side.getEnd(edit) - lastPos;
if (c < b) {
// There is text at the start of this line that is common
// with the other side. Copy it with no style around it.
//
final int cmnLen = Math.min(b, line.length());
buf.openSpan();
buf.setStyleName("wdc");
appendShowBareCR(buf, line.substring(c, cmnLen), //
cmnLen == line.length() - 1);
buf.closeSpan();
c = cmnLen;
}
final int modLen = Math.min(e, line.length());
if (c < e && c < modLen) {
buf.openSpan();
buf.setStyleName(side.getStyleName());
appendShowBareCR(buf, line.substring(c, modLen), //
modLen == line.length() - 1);
buf.closeSpan();
if (modLen == line.length()) {
trailingEdits.add(index);
}
c = modLen;
}
if (e <= c) {
lastIdx++;
}
}
lastPos += line.length();
} else {
appendShowBareCR(buf, src.get(index), true);
buf.append('\n');
}
}
return buf;
}