Fix various issues with display competition and asian characters + testcases

This commit is contained in:
Julian Viereck 2011-01-28 23:16:08 +08:00 • committed by Fabian Jakobs
commit be2e78616e
3 changed files with 65 additions and 23 deletions

View file

@ -283,6 +283,8 @@ exports.launch = function(env) {
return event.preventDefault(e); return event.preventDefault(e);
}); });
window.env = env;
}; };
}); });

View file

@ -764,14 +764,14 @@ var EditSession = function(text, mode) {
addSplit(split); addSplit(split);
} else { } else {
// Search for the first non space/tab token. // Search for the first non space/tab token.
for (split; split != lastSplit; split--) { for (split; split != lastSplit - 1; split--) {
if (tokens[split] >= SPACE) { if (tokens[split] >= SPACE) {
split++; split++;
break; break;
} }
} }
// If we found one, then add the split. // If we found one, then add the split.
if (split != lastSplit) { if (split > lastSplit) {
addSplit(split); addSplit(split);
} }
// No space or tab around? Well, force a split then. // No space or tab around? Well, force a split then.
@ -953,7 +953,7 @@ var EditSession = function(text, mode) {
docRow = row; docRow = row;
row = 0; row = 0;
docColumn = 0; docColumn = 0;
line = this.getLine(docRow).split("\t"); line = this.getLine(docRow);
} else { } else {
var wrapData = this.$wrapData, linesCount = this.getLength(); var wrapData = this.$wrapData, linesCount = this.getLength();
@ -968,22 +968,42 @@ var EditSession = function(text, mode) {
}; };
} }
docColumn = wrapData[docRow][row - 1] || 0; docColumn = wrapData[docRow][row - 1] || 0;
line = this.getLine(docRow).substring(docColumn).split("\t"); line = this.getLine(docRow).substring(docColumn);
} }
var tabSize = this.getTabSize(); var tabSize = this.getTabSize();
for(var i = 0; i < line.length; i++) { for(var i = 0; i < line.length; i++) {
var len = line[i].length; var c = line.charCodeAt(i);
if (remaining >= len + tabSize) {
remaining -= (len + tabSize); if (remaining > 0) {
docColumn += (len + 1); docColumn += 1;
// tab
if (c == 9) {
if (remaining >= tabSize) {
remaining -= tabSize;
} else {
remaining = 0;
docColumn -= 1;
} }
else if (remaining > len){
docColumn += len;
break;
} }
else { // CJK characters
docColumn += remaining; else if (
c >= 0x3040 && c <= 0x309F || // Hiragana
c >= 0x30A0 && c <= 0x30FF || // Katakana
c >= 0x4E00 && c <= 0x9FFF || // Single CJK ideographs
c >= 0xF900 && c <= 0xFAFF ||
c >= 0x3400 && c <= 0x4DBF
) {
if (remaining >= 2) {
remaining -= 2;
} else {
remaining = 0;
docColumn -= 1;
}
} else {
remaining -= 1;
}
} else {
break; break;
} }
} }
@ -1065,7 +1085,7 @@ var EditSession = function(text, mode) {
if (!this.$useWrapMode) { if (!this.$useWrapMode) {
str = this.getLine(row).substring(0, column); str = this.getLine(row).substring(0, column);
column += (str.split("\t").length - 1) * (tabSize - 1); column = this.$getStringScreenWidth(str);
return { return {
row: row, row: row,
column: column column: column
@ -1085,11 +1105,10 @@ var EditSession = function(text, mode) {
var rowData = this.$documentToScreenRow(row, column); var rowData = this.$documentToScreenRow(row, column);
screenRow = rowData[0]; screenRow = rowData[0];
screenRowOffset = rowData[1]; screenRowOffset = rowData[1];
screenColumn = column - (wrapRowData[screenRowOffset - 1] || 0);
str = this.getLine(row).substring( str = this.getLine(row).substring(
wrapRowData[screenRowOffset - 1] || 0, column); wrapRowData[screenRowOffset - 1] || 0, column);
screenColumn += (str.split("\t").length - 1) * (tabSize - 1); screenColumn = this.$getStringScreenWidth(str);
return { return {
row: screenRow, row: screenRow,

View file

@ -283,14 +283,14 @@ var Test = {
"test: wrapLine split function" : function() { "test: wrapLine split function" : function() {
var splits; var splits;
var tabSize = 4;
var wrapLimit = 12;
var computeWrapSplits = EditSession.prototype.$computeWrapSplits; var computeWrapSplits = EditSession.prototype.$computeWrapSplits;
var c = 0; var c = 0;
function computeAndAssert(line, assertEqual) { function computeAndAssert(line, assertEqual, wrapLimit, tabSize) {
wrapLimit = wrapLimit || 12;
tabSize = tabSize || 4;
splits = computeWrapSplits.call(EditSession.prototype, line, wrapLimit, tabSize); splits = computeWrapSplits.call(EditSession.prototype, line, wrapLimit, tabSize);
// console.log("String:", line, "Result:", splits, "Expected:", assertEqual); console.log("String:", line, "Result:", splits, "Expected:", assertEqual);
assert.ok(splits.length == assertEqual.length); assert.ok(splits.length == assertEqual.length);
for (var i = 0; i < splits.length; i++) { for (var i = 0; i < splits.length; i++) {
assert.ok(splits[i] == assertEqual[i]); assert.ok(splits[i] == assertEqual[i]);
@ -317,6 +317,12 @@ var Test = {
// Ignore spaces/tabs at beginning of split. // Ignore spaces/tabs at beginning of split.
computeAndAssert("foo \t \t \t \t bar", [ 14 ]); computeAndAssert("foo \t \t \t \t bar", [ 14 ]);
// Test wrapping for asian characters.
computeAndAssert("ぁぁ", [1], 2);
computeAndAssert(" ぁぁ", [1, 2], 2);
computeAndAssert(" ぁ\tぁ", [1, 3], 2);
computeAndAssert(" ぁぁ\tぁ", [1, 4], 4);
}, },
"test: documentToScreen": function() { "test: documentToScreen": function() {
@ -328,6 +334,13 @@ var Test = {
assert.position(session.documentToScreenPosition(0, 11), 0, 11); assert.position(session.documentToScreenPosition(0, 11), 0, 11);
assert.position(session.documentToScreenPosition(0, 12), 1, 0); assert.position(session.documentToScreenPosition(0, 12), 1, 0);
session = new EditSession(["ぁぁa"]);
session.setUseWrapMode(true);
session.setWrapLimit(2);
assert.position(session.documentToScreenPosition(0, 1), 1, 0);
assert.position(session.documentToScreenPosition(0, 2), 2, 0);
assert.position(session.documentToScreenPosition(0, 4), 2, 1);
}, },
"test: screenToDocument": function() { "test: screenToDocument": function() {
@ -342,6 +355,14 @@ var Test = {
// Check if the position is clamped the right way. // Check if the position is clamped the right way.
assert.position(session.screenToDocumentPosition(0, 12), 0, 11); assert.position(session.screenToDocumentPosition(0, 12), 0, 11);
assert.position(session.screenToDocumentPosition(0, 20), 0, 11); assert.position(session.screenToDocumentPosition(0, 20), 0, 11);
session = new EditSession(["ぁ a"]);
session.setUseWrapMode(true);
assert.position(session.screenToDocumentPosition(0, 1), 0, 0);
assert.position(session.screenToDocumentPosition(0, 2), 0, 1);
assert.position(session.screenToDocumentPosition(0, 3), 0, 2);
assert.position(session.screenToDocumentPosition(0, 4), 0, 3);
assert.position(session.screenToDocumentPosition(0, 5), 0, 3);
} }
}; };