use APF style class declaration
This commit is contained in:
parent
7344f24d71
commit
2b736e7c8e
20 changed files with 1945 additions and 1867 deletions
|
|
@ -41,62 +41,67 @@ ace.BackgroundTokenizer = function(tokenizer) {
|
|||
|
||||
this.$initEvents();
|
||||
};
|
||||
ace.mixin(ace.BackgroundTokenizer.prototype, ace.MEventEmitter);
|
||||
|
||||
ace.BackgroundTokenizer.prototype.setTokenizer = function(tokenizer) {
|
||||
this.tokenizer = tokenizer;
|
||||
this.lines = [];
|
||||
(function(){
|
||||
|
||||
this.start(0);
|
||||
};
|
||||
ace.mixin(this, ace.MEventEmitter);
|
||||
|
||||
ace.BackgroundTokenizer.prototype.setLines = function(textLines) {
|
||||
this.textLines = textLines;
|
||||
this.lines = [];
|
||||
this.setTokenizer = function(tokenizer) {
|
||||
this.tokenizer = tokenizer;
|
||||
this.lines = [];
|
||||
|
||||
this.stop();
|
||||
};
|
||||
|
||||
ace.BackgroundTokenizer.prototype.fireUpdateEvent = function(firstRow, lastRow) {
|
||||
var data = {
|
||||
first: firstRow,
|
||||
last: lastRow
|
||||
this.start(0);
|
||||
};
|
||||
this.$dispatchEvent("update", {data: data});
|
||||
};
|
||||
|
||||
ace.BackgroundTokenizer.prototype.start = function(startRow) {
|
||||
this.currentLine = Math.min(startRow || 0, this.currentLine,
|
||||
this.textLines.length);
|
||||
this.setLines = function(textLines) {
|
||||
this.textLines = textLines;
|
||||
this.lines = [];
|
||||
|
||||
this.lines.splice(this.currentLine, this.lines.length);
|
||||
this.stop();
|
||||
};
|
||||
|
||||
if (!this.running) {
|
||||
clearTimeout(this.running);
|
||||
// pretty long delay to prevent the tokenizer from interfering with the user
|
||||
this.running = setTimeout(this._worker, 200);
|
||||
}
|
||||
};
|
||||
this.fireUpdateEvent = function(firstRow, lastRow) {
|
||||
var data = {
|
||||
first: firstRow,
|
||||
last: lastRow
|
||||
};
|
||||
this.$dispatchEvent("update", {data: data});
|
||||
};
|
||||
|
||||
ace.BackgroundTokenizer.prototype.stop = function() {
|
||||
this.running = false;
|
||||
};
|
||||
this.start = function(startRow) {
|
||||
this.currentLine = Math.min(startRow || 0, this.currentLine,
|
||||
this.textLines.length);
|
||||
|
||||
ace.BackgroundTokenizer.prototype.getTokens = function(row) {
|
||||
return this._tokenizeRow(row).tokens;
|
||||
};
|
||||
this.lines.splice(this.currentLine, this.lines.length);
|
||||
|
||||
ace.BackgroundTokenizer.prototype.getState = function(row) {
|
||||
return this._tokenizeRow(row).state;
|
||||
};
|
||||
|
||||
ace.BackgroundTokenizer.prototype._tokenizeRow = function(row) {
|
||||
if (!this.lines[row]) {
|
||||
var state = "start";
|
||||
if (row > 0 && this.lines[row - 1]) {
|
||||
state = this.lines[row - 1].state;
|
||||
if (!this.running) {
|
||||
clearTimeout(this.running);
|
||||
// pretty long delay to prevent the tokenizer from interfering with the user
|
||||
this.running = setTimeout(this._worker, 200);
|
||||
}
|
||||
this.lines[row] = this.tokenizer.getLineTokens(this.textLines[row] || "", state);
|
||||
}
|
||||
return this.lines[row];
|
||||
};
|
||||
};
|
||||
|
||||
this.stop = function() {
|
||||
this.running = false;
|
||||
};
|
||||
|
||||
this.getTokens = function(row) {
|
||||
return this._tokenizeRow(row).tokens;
|
||||
};
|
||||
|
||||
this.getState = function(row) {
|
||||
return this._tokenizeRow(row).state;
|
||||
};
|
||||
|
||||
this._tokenizeRow = function(row) {
|
||||
if (!this.lines[row]) {
|
||||
var state = "start";
|
||||
if (row > 0 && this.lines[row - 1]) {
|
||||
state = this.lines[row - 1].state;
|
||||
}
|
||||
this.lines[row] = this.tokenizer.getLineTokens(this.textLines[row] || "", state);
|
||||
}
|
||||
return this.lines[row];
|
||||
};
|
||||
|
||||
}).call(ace.BackgroundTokenizer.prototype);
|
||||
641
src/Document.js
641
src/Document.js
|
|
@ -13,377 +13,380 @@ ace.Document = function(text, mode) {
|
|||
}
|
||||
};
|
||||
|
||||
ace.mixin(ace.Document.prototype, ace.MEventEmitter);
|
||||
(function() {
|
||||
|
||||
ace.Document.prototype._split = function(text) {
|
||||
return text.split(/\r\n|\r|\n/);
|
||||
};
|
||||
ace.mixin(ace.Document.prototype, ace.MEventEmitter);
|
||||
|
||||
ace.Document.prototype.toString = function() {
|
||||
return this.lines.join("\n");
|
||||
};
|
||||
|
||||
ace.Document.prototype.getSelection = function() {
|
||||
return this.selection;
|
||||
};
|
||||
|
||||
ace.Document.prototype.fireChangeEvent = function(firstRow, lastRow) {
|
||||
var data = {
|
||||
firstRow: firstRow,
|
||||
lastRow: lastRow
|
||||
this._split = function(text) {
|
||||
return text.split(/\r\n|\r|\n/);
|
||||
};
|
||||
this.$dispatchEvent("change", { data: data});
|
||||
};
|
||||
|
||||
ace.Document.prototype.getTabString = function() {
|
||||
if (this.getUseSoftTabs()) {
|
||||
return new Array(this.getTabSize()+1).join(" ");
|
||||
}
|
||||
return "\t";
|
||||
};
|
||||
this.toString = function() {
|
||||
return this.lines.join("\n");
|
||||
};
|
||||
|
||||
ace.Document.prototype._useSoftTabs = true;
|
||||
ace.Document.prototype.setUseSoftTabs = function(useSoftTabs) {
|
||||
if (this._useSoftTabs === useSoftTabs) return;
|
||||
this.getSelection = function() {
|
||||
return this.selection;
|
||||
};
|
||||
|
||||
this._useSoftTabs = useSoftTabs;
|
||||
};
|
||||
this.fireChangeEvent = function(firstRow, lastRow) {
|
||||
var data = {
|
||||
firstRow: firstRow,
|
||||
lastRow: lastRow
|
||||
};
|
||||
this.$dispatchEvent("change", { data: data});
|
||||
};
|
||||
|
||||
ace.Document.prototype.getUseSoftTabs = function() {
|
||||
return this._useSoftTabs;
|
||||
};
|
||||
|
||||
ace.Document.prototype._tabSize = 4;
|
||||
ace.Document.prototype.setTabSize = function(tabSize) {
|
||||
if (this._tabSize === tabSize) return;
|
||||
|
||||
this._tabSize = tabSize;
|
||||
this.$dispatchEvent("changeTabSize");
|
||||
};
|
||||
|
||||
ace.Document.prototype.getTabSize = function() {
|
||||
return this._tabSize;
|
||||
};
|
||||
|
||||
ace.Document.prototype._mode = null;
|
||||
ace.Document.prototype.setMode = function(mode) {
|
||||
if (this._mode === mode) return;
|
||||
|
||||
this._mode = mode;
|
||||
this.$dispatchEvent("changeMode");
|
||||
};
|
||||
|
||||
ace.Document.prototype.getMode = function() {
|
||||
if (!this._mode) {
|
||||
this._mode = new ace.mode.Text();
|
||||
}
|
||||
return this._mode;
|
||||
};
|
||||
|
||||
ace.Document.prototype._scrollTop = 0;
|
||||
ace.Document.prototype.setScrollTopRow = function(scrollTopRow) {
|
||||
if (this._scrollTop === scrollTopRow) return;
|
||||
|
||||
this._scrollTop = scrollTopRow;
|
||||
this.$dispatchEvent("changeScrollTop");
|
||||
};
|
||||
|
||||
ace.Document.prototype.getScrollTopRow = function() {
|
||||
return this._scrollTop;
|
||||
};
|
||||
|
||||
ace.Document.prototype.getWidth = function() {
|
||||
if (this.modified) {
|
||||
this.modified = false;
|
||||
|
||||
var lines = this.lines;
|
||||
var longestLine = 0;
|
||||
for ( var i = 0; i < lines.length; i++) {
|
||||
longestLine = Math.max(longestLine, lines[i].length);
|
||||
this.getTabString = function() {
|
||||
if (this.getUseSoftTabs()) {
|
||||
return new Array(this.getTabSize()+1).join(" ");
|
||||
}
|
||||
this.width = longestLine;
|
||||
}
|
||||
return this.width;
|
||||
};
|
||||
return "\t";
|
||||
};
|
||||
|
||||
ace.Document.prototype.getLine = function(row) {
|
||||
return this.lines[row] || "";
|
||||
};
|
||||
this._useSoftTabs = false;
|
||||
this.setUseSoftTabs = function(useSoftTabs) {
|
||||
if (this._useSoftTabs === useSoftTabs) return;
|
||||
|
||||
ace.Document.prototype.getLength = function() {
|
||||
return this.lines.length;
|
||||
};
|
||||
this._useSoftTabs = useSoftTabs;
|
||||
};
|
||||
|
||||
ace.Document.prototype.getTextRange = function(range) {
|
||||
if (range.start.row == range.end.row) {
|
||||
return this.lines[range.start.row].substring(range.start.column,
|
||||
range.end.column);
|
||||
}
|
||||
else {
|
||||
var lines = [];
|
||||
lines.push(this.lines[range.start.row].substring(range.start.column));
|
||||
lines.push.apply(lines, this.getLines(range.start.row+1, range.end.row-1));
|
||||
lines.push(this.lines[range.end.row].substring(0, range.end.column));
|
||||
return lines.join("\n");
|
||||
}
|
||||
};
|
||||
this.getUseSoftTabs = function() {
|
||||
return this._useSoftTabs;
|
||||
};
|
||||
|
||||
ace.Document.prototype.getLines = function(firstRow, lastRow) {
|
||||
return this.lines.slice(firstRow, lastRow+1);
|
||||
};
|
||||
this._tabSize = 4;
|
||||
this.setTabSize = function(tabSize) {
|
||||
if (this._tabSize === tabSize) return;
|
||||
|
||||
ace.Document.prototype.findMatchingBracket = function(position) {
|
||||
if (position.column == 0) return null;
|
||||
this._tabSize = tabSize;
|
||||
this.$dispatchEvent("changeTabSize");
|
||||
};
|
||||
|
||||
var charBeforeCursor = this.getLine(position.row).charAt(position.column-1);
|
||||
if (charBeforeCursor == "") return null;
|
||||
this.getTabSize = function() {
|
||||
return this._tabSize;
|
||||
};
|
||||
|
||||
var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/);
|
||||
if (!match) {
|
||||
this._mode = null;
|
||||
this.setMode = function(mode) {
|
||||
if (this._mode === mode) return;
|
||||
|
||||
this._mode = mode;
|
||||
this.$dispatchEvent("changeMode");
|
||||
};
|
||||
|
||||
this.getMode = function() {
|
||||
if (!this._mode) {
|
||||
this._mode = new ace.mode.Text();
|
||||
}
|
||||
return this._mode;
|
||||
};
|
||||
|
||||
this._scrollTop = 0;
|
||||
this.setScrollTopRow = function(scrollTopRow) {
|
||||
if (this._scrollTop === scrollTopRow) return;
|
||||
|
||||
this._scrollTop = scrollTopRow;
|
||||
this.$dispatchEvent("changeScrollTop");
|
||||
};
|
||||
|
||||
this.getScrollTopRow = function() {
|
||||
return this._scrollTop;
|
||||
};
|
||||
|
||||
this.getWidth = function() {
|
||||
if (this.modified) {
|
||||
this.modified = false;
|
||||
|
||||
var lines = this.lines;
|
||||
var longestLine = 0;
|
||||
for ( var i = 0; i < lines.length; i++) {
|
||||
longestLine = Math.max(longestLine, lines[i].length);
|
||||
}
|
||||
this.width = longestLine;
|
||||
}
|
||||
return this.width;
|
||||
};
|
||||
|
||||
this.getLine = function(row) {
|
||||
return this.lines[row] || "";
|
||||
};
|
||||
|
||||
this.getLength = function() {
|
||||
return this.lines.length;
|
||||
};
|
||||
|
||||
this.getTextRange = function(range) {
|
||||
if (range.start.row == range.end.row) {
|
||||
return this.lines[range.start.row].substring(range.start.column,
|
||||
range.end.column);
|
||||
}
|
||||
else {
|
||||
var lines = [];
|
||||
lines.push(this.lines[range.start.row].substring(range.start.column));
|
||||
lines.push.apply(lines, this.getLines(range.start.row+1, range.end.row-1));
|
||||
lines.push(this.lines[range.end.row].substring(0, range.end.column));
|
||||
return lines.join("\n");
|
||||
}
|
||||
};
|
||||
|
||||
this.getLines = function(firstRow, lastRow) {
|
||||
return this.lines.slice(firstRow, lastRow+1);
|
||||
};
|
||||
|
||||
this.findMatchingBracket = function(position) {
|
||||
if (position.column == 0) return null;
|
||||
|
||||
var charBeforeCursor = this.getLine(position.row).charAt(position.column-1);
|
||||
if (charBeforeCursor == "") return null;
|
||||
|
||||
var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/);
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (match[1]) {
|
||||
return this._findClosingBracket(match[1], position);
|
||||
} else {
|
||||
return this._findOpeningBracket(match[2], position);
|
||||
}
|
||||
};
|
||||
|
||||
this._brackets = {
|
||||
")": "(",
|
||||
"(": ")",
|
||||
"]": "[",
|
||||
"[": "]",
|
||||
"{": "}",
|
||||
"}": "{"
|
||||
};
|
||||
|
||||
this._findOpeningBracket = function(bracket, position) {
|
||||
var openBracket = this._brackets[bracket];
|
||||
|
||||
var column = position.column - 2;
|
||||
var row = position.row;
|
||||
var depth = 1;
|
||||
|
||||
var line = this.getLine(row);
|
||||
|
||||
while (true) {
|
||||
while(column >= 0) {
|
||||
var char = line.charAt(column);
|
||||
if (char == openBracket) {
|
||||
depth -= 1;
|
||||
if (depth == 0) {
|
||||
return {row: row, column: column};
|
||||
}
|
||||
}
|
||||
else if (char == bracket) {
|
||||
depth +=1;
|
||||
}
|
||||
column -= 1;
|
||||
}
|
||||
row -=1;
|
||||
if (row < 0) break;
|
||||
|
||||
var line = this.getLine(row);
|
||||
var column = line.length-1;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
if (match[1]) {
|
||||
return this._findClosingBracket(match[1], position);
|
||||
} else {
|
||||
return this._findOpeningBracket(match[2], position);
|
||||
}
|
||||
};
|
||||
this._findClosingBracket = function(bracket, position) {
|
||||
var closingBracket = this._brackets[bracket];
|
||||
|
||||
ace.Document.prototype._brackets = {
|
||||
")": "(",
|
||||
"(": ")",
|
||||
"]": "[",
|
||||
"[": "]",
|
||||
"{": "}",
|
||||
"}": "{"
|
||||
};
|
||||
|
||||
ace.Document.prototype._findOpeningBracket = function(bracket, position) {
|
||||
var openBracket = this._brackets[bracket];
|
||||
|
||||
var column = position.column - 2;
|
||||
var row = position.row;
|
||||
var depth = 1;
|
||||
|
||||
var line = this.getLine(row);
|
||||
|
||||
while (true) {
|
||||
while(column >= 0) {
|
||||
var char = line.charAt(column);
|
||||
if (char == openBracket) {
|
||||
depth -= 1;
|
||||
if (depth == 0) {
|
||||
return {row: row, column: column};
|
||||
}
|
||||
}
|
||||
else if (char == bracket) {
|
||||
depth +=1;
|
||||
}
|
||||
column -= 1;
|
||||
}
|
||||
row -=1;
|
||||
if (row < 0) break;
|
||||
var column = position.column;
|
||||
var row = position.row;
|
||||
var depth = 1;
|
||||
|
||||
var line = this.getLine(row);
|
||||
var column = line.length-1;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
var lineCount = this.getLength();
|
||||
|
||||
ace.Document.prototype._findClosingBracket = function(bracket, position) {
|
||||
var closingBracket = this._brackets[bracket];
|
||||
|
||||
var column = position.column;
|
||||
var row = position.row;
|
||||
var depth = 1;
|
||||
|
||||
var line = this.getLine(row);
|
||||
var lineCount = this.getLength();
|
||||
|
||||
while (true) {
|
||||
while(column < line.length) {
|
||||
var char = line.charAt(column);
|
||||
if (char == closingBracket) {
|
||||
depth -= 1;
|
||||
if (depth == 0) {
|
||||
return {row: row, column: column};
|
||||
while (true) {
|
||||
while(column < line.length) {
|
||||
var char = line.charAt(column);
|
||||
if (char == closingBracket) {
|
||||
depth -= 1;
|
||||
if (depth == 0) {
|
||||
return {row: row, column: column};
|
||||
}
|
||||
}
|
||||
else if (char == bracket) {
|
||||
depth +=1;
|
||||
}
|
||||
column += 1;
|
||||
}
|
||||
else if (char == bracket) {
|
||||
depth +=1;
|
||||
row +=1;
|
||||
if (row >= lineCount) break;
|
||||
|
||||
var line = this.getLine(row);
|
||||
var column = 0;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
this.insert = function(position, text) {
|
||||
var end = this._insert(position, text);
|
||||
this.fireChangeEvent(position.row, position.row == end.row ? position.row
|
||||
: undefined);
|
||||
return end;
|
||||
};
|
||||
|
||||
this._insertLines = function(row, lines) {
|
||||
var args = [row, 0];
|
||||
args.push.apply(args, lines);
|
||||
this.lines.splice.apply(this.lines, args);
|
||||
},
|
||||
|
||||
this._insert = function(position, text) {
|
||||
this.modified = true;
|
||||
|
||||
var newLines = this._split(text);
|
||||
|
||||
if (this._isNewLine(text)) {
|
||||
var line = this.lines[position.row] || "";
|
||||
this.lines[position.row] = line.substring(0, position.column);
|
||||
this.lines.splice(position.row + 1, 0, line.substring(position.column));
|
||||
|
||||
return {
|
||||
row : position.row + 1,
|
||||
column : 0
|
||||
};
|
||||
}
|
||||
else if (newLines.length == 1) {
|
||||
var line = this.lines[position.row] || "";
|
||||
this.lines[position.row] = line.substring(0, position.column) + text
|
||||
+ line.substring(position.column);
|
||||
|
||||
return {
|
||||
row : position.row,
|
||||
column : position.column + text.length
|
||||
};
|
||||
}
|
||||
else {
|
||||
var line = this.lines[position.row] || "";
|
||||
|
||||
this.lines[position.row] = line.substring(0, position.column)
|
||||
+ newLines[0];
|
||||
this.lines[position.row + 1] = newLines[newLines.length - 1]
|
||||
+ line.substring(position.column);
|
||||
|
||||
if (newLines.length > 2) {
|
||||
this._insertLines(position.row + 1, newLines.slice(1, -1));
|
||||
}
|
||||
column += 1;
|
||||
|
||||
return {
|
||||
row : position.row + newLines.length - 1,
|
||||
column : newLines[newLines.length - 1].length
|
||||
};
|
||||
}
|
||||
row +=1;
|
||||
if (row >= lineCount) break;
|
||||
};
|
||||
|
||||
var line = this.getLine(row);
|
||||
var column = 0;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
this._isNewLine = function(text) {
|
||||
return (text == "\r\n" || text == "\r" || text == "\n");
|
||||
};
|
||||
|
||||
ace.Document.prototype.insert = function(position, text) {
|
||||
var end = this._insert(position, text);
|
||||
this.fireChangeEvent(position.row, position.row == end.row ? position.row
|
||||
: undefined);
|
||||
return end;
|
||||
};
|
||||
this.remove = function(range) {
|
||||
this._remove(range);
|
||||
|
||||
ace.Document.prototype._insertLines = function(row, lines) {
|
||||
var args = [row, 0];
|
||||
args.push.apply(args, lines);
|
||||
this.lines.splice.apply(this.lines, args);
|
||||
},
|
||||
this.fireChangeEvent(range.start.row,
|
||||
range.end.row == range.start.row ? range.start.row
|
||||
: undefined);
|
||||
return range.start;
|
||||
};
|
||||
|
||||
ace.Document.prototype._insert = function(position, text) {
|
||||
this.modified = true;
|
||||
this._remove = function(range) {
|
||||
this.modified = true;
|
||||
|
||||
var newLines = this._split(text);
|
||||
var firstRow = range.start.row;
|
||||
var lastRow = range.end.row;
|
||||
|
||||
if (this._isNewLine(text)) {
|
||||
var line = this.lines[position.row] || "";
|
||||
this.lines[position.row] = line.substring(0, position.column);
|
||||
this.lines.splice(position.row + 1, 0, line.substring(position.column));
|
||||
var row = this.lines[firstRow].substring(0, range.start.column)
|
||||
+ this.lines[lastRow].substring(range.end.column);
|
||||
|
||||
return {
|
||||
row : position.row + 1,
|
||||
column : 0
|
||||
};
|
||||
}
|
||||
else if (newLines.length == 1) {
|
||||
var line = this.lines[position.row] || "";
|
||||
this.lines[position.row] = line.substring(0, position.column) + text
|
||||
+ line.substring(position.column);
|
||||
this.lines.splice(firstRow, lastRow - firstRow + 1, row);
|
||||
|
||||
return {
|
||||
row : position.row,
|
||||
column : position.column + text.length
|
||||
};
|
||||
}
|
||||
else {
|
||||
var line = this.lines[position.row] || "";
|
||||
return range.start;
|
||||
};
|
||||
|
||||
this.lines[position.row] = line.substring(0, position.column)
|
||||
+ newLines[0];
|
||||
this.lines[position.row + 1] = newLines[newLines.length - 1]
|
||||
+ line.substring(position.column);
|
||||
|
||||
if (newLines.length > 2) {
|
||||
this._insertLines(position.row + 1, newLines.slice(1, -1));
|
||||
this.replace = function(range, text) {
|
||||
this._remove(range);
|
||||
if (text) {
|
||||
var end = this._insert(range.start, text);
|
||||
}
|
||||
else {
|
||||
end = range.start;
|
||||
}
|
||||
|
||||
return {
|
||||
row : position.row + newLines.length - 1,
|
||||
column : newLines[newLines.length - 1].length
|
||||
};
|
||||
}
|
||||
};
|
||||
var lastRemoved = range.end.column == 0 ? range.end.column - 1
|
||||
: range.end.column;
|
||||
this.fireChangeEvent(range.start.row, lastRemoved == end.row ? lastRemoved
|
||||
: undefined);
|
||||
|
||||
ace.Document.prototype._isNewLine = function(text) {
|
||||
return (text == "\r\n" || text == "\r" || text == "\n");
|
||||
};
|
||||
return end;
|
||||
};
|
||||
|
||||
ace.Document.prototype.remove = function(range) {
|
||||
this._remove(range);
|
||||
this.indentRows = function(range, indentString) {
|
||||
for (var i=range.start.row; i<= range.end.row; i++) {
|
||||
this.lines[i] = indentString + this.getLine(i);
|
||||
}
|
||||
this.fireChangeEvent(range.start.row, range.end.row);
|
||||
return indentString.length;
|
||||
};
|
||||
|
||||
this.fireChangeEvent(range.start.row,
|
||||
range.end.row == range.start.row ? range.start.row
|
||||
: undefined);
|
||||
return range.start;
|
||||
};
|
||||
this.outdentRows = function(range, indentString) {
|
||||
outdentLength = indentString.length;
|
||||
|
||||
ace.Document.prototype._remove = function(range) {
|
||||
this.modified = true;
|
||||
|
||||
var firstRow = range.start.row;
|
||||
var lastRow = range.end.row;
|
||||
|
||||
var row = this.lines[firstRow].substring(0, range.start.column)
|
||||
+ this.lines[lastRow].substring(range.end.column);
|
||||
|
||||
this.lines.splice(firstRow, lastRow - firstRow + 1, row);
|
||||
|
||||
return range.start;
|
||||
};
|
||||
|
||||
ace.Document.prototype.replace = function(range, text) {
|
||||
this._remove(range);
|
||||
if (text) {
|
||||
var end = this._insert(range.start, text);
|
||||
}
|
||||
else {
|
||||
end = range.start;
|
||||
}
|
||||
|
||||
var lastRemoved = range.end.column == 0 ? range.end.column - 1
|
||||
: range.end.column;
|
||||
this.fireChangeEvent(range.start.row, lastRemoved == end.row ? lastRemoved
|
||||
: undefined);
|
||||
|
||||
return end;
|
||||
};
|
||||
|
||||
ace.Document.prototype.indentRows = function(range, indentString) {
|
||||
for (var i=range.start.row; i<= range.end.row; i++) {
|
||||
this.lines[i] = indentString + this.getLine(i);
|
||||
}
|
||||
this.fireChangeEvent(range.start.row, range.end.row);
|
||||
return indentString.length;
|
||||
};
|
||||
|
||||
ace.Document.prototype.outdentRows = function(range, indentString) {
|
||||
outdentLength = indentString.length;
|
||||
|
||||
for (var i=range.start.row; i<= range.end.row; i++) {
|
||||
if (this.getLine(i).substr(0, outdentLength) !== indentString) {
|
||||
return 0;
|
||||
for (var i=range.start.row; i<= range.end.row; i++) {
|
||||
if (this.getLine(i).substr(0, outdentLength) !== indentString) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i=range.start.row; i<= range.end.row; i++) {
|
||||
this.lines[i] = this.getLine(i).substring(outdentLength);
|
||||
}
|
||||
for (var i=range.start.row; i<= range.end.row; i++) {
|
||||
this.lines[i] = this.getLine(i).substring(outdentLength);
|
||||
}
|
||||
|
||||
this.fireChangeEvent(range.start.row, range.end.row);
|
||||
return -outdentLength;
|
||||
};
|
||||
this.fireChangeEvent(range.start.row, range.end.row);
|
||||
return -outdentLength;
|
||||
};
|
||||
|
||||
ace.Document.prototype.moveLinesUp = function(firstRow, lastRow) {
|
||||
if (firstRow <= 0) return 0;
|
||||
this.moveLinesUp = function(firstRow, lastRow) {
|
||||
if (firstRow <= 0) return 0;
|
||||
|
||||
var removed = this.lines.splice(firstRow, lastRow-firstRow+1);
|
||||
this._insertLines(firstRow-1, removed);
|
||||
var removed = this.lines.splice(firstRow, lastRow-firstRow+1);
|
||||
this._insertLines(firstRow-1, removed);
|
||||
|
||||
this.fireChangeEvent(firstRow-1, lastRow);
|
||||
return -1;
|
||||
};
|
||||
this.fireChangeEvent(firstRow-1, lastRow);
|
||||
return -1;
|
||||
};
|
||||
|
||||
ace.Document.prototype.moveLinesDown = function(firstRow, lastRow) {
|
||||
if (lastRow >= this.lines.length-1) return 0;
|
||||
this.moveLinesDown = function(firstRow, lastRow) {
|
||||
if (lastRow >= this.lines.length-1) return 0;
|
||||
|
||||
var removed = this.lines.splice(firstRow, lastRow-firstRow+1);
|
||||
this._insertLines(firstRow+1, removed);
|
||||
var removed = this.lines.splice(firstRow, lastRow-firstRow+1);
|
||||
this._insertLines(firstRow+1, removed);
|
||||
|
||||
this.fireChangeEvent(firstRow, lastRow+1);
|
||||
return 1;
|
||||
};
|
||||
this.fireChangeEvent(firstRow, lastRow+1);
|
||||
return 1;
|
||||
};
|
||||
|
||||
ace.Document.prototype.duplicateLines = function(firstRow, lastRow) {
|
||||
var firstRow = this._clipRowToDocument(firstRow);
|
||||
var lastRow = this._clipRowToDocument(lastRow);
|
||||
this.duplicateLines = function(firstRow, lastRow) {
|
||||
var firstRow = this._clipRowToDocument(firstRow);
|
||||
var lastRow = this._clipRowToDocument(lastRow);
|
||||
|
||||
var lines = this.getLines(firstRow, lastRow);
|
||||
this._insertLines(firstRow, lines);
|
||||
var lines = this.getLines(firstRow, lastRow);
|
||||
this._insertLines(firstRow, lines);
|
||||
|
||||
var addedRows = lastRow - firstRow + 1;
|
||||
this.fireChangeEvent(firstRow, lastRow+addedRows);
|
||||
var addedRows = lastRow - firstRow + 1;
|
||||
this.fireChangeEvent(firstRow, lastRow+addedRows);
|
||||
|
||||
return addedRows;
|
||||
};
|
||||
return addedRows;
|
||||
};
|
||||
|
||||
ace.Document.prototype._clipRowToDocument = function(row) {
|
||||
return Math.max(0, Math.min(row, this.lines.length-1));
|
||||
};
|
||||
this._clipRowToDocument = function(row) {
|
||||
return Math.max(0, Math.min(row, this.lines.length-1));
|
||||
};
|
||||
|
||||
}).call(ace.Document.prototype);
|
||||
|
|
|
|||
1020
src/Editor.js
1020
src/Editor.js
File diff suppressed because it is too large
Load diff
|
|
@ -1,26 +1,9 @@
|
|||
ace.provide("ace.KeyBinding");
|
||||
|
||||
(function() {
|
||||
|
||||
var keys = {
|
||||
UP : 38,
|
||||
RIGHT : 39,
|
||||
DOWN : 40,
|
||||
LEFT : 37,
|
||||
PAGEUP : 33,
|
||||
PAGEDOWN : 34,
|
||||
POS1 : 36,
|
||||
END : 35,
|
||||
DELETE : 46,
|
||||
BACKSPACE : 8,
|
||||
TAB : 9,
|
||||
A : 65,
|
||||
D: 68,
|
||||
L: 76,
|
||||
"7": 55
|
||||
};
|
||||
|
||||
ace.KeyBinding = function(element, editor) {
|
||||
|
||||
var keys = this.keys;
|
||||
|
||||
ace.addListener(element, "keydown", function(e) {
|
||||
var key = e.keyCode;
|
||||
var selection = editor.getSelection();
|
||||
|
|
@ -198,4 +181,22 @@ ace.KeyBinding = function(element, editor) {
|
|||
});
|
||||
};
|
||||
|
||||
})();
|
||||
(function() {
|
||||
this.keys = {
|
||||
UP : 38,
|
||||
RIGHT : 39,
|
||||
DOWN : 40,
|
||||
LEFT : 37,
|
||||
PAGEUP : 33,
|
||||
PAGEDOWN : 34,
|
||||
POS1 : 36,
|
||||
END : 35,
|
||||
DELETE : 46,
|
||||
BACKSPACE : 8,
|
||||
TAB : 9,
|
||||
A : 65,
|
||||
D: 68,
|
||||
L: 76,
|
||||
"7": 55
|
||||
};
|
||||
}).call(ace.KeyBinding.prototype);
|
||||
|
|
|
|||
|
|
@ -17,24 +17,28 @@ ace.ScrollBar = function(parent) {
|
|||
ace.addListener(this.element, "scroll", ace.bind(this.onScroll, this));
|
||||
};
|
||||
|
||||
ace.mixin(ace.ScrollBar.prototype, ace.MEventEmitter);
|
||||
(function() {
|
||||
|
||||
ace.ScrollBar.prototype.onScroll = function() {
|
||||
this.$dispatchEvent("scroll", {data: this.element.scrollTop});
|
||||
};
|
||||
ace.mixin(ace.ScrollBar.prototype, ace.MEventEmitter);
|
||||
|
||||
ace.ScrollBar.prototype.getWidth = function() {
|
||||
return this.width;
|
||||
};
|
||||
this.onScroll = function() {
|
||||
this.$dispatchEvent("scroll", {data: this.element.scrollTop});
|
||||
};
|
||||
|
||||
ace.ScrollBar.prototype.setHeight = function(height) {
|
||||
this.element.style.height = Math.max(0, height - this.width) + "px";
|
||||
};
|
||||
this.getWidth = function() {
|
||||
return this.width;
|
||||
};
|
||||
|
||||
ace.ScrollBar.prototype.setInnerHeight = function(height) {
|
||||
this.inner.style.height = height + "px";
|
||||
};
|
||||
this.setHeight = function(height) {
|
||||
this.element.style.height = Math.max(0, height - this.width) + "px";
|
||||
};
|
||||
|
||||
ace.ScrollBar.prototype.setScrollTop = function(scrollTop) {
|
||||
this.element.scrollTop = scrollTop;
|
||||
};
|
||||
this.setInnerHeight = function(height) {
|
||||
this.inner.style.height = height + "px";
|
||||
};
|
||||
|
||||
this.setScrollTop = function(scrollTop) {
|
||||
this.element.scrollTop = scrollTop;
|
||||
};
|
||||
|
||||
}).call(ace.ScrollBar.prototype);
|
||||
697
src/Selection.js
697
src/Selection.js
|
|
@ -11,371 +11,376 @@ ace.Selection = function(doc) {
|
|||
column: 0
|
||||
};
|
||||
};
|
||||
ace.mixin(ace.Selection.prototype, ace.MEventEmitter);
|
||||
|
||||
ace.Selection.prototype.updateCursor = function() {
|
||||
this.$dispatchEvent("changeCursor", { data: this.getCursor() });
|
||||
};
|
||||
(function() {
|
||||
|
||||
ace.Selection.prototype.updateSelection = function() {
|
||||
this.$dispatchEvent("changeSelection", {});
|
||||
};
|
||||
ace.mixin(ace.Selection.prototype, ace.MEventEmitter);
|
||||
|
||||
ace.Selection.prototype.isEmpty = function() {
|
||||
return (this.selectionAnchor == null);
|
||||
};
|
||||
this.updateCursor = function() {
|
||||
this.$dispatchEvent("changeCursor", { data: this.getCursor() });
|
||||
};
|
||||
|
||||
ace.Selection.prototype.isMultiLine = function() {
|
||||
if (this.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
this.updateSelection = function() {
|
||||
this.$dispatchEvent("changeSelection", {});
|
||||
};
|
||||
|
||||
var range = this.getRange();
|
||||
return (range.start.row !== range.end.row);
|
||||
};
|
||||
this.isEmpty = function() {
|
||||
return (this.selectionAnchor == null);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.getCursor = function() {
|
||||
return this.selectionLead;
|
||||
};
|
||||
this.isMultiLine = function() {
|
||||
if (this.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ace.Selection.prototype.setSelectionAnchor = function(row, column) {
|
||||
this.clearSelection();
|
||||
var range = this.getRange();
|
||||
return (range.start.row !== range.end.row);
|
||||
};
|
||||
|
||||
this.selectionAnchor = this._clipPositionToDocument(row, column);
|
||||
};
|
||||
this.getCursor = function() {
|
||||
return this.selectionLead;
|
||||
};
|
||||
|
||||
ace.Selection.prototype.getSelectionAnchor = function() {
|
||||
if (this.selectionAnchor) {
|
||||
return this._clone(this.selectionAnchor);
|
||||
} else {
|
||||
this.setSelectionAnchor = function(row, column) {
|
||||
this.clearSelection();
|
||||
|
||||
this.selectionAnchor = this._clipPositionToDocument(row, column);
|
||||
};
|
||||
|
||||
this.getSelectionAnchor = function() {
|
||||
if (this.selectionAnchor) {
|
||||
return this._clone(this.selectionAnchor);
|
||||
} else {
|
||||
return this._clone(this.selectionLead);
|
||||
}
|
||||
};
|
||||
|
||||
this.getSelectionLead = function() {
|
||||
return this._clone(this.selectionLead);
|
||||
}
|
||||
};
|
||||
|
||||
ace.Selection.prototype.getSelectionLead = function() {
|
||||
return this._clone(this.selectionLead);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.shiftSelection = function(columns) {
|
||||
if (this.isEmpty()) {
|
||||
this.moveCursorTo(this.selectionLead.row, this.selectionLead.column + columns);
|
||||
return;
|
||||
};
|
||||
|
||||
var anchor = this.getSelectionAnchor();
|
||||
var lead = this.getSelectionLead();
|
||||
|
||||
this.setSelectionAnchor(anchor.row, anchor.column + columns);
|
||||
this._moveSelection(function() {
|
||||
this.moveCursorTo(lead.row, lead.column + columns);
|
||||
});
|
||||
};
|
||||
|
||||
ace.Selection.prototype.getRange = function() {
|
||||
var anchor = this.selectionAnchor || this.selectionLead;
|
||||
var lead = this.selectionLead;
|
||||
|
||||
if (anchor.row > lead.row
|
||||
|| (anchor.row == lead.row && anchor.column > lead.column)) {
|
||||
return {
|
||||
start : lead,
|
||||
end : anchor
|
||||
this.shiftSelection = function(columns) {
|
||||
if (this.isEmpty()) {
|
||||
this.moveCursorTo(this.selectionLead.row, this.selectionLead.column + columns);
|
||||
return;
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {
|
||||
start : anchor,
|
||||
end : lead
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
ace.Selection.prototype.clearSelection = function() {
|
||||
this.selectionAnchor = null;
|
||||
this.updateSelection();
|
||||
};
|
||||
var anchor = this.getSelectionAnchor();
|
||||
var lead = this.getSelectionLead();
|
||||
|
||||
this.setSelectionAnchor(anchor.row, anchor.column + columns);
|
||||
this._moveSelection(function() {
|
||||
this.moveCursorTo(lead.row, lead.column + columns);
|
||||
});
|
||||
};
|
||||
|
||||
ace.Selection.prototype.selectAll = function() {
|
||||
var lastRow = this.doc.getLength() - 1;
|
||||
this.setSelectionAnchor(lastRow, this.doc.getLine(lastRow).length);
|
||||
this.getRange = function() {
|
||||
var anchor = this.selectionAnchor || this.selectionLead;
|
||||
var lead = this.selectionLead;
|
||||
|
||||
this._moveSelection(function() {
|
||||
this.moveCursorTo(0, 0);
|
||||
});
|
||||
};
|
||||
|
||||
ace.Selection.prototype._moveSelection = function(mover) {
|
||||
if (!this.selectionAnchor) {
|
||||
this.selectionAnchor = this._clone(this.selectionLead);
|
||||
}
|
||||
|
||||
mover.call(this);
|
||||
this.updateSelection();
|
||||
};
|
||||
|
||||
ace.Selection.prototype.selectTo = function(row, column) {
|
||||
this._moveSelection(function() {
|
||||
this.moveCursorTo(row, column);
|
||||
});
|
||||
};
|
||||
|
||||
ace.Selection.prototype.selectToPosition = function(pos) {
|
||||
this._moveSelection(function() {
|
||||
this.moveCursorToPosition(pos);
|
||||
});
|
||||
};
|
||||
|
||||
ace.Selection.prototype.selectUp = function() {
|
||||
this._moveSelection(this.moveCursorUp);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.selectDown = function() {
|
||||
this._moveSelection(this.moveCursorDown);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.selectRight = function() {
|
||||
this._moveSelection(this.moveCursorRight);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.selectLeft = function() {
|
||||
this._moveSelection(this.moveCursorLeft);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.selectLineStart = function() {
|
||||
this._moveSelection(this.moveCursorLineStart);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.selectLineEnd = function() {
|
||||
this._moveSelection(this.moveCursorLineEnd);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.selectPageDown = function() {
|
||||
var row = this.getPageDownRow() + Math.floor(this.getVisibleRowCount() / 2);
|
||||
|
||||
this.scrollPageDown();
|
||||
|
||||
this._moveSelection(function() {
|
||||
this.moveCursorTo(row, this.selectionLead.column);
|
||||
});
|
||||
};
|
||||
|
||||
ace.Selection.prototype.selectPageUp = function() {
|
||||
var visibleRows = this.getLastVisibleRow() - this.getFirstVisibleRow();
|
||||
var row = this.getPageUpRow() + Math.round(visibleRows / 2);
|
||||
|
||||
this.scrollPageUp();
|
||||
|
||||
this._moveSelection(function() {
|
||||
this.moveCursorTo(row, this.selectionLead.column);
|
||||
});
|
||||
};
|
||||
|
||||
ace.Selection.prototype.selectFileEnd = function() {
|
||||
this._moveSelection(this.moveCursorFileEnd);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.selectFileStart = function() {
|
||||
this._moveSelection(this.moveCursorFileStart);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.tokenRe = /^[\w\d]+/g;
|
||||
ace.Selection.prototype.nonTokenRe = /^[^\w\d]+/g;
|
||||
|
||||
ace.Selection.prototype.selectWordRight = function() {
|
||||
this._moveSelection(this.moveCursorWordRight);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.selectWordLeft = function() {
|
||||
this._moveSelection(this.moveCursorWordLeft);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.selectWord = function() {
|
||||
var cursor = this.selectionLead;
|
||||
|
||||
var line = this.doc.getLine(cursor.row);
|
||||
var column = cursor.column;
|
||||
|
||||
var inToken = false;
|
||||
if (column > 0) {
|
||||
inToken = !!line.charAt(column - 1).match(this.tokenRe);
|
||||
}
|
||||
|
||||
if (!inToken) {
|
||||
inToken = !!line.charAt(column).match(this.tokenRe);
|
||||
}
|
||||
|
||||
var re = inToken ? this.tokenRe : this.nonTokenRe;
|
||||
|
||||
var start = column;
|
||||
if (start > 0) {
|
||||
do {
|
||||
start--;
|
||||
if (anchor.row > lead.row
|
||||
|| (anchor.row == lead.row && anchor.column > lead.column)) {
|
||||
return {
|
||||
start : lead,
|
||||
end : anchor
|
||||
};
|
||||
}
|
||||
while (start >= 0 && line.charAt(start).match(re));
|
||||
start++;
|
||||
}
|
||||
|
||||
var end = column;
|
||||
while (end < line.length && line.charAt(end).match(re)) {
|
||||
end++;
|
||||
}
|
||||
|
||||
this.setSelectionAnchor(cursor.row, start);
|
||||
this._moveSelection(function() {
|
||||
this.moveCursorTo(cursor.row, end);
|
||||
});
|
||||
};
|
||||
|
||||
ace.Selection.prototype.selectLine = function() {
|
||||
this.setSelectionAnchor(this.selectionLead.row, 0);
|
||||
this._moveSelection(function() {
|
||||
this.moveCursorTo(this.selectionLead.row + 1, 0);
|
||||
});
|
||||
};
|
||||
|
||||
ace.Selection.prototype.moveCursorUp = function() {
|
||||
this.moveCursorBy(-1, 0);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.moveCursorDown = function() {
|
||||
this.moveCursorBy(1, 0);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.moveCursorLeft = function() {
|
||||
if (this.selectionLead.column == 0) {
|
||||
if (this.selectionLead.row > 0) {
|
||||
this.moveCursorTo(this.selectionLead.row - 1, this.doc
|
||||
.getLine(this.selectionLead.row - 1).length);
|
||||
else {
|
||||
return {
|
||||
start : anchor,
|
||||
end : lead
|
||||
};
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.moveCursorBy(0, -1);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
ace.Selection.prototype.moveCursorRight = function() {
|
||||
if (this.selectionLead.column == this.doc.getLine(this.selectionLead.row).length) {
|
||||
if (this.selectionLead.row < this.doc.getLength() - 1) {
|
||||
this.clearSelection = function() {
|
||||
this.selectionAnchor = null;
|
||||
this.updateSelection();
|
||||
};
|
||||
|
||||
|
||||
this.selectAll = function() {
|
||||
var lastRow = this.doc.getLength() - 1;
|
||||
this.setSelectionAnchor(lastRow, this.doc.getLine(lastRow).length);
|
||||
|
||||
this._moveSelection(function() {
|
||||
this.moveCursorTo(0, 0);
|
||||
});
|
||||
};
|
||||
|
||||
this._moveSelection = function(mover) {
|
||||
if (!this.selectionAnchor) {
|
||||
this.selectionAnchor = this._clone(this.selectionLead);
|
||||
}
|
||||
|
||||
mover.call(this);
|
||||
this.updateSelection();
|
||||
};
|
||||
|
||||
this.selectTo = function(row, column) {
|
||||
this._moveSelection(function() {
|
||||
this.moveCursorTo(row, column);
|
||||
});
|
||||
};
|
||||
|
||||
this.selectToPosition = function(pos) {
|
||||
this._moveSelection(function() {
|
||||
this.moveCursorToPosition(pos);
|
||||
});
|
||||
};
|
||||
|
||||
this.selectUp = function() {
|
||||
this._moveSelection(this.moveCursorUp);
|
||||
};
|
||||
|
||||
this.selectDown = function() {
|
||||
this._moveSelection(this.moveCursorDown);
|
||||
};
|
||||
|
||||
this.selectRight = function() {
|
||||
this._moveSelection(this.moveCursorRight);
|
||||
};
|
||||
|
||||
this.selectLeft = function() {
|
||||
this._moveSelection(this.moveCursorLeft);
|
||||
};
|
||||
|
||||
this.selectLineStart = function() {
|
||||
this._moveSelection(this.moveCursorLineStart);
|
||||
};
|
||||
|
||||
this.selectLineEnd = function() {
|
||||
this._moveSelection(this.moveCursorLineEnd);
|
||||
};
|
||||
|
||||
this.selectPageDown = function() {
|
||||
var row = this.getPageDownRow() + Math.floor(this.getVisibleRowCount() / 2);
|
||||
|
||||
this.scrollPageDown();
|
||||
|
||||
this._moveSelection(function() {
|
||||
this.moveCursorTo(row, this.selectionLead.column);
|
||||
});
|
||||
};
|
||||
|
||||
this.selectPageUp = function() {
|
||||
var visibleRows = this.getLastVisibleRow() - this.getFirstVisibleRow();
|
||||
var row = this.getPageUpRow() + Math.round(visibleRows / 2);
|
||||
|
||||
this.scrollPageUp();
|
||||
|
||||
this._moveSelection(function() {
|
||||
this.moveCursorTo(row, this.selectionLead.column);
|
||||
});
|
||||
};
|
||||
|
||||
this.selectFileEnd = function() {
|
||||
this._moveSelection(this.moveCursorFileEnd);
|
||||
};
|
||||
|
||||
this.selectFileStart = function() {
|
||||
this._moveSelection(this.moveCursorFileStart);
|
||||
};
|
||||
|
||||
this.tokenRe = /^[\w\d]+/g;
|
||||
this.nonTokenRe = /^[^\w\d]+/g;
|
||||
|
||||
this.selectWordRight = function() {
|
||||
this._moveSelection(this.moveCursorWordRight);
|
||||
};
|
||||
|
||||
this.selectWordLeft = function() {
|
||||
this._moveSelection(this.moveCursorWordLeft);
|
||||
};
|
||||
|
||||
this.selectWord = function() {
|
||||
var cursor = this.selectionLead;
|
||||
|
||||
var line = this.doc.getLine(cursor.row);
|
||||
var column = cursor.column;
|
||||
|
||||
var inToken = false;
|
||||
if (column > 0) {
|
||||
inToken = !!line.charAt(column - 1).match(this.tokenRe);
|
||||
}
|
||||
|
||||
if (!inToken) {
|
||||
inToken = !!line.charAt(column).match(this.tokenRe);
|
||||
}
|
||||
|
||||
var re = inToken ? this.tokenRe : this.nonTokenRe;
|
||||
|
||||
var start = column;
|
||||
if (start > 0) {
|
||||
do {
|
||||
start--;
|
||||
}
|
||||
while (start >= 0 && line.charAt(start).match(re));
|
||||
start++;
|
||||
}
|
||||
|
||||
var end = column;
|
||||
while (end < line.length && line.charAt(end).match(re)) {
|
||||
end++;
|
||||
}
|
||||
|
||||
this.setSelectionAnchor(cursor.row, start);
|
||||
this._moveSelection(function() {
|
||||
this.moveCursorTo(cursor.row, end);
|
||||
});
|
||||
};
|
||||
|
||||
this.selectLine = function() {
|
||||
this.setSelectionAnchor(this.selectionLead.row, 0);
|
||||
this._moveSelection(function() {
|
||||
this.moveCursorTo(this.selectionLead.row + 1, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.moveCursorBy(0, 1);
|
||||
}
|
||||
};
|
||||
|
||||
ace.Selection.prototype.moveCursorLineStart = function() {
|
||||
this.moveCursorTo(this.selectionLead.row, 0);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.moveCursorLineEnd = function() {
|
||||
this.moveCursorTo(this.selectionLead.row,
|
||||
this.doc.getLine(this.selectionLead.row).length);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.moveCursorFileEnd = function() {
|
||||
var row = this.doc.getLength() - 1;
|
||||
var column = this.doc.getLine(row).length;
|
||||
this.moveCursorTo(row, column);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.moveCursorFileStart = function() {
|
||||
this.moveCursorTo(0, 0);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.moveCursorWordRight = function() {
|
||||
var row = this.selectionLead.row;
|
||||
var column = this.selectionLead.column;
|
||||
var line = this.doc.getLine(row);
|
||||
var rightOfCursor = line.substring(column);
|
||||
|
||||
var match;
|
||||
this.nonTokenRe.lastIndex = 0;
|
||||
this.tokenRe.lastIndex = 0;
|
||||
|
||||
if (column == line.length) {
|
||||
this.moveCursorRight();
|
||||
return;
|
||||
}
|
||||
else if (match = this.nonTokenRe.exec(rightOfCursor)) {
|
||||
column += this.nonTokenRe.lastIndex;
|
||||
this.nonTokenRe.lastIndex = 0;
|
||||
}
|
||||
else if (match = this.tokenRe.exec(rightOfCursor)) {
|
||||
column += this.tokenRe.lastIndex;
|
||||
this.tokenRe.lastIndex = 0;
|
||||
}
|
||||
|
||||
this.moveCursorTo(row, column);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.moveCursorWordLeft = function() {
|
||||
var row = this.selectionLead.row;
|
||||
var column = this.selectionLead.column;
|
||||
var line = this.doc.getLine(row);
|
||||
var leftOfCursor = ace.stringReverse(line.substring(0, column));
|
||||
|
||||
var match;
|
||||
this.nonTokenRe.lastIndex = 0;
|
||||
this.tokenRe.lastIndex = 0;
|
||||
|
||||
if (column == 0) {
|
||||
this.moveCursorLeft();
|
||||
return;
|
||||
}
|
||||
else if (match = this.nonTokenRe.exec(leftOfCursor)) {
|
||||
column -= this.nonTokenRe.lastIndex;
|
||||
this.nonTokenRe.lastIndex = 0;
|
||||
}
|
||||
else if (match = this.tokenRe.exec(leftOfCursor)) {
|
||||
column -= this.tokenRe.lastIndex;
|
||||
this.tokenRe.lastIndex = 0;
|
||||
}
|
||||
|
||||
this.moveCursorTo(row, column);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.moveCursorBy = function(rows, chars) {
|
||||
this.moveCursorTo(this.selectionLead.row + rows, this.selectionLead.column + chars);
|
||||
};
|
||||
|
||||
|
||||
ace.Selection.prototype.moveCursorToPosition = function(position) {
|
||||
this.moveCursorTo(position.row, position.column);
|
||||
};
|
||||
|
||||
ace.Selection.prototype.moveCursorTo = function(row, column) {
|
||||
this.selectionLead = this._clipPositionToDocument(row, column);
|
||||
this.updateCursor();
|
||||
};
|
||||
|
||||
ace.Selection.prototype.moveCursorUp = function() {
|
||||
this.moveCursorBy(-1, 0);
|
||||
};
|
||||
|
||||
ace.Selection.prototype._clipPositionToDocument = function(row, column) {
|
||||
var pos = {};
|
||||
|
||||
if (row >= this.doc.getLength()) {
|
||||
pos.row = this.doc.getLength() - 1;
|
||||
pos.column = this.doc.getLine(pos.row).length;
|
||||
}
|
||||
else if (row < 0) {
|
||||
pos.row = 0;
|
||||
pos.column = 0;
|
||||
}
|
||||
else {
|
||||
pos.row = row;
|
||||
pos.column = Math.min(this.doc.getLine(pos.row).length,
|
||||
Math.max(0, column));
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
ace.Selection.prototype._clone = function(pos) {
|
||||
return {
|
||||
row: pos.row,
|
||||
column: pos.column
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
this.moveCursorUp = function() {
|
||||
this.moveCursorBy(-1, 0);
|
||||
};
|
||||
|
||||
this.moveCursorDown = function() {
|
||||
this.moveCursorBy(1, 0);
|
||||
};
|
||||
|
||||
this.moveCursorLeft = function() {
|
||||
if (this.selectionLead.column == 0) {
|
||||
if (this.selectionLead.row > 0) {
|
||||
this.moveCursorTo(this.selectionLead.row - 1, this.doc
|
||||
.getLine(this.selectionLead.row - 1).length);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.moveCursorBy(0, -1);
|
||||
}
|
||||
};
|
||||
|
||||
this.moveCursorRight = function() {
|
||||
if (this.selectionLead.column == this.doc.getLine(this.selectionLead.row).length) {
|
||||
if (this.selectionLead.row < this.doc.getLength() - 1) {
|
||||
this.moveCursorTo(this.selectionLead.row + 1, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.moveCursorBy(0, 1);
|
||||
}
|
||||
};
|
||||
|
||||
this.moveCursorLineStart = function() {
|
||||
this.moveCursorTo(this.selectionLead.row, 0);
|
||||
};
|
||||
|
||||
this.moveCursorLineEnd = function() {
|
||||
this.moveCursorTo(this.selectionLead.row,
|
||||
this.doc.getLine(this.selectionLead.row).length);
|
||||
};
|
||||
|
||||
this.moveCursorFileEnd = function() {
|
||||
var row = this.doc.getLength() - 1;
|
||||
var column = this.doc.getLine(row).length;
|
||||
this.moveCursorTo(row, column);
|
||||
};
|
||||
|
||||
this.moveCursorFileStart = function() {
|
||||
this.moveCursorTo(0, 0);
|
||||
};
|
||||
|
||||
this.moveCursorWordRight = function() {
|
||||
var row = this.selectionLead.row;
|
||||
var column = this.selectionLead.column;
|
||||
var line = this.doc.getLine(row);
|
||||
var rightOfCursor = line.substring(column);
|
||||
|
||||
var match;
|
||||
this.nonTokenRe.lastIndex = 0;
|
||||
this.tokenRe.lastIndex = 0;
|
||||
|
||||
if (column == line.length) {
|
||||
this.moveCursorRight();
|
||||
return;
|
||||
}
|
||||
else if (match = this.nonTokenRe.exec(rightOfCursor)) {
|
||||
column += this.nonTokenRe.lastIndex;
|
||||
this.nonTokenRe.lastIndex = 0;
|
||||
}
|
||||
else if (match = this.tokenRe.exec(rightOfCursor)) {
|
||||
column += this.tokenRe.lastIndex;
|
||||
this.tokenRe.lastIndex = 0;
|
||||
}
|
||||
|
||||
this.moveCursorTo(row, column);
|
||||
};
|
||||
|
||||
this.moveCursorWordLeft = function() {
|
||||
var row = this.selectionLead.row;
|
||||
var column = this.selectionLead.column;
|
||||
var line = this.doc.getLine(row);
|
||||
var leftOfCursor = ace.stringReverse(line.substring(0, column));
|
||||
|
||||
var match;
|
||||
this.nonTokenRe.lastIndex = 0;
|
||||
this.tokenRe.lastIndex = 0;
|
||||
|
||||
if (column == 0) {
|
||||
this.moveCursorLeft();
|
||||
return;
|
||||
}
|
||||
else if (match = this.nonTokenRe.exec(leftOfCursor)) {
|
||||
column -= this.nonTokenRe.lastIndex;
|
||||
this.nonTokenRe.lastIndex = 0;
|
||||
}
|
||||
else if (match = this.tokenRe.exec(leftOfCursor)) {
|
||||
column -= this.tokenRe.lastIndex;
|
||||
this.tokenRe.lastIndex = 0;
|
||||
}
|
||||
|
||||
this.moveCursorTo(row, column);
|
||||
};
|
||||
|
||||
this.moveCursorBy = function(rows, chars) {
|
||||
this.moveCursorTo(this.selectionLead.row + rows, this.selectionLead.column + chars);
|
||||
};
|
||||
|
||||
|
||||
this.moveCursorToPosition = function(position) {
|
||||
this.moveCursorTo(position.row, position.column);
|
||||
};
|
||||
|
||||
this.moveCursorTo = function(row, column) {
|
||||
this.selectionLead = this._clipPositionToDocument(row, column);
|
||||
this.updateCursor();
|
||||
};
|
||||
|
||||
this.moveCursorUp = function() {
|
||||
this.moveCursorBy(-1, 0);
|
||||
};
|
||||
|
||||
this._clipPositionToDocument = function(row, column) {
|
||||
var pos = {};
|
||||
|
||||
if (row >= this.doc.getLength()) {
|
||||
pos.row = this.doc.getLength() - 1;
|
||||
pos.column = this.doc.getLine(pos.row).length;
|
||||
}
|
||||
else if (row < 0) {
|
||||
pos.row = 0;
|
||||
pos.column = 0;
|
||||
}
|
||||
else {
|
||||
pos.row = row;
|
||||
pos.column = Math.min(this.doc.getLine(pos.row).length,
|
||||
Math.max(0, column));
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
this._clone = function(pos) {
|
||||
return {
|
||||
row: pos.row,
|
||||
column: pos.column
|
||||
};
|
||||
};
|
||||
|
||||
}).call(ace.Selection.prototype);
|
||||
110
src/Tokenizer.js
110
src/Tokenizer.js
|
|
@ -17,72 +17,76 @@ ace.Tokenizer = function(rules) {
|
|||
}
|
||||
};
|
||||
|
||||
ace.Tokenizer.prototype.getLineTokens = function(line, startState) {
|
||||
var currentState = startState;
|
||||
var state = this.rules[currentState];
|
||||
var re = this.regExps[currentState];
|
||||
re.lastIndex = 0;
|
||||
(function() {
|
||||
|
||||
var match, tokens = [];
|
||||
this.getLineTokens = function(line, startState) {
|
||||
var currentState = startState;
|
||||
var state = this.rules[currentState];
|
||||
var re = this.regExps[currentState];
|
||||
re.lastIndex = 0;
|
||||
|
||||
var lastIndex = 0;
|
||||
var match, tokens = [];
|
||||
|
||||
var token = {
|
||||
type: null,
|
||||
value: ""
|
||||
};
|
||||
var lastIndex = 0;
|
||||
|
||||
while (match = re.exec(line)) {
|
||||
var type = "text";
|
||||
var value = match[0];
|
||||
var token = {
|
||||
type: null,
|
||||
value: ""
|
||||
};
|
||||
|
||||
if (re.lastIndex == lastIndex) { throw new Error("tokenizer error"); }
|
||||
lastIndex = re.lastIndex;
|
||||
while (match = re.exec(line)) {
|
||||
var type = "text";
|
||||
var value = match[0];
|
||||
|
||||
window.LOG && jstestdriver.console.log(currentState, match);
|
||||
if (re.lastIndex == lastIndex) { throw new Error("tokenizer error"); }
|
||||
lastIndex = re.lastIndex;
|
||||
|
||||
for ( var i = 0; i < state.length; i++) {
|
||||
if (match[i + 1]) {
|
||||
if (typeof state[i].token == "function") {
|
||||
type = state[i].token(match[0]);
|
||||
}
|
||||
else {
|
||||
type = state[i].token;
|
||||
window.LOG && jstestdriver.console.log(currentState, match);
|
||||
|
||||
for ( var i = 0; i < state.length; i++) {
|
||||
if (match[i + 1]) {
|
||||
if (typeof state[i].token == "function") {
|
||||
type = state[i].token(match[0]);
|
||||
}
|
||||
else {
|
||||
type = state[i].token;
|
||||
}
|
||||
|
||||
if (state[i].next && state[i].next !== currentState) {
|
||||
currentState = state[i].next;
|
||||
var state = this.rules[currentState];
|
||||
var lastIndex = re.lastIndex;
|
||||
|
||||
var re = this.regExps[currentState];
|
||||
re.lastIndex = lastIndex;
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
if (state[i].next && state[i].next !== currentState) {
|
||||
currentState = state[i].next;
|
||||
var state = this.rules[currentState];
|
||||
var lastIndex = re.lastIndex;
|
||||
|
||||
var re = this.regExps[currentState];
|
||||
re.lastIndex = lastIndex;
|
||||
if (token.type !== type) {
|
||||
if (token.type) {
|
||||
tokens.push(token);
|
||||
}
|
||||
break;
|
||||
token = {
|
||||
type: type,
|
||||
value: value
|
||||
};
|
||||
} else {
|
||||
token.value += value;
|
||||
}
|
||||
};
|
||||
|
||||
if (token.type !== type) {
|
||||
if (token.type) {
|
||||
tokens.push(token);
|
||||
}
|
||||
token = {
|
||||
type: type,
|
||||
value: value
|
||||
};
|
||||
} else {
|
||||
token.value += value;
|
||||
if (token.type) {
|
||||
tokens.push(token);
|
||||
}
|
||||
|
||||
window.LOG && jstestdriver.console.log(tokens, currentState);
|
||||
|
||||
return {
|
||||
tokens : tokens,
|
||||
state : currentState
|
||||
};
|
||||
};
|
||||
|
||||
if (token.type) {
|
||||
tokens.push(token);
|
||||
}
|
||||
|
||||
window.LOG && jstestdriver.console.log(tokens, currentState);
|
||||
|
||||
return {
|
||||
tokens : tokens,
|
||||
state : currentState
|
||||
};
|
||||
};
|
||||
}).call(ace.Tokenizer.prototype);
|
||||
|
|
@ -38,213 +38,217 @@ ace.VirtualRenderer = function(container) {
|
|||
this.onResize();
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.setDocument = function(doc) {
|
||||
this.lines = doc.lines;
|
||||
this.doc = doc;
|
||||
this.markerLayer.setDocument(doc);
|
||||
this.textLayer.setTabSize(doc.getTabSize());
|
||||
};
|
||||
(function() {
|
||||
|
||||
ace.VirtualRenderer.prototype.setTokenizer = function(tokenizer) {
|
||||
this.textLayer.setTokenizer(tokenizer);
|
||||
};
|
||||
this.setDocument = function(doc) {
|
||||
this.lines = doc.lines;
|
||||
this.doc = doc;
|
||||
this.markerLayer.setDocument(doc);
|
||||
this.textLayer.setTabSize(doc.getTabSize());
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.getContainerElement = function() {
|
||||
return this.container;
|
||||
};
|
||||
this.setTokenizer = function(tokenizer) {
|
||||
this.textLayer.setTokenizer(tokenizer);
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.getMouseEventTarget = function() {
|
||||
return this.scroller;
|
||||
};
|
||||
this.getContainerElement = function() {
|
||||
return this.container;
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.getFirstVisibleRow = function() {
|
||||
return this.layerConfig.firstRow || 0;
|
||||
};
|
||||
this.getMouseEventTarget = function() {
|
||||
return this.scroller;
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.getLastVisibleRow = function() {
|
||||
return this.layerConfig.lastRow || 0;
|
||||
};
|
||||
this.getFirstVisibleRow = function() {
|
||||
return this.layerConfig.firstRow || 0;
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.onResize = function()
|
||||
{
|
||||
var height = ace.getInnerHeight(this.container);
|
||||
this.gutter.style.height = height + "px";
|
||||
this.scroller.style.height = height + "px";
|
||||
this.scrollBar.setHeight(height);
|
||||
this.getLastVisibleRow = function() {
|
||||
return this.layerConfig.lastRow || 0;
|
||||
};
|
||||
|
||||
var width = ace.getInnerWidth(this.container);
|
||||
var gutterWidth = this.gutter.offsetWidth;
|
||||
this.scroller.style.left = gutterWidth + "px";
|
||||
this.scroller.style.width = Math.max(0, width - gutterWidth - this.scrollBar.getWidth()) + "px";
|
||||
this.onResize = function()
|
||||
{
|
||||
var height = ace.getInnerHeight(this.container);
|
||||
this.gutter.style.height = height + "px";
|
||||
this.scroller.style.height = height + "px";
|
||||
this.scrollBar.setHeight(height);
|
||||
|
||||
var width = ace.getInnerWidth(this.container);
|
||||
var gutterWidth = this.gutter.offsetWidth;
|
||||
this.scroller.style.left = gutterWidth + "px";
|
||||
this.scroller.style.width = Math.max(0, width - gutterWidth - this.scrollBar.getWidth()) + "px";
|
||||
|
||||
if (this.doc) {
|
||||
this._updateScrollBar();
|
||||
this.scrollToY(this.getScrollTop());
|
||||
this.draw();
|
||||
}
|
||||
};
|
||||
|
||||
this.onScroll = function(e) {
|
||||
this.scrollToY(e.data);
|
||||
};
|
||||
|
||||
this._updateScrollBar = function() {
|
||||
this.scrollBar.setInnerHeight(this.doc.getLength() * this.lineHeight);
|
||||
this.scrollBar.setScrollTop(this.scrollTop);
|
||||
};
|
||||
|
||||
this.updateLines = function(firstRow, lastRow) {
|
||||
var layerConfig = this.layerConfig;
|
||||
|
||||
if (firstRow > layerConfig.lastRow + 1) { return; }
|
||||
if (lastRow < layerConfig.firstRow) { return; }
|
||||
|
||||
// if the last row is unknown -> redraw everything
|
||||
if (lastRow === undefined) {
|
||||
this.draw();
|
||||
return;
|
||||
}
|
||||
|
||||
// else update only the changed rows
|
||||
this.textLayer.updateLines(layerConfig, firstRow, lastRow);
|
||||
};
|
||||
|
||||
this.draw = function() {
|
||||
var lines = this.lines;
|
||||
|
||||
var offset = this.scrollTop % this.lineHeight;
|
||||
var minHeight = this.scroller.clientHeight + offset;
|
||||
|
||||
var longestLine = Math.max(this.scroller.clientWidth, Math.round(this.doc.getWidth() * this.characterWidth));
|
||||
|
||||
var lineCount = Math.ceil(minHeight / this.lineHeight);
|
||||
var firstRow = Math.round((this.scrollTop - offset) / this.lineHeight);
|
||||
var lastRow = Math.min(lines.length, firstRow + lineCount) - 1;
|
||||
|
||||
var layerConfig = this.layerConfig = {
|
||||
width : longestLine,
|
||||
firstRow : firstRow,
|
||||
lastRow : lastRow,
|
||||
lineHeight : this.lineHeight,
|
||||
characterWidth : this.characterWidth
|
||||
};
|
||||
|
||||
for ( var i = 0; i < this.layers.length; i++) {
|
||||
var layer = this.layers[i];
|
||||
|
||||
var style = layer.element.style;
|
||||
style.marginTop = (-offset) + "px";
|
||||
style.height = minHeight + "px";
|
||||
style.width = longestLine + "px";
|
||||
|
||||
layer.update(layerConfig);
|
||||
};
|
||||
|
||||
this.gutterLayer.element.style.marginTop = (-offset) + "px";
|
||||
this.gutterLayer.element.style.height = minHeight + "px";
|
||||
this.gutterLayer.update(layerConfig);
|
||||
|
||||
if (this.doc) {
|
||||
this._updateScrollBar();
|
||||
this.scrollToY(this.getScrollTop());
|
||||
this.draw();
|
||||
}
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.onScroll = function(e) {
|
||||
this.scrollToY(e.data);
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype._updateScrollBar = function() {
|
||||
this.scrollBar.setInnerHeight(this.doc.getLength() * this.lineHeight);
|
||||
this.scrollBar.setScrollTop(this.scrollTop);
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.updateLines = function(firstRow, lastRow) {
|
||||
var layerConfig = this.layerConfig;
|
||||
|
||||
if (firstRow > layerConfig.lastRow + 1) { return; }
|
||||
if (lastRow < layerConfig.firstRow) { return; }
|
||||
|
||||
// if the last row is unknown -> redraw everything
|
||||
if (lastRow === undefined) {
|
||||
this.draw();
|
||||
return;
|
||||
}
|
||||
|
||||
// else update only the changed rows
|
||||
this.textLayer.updateLines(layerConfig, firstRow, lastRow);
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.draw = function() {
|
||||
var lines = this.lines;
|
||||
|
||||
var offset = this.scrollTop % this.lineHeight;
|
||||
var minHeight = this.scroller.clientHeight + offset;
|
||||
|
||||
var longestLine = Math.max(this.scroller.clientWidth, Math.round(this.doc.getWidth() * this.characterWidth));
|
||||
|
||||
var lineCount = Math.ceil(minHeight / this.lineHeight);
|
||||
var firstRow = Math.round((this.scrollTop - offset) / this.lineHeight);
|
||||
var lastRow = Math.min(lines.length, firstRow + lineCount) - 1;
|
||||
|
||||
var layerConfig = this.layerConfig = {
|
||||
width : longestLine,
|
||||
firstRow : firstRow,
|
||||
lastRow : lastRow,
|
||||
lineHeight : this.lineHeight,
|
||||
characterWidth : this.characterWidth
|
||||
};
|
||||
|
||||
for ( var i = 0; i < this.layers.length; i++) {
|
||||
var layer = this.layers[i];
|
||||
|
||||
var style = layer.element.style;
|
||||
style.marginTop = (-offset) + "px";
|
||||
style.height = minHeight + "px";
|
||||
style.width = longestLine + "px";
|
||||
|
||||
layer.update(layerConfig);
|
||||
this.addMarker = function(range, clazz, type) {
|
||||
return this.markerLayer.addMarker(range, clazz, type);
|
||||
};
|
||||
|
||||
this.gutterLayer.element.style.marginTop = (-offset) + "px";
|
||||
this.gutterLayer.element.style.height = minHeight + "px";
|
||||
this.gutterLayer.update(layerConfig);
|
||||
|
||||
this._updateScrollBar();
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.addMarker = function(range, clazz, type) {
|
||||
return this.markerLayer.addMarker(range, clazz, type);
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.removeMarker = function(markerId) {
|
||||
this.markerLayer.removeMarker(markerId);
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.updateCursor = function(position) {
|
||||
this.cursorLayer.setCursor(position);
|
||||
this.cursorLayer.update(this.layerConfig);
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.hideCursor = function() {
|
||||
this.cursorLayer.hideCursor();
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.showCursor = function() {
|
||||
this.cursorLayer.showCursor();
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.scrollCursorIntoView = function() {
|
||||
var pos = this.cursorLayer.getPixelPosition();
|
||||
|
||||
var left = pos.left;
|
||||
var top = pos.top;
|
||||
|
||||
if (this.getScrollTop() > top) {
|
||||
this.scrollToY(top);
|
||||
}
|
||||
|
||||
if (this.getScrollTop() + this.scroller.clientHeight < top
|
||||
+ this.lineHeight) {
|
||||
this.scrollToY(top + this.lineHeight - this.scroller.clientHeight);
|
||||
}
|
||||
|
||||
if (this.scroller.scrollLeft > left) {
|
||||
this.scroller.scrollLeft = left;
|
||||
}
|
||||
|
||||
if (this.scroller.scrollLeft + this.scroller.clientWidth < left
|
||||
+ this.characterWidth) {
|
||||
this.scroller.scrollLeft = Math.round(left + this.characterWidth
|
||||
- this.scroller.clientWidth);
|
||||
}
|
||||
},
|
||||
|
||||
ace.VirtualRenderer.prototype.getScrollTop = function() {
|
||||
return this.scrollTop;
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.getScrollTopRow = function() {
|
||||
return this.scrollTop / this.lineHeight;
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.scrollToRow = function(row) {
|
||||
this.scrollToY(row * this.lineHeight);
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.scrollToY = function(scrollTop) {
|
||||
var maxHeight = this.lines.length * this.lineHeight
|
||||
- this.scroller.clientHeight;
|
||||
var scrollTop = Math.max(0, Math.min(maxHeight, scrollTop));
|
||||
|
||||
if (this.scrollTop !== scrollTop) {
|
||||
this.scrollTop = scrollTop;
|
||||
this._updateScrollBar();
|
||||
this.draw();
|
||||
}
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.screenToTextCoordinates = function(pageX, pageY) {
|
||||
var canvasPos = this.scroller.getBoundingClientRect();
|
||||
|
||||
var col = Math.floor((pageX + this.scroller.scrollLeft - canvasPos.left)
|
||||
/ this.characterWidth);
|
||||
var row = Math.floor((pageY + this.scrollTop - canvasPos.top)
|
||||
/ this.lineHeight);
|
||||
|
||||
return {
|
||||
row : row,
|
||||
column : col
|
||||
this.removeMarker = function(markerId) {
|
||||
this.markerLayer.removeMarker(markerId);
|
||||
};
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.visualizeFocus = function() {
|
||||
ace.addCssClass(this.container, "focus");
|
||||
};
|
||||
this.updateCursor = function(position) {
|
||||
this.cursorLayer.setCursor(position);
|
||||
this.cursorLayer.update(this.layerConfig);
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.visualizeBlur = function() {
|
||||
ace.removeCssClass(this.container, "focus");
|
||||
};
|
||||
this.hideCursor = function() {
|
||||
this.cursorLayer.hideCursor();
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.showComposition = function(position) {
|
||||
};
|
||||
this.showCursor = function() {
|
||||
this.cursorLayer.showCursor();
|
||||
};
|
||||
|
||||
ace.VirtualRenderer.prototype.setCompositionText = function(text) {
|
||||
};
|
||||
this.scrollCursorIntoView = function() {
|
||||
var pos = this.cursorLayer.getPixelPosition();
|
||||
|
||||
ace.VirtualRenderer.prototype.hideComposition = function() {
|
||||
};
|
||||
var left = pos.left;
|
||||
var top = pos.top;
|
||||
|
||||
if (this.getScrollTop() > top) {
|
||||
this.scrollToY(top);
|
||||
}
|
||||
|
||||
if (this.getScrollTop() + this.scroller.clientHeight < top
|
||||
+ this.lineHeight) {
|
||||
this.scrollToY(top + this.lineHeight - this.scroller.clientHeight);
|
||||
}
|
||||
|
||||
if (this.scroller.scrollLeft > left) {
|
||||
this.scroller.scrollLeft = left;
|
||||
}
|
||||
|
||||
if (this.scroller.scrollLeft + this.scroller.clientWidth < left
|
||||
+ this.characterWidth) {
|
||||
this.scroller.scrollLeft = Math.round(left + this.characterWidth
|
||||
- this.scroller.clientWidth);
|
||||
}
|
||||
},
|
||||
|
||||
this.getScrollTop = function() {
|
||||
return this.scrollTop;
|
||||
};
|
||||
|
||||
this.getScrollTopRow = function() {
|
||||
return this.scrollTop / this.lineHeight;
|
||||
};
|
||||
|
||||
this.scrollToRow = function(row) {
|
||||
this.scrollToY(row * this.lineHeight);
|
||||
};
|
||||
|
||||
this.scrollToY = function(scrollTop) {
|
||||
var maxHeight = this.lines.length * this.lineHeight
|
||||
- this.scroller.clientHeight;
|
||||
var scrollTop = Math.max(0, Math.min(maxHeight, scrollTop));
|
||||
|
||||
if (this.scrollTop !== scrollTop) {
|
||||
this.scrollTop = scrollTop;
|
||||
this._updateScrollBar();
|
||||
this.draw();
|
||||
}
|
||||
};
|
||||
|
||||
this.screenToTextCoordinates = function(pageX, pageY) {
|
||||
var canvasPos = this.scroller.getBoundingClientRect();
|
||||
|
||||
var col = Math.floor((pageX + this.scroller.scrollLeft - canvasPos.left)
|
||||
/ this.characterWidth);
|
||||
var row = Math.floor((pageY + this.scrollTop - canvasPos.top)
|
||||
/ this.lineHeight);
|
||||
|
||||
return {
|
||||
row : row,
|
||||
column : col
|
||||
};
|
||||
};
|
||||
|
||||
this.visualizeFocus = function() {
|
||||
ace.addCssClass(this.container, "focus");
|
||||
};
|
||||
|
||||
this.visualizeBlur = function() {
|
||||
ace.removeCssClass(this.container, "focus");
|
||||
};
|
||||
|
||||
this.showComposition = function(position) {
|
||||
};
|
||||
|
||||
this.setCompositionText = function(text) {
|
||||
};
|
||||
|
||||
this.hideComposition = function() {
|
||||
};
|
||||
|
||||
}).call(ace.VirtualRenderer.prototype);
|
||||
|
|
@ -11,71 +11,75 @@ ace.layer.Cursor = function(parentEl) {
|
|||
this.isVisible = false;
|
||||
};
|
||||
|
||||
ace.layer.Cursor.prototype.setCursor = function(position) {
|
||||
this.position = {
|
||||
row : position.row,
|
||||
column : position.column
|
||||
};
|
||||
};
|
||||
(function() {
|
||||
|
||||
ace.layer.Cursor.prototype.hideCursor = function() {
|
||||
this.isVisible = false;
|
||||
if (this.cursor.parentNode) {
|
||||
this.cursor.parentNode.removeChild(this.cursor);
|
||||
}
|
||||
clearInterval(this.blinkId);
|
||||
};
|
||||
|
||||
ace.layer.Cursor.prototype.showCursor = function() {
|
||||
this.isVisible = true;
|
||||
this.element.appendChild(this.cursor);
|
||||
|
||||
var cursor = this.cursor;
|
||||
cursor.style.visibility = "visible";
|
||||
this.restartTimer();
|
||||
};
|
||||
|
||||
ace.layer.Cursor.prototype.restartTimer = function() {
|
||||
clearInterval(this.blinkId);
|
||||
if (!this.isVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
var cursor = this.cursor;
|
||||
this.blinkId = setInterval(function() {
|
||||
cursor.style.visibility = "hidden";
|
||||
setTimeout(function() {
|
||||
cursor.style.visibility = "visible";
|
||||
}, 400);
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
ace.layer.Cursor.prototype.getPixelPosition = function() {
|
||||
return this.pixelPos || {
|
||||
left : 0,
|
||||
top : 0
|
||||
};
|
||||
};
|
||||
|
||||
ace.layer.Cursor.prototype.update = function(config) {
|
||||
if (!this.position)
|
||||
return;
|
||||
|
||||
var cursorLeft = Math.round(this.position.column * config.characterWidth);
|
||||
var cursorTop = this.position.row * config.lineHeight;
|
||||
|
||||
this.pixelPos = {
|
||||
left : cursorLeft,
|
||||
top : cursorTop
|
||||
this.setCursor = function(position) {
|
||||
this.position = {
|
||||
row : position.row,
|
||||
column : position.column
|
||||
};
|
||||
};
|
||||
|
||||
this.cursor.style.left = cursorLeft + "px";
|
||||
this.cursor.style.top = (cursorTop - (config.firstRow * config.lineHeight))
|
||||
+ "px";
|
||||
this.cursor.style.height = config.lineHeight + "px";
|
||||
this.hideCursor = function() {
|
||||
this.isVisible = false;
|
||||
if (this.cursor.parentNode) {
|
||||
this.cursor.parentNode.removeChild(this.cursor);
|
||||
}
|
||||
clearInterval(this.blinkId);
|
||||
};
|
||||
|
||||
if (this.isVisible) {
|
||||
this.showCursor = function() {
|
||||
this.isVisible = true;
|
||||
this.element.appendChild(this.cursor);
|
||||
}
|
||||
this.restartTimer();
|
||||
};
|
||||
|
||||
var cursor = this.cursor;
|
||||
cursor.style.visibility = "visible";
|
||||
this.restartTimer();
|
||||
};
|
||||
|
||||
this.restartTimer = function() {
|
||||
clearInterval(this.blinkId);
|
||||
if (!this.isVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
var cursor = this.cursor;
|
||||
this.blinkId = setInterval(function() {
|
||||
cursor.style.visibility = "hidden";
|
||||
setTimeout(function() {
|
||||
cursor.style.visibility = "visible";
|
||||
}, 400);
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
this.getPixelPosition = function() {
|
||||
return this.pixelPos || {
|
||||
left : 0,
|
||||
top : 0
|
||||
};
|
||||
};
|
||||
|
||||
this.update = function(config) {
|
||||
if (!this.position)
|
||||
return;
|
||||
|
||||
var cursorLeft = Math.round(this.position.column * config.characterWidth);
|
||||
var cursorTop = this.position.row * config.lineHeight;
|
||||
|
||||
this.pixelPos = {
|
||||
left : cursorLeft,
|
||||
top : cursorTop
|
||||
};
|
||||
|
||||
this.cursor.style.left = cursorLeft + "px";
|
||||
this.cursor.style.top = (cursorTop - (config.firstRow * config.lineHeight))
|
||||
+ "px";
|
||||
this.cursor.style.height = config.lineHeight + "px";
|
||||
|
||||
if (this.isVisible) {
|
||||
this.element.appendChild(this.cursor);
|
||||
}
|
||||
this.restartTimer();
|
||||
};
|
||||
|
||||
}).call(ace.layer.Cursor.prototype);
|
||||
|
|
@ -6,13 +6,17 @@ ace.layer.Gutter = function(parentEl) {
|
|||
parentEl.appendChild(this.element);
|
||||
};
|
||||
|
||||
ace.layer.Gutter.prototype.update = function(config) {
|
||||
var html = [];
|
||||
for ( var i = config.firstRow; i <= config.lastRow; i++) {
|
||||
html.push("<div class='gutter-cell' style='height:" + config.lineHeight
|
||||
+ "px;'>", (i+1), "</div>");
|
||||
html.push("</div>");
|
||||
}
|
||||
(function() {
|
||||
|
||||
this.element.innerHTML = html.join("");
|
||||
};
|
||||
this.update = function(config) {
|
||||
var html = [];
|
||||
for ( var i = config.firstRow; i <= config.lastRow; i++) {
|
||||
html.push("<div class='gutter-cell' style='height:" + config.lineHeight
|
||||
+ "px;'>", (i+1), "</div>");
|
||||
html.push("</div>");
|
||||
}
|
||||
|
||||
this.element.innerHTML = html.join("");
|
||||
};
|
||||
|
||||
}).call(ace.layer.Gutter.prototype);
|
||||
|
|
@ -9,153 +9,157 @@ ace.layer.Marker = function(parentEl) {
|
|||
this._markerId = 1;
|
||||
};
|
||||
|
||||
ace.layer.Marker.prototype.setDocument = function(doc) {
|
||||
this.doc = doc;
|
||||
};
|
||||
(function() {
|
||||
|
||||
ace.layer.Marker.prototype.addMarker = function(range, clazz, type) {
|
||||
var id = this._markerId++;
|
||||
this.markers[id] = {
|
||||
range : range,
|
||||
type : type || "line",
|
||||
clazz : clazz
|
||||
this.setDocument = function(doc) {
|
||||
this.doc = doc;
|
||||
};
|
||||
|
||||
this.update();
|
||||
return id;
|
||||
};
|
||||
|
||||
ace.layer.Marker.prototype.removeMarker = function(markerId) {
|
||||
var marker = this.markers[markerId];
|
||||
if (marker) {
|
||||
delete (this.markers[markerId]);
|
||||
this.update();
|
||||
}
|
||||
};
|
||||
|
||||
ace.layer.Marker.prototype.update = function(config) {
|
||||
var config = config || this.config;
|
||||
if (!config)
|
||||
return;
|
||||
|
||||
this.config = config;
|
||||
|
||||
var html = [];
|
||||
for ( var key in this.markers) {
|
||||
var marker = this.markers[key];
|
||||
var range = {
|
||||
start: marker.range.start,
|
||||
end: marker.range.end
|
||||
this.addMarker = function(range, clazz, type) {
|
||||
var id = this._markerId++;
|
||||
this.markers[id] = {
|
||||
range : range,
|
||||
type : type || "line",
|
||||
clazz : clazz
|
||||
};
|
||||
|
||||
// clip
|
||||
if (range.start.row > config.lastRow) continue;
|
||||
if (range.end.row < config.firstRow) continue;
|
||||
this.update();
|
||||
return id;
|
||||
};
|
||||
|
||||
if (range.end.row > config.lastRow) {
|
||||
range.end = {
|
||||
row: config.lastRow+1,
|
||||
column: 0
|
||||
};
|
||||
this.removeMarker = function(markerId) {
|
||||
var marker = this.markers[markerId];
|
||||
if (marker) {
|
||||
delete (this.markers[markerId]);
|
||||
this.update();
|
||||
}
|
||||
};
|
||||
|
||||
if (range.start.row < config.firstRow) {
|
||||
range.start = {
|
||||
row: config.firstRow,
|
||||
column: 0
|
||||
this.update = function(config) {
|
||||
var config = config || this.config;
|
||||
if (!config)
|
||||
return;
|
||||
|
||||
this.config = config;
|
||||
|
||||
var html = [];
|
||||
for ( var key in this.markers) {
|
||||
var marker = this.markers[key];
|
||||
var range = {
|
||||
start: marker.range.start,
|
||||
end: marker.range.end
|
||||
};
|
||||
}
|
||||
|
||||
if (range.start.row !== range.end.row) {
|
||||
if (marker.type == "text") {
|
||||
this.drawTextMarker(html, range, marker.clazz, config);
|
||||
} else {
|
||||
this.drawMultiLineMarker(html, range, marker.clazz, config);
|
||||
// clip
|
||||
if (range.start.row > config.lastRow) continue;
|
||||
if (range.end.row < config.firstRow) continue;
|
||||
|
||||
if (range.end.row > config.lastRow) {
|
||||
range.end = {
|
||||
row: config.lastRow+1,
|
||||
column: 0
|
||||
};
|
||||
}
|
||||
|
||||
if (range.start.row < config.firstRow) {
|
||||
range.start = {
|
||||
row: config.firstRow,
|
||||
column: 0
|
||||
};
|
||||
}
|
||||
|
||||
if (range.start.row !== range.end.row) {
|
||||
if (marker.type == "text") {
|
||||
this.drawTextMarker(html, range, marker.clazz, config);
|
||||
} else {
|
||||
this.drawMultiLineMarker(html, range, marker.clazz, config);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.drawSingleLineMarker(html, range, marker.clazz, config);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.drawSingleLineMarker(html, range, marker.clazz, config);
|
||||
}
|
||||
}
|
||||
this.element.innerHTML = html.join("");
|
||||
};
|
||||
this.element.innerHTML = html.join("");
|
||||
};
|
||||
|
||||
ace.layer.Marker.prototype.drawTextMarker = function(stringBuilder, range, clazz, layerConfig) {
|
||||
this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig) {
|
||||
|
||||
// selection start
|
||||
var row = range.start.row;
|
||||
var lineRange = { start: {}, end: {}};
|
||||
// selection start
|
||||
var row = range.start.row;
|
||||
var lineRange = { start: {}, end: {}};
|
||||
|
||||
lineRange.start.row = row;
|
||||
lineRange.start.column = range.start.column;
|
||||
lineRange.end.row = row;
|
||||
lineRange.end.column = this.doc.getLine(row).length;
|
||||
this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig);
|
||||
|
||||
// selection end
|
||||
var row = range.end.row;
|
||||
lineRange.start.row = row;
|
||||
lineRange.start.column = 0;
|
||||
lineRange.end.row = row;
|
||||
lineRange.end.column = range.end.column;
|
||||
this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig);
|
||||
|
||||
for (var row = range.start.row + 1; row < range.end.row; row++) {
|
||||
lineRange.start.row = row;
|
||||
lineRange.start.column = range.start.column;
|
||||
lineRange.end.row = row;
|
||||
lineRange.end.column = this.doc.getLine(row).length;
|
||||
this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig);
|
||||
}
|
||||
};
|
||||
|
||||
ace.layer.Marker.prototype.drawMultiLineMarker = function(stringBuilder, range, clazz, layerConfig) {
|
||||
// selection end
|
||||
var row = range.end.row;
|
||||
lineRange.start.row = row;
|
||||
lineRange.start.column = 0;
|
||||
lineRange.end.row = row;
|
||||
lineRange.end.column = range.end.column;
|
||||
this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig);
|
||||
|
||||
var height = layerConfig.lineHeight;
|
||||
var width = Math.round(layerConfig.width - (range.start.column * layerConfig.characterWidth));
|
||||
var top = (range.start.row - layerConfig.firstRow) * layerConfig.lineHeight;
|
||||
var left = Math.round(range.start.column * layerConfig.characterWidth);
|
||||
for (var row = range.start.row + 1; row < range.end.row; row++) {
|
||||
lineRange.start.row = row;
|
||||
lineRange.end.row = row;
|
||||
lineRange.end.column = this.doc.getLine(row).length;
|
||||
this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig);
|
||||
}
|
||||
};
|
||||
|
||||
stringBuilder.push(
|
||||
"<div class='", clazz, "' style='",
|
||||
"height:", height, "px;",
|
||||
"width:", width, "px;",
|
||||
"top:", top, "px;",
|
||||
"left:", left, "px;'></div>"
|
||||
);
|
||||
this.drawMultiLineMarker = function(stringBuilder, range, clazz, layerConfig) {
|
||||
|
||||
var top = (range.end.row - layerConfig.firstRow) * layerConfig.lineHeight;
|
||||
var width = Math.round(range.end.column * layerConfig.characterWidth);
|
||||
var height = layerConfig.lineHeight;
|
||||
var width = Math.round(layerConfig.width - (range.start.column * layerConfig.characterWidth));
|
||||
var top = (range.start.row - layerConfig.firstRow) * layerConfig.lineHeight;
|
||||
var left = Math.round(range.start.column * layerConfig.characterWidth);
|
||||
|
||||
stringBuilder.push(
|
||||
"<div class='", clazz, "' style='",
|
||||
"height:", height, "px;",
|
||||
"top:", top, "px;",
|
||||
"width:", width, "px;'></div>"
|
||||
);
|
||||
|
||||
for (var row = range.start.row + 1; row < range.end.row; row++) {
|
||||
var top = (row - layerConfig.firstRow) * layerConfig.lineHeight;
|
||||
stringBuilder.push(
|
||||
"<div class='", clazz, "' style='",
|
||||
"height:", height, "px;",
|
||||
"width:", layerConfig.width, "px;",
|
||||
"top:", top, "px;'></div>"
|
||||
"width:", width, "px;",
|
||||
"top:", top, "px;",
|
||||
"left:", left, "px;'></div>"
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
ace.layer.Marker.prototype.drawSingleLineMarker = function(stringBuilder, range, clazz, layerConfig) {
|
||||
var top = (range.end.row - layerConfig.firstRow) * layerConfig.lineHeight;
|
||||
var width = Math.round(range.end.column * layerConfig.characterWidth);
|
||||
|
||||
var height = layerConfig.lineHeight;
|
||||
var width = Math.round((range.end.column - range.start.column) * layerConfig.characterWidth);
|
||||
var top = (range.start.row - layerConfig.firstRow) * layerConfig.lineHeight;
|
||||
var left = Math.round(range.start.column * layerConfig.characterWidth);
|
||||
stringBuilder.push(
|
||||
"<div class='", clazz, "' style='",
|
||||
"height:", height, "px;",
|
||||
"top:", top, "px;",
|
||||
"width:", width, "px;'></div>"
|
||||
);
|
||||
|
||||
stringBuilder.push(
|
||||
"<div class='", clazz, "' style='",
|
||||
"height:", height, "px;",
|
||||
"width:", width, "px;",
|
||||
"top:", top, "px;",
|
||||
"left:", left,"px;'></div>"
|
||||
);
|
||||
};
|
||||
for (var row = range.start.row + 1; row < range.end.row; row++) {
|
||||
var top = (row - layerConfig.firstRow) * layerConfig.lineHeight;
|
||||
stringBuilder.push(
|
||||
"<div class='", clazz, "' style='",
|
||||
"height:", height, "px;",
|
||||
"width:", layerConfig.width, "px;",
|
||||
"top:", top, "px;'></div>"
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
this.drawSingleLineMarker = function(stringBuilder, range, clazz, layerConfig) {
|
||||
|
||||
var height = layerConfig.lineHeight;
|
||||
var width = Math.round((range.end.column - range.start.column) * layerConfig.characterWidth);
|
||||
var top = (range.start.row - layerConfig.firstRow) * layerConfig.lineHeight;
|
||||
var left = Math.round(range.start.column * layerConfig.characterWidth);
|
||||
|
||||
stringBuilder.push(
|
||||
"<div class='", clazz, "' style='",
|
||||
"height:", height, "px;",
|
||||
"width:", width, "px;",
|
||||
"top:", top, "px;",
|
||||
"left:", left,"px;'></div>"
|
||||
);
|
||||
};
|
||||
|
||||
}).call(ace.layer.Marker.prototype);
|
||||
|
|
@ -9,86 +9,93 @@ ace.layer.Text = function(parentEl) {
|
|||
this._tabString = " ";
|
||||
};
|
||||
|
||||
ace.layer.Text.prototype.setTokenizer = function(tokenizer) {
|
||||
this.tokenizer = tokenizer;
|
||||
};
|
||||
(function() {
|
||||
|
||||
ace.layer.Text.prototype.getLineHeight = function() {
|
||||
return this.lineHeight;
|
||||
};
|
||||
this.setTokenizer = function(tokenizer) {
|
||||
this.tokenizer = tokenizer;
|
||||
};
|
||||
|
||||
ace.layer.Text.prototype.getCharacterWidth = function() {
|
||||
return this.characterWidth;
|
||||
};
|
||||
this.getLineHeight = function() {
|
||||
return this.lineHeight;
|
||||
};
|
||||
|
||||
ace.layer.Text.prototype._measureSizes = function() {
|
||||
var measureNode = document.createElement("div");
|
||||
var style = measureNode.style;
|
||||
style.width = style.height = "auto";
|
||||
style.left = style.top = "-1000px";
|
||||
style.visibility = "hidden";
|
||||
style.position = "absolute";
|
||||
style.overflow = "visible";
|
||||
this.getCharacterWidth = function() {
|
||||
return this.characterWidth;
|
||||
};
|
||||
|
||||
measureNode.innerHTML = new Array(1000).join("Xy");
|
||||
this.element.appendChild(measureNode);
|
||||
this._measureSizes = function() {
|
||||
var measureNode = document.createElement("div");
|
||||
var style = measureNode.style;
|
||||
style.width = style.height = "auto";
|
||||
style.left = style.top = "-1000px";
|
||||
style.visibility = "hidden";
|
||||
style.position = "absolute";
|
||||
style.overflow = "visible";
|
||||
|
||||
// in FF 3.6 monospace fonts can have a fixed sub pixel width.
|
||||
// that's why we have to measure many characters
|
||||
// Note: characterWidth can be a float!
|
||||
this.lineHeight = measureNode.offsetHeight;
|
||||
this.characterWidth = measureNode.offsetWidth / 2000;
|
||||
measureNode.innerHTML = new Array(1000).join("Xy");
|
||||
this.element.appendChild(measureNode);
|
||||
|
||||
this.element.removeChild(measureNode);
|
||||
};
|
||||
// in FF 3.6 monospace fonts can have a fixed sub pixel width.
|
||||
// that's why we have to measure many characters
|
||||
// Note: characterWidth can be a float!
|
||||
this.lineHeight = measureNode.offsetHeight;
|
||||
this.characterWidth = measureNode.offsetWidth / 2000;
|
||||
|
||||
ace.layer.Text.prototype.setTabSize = function(tabSize) {
|
||||
this._tabString = new Array(tabSize+1).join(" ");
|
||||
};
|
||||
this.element.removeChild(measureNode);
|
||||
};
|
||||
|
||||
ace.layer.Text.prototype.updateLines = function(layerConfig, firstRow, lastRow) {
|
||||
var first = Math.max(firstRow, layerConfig.firstRow);
|
||||
var last = Math.min(lastRow, layerConfig.lastRow);
|
||||
this.setTabSize = function(tabSize) {
|
||||
this._tabString = new Array(tabSize+1).join(" ");
|
||||
};
|
||||
|
||||
var lineElements = this.element.childNodes;
|
||||
this.updateLines = function(layerConfig, firstRow, lastRow) {
|
||||
var first = Math.max(firstRow, layerConfig.firstRow);
|
||||
var last = Math.min(lastRow, layerConfig.lastRow);
|
||||
|
||||
for ( var i = first; i <= last; i++) {
|
||||
var lineElements = this.element.childNodes;
|
||||
|
||||
for ( var i = first; i <= last; i++) {
|
||||
var html = [];
|
||||
this.renderLine(html, i);
|
||||
|
||||
var lineElement = lineElements[i - layerConfig.firstRow];
|
||||
lineElement.innerHTML = html.join("");
|
||||
};
|
||||
};
|
||||
|
||||
this.update = function(config) {
|
||||
var html = [];
|
||||
this.renderLine(html, i);
|
||||
|
||||
var lineElement = lineElements[i - layerConfig.firstRow];
|
||||
lineElement.innerHTML = html.join("");
|
||||
};
|
||||
};
|
||||
|
||||
ace.layer.Text.prototype.update = function(config) {
|
||||
var html = [];
|
||||
for ( var i = config.firstRow; i <= config.lastRow; i++) {
|
||||
html.push("<div class='line' style='height:" + this.lineHeight + "px;", "width:",
|
||||
config.width, "px'>");
|
||||
this.renderLine(html, i), html.push("</div>");
|
||||
}
|
||||
|
||||
this.element.innerHTML = html.join("");
|
||||
};
|
||||
|
||||
ace.layer.Text.prototype.renderLine = function(stringBuilder, row) {
|
||||
var tokens = this.tokenizer.getTokens(row);
|
||||
for ( var i = 0; i < tokens.length; i++) {
|
||||
var token = tokens[i];
|
||||
|
||||
var output = token.value
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/\t/g, this._tabString)
|
||||
.replace(/\s/g, " ");
|
||||
|
||||
if (token.type !== "text") {
|
||||
stringBuilder.push("<span class='", token.type, "'>", output,
|
||||
"</span>");
|
||||
}
|
||||
else {
|
||||
stringBuilder.push(output);
|
||||
for ( var i = config.firstRow; i <= config.lastRow; i++) {
|
||||
html.push("<div class='line' style='height:" + this.lineHeight + "px;", "width:",
|
||||
config.width, "px'>");
|
||||
this.renderLine(html, i), html.push("</div>");
|
||||
}
|
||||
|
||||
this.element.innerHTML = html.join("");
|
||||
};
|
||||
};
|
||||
|
||||
this.renderLine = function(stringBuilder, row) {
|
||||
var tokens = this.tokenizer.getTokens(row);
|
||||
for ( var i = 0; i < tokens.length; i++) {
|
||||
var token = tokens[i];
|
||||
|
||||
var output = token.value
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
//.replace(/\t/g, "‣ ")
|
||||
.replace(/\t/g, this._tabString)
|
||||
.replace(/\s/g, " ");
|
||||
|
||||
if (token.type !== "text") {
|
||||
stringBuilder.push("<span class='", token.type, "'>", output,
|
||||
"</span>");
|
||||
}
|
||||
else {
|
||||
stringBuilder.push(output);
|
||||
}
|
||||
};
|
||||
// TODO: show invisibles
|
||||
//stringBuilder.push("¶");
|
||||
};
|
||||
|
||||
}).call(ace.layer.Text.prototype);
|
||||
|
|
@ -5,19 +5,23 @@ ace.mode.Css = function() {
|
|||
};
|
||||
ace.inherits(ace.mode.Css, ace.mode.Text);
|
||||
|
||||
ace.mode.Css.prototype.getNextLineIndent = function(line, state, tab) {
|
||||
var indent = this.$getIndent(line);
|
||||
(function() {
|
||||
|
||||
this.getNextLineIndent = function(line, state, tab) {
|
||||
var indent = this.$getIndent(line);
|
||||
|
||||
// ignore braces in comments
|
||||
var tokens = this.$tokenizer.getLineTokens(line, state).tokens;
|
||||
if (tokens.length && tokens[tokens.length-1].type == "comment") {
|
||||
return indent;
|
||||
}
|
||||
|
||||
var match = line.match(/^.*\{\s*$/);
|
||||
if (match) {
|
||||
indent += tab;
|
||||
}
|
||||
|
||||
// ignore braces in comments
|
||||
var tokens = this.$tokenizer.getLineTokens(line, state).tokens;
|
||||
if (tokens.length && tokens[tokens.length-1].type == "comment") {
|
||||
return indent;
|
||||
}
|
||||
};
|
||||
|
||||
var match = line.match(/^.*\{\s*$/);
|
||||
if (match) {
|
||||
indent += tab;
|
||||
}
|
||||
|
||||
return indent;
|
||||
};
|
||||
}).call(ace.mode.Css.prototype);
|
||||
|
|
@ -175,6 +175,10 @@ ace.mode.CssHighlightRules = function() {
|
|||
};
|
||||
};
|
||||
|
||||
ace.mode.CssHighlightRules.prototype.getRules = function() {
|
||||
return this._rules;
|
||||
};
|
||||
(function() {
|
||||
|
||||
this.getRules = function() {
|
||||
return this._rules;
|
||||
};
|
||||
|
||||
}).call(ace.mode.CssHighlightRules.prototype);
|
||||
|
|
@ -8,30 +8,34 @@ ace.mode.Html = function() {
|
|||
};
|
||||
ace.inherits(ace.mode.Html, ace.mode.Text);
|
||||
|
||||
ace.mode.Html.prototype.toggleCommentLines = function(doc, range, state) {
|
||||
var split = state.split("js-");
|
||||
if (!split[0] && split[1]) {
|
||||
return this._js.toggleCommentLines(doc, range, state);
|
||||
}
|
||||
(function() {
|
||||
|
||||
var split = state.split("css-");
|
||||
if (!split[0] && split[1]) {
|
||||
return this._css.toggleCommentLines(doc, range, state);
|
||||
}
|
||||
this.toggleCommentLines = function(doc, range, state) {
|
||||
var split = state.split("js-");
|
||||
if (!split[0] && split[1]) {
|
||||
return this._js.toggleCommentLines(doc, range, state);
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
var split = state.split("css-");
|
||||
if (!split[0] && split[1]) {
|
||||
return this._css.toggleCommentLines(doc, range, state);
|
||||
}
|
||||
|
||||
ace.mode.Html.prototype.getNextLineIndent = function(line, state, tab) {
|
||||
var split = state.split("js-");
|
||||
if (!split[0] && split[1]) {
|
||||
return this._js.getNextLineIndent(line, split[1], tab);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
var split = state.split("css-");
|
||||
if (!split[0] && split[1]) {
|
||||
return this._css.getNextLineIndent(line, split[1], tab);
|
||||
}
|
||||
this.getNextLineIndent = function(line, state, tab) {
|
||||
var split = state.split("js-");
|
||||
if (!split[0] && split[1]) {
|
||||
return this._js.getNextLineIndent(line, split[1], tab);
|
||||
}
|
||||
|
||||
return "";
|
||||
};
|
||||
var split = state.split("css-");
|
||||
if (!split[0] && split[1]) {
|
||||
return this._css.getNextLineIndent(line, split[1], tab);
|
||||
}
|
||||
|
||||
return "";
|
||||
};
|
||||
|
||||
}).call(ace.mode.Html.prototype);
|
||||
|
|
@ -130,20 +130,23 @@ ace.mode.HtmlHighlightRules = function() {
|
|||
});
|
||||
};
|
||||
|
||||
(function() {
|
||||
|
||||
ace.mode.HtmlHighlightRules.prototype._addRules = function(rules, prefix) {
|
||||
for (var key in rules) {
|
||||
var state = rules[key];
|
||||
for (var i=0; i<state.length; i++) {
|
||||
var rule = state[i];
|
||||
if (rule.next) {
|
||||
rule.next = prefix + rule.next;
|
||||
this._addRules = function(rules, prefix) {
|
||||
for (var key in rules) {
|
||||
var state = rules[key];
|
||||
for (var i=0; i<state.length; i++) {
|
||||
var rule = state[i];
|
||||
if (rule.next) {
|
||||
rule.next = prefix + rule.next;
|
||||
}
|
||||
}
|
||||
this._rules[prefix + key] = state;
|
||||
}
|
||||
this._rules[prefix + key] = state;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
ace.mode.HtmlHighlightRules.prototype.getRules = function() {
|
||||
return this._rules;
|
||||
};
|
||||
this.getRules = function() {
|
||||
return this._rules;
|
||||
};
|
||||
|
||||
}).call(ace.mode.HtmlHighlightRules.prototype);
|
||||
|
|
@ -5,42 +5,46 @@ ace.mode.JavaScript = function() {
|
|||
};
|
||||
ace.inherits(ace.mode.JavaScript, ace.mode.Text);
|
||||
|
||||
ace.mode.JavaScript.prototype.toggleCommentLines = function(doc, range, state) {
|
||||
var addedRows = doc.outdentRows(range, "//");
|
||||
if (addedRows == 0) {
|
||||
var addedRows = doc.indentRows(range, "//");
|
||||
(function() {
|
||||
|
||||
this.toggleCommentLines = function(doc, range, state) {
|
||||
var addedRows = doc.outdentRows(range, "//");
|
||||
if (addedRows == 0) {
|
||||
var addedRows = doc.indentRows(range, "//");
|
||||
};
|
||||
return addedRows;
|
||||
};
|
||||
return addedRows;
|
||||
};
|
||||
|
||||
ace.mode.JavaScript.prototype.getNextLineIndent = function(line, state, tab) {
|
||||
var indent = this.$getIndent(line);
|
||||
this.getNextLineIndent = function(line, state, tab) {
|
||||
var indent = this.$getIndent(line);
|
||||
|
||||
var tokenizedLine = this.$tokenizer.getLineTokens(line, state);
|
||||
var tokens = tokenizedLine.tokens;
|
||||
var endState = tokenizedLine.state;
|
||||
var tokenizedLine = this.$tokenizer.getLineTokens(line, state);
|
||||
var tokens = tokenizedLine.tokens;
|
||||
var endState = tokenizedLine.state;
|
||||
|
||||
if (tokens.length && tokens[tokens.length-1].type == "comment") {
|
||||
return indent;
|
||||
}
|
||||
|
||||
if (state == "start") {
|
||||
var match = line.match(/^.*[\{\(\[]\s*$/);
|
||||
if (match) {
|
||||
indent += tab;
|
||||
if (tokens.length && tokens[tokens.length-1].type == "comment") {
|
||||
return indent;
|
||||
}
|
||||
} else if (state == "doc-comment") {
|
||||
if (endState == "start") {
|
||||
return "";
|
||||
}
|
||||
var match = line.match(/^\s*(\/?)\*/);
|
||||
if (match) {
|
||||
if (match[1]) {
|
||||
indent += " ";
|
||||
|
||||
if (state == "start") {
|
||||
var match = line.match(/^.*[\{\(\[]\s*$/);
|
||||
if (match) {
|
||||
indent += tab;
|
||||
}
|
||||
} else if (state == "doc-comment") {
|
||||
if (endState == "start") {
|
||||
return "";
|
||||
}
|
||||
var match = line.match(/^\s*(\/?)\*/);
|
||||
if (match) {
|
||||
if (match[1]) {
|
||||
indent += " ";
|
||||
}
|
||||
indent += "* ";
|
||||
}
|
||||
indent += "* ";
|
||||
}
|
||||
}
|
||||
|
||||
return indent;
|
||||
};
|
||||
return indent;
|
||||
};
|
||||
|
||||
}).call(ace.mode.JavaScript.prototype);
|
||||
|
|
@ -127,6 +127,10 @@ ace.mode.JavaScriptHighlightRules = function() {
|
|||
};
|
||||
};
|
||||
|
||||
ace.mode.JavaScriptHighlightRules.prototype.getRules = function() {
|
||||
return this._rules;
|
||||
};
|
||||
(function() {
|
||||
|
||||
this.getRules = function() {
|
||||
return this._rules;
|
||||
};
|
||||
|
||||
}).call(ace.mode.JavaScriptHighlightRules.prototype);
|
||||
|
|
@ -10,23 +10,27 @@ ace.mode.Text = function() {
|
|||
this.$tokenizer = new ace.Tokenizer(rules);
|
||||
};
|
||||
|
||||
ace.mode.Text.prototype.getTokenizer = function() {
|
||||
return this.$tokenizer;
|
||||
};
|
||||
(function() {
|
||||
|
||||
ace.mode.Text.prototype.toggleCommentLines = function(doc, range, state) {
|
||||
return 0;
|
||||
};
|
||||
this.getTokenizer = function() {
|
||||
return this.$tokenizer;
|
||||
};
|
||||
|
||||
ace.mode.Text.prototype.getNextLineIndent = function(line, state, tab) {
|
||||
return "";
|
||||
};
|
||||
this.toggleCommentLines = function(doc, range, state) {
|
||||
return 0;
|
||||
};
|
||||
|
||||
ace.mode.Text.prototype.$getIndent = function(line) {
|
||||
var match = line.match(/^(\s+)/);
|
||||
if (match) {
|
||||
return match[1];
|
||||
}
|
||||
this.getNextLineIndent = function(line, state, tab) {
|
||||
return "";
|
||||
};
|
||||
|
||||
return "";
|
||||
};
|
||||
this.$getIndent = function(line) {
|
||||
var match = line.match(/^(\s+)/);
|
||||
if (match) {
|
||||
return match[1];
|
||||
}
|
||||
|
||||
return "";
|
||||
};
|
||||
|
||||
}).call(ace.mode.Text.prototype);
|
||||
|
|
@ -70,6 +70,10 @@ ace.mode.XmlHighlightRules = function() {
|
|||
};
|
||||
};
|
||||
|
||||
ace.mode.XmlHighlightRules.prototype.getRules = function() {
|
||||
return this._rules;
|
||||
};
|
||||
(function() {
|
||||
|
||||
this.getRules = function() {
|
||||
return this._rules;
|
||||
};
|
||||
|
||||
}).call(ace.mode.XmlHighlightRules.prototype);
|
||||
Loading…
Add table
Add a link
Reference in a new issue