Merge branch 'master' of https://github.com/ajaxorg/ace
This commit is contained in:
commit
ad4987ca0f
46 changed files with 1980 additions and 230 deletions
|
|
@ -1,3 +1,26 @@
|
|||
2011.02.14, Version 0.1.6
|
||||
|
||||
* Extensive support for Cocoa style keybindings on the Mac <https://github.com/ajaxorg/ace/issues/closed#issue/116/comment/767803>
|
||||
* New commands:
|
||||
- center selection in viewport
|
||||
- remove to end/start of line
|
||||
- split line
|
||||
- transpose letters
|
||||
* Refator markers
|
||||
- Custom code can be used to render markers
|
||||
- Markers can be in front or behind the text
|
||||
- Markers are now stored in the session (was in the renderer)
|
||||
* Lots of IE8 fixes including copy, cut and selections
|
||||
* Unit tests can also be run in the browser <https://github.com/ajaxorg/ace/blob/master/lib/ace/test/tests.html>
|
||||
* Soft wrap can adapt to the width of the editor (Mike Ratcliffe, Joe Cheng)
|
||||
* Add minimal node server server.js to run the Ace demo in Chrome
|
||||
* The top level editor.html demo has been renamed to index.html
|
||||
* Bug fixes
|
||||
- Fixed gotoLine to consider wrapped lines when calculating where to scroll to (James Allen)
|
||||
- Fixed isues when the editor was scrolled in the web page (Eric Allam)
|
||||
- Highlighting of Python string literals
|
||||
- Syntax rule for PHP comments
|
||||
|
||||
2011.02.08, Version 0.1.5
|
||||
|
||||
* Add Coffeescript Mode (Satoshi Murakami)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,26 @@
|
|||
2011.02.14, Version 0.1.6
|
||||
|
||||
* Extensive support for Cocoa style keybindings on the Mac <https://github.com/ajaxorg/ace/issues/closed#issue/116/comment/767803>
|
||||
* New commands:
|
||||
- center selection in viewport
|
||||
- remove to end/start of line
|
||||
- split line
|
||||
- transpose letters
|
||||
* Refator markers
|
||||
- Custom code can be used to render markers
|
||||
- Markers can be in front or behind the text
|
||||
- Markers are now stored in the session (was in the renderer)
|
||||
* Lots of IE8 fixes including copy, cut and selections
|
||||
* Unit tests can also be run in the browser <https://github.com/ajaxorg/ace/blob/master/lib/ace/test/tests.html>
|
||||
* Soft wrap can adapt to the width of the editor (Mike Ratcliffe, Joe Cheng)
|
||||
* Add minimal node server server.js to run the Ace demo in Chrome
|
||||
* The top level editor.html demo has been renamed to index.html
|
||||
* Bug fixes
|
||||
- Fixed gotoLine to consider wrapped lines when calculating where to scroll to (James Allen)
|
||||
- Fixed isues when the editor was scrolled in the web page (Eric Allam)
|
||||
- Highlighting of Python string literals
|
||||
- Syntax rule for PHP comments
|
||||
|
||||
2011.02.08, Version 0.1.5
|
||||
|
||||
* Add Coffeescript Mode (Satoshi Murakami)
|
||||
|
|
|
|||
|
|
@ -598,23 +598,21 @@ if (!Object.isFrozen) Object.isFrozen = no;
|
|||
// ES5 15.2.3.13
|
||||
if (!Object.isExtensible) Object.isExtensible = yes;
|
||||
|
||||
|
||||
|
||||
if (!String.prototype.trim) {
|
||||
String.prototype.trim = function() {
|
||||
return this.replace(/^\s+/, "").replace(/\s+$/, "");
|
||||
return this.trimLeft().trimRight();
|
||||
}
|
||||
}
|
||||
|
||||
if (!String.prototype.trimRight) {
|
||||
String.prototype.trimRight = function() {
|
||||
return this.replace(/\s+$/, "");
|
||||
return this.replace(/[\t\v\f\s\u00a0\ufeff]+$/, "");
|
||||
}
|
||||
}
|
||||
|
||||
if (!String.prototype.trimLeft) {
|
||||
String.prototype.trimRight = function() {
|
||||
return this.replace(/^\s+/, "");
|
||||
String.prototype.trimLeft = function() {
|
||||
return this.replace(/^[\t\v\f\s\u00a0\ufeff]+/, "");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4101,10 +4099,7 @@ var Editor =function(renderer, session) {
|
|||
this.$mouseHandler = new MouseHandler(this);
|
||||
}
|
||||
|
||||
this.$selectionMarker = null;
|
||||
this.$highlightLineMarker = null;
|
||||
this.$blockScrolling = 0;
|
||||
|
||||
this.$search = new Search().set({
|
||||
wrap: true
|
||||
});
|
||||
|
|
@ -4158,6 +4153,8 @@ var Editor =function(renderer, session) {
|
|||
this.session.removeEventListener("changeTabSize", this.$onDocumentChangeTabSize);
|
||||
this.session.removeEventListener("changeWrapLimit", this.$onDocumentChangeWrapLimit);
|
||||
this.session.removeEventListener("changeWrapMode", this.$onDocumentChangeWrapMode);
|
||||
this.session.removeEventListener("changeFrontMarker", this.$onChangeFrontMarker);
|
||||
this.session.removeEventListener("changeBackMarker", this.$onChangeBackMarker);
|
||||
this.session.removeEventListener("changeBreakpoint", this.$onDocumentChangeBreakpoint);
|
||||
this.session.removeEventListener("changeAnnotation", this.$onDocumentChangeAnnotation);
|
||||
|
||||
|
|
@ -4186,6 +4183,12 @@ var Editor =function(renderer, session) {
|
|||
this.$onDocumentChangeWrapMode = this.onDocumentChangeWrapMode.bind(this);
|
||||
session.addEventListener("changeWrapMode", this.$onDocumentChangeWrapMode);
|
||||
|
||||
this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this);
|
||||
this.session.addEventListener("changeFrontMarker", this.$onChangeFrontMarker);
|
||||
|
||||
this.$onChangeBackMarker = this.onChangeBackMarker.bind(this);
|
||||
this.session.addEventListener("changeBackMarker", this.$onChangeBackMarker);
|
||||
|
||||
this.$onDocumentChangeBreakpoint = this.onDocumentChangeBreakpoint.bind(this);
|
||||
this.session.addEventListener("changeBreakpoint", this.$onDocumentChangeBreakpoint);
|
||||
|
||||
|
|
@ -4206,6 +4209,8 @@ var Editor =function(renderer, session) {
|
|||
|
||||
this.onCursorChange();
|
||||
this.onSelectionChange();
|
||||
this.onChangeFrontMarker();
|
||||
this.onChangeBackMarker();
|
||||
this.onDocumentChangeBreakpoint();
|
||||
this.onDocumentChangeAnnotation();
|
||||
this.renderer.scrollToRow(session.getScrollTopRow());
|
||||
|
|
@ -4243,7 +4248,7 @@ var Editor =function(renderer, session) {
|
|||
|
||||
this.$highlightBrackets = function() {
|
||||
if (this.$bracketHighlight) {
|
||||
this.renderer.removeMarker(this.$bracketHighlight);
|
||||
this.session.removeMarker(this.$bracketHighlight);
|
||||
this.$bracketHighlight = null;
|
||||
}
|
||||
|
||||
|
|
@ -4260,7 +4265,7 @@ var Editor =function(renderer, session) {
|
|||
var pos = self.session.findMatchingBracket(self.getCursorPosition());
|
||||
if (pos) {
|
||||
var range = new Range(pos.row, pos.column, pos.row, pos.column+1);
|
||||
self.$bracketHighlight = self.renderer.addMarker(range, "ace_bracket");
|
||||
self.$bracketHighlight = self.session.addMarker(range, "ace_bracket");
|
||||
}
|
||||
}, 10);
|
||||
};
|
||||
|
|
@ -4328,33 +4333,45 @@ var Editor =function(renderer, session) {
|
|||
};
|
||||
|
||||
this.$updateHighlightActiveLine = function() {
|
||||
if (this.$highlightLineMarker) {
|
||||
this.renderer.removeMarker(this.$highlightLineMarker);
|
||||
var session = this.getSession();
|
||||
|
||||
if (session.$highlightLineMarker) {
|
||||
session.removeMarker(session.$highlightLineMarker);
|
||||
}
|
||||
this.$highlightLineMarker = null;
|
||||
session.$highlightLineMarker = null;
|
||||
|
||||
if (this.getHighlightActiveLine() && (this.getSelectionStyle() != "line" || !this.selection.isMultiLine())) {
|
||||
var cursor = this.getCursorPosition();
|
||||
var range = new Range(cursor.row, 0, cursor.row+1, 0);
|
||||
this.$highlightLineMarker = this.renderer.addMarker(range, "ace_active_line", "line");
|
||||
session.$highlightLineMarker = session.addMarker(range, "ace_active_line", "line");
|
||||
}
|
||||
};
|
||||
|
||||
this.onSelectionChange = function(e) {
|
||||
if (this.$selectionMarker) {
|
||||
this.renderer.removeMarker(this.$selectionMarker);
|
||||
var session = this.getSession();
|
||||
|
||||
if (session.$selectionMarker) {
|
||||
session.removeMarker(session.$selectionMarker);
|
||||
}
|
||||
this.$selectionMarker = null;
|
||||
session.$selectionMarker = null;
|
||||
|
||||
if (!this.selection.isEmpty()) {
|
||||
var range = this.selection.getRange();
|
||||
var style = this.getSelectionStyle();
|
||||
this.$selectionMarker = this.renderer.addMarker(range, "ace_selection", style);
|
||||
session.$selectionMarker = session.addMarker(range, "ace_selection", style);
|
||||
}
|
||||
|
||||
this.onCursorChange(e);
|
||||
};
|
||||
|
||||
this.onChangeFrontMarker = function() {
|
||||
this.renderer.updateFrontMarkers();
|
||||
};
|
||||
|
||||
this.onChangeBackMarker = function() {
|
||||
this.renderer.updateBackMarkers();
|
||||
};
|
||||
|
||||
this.onDocumentChangeBreakpoint = function() {
|
||||
this.renderer.setBreakpoints(this.session.getBreakpoints());
|
||||
};
|
||||
|
|
@ -4435,6 +4452,8 @@ var Editor =function(renderer, session) {
|
|||
var lineIndent = this.mode.getNextLineIndent(lineState, line.slice(0, cursor.column), this.session.getTabString());
|
||||
var end = this.session.insert(cursor, text);
|
||||
|
||||
this.moveCursorToPosition(end);
|
||||
|
||||
var lineState = this.bgTokenizer.getState(cursor.row);
|
||||
// multi line insert
|
||||
if (cursor.row !== end.row) {
|
||||
|
|
@ -4465,14 +4484,14 @@ var Editor =function(renderer, session) {
|
|||
outdent -= size;
|
||||
else if (line.charAt(i) == ' ')
|
||||
outdent -= 1;
|
||||
this.session.replace(new Range(row, 0, row, line.length), line.substr(i));
|
||||
this.session.remove(new Range(row, 0, row, i));
|
||||
}
|
||||
this.session.indentRows(cursor.row + 1, end.row, lineIndent);
|
||||
} else {
|
||||
if (shouldOutdent) {
|
||||
this.mode.autoOutdent(lineState, this.session, cursor.row);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
this.onTextInput = function(text) {
|
||||
|
|
@ -4594,7 +4613,90 @@ var Editor =function(renderer, session) {
|
|||
this.session.remove(this.getSelectionRange());
|
||||
this.clearSelection();
|
||||
};
|
||||
|
||||
this.removeWordRight = function() {
|
||||
if (this.$readOnly)
|
||||
return;
|
||||
|
||||
if (this.selection.isEmpty())
|
||||
this.selection.selectWordRight();
|
||||
|
||||
this.session.remove(this.getSelectionRange());
|
||||
this.clearSelection();
|
||||
};
|
||||
|
||||
this.removeWordLeft = function() {
|
||||
if (this.$readOnly)
|
||||
return;
|
||||
|
||||
if (this.selection.isEmpty())
|
||||
this.selection.selectWordLeft();
|
||||
|
||||
this.session.remove(this.getSelectionRange());
|
||||
this.clearSelection();
|
||||
};
|
||||
|
||||
this.removeToLineStart = function() {
|
||||
if (this.$readOnly)
|
||||
return;
|
||||
|
||||
if (this.selection.isEmpty())
|
||||
this.selection.selectLineStart();
|
||||
|
||||
this.session.remove(this.getSelectionRange());
|
||||
this.clearSelection();
|
||||
};
|
||||
|
||||
this.removeToLineEnd = function() {
|
||||
if (this.$readOnly)
|
||||
return;
|
||||
|
||||
if (this.selection.isEmpty())
|
||||
this.selection.selectLineEnd();
|
||||
|
||||
this.session.remove(this.getSelectionRange());
|
||||
this.clearSelection();
|
||||
};
|
||||
|
||||
this.splitLine = function() {
|
||||
if (this.$readOnly)
|
||||
return;
|
||||
|
||||
if (!this.selection.isEmpty()) {
|
||||
this.session.remove(this.getSelectionRange());
|
||||
this.clearSelection();
|
||||
}
|
||||
|
||||
var cursor = this.getCursorPosition();
|
||||
this.insert("\n");
|
||||
this.moveCursorToPosition(cursor);
|
||||
};
|
||||
|
||||
this.transposeLetters = function() {
|
||||
if (this.$readOnly)
|
||||
return;
|
||||
|
||||
if (!this.selection.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var cursor = this.getCursorPosition();
|
||||
var column = cursor.column;
|
||||
if (column == 0)
|
||||
return;
|
||||
|
||||
var line = this.session.getLine(cursor.row);
|
||||
if (column < line.length) {
|
||||
var swap = line.charAt(column) + line.charAt(column-1);
|
||||
var range = new Range(cursor.row, column-1, cursor.row, column+1)
|
||||
}
|
||||
else {
|
||||
var swap = line.charAt(column-1) + line.charAt(column-2);
|
||||
var range = new Range(cursor.row, column-2, cursor.row, column)
|
||||
}
|
||||
this.session.replace(range, swap);
|
||||
};
|
||||
|
||||
this.indent = function() {
|
||||
if (this.$readOnly)
|
||||
return;
|
||||
|
|
@ -4799,6 +4901,15 @@ var Editor =function(renderer, session) {
|
|||
this.renderer.scrollToRow(row);
|
||||
};
|
||||
|
||||
this.scrollToLine = function(line, center) {
|
||||
this.renderer.scrollToLine(line, center);
|
||||
};
|
||||
|
||||
this.centerSelection = function() {
|
||||
var range = this.getSelectionRange();
|
||||
var line = Math.floor(range.start.row + (range.end.row - range.start.row) / 2);
|
||||
this.renderer.scrollToLine(line, true);
|
||||
};
|
||||
|
||||
this.getCursorPosition = function() {
|
||||
return this.selection.getCursor();
|
||||
|
|
@ -4836,7 +4947,7 @@ var Editor =function(renderer, session) {
|
|||
this.$blockScrolling -= 1;
|
||||
|
||||
if (!this.isRowVisible(this.getCursorPosition().row)) {
|
||||
this.scrollToRow(lineNumber - 1 - Math.floor(this.getVisibleRowCount() / 2));
|
||||
this.scrollToLine(lineNumber, true);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -4934,13 +5045,16 @@ var Editor =function(renderer, session) {
|
|||
if (!ranges.length)
|
||||
return;
|
||||
|
||||
var selection = this.getSelectionRange();
|
||||
this.clearSelection();
|
||||
this.selection.moveCursorTo(0, 0);
|
||||
|
||||
this.$blockScrolling += 1;
|
||||
for (var i = ranges.length - 1; i >= 0; --i)
|
||||
this.$tryReplace(ranges[i], replacement);
|
||||
if (ranges[0] !== null)
|
||||
this.selection.setSelectionRange(ranges[0]);
|
||||
|
||||
this.selection.setSelectionRange(selection);
|
||||
this.$blockScrolling -= 1;
|
||||
},
|
||||
|
||||
this.$tryReplace = function(range, replacement) {
|
||||
|
|
@ -5554,11 +5668,11 @@ if (window.pageYOffset !== undefined) {
|
|||
}
|
||||
else {
|
||||
exports.getPageScrollTop = function() {
|
||||
return ocument.body.scrollTop;
|
||||
return document.body.scrollTop;
|
||||
};
|
||||
|
||||
exports.getPageScrollLeft = function() {
|
||||
return ocument.body.scrollLeft;
|
||||
return document.body.scrollLeft;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -5783,7 +5897,6 @@ var TextInput = function(parentNode, host) {
|
|||
setTimeout(function () {
|
||||
sendText();
|
||||
}, 0);
|
||||
|
||||
};
|
||||
|
||||
var onCut = function(e) {
|
||||
|
|
@ -5798,7 +5911,6 @@ var TextInput = function(parentNode, host) {
|
|||
setTimeout(function () {
|
||||
sendText();
|
||||
}, 0);
|
||||
|
||||
};
|
||||
|
||||
event.addCommandKeyListener(text, host.onCommandKey.bind(host));
|
||||
|
|
@ -5832,8 +5944,29 @@ var TextInput = function(parentNode, host) {
|
|||
event.addListener(text, "propertychange", onTextInput);
|
||||
};
|
||||
|
||||
event.addListener(text, "copy", onCopy);
|
||||
event.addListener(text, "cut", onCut);
|
||||
if (useragent.isIE) {
|
||||
event.addListener(text, "beforecopy", function(e) {
|
||||
var copyText = host.getCopyText();
|
||||
if(copyText)
|
||||
clipboardData.setData("Text", copyText);
|
||||
else
|
||||
e.preventDefault();
|
||||
});
|
||||
event.addListener(parentNode, "keydown", function(e) {
|
||||
if (e.ctrlKey && e.keyCode == 88) {
|
||||
var copyText = host.getCopyText();
|
||||
if (copyText) {
|
||||
clipboardData.setData("Text", copyText);
|
||||
host.onCut();
|
||||
}
|
||||
event.preventDefault(e)
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
event.addListener(text, "copy", onCopy);
|
||||
event.addListener(text, "cut", onCut);
|
||||
}
|
||||
|
||||
event.addListener(text, "compositionstart", onCompositionStart);
|
||||
if (useragent.isGecko) {
|
||||
|
|
@ -6339,37 +6472,44 @@ exports.bindings = {
|
|||
"selecttostart": "Command-Shift-Up",
|
||||
"gotostart": "Command-Home|Command-Up",
|
||||
"selectup": "Shift-Up",
|
||||
"golineup": "Up",
|
||||
"golineup": "Up|Ctrl-P",
|
||||
"copylinesdown": "Command-Option-Down",
|
||||
"movelinesdown": "Option-Down",
|
||||
"selecttoend": "Command-Shift-Down",
|
||||
"gotoend": "Command-End|Command-Down",
|
||||
"selectdown": "Shift-Down",
|
||||
"golinedown": "Down",
|
||||
"golinedown": "Down|Ctrl-N",
|
||||
"selectwordleft": "Option-Shift-Left",
|
||||
"gotowordleft": "Option-Left",
|
||||
"selecttolinestart": "Command-Shift-Left",
|
||||
"gotolinestart": "Command-Left|Home",
|
||||
"gotolinestart": "Command-Left|Home|Ctrl-A",
|
||||
"selectleft": "Shift-Left",
|
||||
"gotoleft": "Left",
|
||||
"gotoleft": "Left|Ctrl-B",
|
||||
"selectwordright": "Option-Shift-Right",
|
||||
"gotowordright": "Option-Right",
|
||||
"selecttolineend": "Command-Shift-Right",
|
||||
"gotolineend": "Command-Right|End",
|
||||
"gotolineend": "Command-Right|End|Ctrl-E",
|
||||
"selectright": "Shift-Right",
|
||||
"gotoright": "Right",
|
||||
"gotoright": "Right|Ctrl-F",
|
||||
"selectpagedown": "Shift-PageDown",
|
||||
"pagedown": "PageDown",
|
||||
"gotopagedown": "Option-PageDown",
|
||||
"gotopagedown": "Option-PageDown|Ctrl-V",
|
||||
"selectpageup": "Shift-PageUp",
|
||||
"pageup": "PageUp",
|
||||
"gotopageup": "Option-PageUp",
|
||||
"selectlinestart": "Shift-Home",
|
||||
"selectlineend": "Shift-End",
|
||||
"del": "Delete",
|
||||
"backspace": "Ctrl-Backspace|Command-Backspace|Option-Backspace|Shift-Backspace|Backspace",
|
||||
"del": "Delete|Ctrl-D",
|
||||
"backspace": "Ctrl-Backspace|Command-Backspace|Shift-Backspace|Backspace|Ctrl-H",
|
||||
"removetolineend": "Ctrl-K",
|
||||
"removetolinestart": "Option-Backspace",
|
||||
"removewordleft": "Alt-Backspace|Ctrl-Alt-Backspace",
|
||||
"removewordright": "Alt-Delete",
|
||||
"outdent": "Shift-Tab",
|
||||
"indent": "Tab"
|
||||
"indent": "Tab",
|
||||
"transposeletters": "Ctrl-T",
|
||||
"splitline": "Ctrl-O",
|
||||
"centerselection": "Ctrl-L"
|
||||
};
|
||||
|
||||
});/* ***** BEGIN LICENSE BLOCK *****
|
||||
|
|
@ -6704,6 +6844,22 @@ canon.addCommand({
|
|||
name: "backspace",
|
||||
exec: function(env, args, request) { env.editor.removeLeft(); }
|
||||
});
|
||||
canon.addCommand({
|
||||
name: "removetolinestart",
|
||||
exec: function(env, args, request) { env.editor.removeToLineStart(); }
|
||||
});
|
||||
canon.addCommand({
|
||||
name: "removetolineend",
|
||||
exec: function(env, args, request) { env.editor.removeToLineEnd(); }
|
||||
});
|
||||
canon.addCommand({
|
||||
name: "removewordleft",
|
||||
exec: function(env, args, request) { env.editor.removeWordLeft(); }
|
||||
});
|
||||
canon.addCommand({
|
||||
name: "removewordright",
|
||||
exec: function(env, args, request) { env.editor.removeWordRight(); }
|
||||
});
|
||||
canon.addCommand({
|
||||
name: "outdent",
|
||||
exec: function(env, args, request) { env.editor.blockOutdent(); }
|
||||
|
|
@ -6715,10 +6871,22 @@ canon.addCommand({
|
|||
canon.addCommand({
|
||||
name: "inserttext",
|
||||
exec: function(env, args, request) {
|
||||
env.editor.insert(lang.stringRepeat(args.text || "",
|
||||
args.times || 1));
|
||||
env.editor.insert(lang.stringRepeat(args.text || "", args.times || 1));
|
||||
}
|
||||
});
|
||||
canon.addCommand({
|
||||
name: "centerselection",
|
||||
exec: function(env, args, request) { env.editor.centerSelection(); }
|
||||
});
|
||||
canon.addCommand({
|
||||
name: "splitline",
|
||||
exec: function(env, args, request) { env.editor.splitLine(); }
|
||||
});
|
||||
canon.addCommand({
|
||||
name: "transposeletters",
|
||||
exec: function(env, args, request) { env.editor.transposeLetters(); }
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
|
|
@ -6773,6 +6941,9 @@ var NO_CHANGE_DELTAS = {};
|
|||
var EditSession = function(text, mode) {
|
||||
this.$modified = true;
|
||||
this.$breakpoints = [];
|
||||
this.$frontMarkers = {};
|
||||
this.$backMarkers = {};
|
||||
this.$markerId = 1;
|
||||
this.$wrapData = [];
|
||||
this.listeners = [];
|
||||
|
||||
|
|
@ -6927,6 +7098,44 @@ var EditSession = function(text, mode) {
|
|||
return this.$breakpoints;
|
||||
};
|
||||
|
||||
this.addMarker = function(range, clazz, type, inFront) {
|
||||
var id = this.$markerId++;
|
||||
|
||||
var marker = {
|
||||
range : range,
|
||||
type : type || "line",
|
||||
renderer: typeof type == "function" ? type : null,
|
||||
clazz : clazz,
|
||||
inFront: !!inFront
|
||||
}
|
||||
|
||||
if (inFront) {
|
||||
this.$frontMarkers[id] = marker;
|
||||
this._dispatchEvent("changeFrontMarker")
|
||||
} else {
|
||||
this.$backMarkers[id] = marker;
|
||||
this._dispatchEvent("changeBackMarker")
|
||||
}
|
||||
|
||||
return id;
|
||||
};
|
||||
|
||||
this.removeMarker = function(markerId) {
|
||||
var marker = this.$frontMarkers[markerId] || this.$backMarkers[markerId];
|
||||
if (!marker)
|
||||
return;
|
||||
|
||||
var markers = marker.inFront ? this.$frontMarkers : this.$backMarkers;
|
||||
if (marker) {
|
||||
delete (markers[markerId]);
|
||||
this._dispatchEvent(marker.inFront ? "changeFrontMarker" : "changeBackMarker");
|
||||
}
|
||||
};
|
||||
|
||||
this.getMarkers = function(inFront) {
|
||||
return inFront ? this.$frontMarkers : this.$backMarkers;
|
||||
};
|
||||
|
||||
/**
|
||||
* Error:
|
||||
* {
|
||||
|
|
@ -7833,6 +8042,10 @@ var EditSession = function(text, mode) {
|
|||
column: column
|
||||
};
|
||||
}
|
||||
|
||||
var rowData = this.$documentToScreenRow(row, column);
|
||||
var screenRow = rowData[0];
|
||||
|
||||
if (row >= this.getLength()) {
|
||||
return {
|
||||
row: screenRow,
|
||||
|
|
@ -7842,11 +8055,8 @@ var EditSession = function(text, mode) {
|
|||
|
||||
var split;
|
||||
var wrapRowData = this.$wrapData[row];
|
||||
var screenRow, screenRowOffset;
|
||||
var screenColumn;
|
||||
var rowData = this.$documentToScreenRow(row, column);
|
||||
screenRow = rowData[0];
|
||||
screenRowOffset = rowData[1];
|
||||
var screenRowOffset = rowData[1];
|
||||
|
||||
str = this.getLine(row).substring(
|
||||
wrapRowData[screenRowOffset - 1] || 0, column);
|
||||
|
|
@ -7873,8 +8083,7 @@ var EditSession = function(text, mode) {
|
|||
}).call(EditSession.prototype);
|
||||
|
||||
exports.EditSession = EditSession;
|
||||
});
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
});/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
|
|
@ -7929,10 +8138,12 @@ var Selection = function(session) {
|
|||
this.selectionAnchor = new Anchor(this.doc, 0, 0);
|
||||
|
||||
var _self = this;
|
||||
this.selectionLead.on("change", function() {
|
||||
this.selectionLead.on("change", function(e) {
|
||||
_self._dispatchEvent("changeCursor");
|
||||
if (!_self.$isEmpty)
|
||||
_self._dispatchEvent("changeSelection");
|
||||
if (e.old.row == e.value.row)
|
||||
_self.$updateDesiredColumn();
|
||||
});
|
||||
|
||||
this.selectionAnchor.on("change", function() {
|
||||
|
|
@ -8052,9 +8263,7 @@ var Selection = function(session) {
|
|||
|
||||
this.$updateDesiredColumn = function() {
|
||||
var cursor = this.getCursor();
|
||||
if (cursor) {
|
||||
this.$desiredColumn = this.session.documentToScreenColumn(cursor.row, cursor.column);
|
||||
}
|
||||
this.$desiredColumn = this.session.documentToScreenColumn(cursor.row, cursor.column);
|
||||
};
|
||||
|
||||
this.$moveSelection = function(mover) {
|
||||
|
|
@ -8595,9 +8804,17 @@ var Anchor = exports.Anchor = function(doc, row, column) {
|
|||
if (this.row == pos.row && this.column == pos.column)
|
||||
return;
|
||||
|
||||
var old = {
|
||||
row: this.row,
|
||||
column: this.column
|
||||
};
|
||||
|
||||
this.row = pos.row;
|
||||
this.column = pos.column;
|
||||
this._dispatchEvent("change");
|
||||
this._dispatchEvent("change", {
|
||||
old: old,
|
||||
value: pos
|
||||
});
|
||||
};
|
||||
|
||||
this.detach = function() {
|
||||
|
|
@ -8789,7 +9006,7 @@ var Tokenizer = function(rules) {
|
|||
var value = match[0];
|
||||
|
||||
for ( var i = 0; i < state.length; i++) {
|
||||
if (match[i + 1] !== undefined) {
|
||||
if (match[i + 1]) {
|
||||
if (typeof state[i].token == "function") {
|
||||
type = state[i].token(match[0]);
|
||||
}
|
||||
|
|
@ -8823,10 +9040,10 @@ var Tokenizer = function(rules) {
|
|||
}
|
||||
|
||||
if (lastIndex == line.length) {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
lastIndex = re.lastIndex;
|
||||
lastIndex = re.lastIndex;
|
||||
};
|
||||
|
||||
if (token.type) {
|
||||
|
|
@ -10095,19 +10312,19 @@ var VirtualRenderer = function(container, theme) {
|
|||
this.scroller.appendChild(this.content);
|
||||
|
||||
this.$gutterLayer = new GutterLayer(this.$gutter);
|
||||
this.$markerLayer = new MarkerLayer(this.content);
|
||||
this.$markerBack = new MarkerLayer(this.content);
|
||||
|
||||
var textLayer = this.$textLayer = new TextLayer(this.content);
|
||||
this.canvas = textLayer.element;
|
||||
|
||||
this.$markerFront = new MarkerLayer(this.content);
|
||||
|
||||
this.characterWidth = textLayer.getCharacterWidth();
|
||||
this.lineHeight = textLayer.getLineHeight();
|
||||
|
||||
this.$cursorLayer = new CursorLayer(this.content);
|
||||
this.$cursorPadding = 8;
|
||||
|
||||
this.layers = [ this.$markerLayer, textLayer, this.$cursorLayer ];
|
||||
|
||||
this.scrollBar = new ScrollBar(container);
|
||||
this.scrollBar.addEventListener("scroll", this.onScroll.bind(this));
|
||||
|
||||
|
|
@ -10153,14 +10370,17 @@ var VirtualRenderer = function(container, theme) {
|
|||
this.CHANGE_LINES = 16;
|
||||
this.CHANGE_TEXT = 32;
|
||||
this.CHANGE_SIZE = 64;
|
||||
this.CHANGE_FULL = 128;
|
||||
this.CHANGE_MARKER_BACK = 128;
|
||||
this.CHANGE_MARKER_FRONT = 256;
|
||||
this.CHANGE_FULL = 512;
|
||||
|
||||
oop.implement(this, EventEmitter);
|
||||
|
||||
this.setSession = function(session) {
|
||||
this.session = session;
|
||||
this.$cursorLayer.setSession(session);
|
||||
this.$markerLayer.setSession(session);
|
||||
this.$markerBack.setSession(session);
|
||||
this.$markerFront.setSession(session);
|
||||
this.$gutterLayer.setSession(session);
|
||||
this.$textLayer.setSession(session);
|
||||
this.$loop.schedule(this.CHANGE_FULL);
|
||||
|
|
@ -10232,7 +10452,8 @@ var VirtualRenderer = function(container, theme) {
|
|||
this.scroller.style.width = Math.max(0, width - gutterWidth - this.scrollBar.getWidth()) + "px";
|
||||
|
||||
if (this.session.getUseWrapMode()) {
|
||||
var limit = Math.floor(this.scroller.clientWidth / this.characterWidth);
|
||||
var availableWidth = this.scroller.clientWidth - this.$padding * 2;
|
||||
var limit = Math.floor(availableWidth / this.characterWidth) - 1;
|
||||
if (this.session.adjustWrapLimit(limit) || force) {
|
||||
changes = changes | this.CHANGE_FULL;
|
||||
}
|
||||
|
|
@ -10403,7 +10624,8 @@ var VirtualRenderer = function(container, theme) {
|
|||
if (changes & this.CHANGE_FULL) {
|
||||
this.$textLayer.update(this.layerConfig);
|
||||
this.showGutter && this.$gutterLayer.update(this.layerConfig);
|
||||
this.$markerLayer.update(this.layerConfig);
|
||||
this.$markerBack.update(this.layerConfig);
|
||||
this.$markerFront.update(this.layerConfig);
|
||||
this.$cursorLayer.update(this.layerConfig);
|
||||
this.$updateScrollBar();
|
||||
this.scrollCursorIntoView();
|
||||
|
|
@ -10417,7 +10639,8 @@ var VirtualRenderer = function(container, theme) {
|
|||
else
|
||||
this.$textLayer.scrollLines(this.layerConfig);
|
||||
this.showGutter && this.$gutterLayer.update(this.layerConfig);
|
||||
this.$markerLayer.update(this.layerConfig);
|
||||
this.$markerBack.update(this.layerConfig);
|
||||
this.$markerFront.update(this.layerConfig);
|
||||
this.$cursorLayer.update(this.layerConfig);
|
||||
this.$updateScrollBar();
|
||||
return;
|
||||
|
|
@ -10438,8 +10661,12 @@ var VirtualRenderer = function(container, theme) {
|
|||
if (changes & this.CHANGE_CURSOR)
|
||||
this.$cursorLayer.update(this.layerConfig);
|
||||
|
||||
if (changes & this.CHANGE_MARKER) {
|
||||
this.$markerLayer.update(this.layerConfig);
|
||||
if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT)) {
|
||||
this.$markerFront.update(this.layerConfig);
|
||||
}
|
||||
|
||||
if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_BACK)) {
|
||||
this.$markerBack.update(this.layerConfig);
|
||||
}
|
||||
|
||||
if (changes & this.CHANGE_SIZE)
|
||||
|
|
@ -10524,15 +10751,14 @@ var VirtualRenderer = function(container, theme) {
|
|||
return Math.max(this.$size.scrollerWidth - this.$padding * 2, Math.round(charCount * this.characterWidth));
|
||||
};
|
||||
|
||||
this.addMarker = function(range, clazz, type) {
|
||||
var id = this.$markerLayer.addMarker(range, clazz, type);
|
||||
this.$loop.schedule(this.CHANGE_MARKER);
|
||||
return id;
|
||||
this.updateFrontMarkers = function() {
|
||||
this.$markerFront.setMarkers(this.session.getMarkers(true));
|
||||
this.$loop.schedule(this.CHANGE_MARKER_FRONT);
|
||||
};
|
||||
|
||||
this.removeMarker = function(markerId) {
|
||||
this.$markerLayer.removeMarker(markerId);
|
||||
this.$loop.schedule(this.CHANGE_MARKER);
|
||||
this.updateBackMarkers = function() {
|
||||
this.$markerBack.setMarkers(this.session.getMarkers());
|
||||
this.$loop.schedule(this.CHANGE_MARKER_BACK);
|
||||
};
|
||||
|
||||
this.addGutterDecoration = function(row, className){
|
||||
|
|
@ -10612,6 +10838,19 @@ var VirtualRenderer = function(container, theme) {
|
|||
this.scrollToY(row * this.lineHeight);
|
||||
};
|
||||
|
||||
this.scrollToLine = function(line, center) {
|
||||
var lineHeight = { lineHeight: this.lineHeight };
|
||||
var offset = 0;
|
||||
for (var l = 1; l < line; l++) {
|
||||
offset += this.session.getRowHeight(lineHeight, l-1);
|
||||
}
|
||||
|
||||
if (center) {
|
||||
offset -= this.$size.scrollerHeight / 2;
|
||||
}
|
||||
this.scrollToY(offset);
|
||||
};
|
||||
|
||||
this.scrollToY = function(scrollTop) {
|
||||
var maxHeight = this.session.getScreenLength() * this.lineHeight - this.$size.scrollerHeight;
|
||||
var scrollTop = Math.max(0, Math.min(maxHeight, scrollTop));
|
||||
|
|
@ -10914,9 +11153,6 @@ var Marker = function(parentEl) {
|
|||
this.element = document.createElement("div");
|
||||
this.element.className = "ace_layer ace_marker-layer";
|
||||
parentEl.appendChild(this.element);
|
||||
|
||||
this.markers = {};
|
||||
this.$markerId = 1;
|
||||
};
|
||||
|
||||
(function() {
|
||||
|
|
@ -10924,23 +11160,9 @@ var Marker = function(parentEl) {
|
|||
this.setSession = function(session) {
|
||||
this.session = session;
|
||||
};
|
||||
|
||||
this.addMarker = function(range, clazz, type) {
|
||||
var id = this.$markerId++;
|
||||
this.markers[id] = {
|
||||
range : range,
|
||||
type : type || "line",
|
||||
clazz : clazz
|
||||
};
|
||||
|
||||
return id;
|
||||
};
|
||||
|
||||
this.removeMarker = function(markerId) {
|
||||
var marker = this.markers[markerId];
|
||||
if (marker) {
|
||||
delete (this.markers[markerId]);
|
||||
}
|
||||
|
||||
this.setMarkers = function(markers) {
|
||||
this.markers = markers;
|
||||
};
|
||||
|
||||
this.update = function(config) {
|
||||
|
|
@ -10950,7 +11172,7 @@ var Marker = function(parentEl) {
|
|||
|
||||
this.config = config;
|
||||
|
||||
var html = [];
|
||||
var html = [];
|
||||
for ( var key in this.markers) {
|
||||
var marker = this.markers[key];
|
||||
|
||||
|
|
@ -10959,7 +11181,12 @@ var Marker = function(parentEl) {
|
|||
|
||||
range = range.toScreenRange(this.session);
|
||||
|
||||
if (range.isMultiLine()) {
|
||||
if (marker.renderer) {
|
||||
var top = this.$getTop(range.start.row, config);
|
||||
var left = Math.round(range.start.column * config.characterWidth);
|
||||
marker.renderer(html, range, left, top, config);
|
||||
}
|
||||
else if (range.isMultiLine()) {
|
||||
if (marker.type == "text") {
|
||||
this.drawTextMarker(html, range, marker.clazz, config);
|
||||
} else {
|
||||
|
|
@ -12387,6 +12614,22 @@ define("text!styles.css", "html {" +
|
|||
" background: white;" +
|
||||
"}" +
|
||||
"" +
|
||||
".cool {" +
|
||||
" position: absolute;" +
|
||||
" background: orange;" +
|
||||
" opacity: 0.8;" +
|
||||
"}" +
|
||||
"" +
|
||||
".cool_header {" +
|
||||
" position: absolute;" +
|
||||
" background: orange;" +
|
||||
" color: black;" +
|
||||
" font-size: 8px;" +
|
||||
" padding: 1px;" +
|
||||
" margin-top: -8px;" +
|
||||
" opacity: 0.8;" +
|
||||
"}" +
|
||||
"" +
|
||||
"#controls {" +
|
||||
" width: 100%;" +
|
||||
"}" +
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -138,9 +138,17 @@ var Anchor = exports.Anchor = function(doc, row, column) {
|
|||
if (this.row == pos.row && this.column == pos.column)
|
||||
return;
|
||||
|
||||
var old = {
|
||||
row: this.row,
|
||||
column: this.column
|
||||
};
|
||||
|
||||
this.row = pos.row;
|
||||
this.column = pos.column;
|
||||
this._dispatchEvent("change");
|
||||
this._dispatchEvent("change", {
|
||||
old: old,
|
||||
value: pos
|
||||
});
|
||||
};
|
||||
|
||||
this.detach = function() {
|
||||
|
|
|
|||
|
|
@ -242,6 +242,22 @@ canon.addCommand({
|
|||
name: "backspace",
|
||||
exec: function(env, args, request) { env.editor.removeLeft(); }
|
||||
});
|
||||
canon.addCommand({
|
||||
name: "removetolinestart",
|
||||
exec: function(env, args, request) { env.editor.removeToLineStart(); }
|
||||
});
|
||||
canon.addCommand({
|
||||
name: "removetolineend",
|
||||
exec: function(env, args, request) { env.editor.removeToLineEnd(); }
|
||||
});
|
||||
canon.addCommand({
|
||||
name: "removewordleft",
|
||||
exec: function(env, args, request) { env.editor.removeWordLeft(); }
|
||||
});
|
||||
canon.addCommand({
|
||||
name: "removewordright",
|
||||
exec: function(env, args, request) { env.editor.removeWordRight(); }
|
||||
});
|
||||
canon.addCommand({
|
||||
name: "outdent",
|
||||
exec: function(env, args, request) { env.editor.blockOutdent(); }
|
||||
|
|
@ -256,5 +272,18 @@ canon.addCommand({
|
|||
env.editor.insert(lang.stringRepeat(args.text || "", args.times || 1));
|
||||
}
|
||||
});
|
||||
canon.addCommand({
|
||||
name: "centerselection",
|
||||
exec: function(env, args, request) { env.editor.centerSelection(); }
|
||||
});
|
||||
canon.addCommand({
|
||||
name: "splitline",
|
||||
exec: function(env, args, request) { env.editor.splitLine(); }
|
||||
});
|
||||
canon.addCommand({
|
||||
name: "transposeletters",
|
||||
exec: function(env, args, request) { env.editor.transposeLetters(); }
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -50,6 +50,9 @@ var NO_CHANGE_DELTAS = {};
|
|||
var EditSession = function(text, mode) {
|
||||
this.$modified = true;
|
||||
this.$breakpoints = [];
|
||||
this.$frontMarkers = {};
|
||||
this.$backMarkers = {};
|
||||
this.$markerId = 1;
|
||||
this.$wrapData = [];
|
||||
this.listeners = [];
|
||||
|
||||
|
|
@ -204,6 +207,44 @@ var EditSession = function(text, mode) {
|
|||
return this.$breakpoints;
|
||||
};
|
||||
|
||||
this.addMarker = function(range, clazz, type, inFront) {
|
||||
var id = this.$markerId++;
|
||||
|
||||
var marker = {
|
||||
range : range,
|
||||
type : type || "line",
|
||||
renderer: typeof type == "function" ? type : null,
|
||||
clazz : clazz,
|
||||
inFront: !!inFront
|
||||
}
|
||||
|
||||
if (inFront) {
|
||||
this.$frontMarkers[id] = marker;
|
||||
this._dispatchEvent("changeFrontMarker")
|
||||
} else {
|
||||
this.$backMarkers[id] = marker;
|
||||
this._dispatchEvent("changeBackMarker")
|
||||
}
|
||||
|
||||
return id;
|
||||
};
|
||||
|
||||
this.removeMarker = function(markerId) {
|
||||
var marker = this.$frontMarkers[markerId] || this.$backMarkers[markerId];
|
||||
if (!marker)
|
||||
return;
|
||||
|
||||
var markers = marker.inFront ? this.$frontMarkers : this.$backMarkers;
|
||||
if (marker) {
|
||||
delete (markers[markerId]);
|
||||
this._dispatchEvent(marker.inFront ? "changeFrontMarker" : "changeBackMarker");
|
||||
}
|
||||
};
|
||||
|
||||
this.getMarkers = function(inFront) {
|
||||
return inFront ? this.$frontMarkers : this.$backMarkers;
|
||||
};
|
||||
|
||||
/**
|
||||
* Error:
|
||||
* {
|
||||
|
|
@ -1110,6 +1151,10 @@ var EditSession = function(text, mode) {
|
|||
column: column
|
||||
};
|
||||
}
|
||||
|
||||
var rowData = this.$documentToScreenRow(row, column);
|
||||
var screenRow = rowData[0];
|
||||
|
||||
if (row >= this.getLength()) {
|
||||
return {
|
||||
row: screenRow,
|
||||
|
|
@ -1119,11 +1164,8 @@ var EditSession = function(text, mode) {
|
|||
|
||||
var split;
|
||||
var wrapRowData = this.$wrapData[row];
|
||||
var screenRow, screenRowOffset;
|
||||
var screenColumn;
|
||||
var rowData = this.$documentToScreenRow(row, column);
|
||||
screenRow = rowData[0];
|
||||
screenRowOffset = rowData[1];
|
||||
var screenRowOffset = rowData[1];
|
||||
|
||||
str = this.getLine(row).substring(
|
||||
wrapRowData[screenRowOffset - 1] || 0, column);
|
||||
|
|
@ -1150,4 +1192,4 @@ var EditSession = function(text, mode) {
|
|||
}).call(EditSession.prototype);
|
||||
|
||||
exports.EditSession = EditSession;
|
||||
});
|
||||
});
|
||||
|
|
@ -71,10 +71,7 @@ var Editor =function(renderer, session) {
|
|||
this.$mouseHandler = new MouseHandler(this);
|
||||
}
|
||||
|
||||
this.$selectionMarker = null;
|
||||
this.$highlightLineMarker = null;
|
||||
this.$blockScrolling = 0;
|
||||
|
||||
this.$search = new Search().set({
|
||||
wrap: true
|
||||
});
|
||||
|
|
@ -128,6 +125,8 @@ var Editor =function(renderer, session) {
|
|||
this.session.removeEventListener("changeTabSize", this.$onDocumentChangeTabSize);
|
||||
this.session.removeEventListener("changeWrapLimit", this.$onDocumentChangeWrapLimit);
|
||||
this.session.removeEventListener("changeWrapMode", this.$onDocumentChangeWrapMode);
|
||||
this.session.removeEventListener("changeFrontMarker", this.$onChangeFrontMarker);
|
||||
this.session.removeEventListener("changeBackMarker", this.$onChangeBackMarker);
|
||||
this.session.removeEventListener("changeBreakpoint", this.$onDocumentChangeBreakpoint);
|
||||
this.session.removeEventListener("changeAnnotation", this.$onDocumentChangeAnnotation);
|
||||
|
||||
|
|
@ -156,6 +155,12 @@ var Editor =function(renderer, session) {
|
|||
this.$onDocumentChangeWrapMode = this.onDocumentChangeWrapMode.bind(this);
|
||||
session.addEventListener("changeWrapMode", this.$onDocumentChangeWrapMode);
|
||||
|
||||
this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this);
|
||||
this.session.addEventListener("changeFrontMarker", this.$onChangeFrontMarker);
|
||||
|
||||
this.$onChangeBackMarker = this.onChangeBackMarker.bind(this);
|
||||
this.session.addEventListener("changeBackMarker", this.$onChangeBackMarker);
|
||||
|
||||
this.$onDocumentChangeBreakpoint = this.onDocumentChangeBreakpoint.bind(this);
|
||||
this.session.addEventListener("changeBreakpoint", this.$onDocumentChangeBreakpoint);
|
||||
|
||||
|
|
@ -176,6 +181,8 @@ var Editor =function(renderer, session) {
|
|||
|
||||
this.onCursorChange();
|
||||
this.onSelectionChange();
|
||||
this.onChangeFrontMarker();
|
||||
this.onChangeBackMarker();
|
||||
this.onDocumentChangeBreakpoint();
|
||||
this.onDocumentChangeAnnotation();
|
||||
this.renderer.scrollToRow(session.getScrollTopRow());
|
||||
|
|
@ -213,7 +220,7 @@ var Editor =function(renderer, session) {
|
|||
|
||||
this.$highlightBrackets = function() {
|
||||
if (this.$bracketHighlight) {
|
||||
this.renderer.removeMarker(this.$bracketHighlight);
|
||||
this.session.removeMarker(this.$bracketHighlight);
|
||||
this.$bracketHighlight = null;
|
||||
}
|
||||
|
||||
|
|
@ -230,7 +237,7 @@ var Editor =function(renderer, session) {
|
|||
var pos = self.session.findMatchingBracket(self.getCursorPosition());
|
||||
if (pos) {
|
||||
var range = new Range(pos.row, pos.column, pos.row, pos.column+1);
|
||||
self.$bracketHighlight = self.renderer.addMarker(range, "ace_bracket");
|
||||
self.$bracketHighlight = self.session.addMarker(range, "ace_bracket");
|
||||
}
|
||||
}, 10);
|
||||
};
|
||||
|
|
@ -298,33 +305,45 @@ var Editor =function(renderer, session) {
|
|||
};
|
||||
|
||||
this.$updateHighlightActiveLine = function() {
|
||||
if (this.$highlightLineMarker) {
|
||||
this.renderer.removeMarker(this.$highlightLineMarker);
|
||||
var session = this.getSession();
|
||||
|
||||
if (session.$highlightLineMarker) {
|
||||
session.removeMarker(session.$highlightLineMarker);
|
||||
}
|
||||
this.$highlightLineMarker = null;
|
||||
session.$highlightLineMarker = null;
|
||||
|
||||
if (this.getHighlightActiveLine() && (this.getSelectionStyle() != "line" || !this.selection.isMultiLine())) {
|
||||
var cursor = this.getCursorPosition();
|
||||
var range = new Range(cursor.row, 0, cursor.row+1, 0);
|
||||
this.$highlightLineMarker = this.renderer.addMarker(range, "ace_active_line", "line");
|
||||
session.$highlightLineMarker = session.addMarker(range, "ace_active_line", "line");
|
||||
}
|
||||
};
|
||||
|
||||
this.onSelectionChange = function(e) {
|
||||
if (this.$selectionMarker) {
|
||||
this.renderer.removeMarker(this.$selectionMarker);
|
||||
var session = this.getSession();
|
||||
|
||||
if (session.$selectionMarker) {
|
||||
session.removeMarker(session.$selectionMarker);
|
||||
}
|
||||
this.$selectionMarker = null;
|
||||
session.$selectionMarker = null;
|
||||
|
||||
if (!this.selection.isEmpty()) {
|
||||
var range = this.selection.getRange();
|
||||
var style = this.getSelectionStyle();
|
||||
this.$selectionMarker = this.renderer.addMarker(range, "ace_selection", style);
|
||||
session.$selectionMarker = session.addMarker(range, "ace_selection", style);
|
||||
}
|
||||
|
||||
this.onCursorChange(e);
|
||||
};
|
||||
|
||||
this.onChangeFrontMarker = function() {
|
||||
this.renderer.updateFrontMarkers();
|
||||
};
|
||||
|
||||
this.onChangeBackMarker = function() {
|
||||
this.renderer.updateBackMarkers();
|
||||
};
|
||||
|
||||
this.onDocumentChangeBreakpoint = function() {
|
||||
this.renderer.setBreakpoints(this.session.getBreakpoints());
|
||||
};
|
||||
|
|
@ -405,6 +424,8 @@ var Editor =function(renderer, session) {
|
|||
var lineIndent = this.mode.getNextLineIndent(lineState, line.slice(0, cursor.column), this.session.getTabString());
|
||||
var end = this.session.insert(cursor, text);
|
||||
|
||||
this.moveCursorToPosition(end);
|
||||
|
||||
var lineState = this.bgTokenizer.getState(cursor.row);
|
||||
// multi line insert
|
||||
if (cursor.row !== end.row) {
|
||||
|
|
@ -435,14 +456,14 @@ var Editor =function(renderer, session) {
|
|||
outdent -= size;
|
||||
else if (line.charAt(i) == ' ')
|
||||
outdent -= 1;
|
||||
this.session.replace(new Range(row, 0, row, line.length), line.substr(i));
|
||||
this.session.remove(new Range(row, 0, row, i));
|
||||
}
|
||||
this.session.indentRows(cursor.row + 1, end.row, lineIndent);
|
||||
} else {
|
||||
if (shouldOutdent) {
|
||||
this.mode.autoOutdent(lineState, this.session, cursor.row);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
this.onTextInput = function(text) {
|
||||
|
|
@ -564,7 +585,90 @@ var Editor =function(renderer, session) {
|
|||
this.session.remove(this.getSelectionRange());
|
||||
this.clearSelection();
|
||||
};
|
||||
|
||||
this.removeWordRight = function() {
|
||||
if (this.$readOnly)
|
||||
return;
|
||||
|
||||
if (this.selection.isEmpty())
|
||||
this.selection.selectWordRight();
|
||||
|
||||
this.session.remove(this.getSelectionRange());
|
||||
this.clearSelection();
|
||||
};
|
||||
|
||||
this.removeWordLeft = function() {
|
||||
if (this.$readOnly)
|
||||
return;
|
||||
|
||||
if (this.selection.isEmpty())
|
||||
this.selection.selectWordLeft();
|
||||
|
||||
this.session.remove(this.getSelectionRange());
|
||||
this.clearSelection();
|
||||
};
|
||||
|
||||
this.removeToLineStart = function() {
|
||||
if (this.$readOnly)
|
||||
return;
|
||||
|
||||
if (this.selection.isEmpty())
|
||||
this.selection.selectLineStart();
|
||||
|
||||
this.session.remove(this.getSelectionRange());
|
||||
this.clearSelection();
|
||||
};
|
||||
|
||||
this.removeToLineEnd = function() {
|
||||
if (this.$readOnly)
|
||||
return;
|
||||
|
||||
if (this.selection.isEmpty())
|
||||
this.selection.selectLineEnd();
|
||||
|
||||
this.session.remove(this.getSelectionRange());
|
||||
this.clearSelection();
|
||||
};
|
||||
|
||||
this.splitLine = function() {
|
||||
if (this.$readOnly)
|
||||
return;
|
||||
|
||||
if (!this.selection.isEmpty()) {
|
||||
this.session.remove(this.getSelectionRange());
|
||||
this.clearSelection();
|
||||
}
|
||||
|
||||
var cursor = this.getCursorPosition();
|
||||
this.insert("\n");
|
||||
this.moveCursorToPosition(cursor);
|
||||
};
|
||||
|
||||
this.transposeLetters = function() {
|
||||
if (this.$readOnly)
|
||||
return;
|
||||
|
||||
if (!this.selection.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var cursor = this.getCursorPosition();
|
||||
var column = cursor.column;
|
||||
if (column == 0)
|
||||
return;
|
||||
|
||||
var line = this.session.getLine(cursor.row);
|
||||
if (column < line.length) {
|
||||
var swap = line.charAt(column) + line.charAt(column-1);
|
||||
var range = new Range(cursor.row, column-1, cursor.row, column+1)
|
||||
}
|
||||
else {
|
||||
var swap = line.charAt(column-1) + line.charAt(column-2);
|
||||
var range = new Range(cursor.row, column-2, cursor.row, column)
|
||||
}
|
||||
this.session.replace(range, swap);
|
||||
};
|
||||
|
||||
this.indent = function() {
|
||||
if (this.$readOnly)
|
||||
return;
|
||||
|
|
@ -772,6 +876,12 @@ var Editor =function(renderer, session) {
|
|||
this.scrollToLine = function(line, center) {
|
||||
this.renderer.scrollToLine(line, center);
|
||||
};
|
||||
|
||||
this.centerSelection = function() {
|
||||
var range = this.getSelectionRange();
|
||||
var line = Math.floor(range.start.row + (range.end.row - range.start.row) / 2);
|
||||
this.renderer.scrollToLine(line, true);
|
||||
};
|
||||
|
||||
this.getCursorPosition = function() {
|
||||
return this.selection.getCursor();
|
||||
|
|
@ -907,13 +1017,16 @@ var Editor =function(renderer, session) {
|
|||
if (!ranges.length)
|
||||
return;
|
||||
|
||||
var selection = this.getSelectionRange();
|
||||
this.clearSelection();
|
||||
this.selection.moveCursorTo(0, 0);
|
||||
|
||||
this.$blockScrolling += 1;
|
||||
for (var i = ranges.length - 1; i >= 0; --i)
|
||||
this.$tryReplace(ranges[i], replacement);
|
||||
if (ranges[0] !== null)
|
||||
this.selection.setSelectionRange(ranges[0]);
|
||||
|
||||
this.selection.setSelectionRange(selection);
|
||||
this.$blockScrolling -= 1;
|
||||
},
|
||||
|
||||
this.$tryReplace = function(range, replacement) {
|
||||
|
|
|
|||
|
|
@ -54,37 +54,44 @@ exports.bindings = {
|
|||
"selecttostart": "Command-Shift-Up",
|
||||
"gotostart": "Command-Home|Command-Up",
|
||||
"selectup": "Shift-Up",
|
||||
"golineup": "Up",
|
||||
"golineup": "Up|Ctrl-P",
|
||||
"copylinesdown": "Command-Option-Down",
|
||||
"movelinesdown": "Option-Down",
|
||||
"selecttoend": "Command-Shift-Down",
|
||||
"gotoend": "Command-End|Command-Down",
|
||||
"selectdown": "Shift-Down",
|
||||
"golinedown": "Down",
|
||||
"golinedown": "Down|Ctrl-N",
|
||||
"selectwordleft": "Option-Shift-Left",
|
||||
"gotowordleft": "Option-Left",
|
||||
"selecttolinestart": "Command-Shift-Left",
|
||||
"gotolinestart": "Command-Left|Home",
|
||||
"gotolinestart": "Command-Left|Home|Ctrl-A",
|
||||
"selectleft": "Shift-Left",
|
||||
"gotoleft": "Left",
|
||||
"gotoleft": "Left|Ctrl-B",
|
||||
"selectwordright": "Option-Shift-Right",
|
||||
"gotowordright": "Option-Right",
|
||||
"selecttolineend": "Command-Shift-Right",
|
||||
"gotolineend": "Command-Right|End",
|
||||
"gotolineend": "Command-Right|End|Ctrl-E",
|
||||
"selectright": "Shift-Right",
|
||||
"gotoright": "Right",
|
||||
"gotoright": "Right|Ctrl-F",
|
||||
"selectpagedown": "Shift-PageDown",
|
||||
"pagedown": "PageDown",
|
||||
"gotopagedown": "Option-PageDown",
|
||||
"gotopagedown": "Option-PageDown|Ctrl-V",
|
||||
"selectpageup": "Shift-PageUp",
|
||||
"pageup": "PageUp",
|
||||
"gotopageup": "Option-PageUp",
|
||||
"selectlinestart": "Shift-Home",
|
||||
"selectlineend": "Shift-End",
|
||||
"del": "Delete",
|
||||
"backspace": "Ctrl-Backspace|Command-Backspace|Option-Backspace|Shift-Backspace|Backspace",
|
||||
"del": "Delete|Ctrl-D",
|
||||
"backspace": "Ctrl-Backspace|Command-Backspace|Shift-Backspace|Backspace|Ctrl-H",
|
||||
"removetolineend": "Ctrl-K",
|
||||
"removetolinestart": "Option-Backspace",
|
||||
"removewordleft": "Alt-Backspace|Ctrl-Alt-Backspace",
|
||||
"removewordright": "Alt-Delete",
|
||||
"outdent": "Shift-Tab",
|
||||
"indent": "Tab"
|
||||
"indent": "Tab",
|
||||
"transposeletters": "Ctrl-T",
|
||||
"splitline": "Ctrl-O",
|
||||
"centerselection": "Ctrl-L"
|
||||
};
|
||||
|
||||
});
|
||||
|
|
@ -114,7 +114,6 @@ var TextInput = function(parentNode, host) {
|
|||
setTimeout(function () {
|
||||
sendText();
|
||||
}, 0);
|
||||
|
||||
};
|
||||
|
||||
var onCut = function(e) {
|
||||
|
|
@ -129,7 +128,6 @@ var TextInput = function(parentNode, host) {
|
|||
setTimeout(function () {
|
||||
sendText();
|
||||
}, 0);
|
||||
|
||||
};
|
||||
|
||||
event.addCommandKeyListener(text, host.onCommandKey.bind(host));
|
||||
|
|
@ -163,8 +161,29 @@ var TextInput = function(parentNode, host) {
|
|||
event.addListener(text, "propertychange", onTextInput);
|
||||
};
|
||||
|
||||
event.addListener(text, "copy", onCopy);
|
||||
event.addListener(text, "cut", onCut);
|
||||
if (useragent.isIE) {
|
||||
event.addListener(text, "beforecopy", function(e) {
|
||||
var copyText = host.getCopyText();
|
||||
if(copyText)
|
||||
clipboardData.setData("Text", copyText);
|
||||
else
|
||||
e.preventDefault();
|
||||
});
|
||||
event.addListener(parentNode, "keydown", function(e) {
|
||||
if (e.ctrlKey && e.keyCode == 88) {
|
||||
var copyText = host.getCopyText();
|
||||
if (copyText) {
|
||||
clipboardData.setData("Text", copyText);
|
||||
host.onCut();
|
||||
}
|
||||
event.preventDefault(e)
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
event.addListener(text, "copy", onCopy);
|
||||
event.addListener(text, "cut", onCut);
|
||||
}
|
||||
|
||||
event.addListener(text, "compositionstart", onCompositionStart);
|
||||
if (useragent.isGecko) {
|
||||
|
|
|
|||
|
|
@ -45,9 +45,6 @@ var Marker = function(parentEl) {
|
|||
this.element = document.createElement("div");
|
||||
this.element.className = "ace_layer ace_marker-layer";
|
||||
parentEl.appendChild(this.element);
|
||||
|
||||
this.markers = {};
|
||||
this.$markerId = 1;
|
||||
};
|
||||
|
||||
(function() {
|
||||
|
|
@ -55,23 +52,9 @@ var Marker = function(parentEl) {
|
|||
this.setSession = function(session) {
|
||||
this.session = session;
|
||||
};
|
||||
|
||||
this.addMarker = function(range, clazz, type) {
|
||||
var id = this.$markerId++;
|
||||
this.markers[id] = {
|
||||
range : range,
|
||||
type : type || "line",
|
||||
clazz : clazz
|
||||
};
|
||||
|
||||
return id;
|
||||
};
|
||||
|
||||
this.removeMarker = function(markerId) {
|
||||
var marker = this.markers[markerId];
|
||||
if (marker) {
|
||||
delete (this.markers[markerId]);
|
||||
}
|
||||
|
||||
this.setMarkers = function(markers) {
|
||||
this.markers = markers;
|
||||
};
|
||||
|
||||
this.update = function(config) {
|
||||
|
|
@ -81,7 +64,7 @@ var Marker = function(parentEl) {
|
|||
|
||||
this.config = config;
|
||||
|
||||
var html = [];
|
||||
var html = [];
|
||||
for ( var key in this.markers) {
|
||||
var marker = this.markers[key];
|
||||
|
||||
|
|
@ -90,7 +73,12 @@ var Marker = function(parentEl) {
|
|||
|
||||
range = range.toScreenRange(this.session);
|
||||
|
||||
if (range.isMultiLine()) {
|
||||
if (marker.renderer) {
|
||||
var top = this.$getTop(range.start.row, config);
|
||||
var left = Math.round(range.start.column * config.characterWidth);
|
||||
marker.renderer(html, range, left, top, config);
|
||||
}
|
||||
else if (range.isMultiLine()) {
|
||||
if (marker.type == "text") {
|
||||
this.drawTextMarker(html, range, marker.clazz, config);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -53,10 +53,12 @@ var Selection = function(session) {
|
|||
this.selectionAnchor = new Anchor(this.doc, 0, 0);
|
||||
|
||||
var _self = this;
|
||||
this.selectionLead.on("change", function() {
|
||||
this.selectionLead.on("change", function(e) {
|
||||
_self._dispatchEvent("changeCursor");
|
||||
if (!_self.$isEmpty)
|
||||
_self._dispatchEvent("changeSelection");
|
||||
if (e.old.row == e.value.row)
|
||||
_self.$updateDesiredColumn();
|
||||
});
|
||||
|
||||
this.selectionAnchor.on("change", function() {
|
||||
|
|
@ -176,9 +178,7 @@ var Selection = function(session) {
|
|||
|
||||
this.$updateDesiredColumn = function() {
|
||||
var cursor = this.getCursor();
|
||||
if (cursor) {
|
||||
this.$desiredColumn = this.session.documentToScreenColumn(cursor.row, cursor.column);
|
||||
}
|
||||
this.$desiredColumn = this.session.documentToScreenColumn(cursor.row, cursor.column);
|
||||
};
|
||||
|
||||
this.$moveSelection = function(mover) {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
require("../../../support/paths");
|
||||
|
||||
require("./mockdom");
|
||||
var async = require("asyncjs");
|
||||
|
||||
async.concat(
|
||||
|
|
|
|||
75
lib/ace/test/all_browser.js
Normal file
75
lib/ace/test/all_browser.js
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
define(function(require, exports, module) {
|
||||
|
||||
require("pilot/fixoldbrowsers");
|
||||
var async = require("asyncjs");
|
||||
var dom = require("pilot/dom");
|
||||
|
||||
var passed = 0
|
||||
var failed = 0
|
||||
var log = document.getElementById("log")
|
||||
|
||||
async.concat(
|
||||
require("./anchor_test"),
|
||||
require("./change_document_test"),
|
||||
require("./document_test"),
|
||||
require("./edit_session_test"),
|
||||
require("./event_emitter_test"),
|
||||
require("./navigation_test"),
|
||||
require("./range_test"),
|
||||
require("./search_test"),
|
||||
require("./selection_test"),
|
||||
require("./text_edit_test"),
|
||||
require("./virtual_renderer_test"),
|
||||
require("./mode/css_test"),
|
||||
require("./mode/css_tokenizer_test"),
|
||||
require("./mode/html_test"),
|
||||
require("./mode/html_tokenizer_test"),
|
||||
require("./mode/javascript_test"),
|
||||
require("./mode/javascript_tokenizer_test"),
|
||||
require("./mode/text_test"),
|
||||
require("./mode/xml_test"),
|
||||
require("./mode/xml_tokenizer_test")
|
||||
)
|
||||
.run()
|
||||
.each(function(test, next) {
|
||||
var node = document.createElement("div");
|
||||
node.className = test.passed ? "passed" : "failed";
|
||||
|
||||
var name = test.name
|
||||
if (test.suiteName)
|
||||
name = test.suiteName + ": " + test.name
|
||||
|
||||
var msg = "[" + test.count + "/" + test.index + "] " + name + " " + (test.passed ? "OK" : "FAIL")
|
||||
if (!test.passed) {
|
||||
if (test.err.stack)
|
||||
var err = test.err.stack
|
||||
else
|
||||
var err = test.err
|
||||
|
||||
msg += "<pre class='error'>" + err + "</pre>";
|
||||
}
|
||||
|
||||
node.innerHTML = msg;
|
||||
log.appendChild(node);
|
||||
|
||||
next()
|
||||
})
|
||||
.each(function(test) {
|
||||
if (test.passed)
|
||||
passed += 1
|
||||
else
|
||||
failed += 1
|
||||
})
|
||||
.end(function() {
|
||||
log.innerHTML += [
|
||||
"<div class='summary'>",
|
||||
"<br>",
|
||||
"Summary: <br>",
|
||||
"<br>",
|
||||
"Total number of tests: " + (passed + failed) + "<br>",
|
||||
(passed ? "Passed tests: " + passed + "<br>" : ""),
|
||||
(failed ? "Failed tests: " + failed + "<br>" : "")
|
||||
].join("")
|
||||
})
|
||||
|
||||
});
|
||||
|
|
@ -35,6 +35,8 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
define(function(require, exports, module) {
|
||||
|
||||
var Document = require("ace/document").Document;
|
||||
var Anchor = require("ace/anchor").Anchor;
|
||||
var Range = require("ace/range").Range;
|
||||
|
|
@ -173,7 +175,9 @@ var Test = {
|
|||
|
||||
module.exports = require("asyncjs/test").testcase(Test);
|
||||
|
||||
if (module === require.main) {
|
||||
});
|
||||
|
||||
if (typeof module !== "undefined" && module === require.main) {
|
||||
require("../../../support/paths");
|
||||
exports.exec()
|
||||
}
|
||||
|
|
|
|||
306
lib/ace/test/asyncjs/assert.js
Normal file
306
lib/ace/test/asyncjs/assert.js
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
define(function(require, exports, module) {
|
||||
|
||||
// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
|
||||
//
|
||||
// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
|
||||
//
|
||||
// Originally from narwhal.js (http://narwhaljs.org)
|
||||
// Copyright (c) 2009 Thomas Robinson <280north.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the 'Software'), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// UTILITY
|
||||
var oop = require('pilot/oop');
|
||||
var pSlice = Array.prototype.slice;
|
||||
|
||||
// 1. The assert module provides functions that throw
|
||||
// AssertionError's when particular conditions are not met. The
|
||||
// assert module must conform to the following interface.
|
||||
|
||||
var assert = exports;
|
||||
|
||||
// 2. The AssertionError is defined in assert.
|
||||
// new assert.AssertionError({ message: message,
|
||||
// actual: actual,
|
||||
// expected: expected })
|
||||
|
||||
assert.AssertionError = function AssertionError(options) {
|
||||
this.name = 'AssertionError';
|
||||
this.message = options.message;
|
||||
this.actual = options.actual;
|
||||
this.expected = options.expected;
|
||||
this.operator = options.operator;
|
||||
var stackStartFunction = options.stackStartFunction || fail;
|
||||
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, stackStartFunction);
|
||||
}
|
||||
};
|
||||
oop.inherits(assert.AssertionError, Error);
|
||||
|
||||
assert.AssertionError.prototype.toString = function() {
|
||||
if (this.message) {
|
||||
return [this.name + ':', this.message].join(' ');
|
||||
} else {
|
||||
return [this.name + ':',
|
||||
JSON.stringify(this.expected),
|
||||
this.operator,
|
||||
JSON.stringify(this.actual)].join(' ');
|
||||
}
|
||||
};
|
||||
|
||||
// assert.AssertionError instanceof Error
|
||||
|
||||
assert.AssertionError.__proto__ = Error.prototype;
|
||||
|
||||
// At present only the three keys mentioned above are used and
|
||||
// understood by the spec. Implementations or sub modules can pass
|
||||
// other keys to the AssertionError's constructor - they will be
|
||||
// ignored.
|
||||
|
||||
// 3. All of the following functions must throw an AssertionError
|
||||
// when a corresponding condition is not met, with a message that
|
||||
// may be undefined if not provided. All assertion methods provide
|
||||
// both the actual and expected values to the assertion error for
|
||||
// display purposes.
|
||||
|
||||
function fail(actual, expected, message, operator, stackStartFunction) {
|
||||
throw new assert.AssertionError({
|
||||
message: message,
|
||||
actual: actual,
|
||||
expected: expected,
|
||||
operator: operator,
|
||||
stackStartFunction: stackStartFunction
|
||||
});
|
||||
}
|
||||
|
||||
// EXTENSION! allows for well behaved errors defined elsewhere.
|
||||
assert.fail = fail;
|
||||
|
||||
// 4. Pure assertion tests whether a value is truthy, as determined
|
||||
// by !!guard.
|
||||
// assert.ok(guard, message_opt);
|
||||
// This statement is equivalent to assert.equal(true, guard,
|
||||
// message_opt);. To test strictly for the value true, use
|
||||
// assert.strictEqual(true, guard, message_opt);.
|
||||
|
||||
assert.ok = function ok(value, message) {
|
||||
if (!!!value) fail(value, true, message, '==', assert.ok);
|
||||
};
|
||||
|
||||
// 5. The equality assertion tests shallow, coercive equality with
|
||||
// ==.
|
||||
// assert.equal(actual, expected, message_opt);
|
||||
|
||||
assert.equal = function equal(actual, expected, message) {
|
||||
if (actual != expected) fail(actual, expected, message, '==', assert.equal);
|
||||
};
|
||||
|
||||
// 6. The non-equality assertion tests for whether two objects are not equal
|
||||
// with != assert.notEqual(actual, expected, message_opt);
|
||||
|
||||
assert.notEqual = function notEqual(actual, expected, message) {
|
||||
if (actual == expected) {
|
||||
fail(actual, expected, message, '!=', assert.notEqual);
|
||||
}
|
||||
};
|
||||
|
||||
// 7. The equivalence assertion tests a deep equality relation.
|
||||
// assert.deepEqual(actual, expected, message_opt);
|
||||
|
||||
assert.deepEqual = function deepEqual(actual, expected, message) {
|
||||
if (!_deepEqual(actual, expected)) {
|
||||
fail(actual, expected, message, 'deepEqual', assert.deepEqual);
|
||||
}
|
||||
};
|
||||
|
||||
function _deepEqual(actual, expected) {
|
||||
// 7.1. All identical values are equivalent, as determined by ===.
|
||||
if (actual === expected) {
|
||||
return true;
|
||||
|
||||
} else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {
|
||||
if (actual.length != expected.length) return false;
|
||||
|
||||
for (var i = 0; i < actual.length; i++) {
|
||||
if (actual[i] !== expected[i]) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
// 7.2. If the expected value is a Date object, the actual value is
|
||||
// equivalent if it is also a Date object that refers to the same time.
|
||||
} else if (actual instanceof Date && expected instanceof Date) {
|
||||
return actual.getTime() === expected.getTime();
|
||||
|
||||
// 7.3. Other pairs that do not both pass typeof value == 'object',
|
||||
// equivalence is determined by ==.
|
||||
} else if (typeof actual != 'object' && typeof expected != 'object') {
|
||||
return actual == expected;
|
||||
|
||||
// 7.4. For all other Object pairs, including Array objects, equivalence is
|
||||
// determined by having the same number of owned properties (as verified
|
||||
// with Object.prototype.hasOwnProperty.call), the same set of keys
|
||||
// (although not necessarily the same order), equivalent values for every
|
||||
// corresponding key, and an identical 'prototype' property. Note: this
|
||||
// accounts for both named and indexed properties on Arrays.
|
||||
} else {
|
||||
return objEquiv(actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
function isUndefinedOrNull(value) {
|
||||
return value === null || value === undefined;
|
||||
}
|
||||
|
||||
function isArguments(object) {
|
||||
return Object.prototype.toString.call(object) == '[object Arguments]';
|
||||
}
|
||||
|
||||
function objEquiv(a, b) {
|
||||
if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
|
||||
return false;
|
||||
// an identical 'prototype' property.
|
||||
if (a.prototype !== b.prototype) return false;
|
||||
//~~~I've managed to break Object.keys through screwy arguments passing.
|
||||
// Converting to array solves the problem.
|
||||
if (isArguments(a)) {
|
||||
if (!isArguments(b)) {
|
||||
return false;
|
||||
}
|
||||
a = pSlice.call(a);
|
||||
b = pSlice.call(b);
|
||||
return _deepEqual(a, b);
|
||||
}
|
||||
try {
|
||||
var ka = Object.keys(a),
|
||||
kb = Object.keys(b),
|
||||
key, i;
|
||||
} catch (e) {//happens when one is a string literal and the other isn't
|
||||
return false;
|
||||
}
|
||||
// having the same number of owned properties (keys incorporates
|
||||
// hasOwnProperty)
|
||||
if (ka.length != kb.length)
|
||||
return false;
|
||||
//the same set of keys (although not necessarily the same order),
|
||||
ka.sort();
|
||||
kb.sort();
|
||||
//~~~cheap key test
|
||||
for (i = ka.length - 1; i >= 0; i--) {
|
||||
if (ka[i] != kb[i])
|
||||
return false;
|
||||
}
|
||||
//equivalent values for every corresponding key, and
|
||||
//~~~possibly expensive deep test
|
||||
for (i = ka.length - 1; i >= 0; i--) {
|
||||
key = ka[i];
|
||||
if (!_deepEqual(a[key], b[key])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 8. The non-equivalence assertion tests for any deep inequality.
|
||||
// assert.notDeepEqual(actual, expected, message_opt);
|
||||
|
||||
assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
|
||||
if (_deepEqual(actual, expected)) {
|
||||
fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
|
||||
}
|
||||
};
|
||||
|
||||
// 9. The strict equality assertion tests strict equality, as determined by ===.
|
||||
// assert.strictEqual(actual, expected, message_opt);
|
||||
|
||||
assert.strictEqual = function strictEqual(actual, expected, message) {
|
||||
if (actual !== expected) {
|
||||
fail(actual, expected, message, '===', assert.strictEqual);
|
||||
}
|
||||
};
|
||||
|
||||
// 10. The strict non-equality assertion tests for strict inequality, as
|
||||
// determined by !==. assert.notStrictEqual(actual, expected, message_opt);
|
||||
|
||||
assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
|
||||
if (actual === expected) {
|
||||
fail(actual, expected, message, '!==', assert.notStrictEqual);
|
||||
}
|
||||
};
|
||||
|
||||
function expectedException(actual, expected) {
|
||||
if (!actual || !expected) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (expected instanceof RegExp) {
|
||||
return expected.test(actual);
|
||||
} else if (actual instanceof expected) {
|
||||
return true;
|
||||
} else if (expected.call({}, actual) === true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function _throws(shouldThrow, block, expected, message) {
|
||||
var actual;
|
||||
|
||||
if (typeof expected === 'string') {
|
||||
message = expected;
|
||||
expected = null;
|
||||
}
|
||||
|
||||
try {
|
||||
block();
|
||||
} catch (e) {
|
||||
actual = e;
|
||||
}
|
||||
|
||||
message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
|
||||
(message ? ' ' + message : '.');
|
||||
|
||||
if (shouldThrow && !actual) {
|
||||
fail('Missing expected exception' + message);
|
||||
}
|
||||
|
||||
if (!shouldThrow && expectedException(actual, expected)) {
|
||||
fail('Got unwanted exception' + message);
|
||||
}
|
||||
|
||||
if ((shouldThrow && actual && expected &&
|
||||
!expectedException(actual, expected)) || (!shouldThrow && actual)) {
|
||||
throw actual;
|
||||
}
|
||||
}
|
||||
|
||||
// 11. Expected to throw an error:
|
||||
// assert.throws(block, Error_opt, message_opt);
|
||||
|
||||
assert.throws = function(block, /*optional*/error, /*optional*/message) {
|
||||
_throws.apply(this, [true].concat(pSlice.call(arguments)));
|
||||
};
|
||||
|
||||
// EXTENSION! This is annoying to write outside this module.
|
||||
assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
|
||||
_throws.apply(this, [false].concat(pSlice.call(arguments)));
|
||||
};
|
||||
|
||||
assert.ifError = function(err) { if (err) {throw err;}};
|
||||
|
||||
});
|
||||
489
lib/ace/test/asyncjs/async.js
Normal file
489
lib/ace/test/asyncjs/async.js
Normal file
|
|
@ -0,0 +1,489 @@
|
|||
/*!
|
||||
* async.js
|
||||
* Copyright(c) 2010 Fabian Jakobs <fabian.jakobs@web.de>
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
define(function(require, exports, module) {
|
||||
|
||||
var STOP = exports.STOP = {}
|
||||
|
||||
exports.Generator = function(source) {
|
||||
if (typeof source == "function")
|
||||
this.source = {
|
||||
next: source
|
||||
}
|
||||
else
|
||||
this.source = source
|
||||
}
|
||||
|
||||
;(function() {
|
||||
this.next = function(callback) {
|
||||
this.source.next(callback)
|
||||
}
|
||||
|
||||
this.map = function(mapper) {
|
||||
if (!mapper)
|
||||
return this
|
||||
|
||||
mapper = makeAsync(1, mapper)
|
||||
|
||||
var source = this.source
|
||||
this.next = function(callback) {
|
||||
source.next(function(err, value) {
|
||||
if (err)
|
||||
callback(err)
|
||||
else {
|
||||
mapper(value, function(err, value) {
|
||||
if (err)
|
||||
callback(err)
|
||||
else
|
||||
callback(null, value)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
return new this.constructor(this)
|
||||
}
|
||||
|
||||
this.filter = function(filter) {
|
||||
if (!filter)
|
||||
return this
|
||||
|
||||
filter = makeAsync(1, filter)
|
||||
|
||||
var source = this.source
|
||||
this.next = function(callback) {
|
||||
source.next(function handler(err, value) {
|
||||
if (err)
|
||||
callback(err)
|
||||
else {
|
||||
filter(value, function(err, takeIt) {
|
||||
if (err)
|
||||
callback(err)
|
||||
else if (takeIt)
|
||||
callback(null, value)
|
||||
else
|
||||
source.next(handler)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
return new this.constructor(this)
|
||||
}
|
||||
|
||||
this.slice = function(begin, end) {
|
||||
var count = -1
|
||||
if (!end || end < 0)
|
||||
var end = Infinity
|
||||
|
||||
var source = this.source
|
||||
this.next = function(callback) {
|
||||
source.next(function handler(err, value) {
|
||||
count++
|
||||
if (err)
|
||||
callback(err)
|
||||
else if (count >= begin && count < end)
|
||||
callback(null, value)
|
||||
else if (count >= end)
|
||||
callback(STOP)
|
||||
else
|
||||
source.next(handler)
|
||||
})
|
||||
}
|
||||
return new this.constructor(this)
|
||||
}
|
||||
|
||||
this.reduce = function(reduce, initialValue) {
|
||||
reduce = makeAsync(3, reduce)
|
||||
|
||||
var index = 0
|
||||
var done = false
|
||||
var previousValue = initialValue
|
||||
|
||||
var source = this.source
|
||||
this.next = function(callback) {
|
||||
if (done)
|
||||
return callback(STOP)
|
||||
|
||||
if (initialValue === undefined) {
|
||||
source.next(function(err, currentValue) {
|
||||
if (err)
|
||||
return callback(err, previousValue)
|
||||
|
||||
previousValue = currentValue
|
||||
reduceAll()
|
||||
})
|
||||
}
|
||||
else
|
||||
reduceAll()
|
||||
|
||||
function reduceAll() {
|
||||
source.next(function handler(err, currentValue) {
|
||||
if (err) {
|
||||
done = true
|
||||
if (err == STOP)
|
||||
return callback(null, previousValue)
|
||||
else
|
||||
return(err)
|
||||
}
|
||||
reduce(previousValue, currentValue, index++, function(err, value) {
|
||||
previousValue = value
|
||||
source.next(handler)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
return new this.constructor(this)
|
||||
}
|
||||
|
||||
this.forEach =
|
||||
this.each = function(fn) {
|
||||
fn = makeAsync(1, fn)
|
||||
|
||||
var source = this.source
|
||||
this.next = function(callback) {
|
||||
source.next(function handler(err, value) {
|
||||
if (err)
|
||||
callback(err)
|
||||
else {
|
||||
fn(value, function(err) {
|
||||
callback(err, value)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
return new this.constructor(this)
|
||||
}
|
||||
|
||||
this.some = function(condition) {
|
||||
condition = makeAsync(1, condition)
|
||||
|
||||
var source = this.source
|
||||
var done = false
|
||||
this.next = function(callback) {
|
||||
if (done)
|
||||
return callback(STOP)
|
||||
|
||||
source.next(function handler(err, value) {
|
||||
if (err)
|
||||
return callback(err)
|
||||
|
||||
condition(value, function(err, result) {
|
||||
if (err) {
|
||||
done = true
|
||||
if (err == STOP)
|
||||
callback(null, false)
|
||||
else
|
||||
callback(err)
|
||||
}
|
||||
else if (result) {
|
||||
done = true
|
||||
callback(null, true)
|
||||
}
|
||||
else
|
||||
source.next(handler)
|
||||
})
|
||||
})
|
||||
}
|
||||
return new this.constructor(this)
|
||||
}
|
||||
|
||||
this.every = function(condition) {
|
||||
condition = makeAsync(1, condition)
|
||||
|
||||
var source = this.source
|
||||
var done = false
|
||||
this.next = function(callback) {
|
||||
if (done)
|
||||
return callback(STOP)
|
||||
|
||||
source.next(function handler(err, value) {
|
||||
if (err)
|
||||
return callback(err)
|
||||
|
||||
condition(value, function(err, result) {
|
||||
if (err) {
|
||||
done = true
|
||||
if (err == STOP)
|
||||
callback(null, true)
|
||||
else
|
||||
callback(err)
|
||||
}
|
||||
else if (!result) {
|
||||
done = true
|
||||
callback(null, false)
|
||||
}
|
||||
else
|
||||
source.next(handler)
|
||||
})
|
||||
})
|
||||
}
|
||||
return new this.constructor(this)
|
||||
}
|
||||
|
||||
this.call = function(context) {
|
||||
var source = this.source
|
||||
return this.map(function(fn, next) {
|
||||
fn = makeAsync(0, fn, context)
|
||||
fn.call(context, function(err, value) {
|
||||
next(err, value)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
this.concat = function(generator) {
|
||||
var generators = [this]
|
||||
generators.push.apply(generators, arguments)
|
||||
var index = 0
|
||||
var source = generators[index++]
|
||||
|
||||
return new this.constructor(function(callback) {
|
||||
source.next(function handler(err, value) {
|
||||
if (err) {
|
||||
if (err == STOP) {
|
||||
source = generators[index++]
|
||||
if (!source)
|
||||
return callback(STOP)
|
||||
else
|
||||
return source.next(handler)
|
||||
}
|
||||
else
|
||||
return callback(err)
|
||||
}
|
||||
else
|
||||
return callback(null, value)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
this.zip = function(generator) {
|
||||
var generators = [this]
|
||||
generators.push.apply(generators, arguments)
|
||||
|
||||
return new this.constructor(function(callback) {
|
||||
exports.list(generators)
|
||||
.map(function(gen, next) {
|
||||
gen.next(next)
|
||||
})
|
||||
.toArray(callback)
|
||||
})
|
||||
}
|
||||
|
||||
this.sort = function(compare) {
|
||||
var self = this
|
||||
var arrGen
|
||||
this.next = function(callback) {
|
||||
if (arrGen)
|
||||
return arrGen.next(callback)
|
||||
|
||||
self.toArray(function(err, arr) {
|
||||
if (err)
|
||||
callback(err)
|
||||
else {
|
||||
arrGen = exports.list(arr.sort(compare))
|
||||
arrGen.next(callback)
|
||||
}
|
||||
})
|
||||
}
|
||||
return new this.constructor(this)
|
||||
}
|
||||
|
||||
this.join = function(separator) {
|
||||
return this.$arrayOp(Array.prototype.join, separator !== undefined ? [separator] : null)
|
||||
}
|
||||
|
||||
this.reverse = function() {
|
||||
return this.$arrayOp(Array.prototype.reverse)
|
||||
}
|
||||
|
||||
this.$arrayOp = function(arrayMethod, args) {
|
||||
var self = this
|
||||
var i = 0
|
||||
this.next = function(callback) {
|
||||
if (i++ > 0)
|
||||
return callback(STOP)
|
||||
|
||||
self.toArray(function(err, arr) {
|
||||
if (err)
|
||||
callback(err, "")
|
||||
else {
|
||||
if (args)
|
||||
callback(null, arrayMethod.apply(arr, args))
|
||||
else
|
||||
callback(null, arrayMethod.call(arr))
|
||||
}
|
||||
})
|
||||
}
|
||||
return new this.constructor(this)
|
||||
|
||||
}
|
||||
|
||||
this.end = function(breakOnError, callback) {
|
||||
if (!callback) {
|
||||
callback = arguments[0]
|
||||
breakOnError = true
|
||||
}
|
||||
|
||||
var source = this.source
|
||||
var last
|
||||
var lastError
|
||||
source.next(function handler(err, value) {
|
||||
if (err) {
|
||||
if (err == STOP)
|
||||
callback && callback(lastError, last)
|
||||
else if (!breakOnError) {
|
||||
lastError = err
|
||||
source.next(handler)
|
||||
}
|
||||
else
|
||||
callback && callback(err, value)
|
||||
}
|
||||
else {
|
||||
last = value
|
||||
source.next(handler)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.toArray = function(breakOnError, callback) {
|
||||
if (!callback) {
|
||||
callback = arguments[0]
|
||||
breakOnError = true
|
||||
}
|
||||
|
||||
var values = []
|
||||
var errors = []
|
||||
var source = this.source
|
||||
|
||||
source.next(function handler(err, value) {
|
||||
if (err) {
|
||||
if (err == STOP) {
|
||||
if (breakOnError)
|
||||
return callback(null, values)
|
||||
else {
|
||||
errors.length = values.length
|
||||
return callback(errors, values)
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (breakOnError)
|
||||
return callback(err)
|
||||
else
|
||||
errors[values.length] = err
|
||||
}
|
||||
}
|
||||
|
||||
values.push(value)
|
||||
source.next(handler)
|
||||
})
|
||||
}
|
||||
|
||||
}).call(exports.Generator.prototype)
|
||||
|
||||
var makeAsync = exports.makeAsync = function(args, fn, context) {
|
||||
if (fn.length > args)
|
||||
return fn
|
||||
else {
|
||||
return function() {
|
||||
var value
|
||||
var next = arguments[args]
|
||||
try {
|
||||
value = fn.apply(context || this, arguments)
|
||||
} catch(e) {
|
||||
return next(e)
|
||||
}
|
||||
next(null, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports.list = function(arr, construct) {
|
||||
var construct = construct || exports.Generator
|
||||
var i = 0
|
||||
var len = arr.length
|
||||
|
||||
return new construct(function(callback) {
|
||||
if (i < len)
|
||||
callback(null, arr[i++])
|
||||
else
|
||||
callback(STOP)
|
||||
})
|
||||
}
|
||||
|
||||
exports.values = function(map, construct) {
|
||||
var values = []
|
||||
for (var key in map)
|
||||
values.push(map[key])
|
||||
|
||||
return exports.list(values, construct)
|
||||
}
|
||||
|
||||
exports.keys = function(map, construct) {
|
||||
var keys = []
|
||||
for (var key in map)
|
||||
keys.push(key)
|
||||
|
||||
return exports.list(keys, construct)
|
||||
}
|
||||
|
||||
/**
|
||||
* range([start,] stop[, step]) -> generator of integers
|
||||
*
|
||||
* Return a generator containing an arithmetic progression of integers.
|
||||
* range(i, j) returns [i, i+1, i+2, ..., j-1] start (!) defaults to 0.
|
||||
* When step is given, it specifies the increment (or decrement).
|
||||
*/
|
||||
exports.range = function(start, stop, step, construct) {
|
||||
var construct = construct || exports.Generator
|
||||
start = start || 0
|
||||
step = step || 1
|
||||
|
||||
if (stop === undefined || stop === null)
|
||||
stop = step > 0 ? Infinity : -Infinity
|
||||
|
||||
var value = start
|
||||
|
||||
return new construct(function(callback) {
|
||||
if (step > 0 && value >= stop || step < 0 && value <= stop)
|
||||
callback(STOP)
|
||||
else {
|
||||
var current = value
|
||||
value += step
|
||||
callback(null, current)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
exports.concat = function(first, varargs) {
|
||||
if (arguments.length > 1)
|
||||
return first.concat.apply(first, Array.prototype.slice.call(arguments, 1))
|
||||
else
|
||||
return first
|
||||
}
|
||||
|
||||
exports.zip = function(first, varargs) {
|
||||
if (arguments.length > 1)
|
||||
return first.zip.apply(first, Array.prototype.slice.call(arguments, 1))
|
||||
else
|
||||
return first.map(function(item, next) {
|
||||
next(null, [item])
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
exports.plugin = function(members, constructors) {
|
||||
if (members) {
|
||||
for (var key in members) {
|
||||
exports.Generator.prototype[key] = members[key]
|
||||
}
|
||||
}
|
||||
|
||||
if (constructors) {
|
||||
for (var key in constructors) {
|
||||
exports[key] = constructors[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
12
lib/ace/test/asyncjs/index.js
Normal file
12
lib/ace/test/asyncjs/index.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*!
|
||||
* async.js
|
||||
* Copyright(c) 2010 Fabian Jakobs <fabian.jakobs@web.de>
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
define(function(require, exports, module) {
|
||||
|
||||
module.exports = require("./async")
|
||||
require("./utils")
|
||||
|
||||
})
|
||||
195
lib/ace/test/asyncjs/test.js
Normal file
195
lib/ace/test/asyncjs/test.js
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
/*!
|
||||
* async.js
|
||||
* Copyright(c) 2010 Fabian Jakobs <fabian.jakobs@web.de>
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
define(function(require, exports, module) {
|
||||
|
||||
var oop = require("pilot/oop")
|
||||
var async = require("asyncjs/async")
|
||||
require("asyncjs/utils")
|
||||
|
||||
exports.TestGenerator = function(source) {
|
||||
async.Generator.call(this, source)
|
||||
}
|
||||
|
||||
oop.inherits(exports.TestGenerator, async.Generator)
|
||||
|
||||
;(function() {
|
||||
|
||||
this.exec = function() {
|
||||
this.run().report().summary(function(err, passed) {
|
||||
console.log("DONE")
|
||||
})
|
||||
}
|
||||
|
||||
this.run = function() {
|
||||
return this.setupTest()
|
||||
.each(function(test, next) {
|
||||
if (test.setUpSuite)
|
||||
test.setUpSuite(next)
|
||||
else
|
||||
next()
|
||||
})
|
||||
.each(function(test, next) {
|
||||
test.test(function(err, passed) {
|
||||
test.err = err
|
||||
test.passed = passed
|
||||
next()
|
||||
})
|
||||
})
|
||||
.each(function(test, next) {
|
||||
if (test.tearDownSuite)
|
||||
test.tearDownSuite(next)
|
||||
else
|
||||
next()
|
||||
})
|
||||
}
|
||||
|
||||
this.report = function() {
|
||||
return this.each(function(test, next) {
|
||||
var color = test.passed ? "\x1b[32m" : "\x1b[31m"
|
||||
var name = test.name
|
||||
if (test.suiteName)
|
||||
name = test.suiteName + ": " + test.name
|
||||
console.log(color + "[" + test.count + "/" + test.index + "] " + name + " " + (test.passed ? "OK" : "FAIL") + "\x1b[0m")
|
||||
if (!test.passed)
|
||||
if (test.err.stack)
|
||||
console.log(test.err.stack)
|
||||
else
|
||||
console.log(test.err)
|
||||
|
||||
next()
|
||||
})
|
||||
}
|
||||
|
||||
this.summary = function(callback) {
|
||||
var passed = 0
|
||||
var failed = 0
|
||||
|
||||
this.each(function(test) {
|
||||
if (test.passed)
|
||||
passed += 1
|
||||
else
|
||||
failed += 1
|
||||
}).end(function() {
|
||||
console.log("")
|
||||
console.log("Summary:")
|
||||
console.log("")
|
||||
console.log( "Total number of tests: " + (passed + failed))
|
||||
passed && console.log("\x1b[32mPassed tests: " + passed + "\x1b[0m")
|
||||
failed && console.log("\x1b[31mFailed tests: " + failed + "\x1b[0m")
|
||||
console.log("")
|
||||
callback(null, failed == 0)
|
||||
})
|
||||
}
|
||||
|
||||
this.setupTest = function() {
|
||||
return this.each(function(test, next) {
|
||||
var empty = function(next) { next() }
|
||||
var context = test.context || this
|
||||
|
||||
if (test.setUp)
|
||||
var setUp = async.makeAsync(0, test.setUp, context)
|
||||
else
|
||||
setUp = empty
|
||||
|
||||
tearDownCalled = false
|
||||
if (test.tearDown)
|
||||
var tearDownInner = async.makeAsync(0, test.tearDown, context)
|
||||
else
|
||||
tearDownInner = empty
|
||||
|
||||
function tearDown(next) {
|
||||
tearDownCalled = true
|
||||
tearDownInner.call(test.context, next)
|
||||
}
|
||||
|
||||
var testFn = async.makeAsync(0, test.fn, context)
|
||||
|
||||
test.test = function(callback) {
|
||||
var called
|
||||
function errorListener(e) {
|
||||
if (called)
|
||||
return
|
||||
called = true
|
||||
//process.removeListener('uncaughtException', errorListener)
|
||||
if (!tearDownCalled) {
|
||||
async.list([tearDown])
|
||||
.call()
|
||||
.timeout(test.timeout)
|
||||
.end(function() {
|
||||
callback(e, false)
|
||||
}) }
|
||||
else
|
||||
callback(e, false)
|
||||
}
|
||||
//process.addListener('uncaughtException', errorListener)
|
||||
|
||||
async.list([setUp, testFn, tearDown])
|
||||
.delay(0)
|
||||
.call(context)
|
||||
.timeout(test.timeout)
|
||||
.toArray(false, function(errors, values) {
|
||||
if (called)
|
||||
return
|
||||
called = true
|
||||
var err = errors[1]
|
||||
//process.removeListener('uncaughtException', errorListener)
|
||||
callback(err, !err)
|
||||
})
|
||||
}
|
||||
|
||||
next()
|
||||
})
|
||||
}
|
||||
|
||||
}).call(exports.TestGenerator.prototype)
|
||||
|
||||
exports.testcase = function(testcase, suiteName, timeout) {
|
||||
var methods = []
|
||||
for (var method in testcase)
|
||||
methods.push(method)
|
||||
|
||||
var setUp = testcase.setUp || null
|
||||
var tearDown = testcase.tearDown || null
|
||||
|
||||
var single
|
||||
methods.forEach(function(name) {
|
||||
if (name.charAt(0) == '>')
|
||||
single = name
|
||||
})
|
||||
if (single)
|
||||
methods = [single]
|
||||
|
||||
var testNames = methods.filter(function(method) {
|
||||
return method.match(/^>?test/) && typeof(testcase[method]) == "function"
|
||||
})
|
||||
var count = testNames.length
|
||||
var i=1
|
||||
tests = testNames.map(function(name) {
|
||||
return {
|
||||
suiteName: suiteName || testcase.name || "",
|
||||
name: name,
|
||||
setUp: setUp,
|
||||
tearDown: tearDown,
|
||||
context: testcase,
|
||||
timeout: timeout === undefined ? 3000 : timeout,
|
||||
fn: testcase[name],
|
||||
count: count,
|
||||
index: i++
|
||||
}
|
||||
})
|
||||
|
||||
if (testcase.setUpSuite) {
|
||||
tests[0].setUpSuite = async.makeAsync(0, testcase.setUpSuite, testcase)
|
||||
}
|
||||
if (testcase.tearDownSuite) {
|
||||
tests[tests.length-1].tearDownSuite = async.makeAsync(0, testcase.tearDownSuite, testcase)
|
||||
}
|
||||
|
||||
return async.list(tests, exports.TestGenerator)
|
||||
}
|
||||
|
||||
})
|
||||
63
lib/ace/test/asyncjs/utils.js
Normal file
63
lib/ace/test/asyncjs/utils.js
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/*!
|
||||
* async.js
|
||||
* Copyright(c) 2010 Fabian Jakobs <fabian.jakobs@web.de>
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
define(function(require, exports, module) {
|
||||
|
||||
var async = require("asyncjs/async")
|
||||
|
||||
async.plugin({
|
||||
delay: function(delay) {
|
||||
return this.each(function(item, next) {
|
||||
setTimeout(next, delay)
|
||||
})
|
||||
},
|
||||
|
||||
timeout: function(timeout) {
|
||||
timeout = timeout || 0
|
||||
var source = this.source
|
||||
|
||||
this.next = function(callback) {
|
||||
var called
|
||||
var id = setTimeout(function() {
|
||||
called = true
|
||||
callback("Source did not respond after " + timeout + "ms!")
|
||||
}, timeout)
|
||||
|
||||
source.next(function(err, value) {
|
||||
if (called)
|
||||
return
|
||||
|
||||
called = true
|
||||
clearTimeout(id)
|
||||
|
||||
callback(err, value)
|
||||
})
|
||||
}
|
||||
return new this.constructor(this)
|
||||
},
|
||||
|
||||
get: function(key) {
|
||||
return this.map(function(value, next) {
|
||||
next(null, value[key])
|
||||
})
|
||||
},
|
||||
|
||||
inspect: function() {
|
||||
return this.each(function(item, next) {
|
||||
console.log(JSON.stringify(item))
|
||||
next()
|
||||
})
|
||||
},
|
||||
|
||||
print: function() {
|
||||
return this.each(function(item, next) {
|
||||
console.log(item)
|
||||
next()
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
|
|
@ -37,8 +37,6 @@
|
|||
|
||||
define(function(require, exports, module) {
|
||||
|
||||
require("./mockdom");
|
||||
|
||||
var EditSession = require("../edit_session").EditSession,
|
||||
Editor = require("../editor").Editor,
|
||||
Text = require("../mode/text").Mode,
|
||||
|
|
@ -158,7 +156,7 @@ var Test = {
|
|||
module.exports = require("asyncjs/test").testcase(Test);
|
||||
});
|
||||
|
||||
if (module === require.main) {
|
||||
if (typeof module !== "undefined" && module === require.main) {
|
||||
require("../../../support/paths");
|
||||
exports.exec()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
define(function(require, exports, module) {
|
||||
|
||||
var Document = require("../document").Document,
|
||||
Range = require("../range").Range,
|
||||
assert = require("./assertions"),
|
||||
|
|
@ -302,7 +304,9 @@ var Test = {
|
|||
|
||||
module.exports = require("asyncjs/test").testcase(Test);
|
||||
|
||||
if (module === require.main) {
|
||||
});
|
||||
|
||||
if (typeof module !== "undefined" && module === require.main) {
|
||||
require("../../../support/paths");
|
||||
exports.exec()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,8 +37,6 @@
|
|||
|
||||
define(function(require, exports, module) {
|
||||
|
||||
require("./mockdom");
|
||||
|
||||
var EditSession = require("ace/edit_session").EditSession,
|
||||
Editor = require("../editor").Editor,
|
||||
UndoManager = require("ace/undomanager").UndoManager,
|
||||
|
|
@ -236,7 +234,7 @@ var Test = {
|
|||
wrapLimit = wrapLimit || 12;
|
||||
tabSize = tabSize || 4;
|
||||
splits = computeWrapSplits.call(EditSession.prototype, line, wrapLimit, tabSize);
|
||||
console.log("String:", line, "Result:", splits, "Expected:", assertEqual);
|
||||
// console.log("String:", line, "Result:", splits, "Expected:", assertEqual);
|
||||
assert.ok(splits.length == assertEqual.length);
|
||||
for (var i = 0; i < splits.length; i++) {
|
||||
assert.ok(splits[i] == assertEqual[i]);
|
||||
|
|
@ -333,7 +331,7 @@ var Test = {
|
|||
module.exports = require("asyncjs/test").testcase(Test);
|
||||
});
|
||||
|
||||
if (module === require.main) {
|
||||
if (typeof module !== "undefined" && module === require.main) {
|
||||
require("../../../support/paths");
|
||||
exports.exec()
|
||||
}
|
||||
|
|
@ -35,10 +35,10 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
require("../../../support/paths");
|
||||
define(function(require, exports, module) {
|
||||
|
||||
var oop = require("pilot/oop");
|
||||
EventEmitter = require("pilot/event_emitter").EventEmitter,
|
||||
EventEmitter = require("pilot/event_emitter").EventEmitter,
|
||||
assert = require("./assertions");
|
||||
|
||||
var Emitter = function() {};
|
||||
|
|
@ -61,6 +61,4 @@ var Test = {
|
|||
};
|
||||
|
||||
module.exports = require("asyncjs/test").testcase(Test)
|
||||
|
||||
if (module === require.main)
|
||||
module.exports.exec()
|
||||
});
|
||||
|
|
@ -123,7 +123,10 @@ MockRenderer.prototype.draw = function() {
|
|||
MockRenderer.prototype.updateLines = function(startRow, endRow) {
|
||||
};
|
||||
|
||||
MockRenderer.prototype.addMarker = function() {
|
||||
MockRenderer.prototype.updateBackMarkers = function() {
|
||||
};
|
||||
|
||||
MockRenderer.prototype.updateFrontMarkers = function() {
|
||||
};
|
||||
|
||||
MockRenderer.prototype.setBreakpoints = function() {
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ var Test = {
|
|||
module.exports = require("asyncjs/test").testcase(Test);
|
||||
});
|
||||
|
||||
if (module === require.main) {
|
||||
if (typeof module !== "undefined" && module === require.main) {
|
||||
require("../../../support/paths");
|
||||
exports.exec()
|
||||
}
|
||||
|
|
@ -88,7 +88,7 @@ module.exports = require("asyncjs/test").testcase(Test, "css tokenizer");
|
|||
|
||||
});
|
||||
|
||||
if (module === require.main) {
|
||||
if (typeof module !== "undefined" && module === require.main) {
|
||||
require("../../../support/paths");
|
||||
exports.exec()
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@ var Test = {
|
|||
module.exports = require("asyncjs/test").testcase(Test);
|
||||
});
|
||||
|
||||
if (module === require.main) {
|
||||
if (typeof module !== "undefined" && module === require.main) {
|
||||
require("../../../support/paths");
|
||||
exports.exec()
|
||||
exports.exec();
|
||||
}
|
||||
|
|
@ -68,7 +68,7 @@ var Test = {
|
|||
module.exports = require("asyncjs/test").testcase(Test);
|
||||
});
|
||||
|
||||
if (module === require.main) {
|
||||
if (typeof module !== "undefined" && module === require.main) {
|
||||
require("../../../support/paths");
|
||||
exports.exec()
|
||||
exports.exec();
|
||||
}
|
||||
|
|
@ -147,7 +147,7 @@ var Test = {
|
|||
module.exports = require("asyncjs/test").testcase(Test);
|
||||
});
|
||||
|
||||
if (module === require.main) {
|
||||
if (typeof module !== "undefined" && module === require.main) {
|
||||
require("../../../support/paths");
|
||||
exports.exec()
|
||||
exports.exec();
|
||||
}
|
||||
|
|
@ -104,7 +104,7 @@ var Test = {
|
|||
module.exports = require("asyncjs/test").testcase(Test);
|
||||
});
|
||||
|
||||
if (module === require.main) {
|
||||
if (typeof module !== "undefined" && module === require.main) {
|
||||
require("../../../support/paths");
|
||||
exports.exec()
|
||||
exports.exec();
|
||||
}
|
||||
|
|
@ -62,7 +62,7 @@ var Test = {
|
|||
module.exports = require("asyncjs/test").testcase(Test);
|
||||
});
|
||||
|
||||
if (module === require.main) {
|
||||
if (typeof module !== "undefined" && module === require.main) {
|
||||
require("../../../support/paths");
|
||||
exports.exec()
|
||||
exports.exec();
|
||||
}
|
||||
|
|
@ -73,7 +73,7 @@ var Test = {
|
|||
module.exports = require("asyncjs/test").testcase(Test);
|
||||
});
|
||||
|
||||
if (module === require.main) {
|
||||
if (typeof module !== "undefined" && module === require.main) {
|
||||
require("../../../support/paths");
|
||||
exports.exec()
|
||||
exports.exec();
|
||||
}
|
||||
|
|
@ -63,7 +63,7 @@ var Test = {
|
|||
module.exports = require("asyncjs/test").testcase(Test);
|
||||
});
|
||||
|
||||
if (module === require.main) {
|
||||
if (typeof module !== "undefined" && module === require.main) {
|
||||
require("../../../support/paths");
|
||||
exports.exec()
|
||||
exports.exec();
|
||||
}
|
||||
|
|
@ -37,8 +37,6 @@
|
|||
|
||||
define(function(require, exports, module) {
|
||||
|
||||
require("./mockdom");
|
||||
|
||||
var EditSession = require("ace/edit_session").EditSession,
|
||||
Editor = require("../editor").Editor,
|
||||
MockRenderer = require("./mockrenderer"),
|
||||
|
|
@ -153,7 +151,7 @@ var Test = {
|
|||
module.exports = require("asyncjs/test").testcase(Test)
|
||||
});
|
||||
|
||||
if (module === require.main) {
|
||||
if (typeof module !== "undefined" && module === require.main) {
|
||||
require("../../../support/paths");
|
||||
exports.exec()
|
||||
exports.exec();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ var Test = {
|
|||
module.exports = require("asyncjs/test").testcase(Test);
|
||||
});
|
||||
|
||||
if (module === require.main) {
|
||||
if (typeof module !== "undefined" && module === require.main) {
|
||||
require("../../../support/paths");
|
||||
exports.exec()
|
||||
exports.exec();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -347,7 +347,7 @@ var Test = {
|
|||
module.exports = require("asyncjs/test").testcase(Test)
|
||||
});
|
||||
|
||||
if (module === require.main) {
|
||||
if (typeof module !== "undefined" && module === require.main) {
|
||||
require("../../../support/paths");
|
||||
exports.exec()
|
||||
exports.exec();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -293,7 +293,7 @@ var Test = {
|
|||
module.exports = require("asyncjs/test").testcase(Test);
|
||||
});
|
||||
|
||||
if (module === require.main) {
|
||||
if (typeof module !== "undefined" && module === require.main) {
|
||||
require("../../../support/paths");
|
||||
exports.exec()
|
||||
}
|
||||
|
|
|
|||
54
lib/ace/test/tests.html
Normal file
54
lib/ace/test/tests.html
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<title>Ace Unit Tests</title>
|
||||
<style type="text/css" media="screen">
|
||||
|
||||
#log .passed {
|
||||
color: green;
|
||||
}
|
||||
|
||||
#log .failed {
|
||||
color: red;
|
||||
}
|
||||
|
||||
#log pre.error {
|
||||
color: black;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="log"></div>
|
||||
|
||||
<script src="../../../demo/require.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script>
|
||||
|
||||
require({
|
||||
paths: {
|
||||
ace: "../lib/ace",
|
||||
cockpit: "../support/cockpit/lib/cockpit",
|
||||
pilot: "../support/pilot/lib/pilot"
|
||||
},
|
||||
packages : [{
|
||||
name: "asyncjs",
|
||||
location: "../lib/ace/test",
|
||||
lib: "asyncjs",
|
||||
main: "index"
|
||||
}, {
|
||||
name: "assert",
|
||||
location: "../lib/ace/test",
|
||||
lib: "asyncjs",
|
||||
main: "assert"
|
||||
}]
|
||||
});
|
||||
|
||||
require(["ace/test/all_browser"], function(tests) {
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -36,7 +36,6 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
define(function(require, exports, module) {
|
||||
require("./mockdom");
|
||||
|
||||
var EditSession = require("ace/edit_session").EditSession,
|
||||
Editor = require("../editor").Editor,
|
||||
|
|
@ -435,13 +434,63 @@ var Test = {
|
|||
editor.moveCursorTo(1, 8);
|
||||
editor.removeLeft();
|
||||
assert.equal(session.toString(), "123\n 456");
|
||||
},
|
||||
|
||||
"test: transpose at line start should be a noop": function() {
|
||||
var session = new EditSession(["123", "4567", "89"]);
|
||||
|
||||
var editor = new Editor(new MockRenderer(), session);
|
||||
editor.moveCursorTo(1, 0);
|
||||
editor.transposeLetters();
|
||||
|
||||
assert.equal(session.getValue(), ["123", "4567", "89"].join("\n"));
|
||||
},
|
||||
|
||||
"test: transpose in line should swap the charaters before and after the cursor": function() {
|
||||
var session = new EditSession(["123", "4567", "89"]);
|
||||
|
||||
var editor = new Editor(new MockRenderer(), session);
|
||||
editor.moveCursorTo(1, 2);
|
||||
editor.transposeLetters();
|
||||
|
||||
assert.equal(session.getValue(), ["123", "4657", "89"].join("\n"));
|
||||
},
|
||||
|
||||
"test: transpose at line end should swap the last two characters": function() {
|
||||
var session = new EditSession(["123", "4567", "89"]);
|
||||
|
||||
var editor = new Editor(new MockRenderer(), session);
|
||||
editor.moveCursorTo(1, 4);
|
||||
editor.transposeLetters();
|
||||
|
||||
assert.equal(session.getValue(), ["123", "4576", "89"].join("\n"));
|
||||
},
|
||||
|
||||
"test: transpose with non empty selection should be a noop": function() {
|
||||
var session = new EditSession(["123", "4567", "89"]);
|
||||
|
||||
var editor = new Editor(new MockRenderer(), session);
|
||||
editor.moveCursorTo(1, 1);
|
||||
editor.getSelection().selectRight();
|
||||
editor.transposeLetters();
|
||||
|
||||
assert.equal(session.getValue(), ["123", "4567", "89"].join("\n"));
|
||||
},
|
||||
|
||||
"test: transpose should move the cursor behind the last swapped character": function() {
|
||||
var session = new EditSession(["123", "4567", "89"]);
|
||||
|
||||
var editor = new Editor(new MockRenderer(), session);
|
||||
editor.moveCursorTo(1, 2);
|
||||
editor.transposeLetters();
|
||||
assert.position(editor.getCursorPosition(), 1, 3);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = require("asyncjs/test").testcase(Test);
|
||||
});
|
||||
|
||||
if (module === require.main) {
|
||||
if (typeof module !== "undefined" && module === require.main) {
|
||||
require("../../../support/paths");
|
||||
exports.exec()
|
||||
exports.exec();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
define(function(require, exports, module) {
|
||||
require("./mockdom");
|
||||
|
||||
var EditSession = require("ace/edit_session").EditSession,
|
||||
VirtualRenderer = require("../virtual_renderer").VirtualRenderer,
|
||||
|
|
@ -75,7 +74,7 @@ var Test = {
|
|||
module.exports = require("asyncjs/test").testcase(Test);
|
||||
});
|
||||
|
||||
if (module === require.main) {
|
||||
if (typeof module !== "undefined" && module === require.main) {
|
||||
require("../../../support/paths");
|
||||
exports.exec()
|
||||
exports.exec();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ var Tokenizer = function(rules) {
|
|||
var value = match[0];
|
||||
|
||||
for ( var i = 0; i < state.length; i++) {
|
||||
if (match[i + 1] !== undefined) {
|
||||
if (match[i + 1]) {
|
||||
if (typeof state[i].token == "function") {
|
||||
type = state[i].token(match[0]);
|
||||
}
|
||||
|
|
@ -109,10 +109,10 @@ var Tokenizer = function(rules) {
|
|||
}
|
||||
|
||||
if (lastIndex == line.length) {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
lastIndex = re.lastIndex;
|
||||
lastIndex = re.lastIndex;
|
||||
};
|
||||
|
||||
if (token.type) {
|
||||
|
|
|
|||
|
|
@ -75,19 +75,19 @@ var VirtualRenderer = function(container, theme) {
|
|||
this.scroller.appendChild(this.content);
|
||||
|
||||
this.$gutterLayer = new GutterLayer(this.$gutter);
|
||||
this.$markerLayer = new MarkerLayer(this.content);
|
||||
this.$markerBack = new MarkerLayer(this.content);
|
||||
|
||||
var textLayer = this.$textLayer = new TextLayer(this.content);
|
||||
this.canvas = textLayer.element;
|
||||
|
||||
this.$markerFront = new MarkerLayer(this.content);
|
||||
|
||||
this.characterWidth = textLayer.getCharacterWidth();
|
||||
this.lineHeight = textLayer.getLineHeight();
|
||||
|
||||
this.$cursorLayer = new CursorLayer(this.content);
|
||||
this.$cursorPadding = 8;
|
||||
|
||||
this.layers = [ this.$markerLayer, textLayer, this.$cursorLayer ];
|
||||
|
||||
this.scrollBar = new ScrollBar(container);
|
||||
this.scrollBar.addEventListener("scroll", this.onScroll.bind(this));
|
||||
|
||||
|
|
@ -133,14 +133,17 @@ var VirtualRenderer = function(container, theme) {
|
|||
this.CHANGE_LINES = 16;
|
||||
this.CHANGE_TEXT = 32;
|
||||
this.CHANGE_SIZE = 64;
|
||||
this.CHANGE_FULL = 128;
|
||||
this.CHANGE_MARKER_BACK = 128;
|
||||
this.CHANGE_MARKER_FRONT = 256;
|
||||
this.CHANGE_FULL = 512;
|
||||
|
||||
oop.implement(this, EventEmitter);
|
||||
|
||||
this.setSession = function(session) {
|
||||
this.session = session;
|
||||
this.$cursorLayer.setSession(session);
|
||||
this.$markerLayer.setSession(session);
|
||||
this.$markerBack.setSession(session);
|
||||
this.$markerFront.setSession(session);
|
||||
this.$gutterLayer.setSession(session);
|
||||
this.$textLayer.setSession(session);
|
||||
this.$loop.schedule(this.CHANGE_FULL);
|
||||
|
|
@ -212,7 +215,8 @@ var VirtualRenderer = function(container, theme) {
|
|||
this.scroller.style.width = Math.max(0, width - gutterWidth - this.scrollBar.getWidth()) + "px";
|
||||
|
||||
if (this.session.getUseWrapMode()) {
|
||||
var limit = Math.floor(this.scroller.clientWidth / this.characterWidth);
|
||||
var availableWidth = this.scroller.clientWidth - this.$padding * 2;
|
||||
var limit = Math.floor(availableWidth / this.characterWidth) - 1;
|
||||
if (this.session.adjustWrapLimit(limit) || force) {
|
||||
changes = changes | this.CHANGE_FULL;
|
||||
}
|
||||
|
|
@ -383,7 +387,8 @@ var VirtualRenderer = function(container, theme) {
|
|||
if (changes & this.CHANGE_FULL) {
|
||||
this.$textLayer.update(this.layerConfig);
|
||||
this.showGutter && this.$gutterLayer.update(this.layerConfig);
|
||||
this.$markerLayer.update(this.layerConfig);
|
||||
this.$markerBack.update(this.layerConfig);
|
||||
this.$markerFront.update(this.layerConfig);
|
||||
this.$cursorLayer.update(this.layerConfig);
|
||||
this.$updateScrollBar();
|
||||
this.scrollCursorIntoView();
|
||||
|
|
@ -397,7 +402,8 @@ var VirtualRenderer = function(container, theme) {
|
|||
else
|
||||
this.$textLayer.scrollLines(this.layerConfig);
|
||||
this.showGutter && this.$gutterLayer.update(this.layerConfig);
|
||||
this.$markerLayer.update(this.layerConfig);
|
||||
this.$markerBack.update(this.layerConfig);
|
||||
this.$markerFront.update(this.layerConfig);
|
||||
this.$cursorLayer.update(this.layerConfig);
|
||||
this.$updateScrollBar();
|
||||
return;
|
||||
|
|
@ -418,8 +424,12 @@ var VirtualRenderer = function(container, theme) {
|
|||
if (changes & this.CHANGE_CURSOR)
|
||||
this.$cursorLayer.update(this.layerConfig);
|
||||
|
||||
if (changes & this.CHANGE_MARKER) {
|
||||
this.$markerLayer.update(this.layerConfig);
|
||||
if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT)) {
|
||||
this.$markerFront.update(this.layerConfig);
|
||||
}
|
||||
|
||||
if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_BACK)) {
|
||||
this.$markerBack.update(this.layerConfig);
|
||||
}
|
||||
|
||||
if (changes & this.CHANGE_SIZE)
|
||||
|
|
@ -504,15 +514,14 @@ var VirtualRenderer = function(container, theme) {
|
|||
return Math.max(this.$size.scrollerWidth - this.$padding * 2, Math.round(charCount * this.characterWidth));
|
||||
};
|
||||
|
||||
this.addMarker = function(range, clazz, type) {
|
||||
var id = this.$markerLayer.addMarker(range, clazz, type);
|
||||
this.$loop.schedule(this.CHANGE_MARKER);
|
||||
return id;
|
||||
this.updateFrontMarkers = function() {
|
||||
this.$markerFront.setMarkers(this.session.getMarkers(true));
|
||||
this.$loop.schedule(this.CHANGE_MARKER_FRONT);
|
||||
};
|
||||
|
||||
this.removeMarker = function(markerId) {
|
||||
this.$markerLayer.removeMarker(markerId);
|
||||
this.$loop.schedule(this.CHANGE_MARKER);
|
||||
this.updateBackMarkers = function() {
|
||||
this.$markerBack.setMarkers(this.session.getMarkers());
|
||||
this.$loop.schedule(this.CHANGE_MARKER_BACK);
|
||||
};
|
||||
|
||||
this.addGutterDecoration = function(row, className){
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "ace",
|
||||
"description": "Ajax.org Code Editor is a full featured source code highlighting editor that powers the Cloud9 IDE",
|
||||
"version": "0.1.5",
|
||||
"version": "0.1.6",
|
||||
"homepage" : "http://github.com/ajaxorg/ace",
|
||||
"engines": {"node": ">= 0.2.0"},
|
||||
"author": "Fabian Jakobs <fabian@ajax.org>",
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit cbfac498d30d43fdb7687d198c5b752736222c2f
|
||||
Subproject commit 5d642573259ba8a77456d3fa066beb2f1b2be23a
|
||||
Loading…
Add table
Add a link
Reference in a new issue