Merge branch 'master' of github.com:ajaxorg/ace
This commit is contained in:
commit
fc01cc6242
62 changed files with 619 additions and 323 deletions
2
.gitmodules
vendored
2
.gitmodules
vendored
|
|
@ -3,4 +3,4 @@
|
|||
url = git://github.com/ajaxorg/ace.wiki.git
|
||||
[submodule "build"]
|
||||
path = build
|
||||
url = https://github.com/ajaxorg/ace-builds.git
|
||||
url = git://github.com/ajaxorg/ace-builds.git
|
||||
|
|
|
|||
|
|
@ -153,10 +153,6 @@ function ace() {
|
|||
source: ACE_HOME + "/LICENSE",
|
||||
dest: "build/LICENSE"
|
||||
});
|
||||
copy({
|
||||
source: ACE_HOME + "/Readme.md",
|
||||
dest: "build/Readme.md"
|
||||
});
|
||||
copy({
|
||||
source: ACE_HOME + "/ChangeLog.txt",
|
||||
dest: "build/ChangeLog.txt"
|
||||
|
|
|
|||
|
|
@ -25,9 +25,9 @@ Features
|
|||
Take Ace for a spin!
|
||||
--------------------
|
||||
|
||||
Check out the Ace live [demo](http://ajaxorg.github.com/ace-builds/kitchen-sink.html) or get a [Cloud9 IDE account](http://c9.io) to experience Ace while editing one of your own GitHub projects.
|
||||
Check out the Ace live [demo](http://ajaxorg.github.com/ace/build/kitchen-sink.html) or get a [Cloud9 IDE account](http://c9.io) to experience Ace while editing one of your own GitHub projects.
|
||||
|
||||
If you want, you can use Ace as a textarea replacement thanks to the [Ace Bookmarklet](http://ajaxorg.github.com/ace-builds/textarea/editor.html).
|
||||
If you want, you can use Ace as a textarea replacement thanks to the [Ace Bookmarklet](http://ajaxorg.github.com/ace/build/textarea/editor.html).
|
||||
|
||||
Getting the code
|
||||
----------------
|
||||
|
|
@ -123,7 +123,7 @@ The editor can then be opened at http://localhost:8888/kitchen-sink.html.
|
|||
Package Ace
|
||||
-----------
|
||||
|
||||
To package Ace we use the dryice build tool developed by the Mozilla Skywriter team. (see the [wiki](https://github.com/ajaxorg/ace/wiki/Building-ace) more for details)
|
||||
To package Ace we use the dryice build tool developed by the Mozilla Skywriter team. (see the [wiki](https://github.com/ajaxorg/ace/wiki/Building-ace) for more details)
|
||||
|
||||
```bash
|
||||
npm install
|
||||
|
|
|
|||
2
build
2
build
|
|
@ -1 +1 @@
|
|||
Subproject commit b5354412bfeb461b7d8020423562451a81da2c85
|
||||
Subproject commit 8f508c64856878dc43cb9d0aeb028ca34ede6f5c
|
||||
|
|
@ -169,47 +169,47 @@ function makeHuge(txt) {
|
|||
}
|
||||
|
||||
var docs = {
|
||||
"docs/c9search.c9search_results": "C9 Search Results",
|
||||
"docs/javascript.js": "JavaScript",
|
||||
"docs/plaintext.txt": {name: "Plain Text", prepare: makeHuge, wrapped: true},
|
||||
"docs/clojure.clj": "Clojure",
|
||||
"docs/coffeescript.coffee": "Coffeescript",
|
||||
"docs/json.json": "JSON",
|
||||
"docs/diff.diff": "Diff",
|
||||
"docs/css.css": "CSS",
|
||||
"docs/scss.scss": "SCSS",
|
||||
"docs/less.less": "LESS",
|
||||
"docs/html.html": "HTML",
|
||||
"docs/xml.xml": "XML",
|
||||
"docs/tcl.tcl": "Tcl",
|
||||
"docs/yaml.yaml": "YAML",
|
||||
"docs/svg.svg": "SVG",
|
||||
"docs/php.php": "PHP",
|
||||
"docs/coldfusion.cfm": "ColdFusion",
|
||||
"docs/python.py": "Python",
|
||||
"docs/ruby.rb": "Ruby",
|
||||
"docs/perl.pl": "Perl",
|
||||
"docs/ocaml.ml": "OCaml",
|
||||
"docs/OpenSCAD.scad": "OpenSCAD",
|
||||
"docs/cpp.cpp": "C/C++",
|
||||
"docs/csharp.cs": "C#",
|
||||
"docs/css.css": "CSS",
|
||||
"docs/diff.diff": "Diff",
|
||||
"docs/golang.go": "Go",
|
||||
"docs/groovy.groovy": "Groovy",
|
||||
"docs/Haxe.hx": "haXe",
|
||||
"docs/html.html": "HTML",
|
||||
"docs/java.java": "Java",
|
||||
"docs/json.json": "JSON",
|
||||
"docs/jsx.jsx": "JSX",
|
||||
"docs/latex.tex": {name: "LaTeX", wrapped: true},
|
||||
"docs/less.less": "LESS",
|
||||
"docs/liquid.liquid": "Liquid",
|
||||
"docs/lua.lua": "Lua",
|
||||
"docs/luapage.lp": "LuaPage",
|
||||
"docs/liquid.liquid": "Liquid",
|
||||
"docs/java.java": "Java",
|
||||
"docs/clojure.clj": "Clojure",
|
||||
"docs/groovy.groovy": "Groovy",
|
||||
"docs/scala.scala": "Scala",
|
||||
"docs/csharp.cs": "C#",
|
||||
"docs/powershell.ps1": "Powershell",
|
||||
"docs/cpp.cpp": "C/C++",
|
||||
"docs/Haxe.hx": "haXe",
|
||||
"docs/sh.sh": "SH",
|
||||
"docs/xquery.xq": "XQuery",
|
||||
"docs/markdown.md": {name: "Markdown", wrapped: true},
|
||||
"docs/textile.textile": {name: "Textile", wrapped: true},
|
||||
"docs/latex.tex": {name: "LaTeX", wrapped: true},
|
||||
"docs/sql.sql": {name: "SQL", wrapped: true},
|
||||
"docs/ocaml.ml": "OCaml",
|
||||
"docs/OpenSCAD.scad": "OpenSCAD",
|
||||
"docs/perl.pl": "Perl",
|
||||
"docs/pgsql.pgsql": {name: "pgSQL", wrapped: true},
|
||||
"docs/golang.go": "Go",
|
||||
"docs/jsx.jsx": "JSX"
|
||||
"docs/php.php": "PHP",
|
||||
"docs/plaintext.txt": {name: "Plain Text", prepare: makeHuge, wrapped: true},
|
||||
"docs/powershell.ps1": "Powershell",
|
||||
"docs/python.py": "Python",
|
||||
"docs/ruby.rb": "Ruby",
|
||||
"docs/scala.scala": "Scala",
|
||||
"docs/scss.scss": "SCSS",
|
||||
"docs/sh.sh": "SH",
|
||||
"docs/sql.sql": {name: "SQL", wrapped: true},
|
||||
"docs/svg.svg": "SVG",
|
||||
"docs/tcl.tcl": "Tcl",
|
||||
"docs/textile.textile": {name: "Textile", wrapped: true},
|
||||
"docs/xml.xml": "XML",
|
||||
"docs/xquery.xq": "XQuery",
|
||||
"docs/yaml.yaml": "YAML",
|
||||
"docs/c9search.c9search_results": "C9 Search Results"
|
||||
}
|
||||
|
||||
var ownSource = {
|
||||
|
|
@ -286,7 +286,7 @@ env.editor.commands.addCommands([{
|
|||
name: "gotoline",
|
||||
bindKey: {win: "Ctrl-L", mac: "Command-L"},
|
||||
exec: function(editor, line) {
|
||||
if (typeof needle == "object") {
|
||||
if (typeof line == "object") {
|
||||
var arg = this.name + " " + editor.getCursorPosition().row;
|
||||
editor.cmdLine.setValue(arg, 1)
|
||||
editor.cmdLine.focus()
|
||||
|
|
@ -328,7 +328,7 @@ cmdLine.commands.bindKeys({
|
|||
},
|
||||
})
|
||||
|
||||
cmdLine.commands.removeCommands(["find", "goToLine", "findAll", "replace", "replaceAll"])
|
||||
cmdLine.commands.removeCommands(["find", "gotoline", "findall", "replace", "replaceall"])
|
||||
|
||||
/**
|
||||
* This demonstrates how you can define commands and bind shortcuts to them.
|
||||
|
|
@ -557,6 +557,10 @@ bindCheckbox("show_hidden", function(checked) {
|
|||
env.editor.setShowInvisibles(checked);
|
||||
});
|
||||
|
||||
bindCheckbox("display_indent_guides", function(checked) {
|
||||
env.editor.setDisplayIndentGuides(checked);
|
||||
});
|
||||
|
||||
bindCheckbox("show_gutter", function(checked) {
|
||||
env.editor.renderer.setShowGutter(checked);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@
|
|||
|
||||
<h2>Take Ace for a spin!</h2>
|
||||
<div class="divider"></div>
|
||||
<p>Check out the <a href="http://ajaxorg.github.com/ace-builds/kitchen-sink.html">Ace live demo</a> or get a <a href="http://c9.io">Cloud9 IDE account</a> to experience Ace while editing one of your own GitHub projects.</p>
|
||||
<p>Check out the <a href="./build/kitchen-sink.html">Ace live demo</a> or get a <a href="http://c9.io">Cloud9 IDE account</a> to experience Ace while editing one of your own GitHub projects.</p>
|
||||
|
||||
<h2>History</h2>
|
||||
<div class="divider"></div>
|
||||
|
|
|
|||
|
|
@ -59,32 +59,36 @@
|
|||
<label for="theme">Theme</label>
|
||||
</td><td>
|
||||
<select id="theme" size="1">
|
||||
<option value="ace/theme/chrome">Chrome</option>
|
||||
<option value="ace/theme/clouds">Clouds</option>
|
||||
<option value="ace/theme/clouds_midnight">Clouds Midnight</option>
|
||||
<option value="ace/theme/cobalt">Cobalt</option>
|
||||
<option value="ace/theme/crimson_editor">Crimson Editor</option>
|
||||
<option value="ace/theme/dawn">Dawn</option>
|
||||
<option value="ace/theme/dreamweaver">Dreamweaver</option>
|
||||
<option value="ace/theme/eclipse">Eclipse</option>
|
||||
<option value="ace/theme/github">GitHub</option>
|
||||
<option value="ace/theme/idle_fingers">idleFingers</option>
|
||||
<option value="ace/theme/kr_theme">krTheme</option>
|
||||
<option value="ace/theme/merbivore">Merbivore</option>
|
||||
<option value="ace/theme/merbivore_soft">Merbivore Soft</option>
|
||||
<option value="ace/theme/mono_industrial">Mono Industrial</option>
|
||||
<option value="ace/theme/monokai">Monokai</option>
|
||||
<option value="ace/theme/pastel_on_dark">Pastel on dark</option>
|
||||
<option value="ace/theme/solarized_dark">Solarized Dark</option>
|
||||
<option value="ace/theme/solarized_light">Solarized Light</option>
|
||||
<option value="ace/theme/textmate" selected="selected">TextMate</option>
|
||||
<option value="ace/theme/twilight">Twilight</option>
|
||||
<option value="ace/theme/tomorrow">Tomorrow</option>
|
||||
<option value="ace/theme/tomorrow_night">Tomorrow Night</option>
|
||||
<option value="ace/theme/tomorrow_night_blue">Tomorrow Night Blue</option>
|
||||
<option value="ace/theme/tomorrow_night_bright">Tomorrow Night Bright</option>
|
||||
<option value="ace/theme/tomorrow_night_eighties">Tomorrow Night 80s</option>
|
||||
<option value="ace/theme/vibrant_ink">Vibrant Ink</option>
|
||||
<optgroup label="Bright">
|
||||
<option value="ace/theme/chrome">Chrome</option>
|
||||
<option value="ace/theme/clouds">Clouds</option>
|
||||
<option value="ace/theme/crimson_editor">Crimson Editor</option>
|
||||
<option value="ace/theme/dawn">Dawn</option>
|
||||
<option value="ace/theme/dreamweaver">Dreamweaver</option>
|
||||
<option value="ace/theme/eclipse">Eclipse</option>
|
||||
<option value="ace/theme/github">GitHub</option>
|
||||
<option value="ace/theme/solarized_light">Solarized Light</option>
|
||||
<option value="ace/theme/textmate" selected="selected">TextMate</option>
|
||||
<option value="ace/theme/tomorrow">Tomorrow</option>
|
||||
</optgroup>
|
||||
<optgroup label="Dark">
|
||||
<option value="ace/theme/clouds_midnight">Clouds Midnight</option>
|
||||
<option value="ace/theme/cobalt">Cobalt</option>
|
||||
<option value="ace/theme/idle_fingers">idleFingers</option>
|
||||
<option value="ace/theme/kr_theme">krTheme</option>
|
||||
<option value="ace/theme/merbivore">Merbivore</option>
|
||||
<option value="ace/theme/merbivore_soft">Merbivore Soft</option>
|
||||
<option value="ace/theme/mono_industrial">Mono Industrial</option>
|
||||
<option value="ace/theme/monokai">Monokai</option>
|
||||
<option value="ace/theme/pastel_on_dark">Pastel on dark</option>
|
||||
<option value="ace/theme/solarized_dark">Solarized Dark</option>
|
||||
<option value="ace/theme/twilight">Twilight</option>
|
||||
<option value="ace/theme/tomorrow_night">Tomorrow Night</option>
|
||||
<option value="ace/theme/tomorrow_night_blue">Tomorrow Night Blue</option>
|
||||
<option value="ace/theme/tomorrow_night_bright">Tomorrow Night Bright</option>
|
||||
<option value="ace/theme/tomorrow_night_eighties">Tomorrow Night 80s</option>
|
||||
<option value="ace/theme/vibrant_ink">Vibrant Ink</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -139,8 +143,8 @@
|
|||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td colspan="2">
|
||||
<table id="more-controls">
|
||||
<tr><td colspan="2">
|
||||
<table id="more-controls">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="select_style">Full Line Selection</label>
|
||||
|
|
@ -162,6 +166,13 @@
|
|||
<input type="checkbox" name="show_hidden" id="show_hidden" checked>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td >
|
||||
<label for="display_indent_guides">Show Indent Guides</label>
|
||||
</td><td>
|
||||
<input type="checkbox" name="display_indent_guides" id="display_indent_guides" checked>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td >
|
||||
<label for="show_hscroll">Persistent HScroll</label>
|
||||
|
|
@ -218,7 +229,7 @@
|
|||
<label for="fade_fold_widgets">Fade Fold Widgets</label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="checkbox" id="fade_fold_widgets" checked>
|
||||
<input type="checkbox" id="fade_fold_widgets">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -117,11 +117,13 @@ exports.commands = [{
|
|||
name: "selecttostart",
|
||||
bindKey: bindKey("Ctrl-Shift-Home", "Command-Shift-Up"),
|
||||
exec: function(editor) { editor.getSelection().selectFileStart(); },
|
||||
multiSelectAction: "forEach",
|
||||
readOnly: true
|
||||
}, {
|
||||
name: "gotostart",
|
||||
bindKey: bindKey("Ctrl-Home", "Command-Home|Command-Up"),
|
||||
exec: function(editor) { editor.navigateFileStart(); },
|
||||
multiSelectAction: "forEach",
|
||||
readOnly: true
|
||||
}, {
|
||||
name: "selectup",
|
||||
|
|
|
|||
|
|
@ -27,6 +27,12 @@
|
|||
z-index: 4;
|
||||
}
|
||||
|
||||
.ace_gutter_active_line {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.ace_scroller.horscroll {
|
||||
box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2029,7 +2029,7 @@ var EditSession = function(text, mode) {
|
|||
* - row (Number): The row number to check
|
||||
*
|
||||
*
|
||||
* Returns the length of the indicated row.
|
||||
* Returns number of screenrows in a wrapped line.
|
||||
**/
|
||||
this.getRowLength = function(row) {
|
||||
if (!this.$useWrapMode || !this.$wrapData[row]) {
|
||||
|
|
@ -2039,18 +2039,6 @@ var EditSession = function(text, mode) {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* EditSession.getRowHeight(config, row) -> Number
|
||||
* - config (Object): An object containing a parameter indicating the `lineHeight`.
|
||||
* - row (Number): The row number to check
|
||||
*
|
||||
* Returns the height of the indicated row. This is mostly relevant for situations where wrapping occurs, and a single line spans across multiple rows.
|
||||
*
|
||||
**/
|
||||
this.getRowHeight = function(config, row) {
|
||||
return this.getRowLength(row) * config.lineHeight;
|
||||
};
|
||||
|
||||
/** internal, hide, related to: EditSession.documentToScreenColumn
|
||||
* EditSession.getScreenLastRowColumn(screenRow) -> Number
|
||||
* - screenRow (Number): The screen row to check
|
||||
|
|
|
|||
|
|
@ -729,7 +729,7 @@ function Folding() {
|
|||
} else {
|
||||
if (addSubfolds)
|
||||
this.foldAll(row + 1, this.getLength());
|
||||
e.target.className += " invalid"
|
||||
(e.target || e.srcElement).className += " invalid"
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ var Editor = function(renderer, session) {
|
|||
this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this);
|
||||
session.addEventListener("tokenizerUpdate", this.$onTokenizerUpdate);
|
||||
|
||||
this.$onChangeTabSize = this.renderer.updateText.bind(this.renderer);
|
||||
this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer);
|
||||
session.addEventListener("changeTabSize", this.$onChangeTabSize);
|
||||
|
||||
this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this);
|
||||
|
|
@ -694,6 +694,9 @@ var Editor = function(renderer, session) {
|
|||
* called whenever a text "paste" happens.
|
||||
**/
|
||||
this.onPaste = function(text) {
|
||||
// todo this should change when paste becomes a command
|
||||
if (this.$readOnly)
|
||||
return;
|
||||
this._emit("paste", text);
|
||||
this.insert(text);
|
||||
};
|
||||
|
|
@ -988,9 +991,6 @@ var Editor = function(renderer, session) {
|
|||
* If `showInvisibiles` is set to `true`, invisible characters—like spaces or new lines—are show in the editor.
|
||||
**/
|
||||
this.setShowInvisibles = function(showInvisibles) {
|
||||
if (this.getShowInvisibles() == showInvisibles)
|
||||
return;
|
||||
|
||||
this.renderer.setShowInvisibles(showInvisibles);
|
||||
};
|
||||
|
||||
|
|
@ -1003,6 +1003,14 @@ var Editor = function(renderer, session) {
|
|||
return this.renderer.getShowInvisibles();
|
||||
};
|
||||
|
||||
this.setDisplayIndentGuides = function(display) {
|
||||
this.renderer.setDisplayIndentGuides(display);
|
||||
};
|
||||
|
||||
this.getDisplayIndentGuides = function() {
|
||||
return this.renderer.getDisplayIndentGuides();
|
||||
};
|
||||
|
||||
/**
|
||||
* Editor.setShowPrintMargin(showPrintMargin)
|
||||
* - showPrintMargin (Boolean): Specifies whether or not to show the print margin
|
||||
|
|
|
|||
|
|
@ -72,11 +72,10 @@ exports.render = function(input, mode, theme, lineStart, disableGutter) {
|
|||
var length = session.getLength();
|
||||
|
||||
for(var ix = 0; ix < length; ix++) {
|
||||
var lineTokens = session.getTokens(ix);
|
||||
stringBuilder.push("<div class='ace_line'>");
|
||||
if (!disableGutter)
|
||||
stringBuilder.push("<span class='ace_gutter ace_gutter-cell' unselectable='on'>" + (ix + lineStart) + "</span>");
|
||||
textLayer.$renderLine(stringBuilder, 0, lineTokens, true);
|
||||
textLayer.$renderLine(stringBuilder, 0, true, false);
|
||||
stringBuilder.push("</div>");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -193,7 +193,6 @@ exports.transformTextarea = function(element, loader) {
|
|||
var settingOpener = document.createElement("div");
|
||||
applyStyles(settingOpener, {
|
||||
position: "absolute",
|
||||
width: "15px",
|
||||
right: "0px",
|
||||
bottom: "0px",
|
||||
background: "red",
|
||||
|
|
|
|||
|
|
@ -118,7 +118,9 @@ var TextInput = function(parentNode, host) {
|
|||
var onPropertyChange = function(e) {
|
||||
setTimeout(function() {
|
||||
if (!inCompostion)
|
||||
sendText();
|
||||
if(text.value != "") {
|
||||
sendText();
|
||||
}
|
||||
}, 0);
|
||||
};
|
||||
|
||||
|
|
@ -166,7 +168,24 @@ var TextInput = function(parentNode, host) {
|
|||
};
|
||||
|
||||
event.addCommandKeyListener(text, host.onCommandKey.bind(host));
|
||||
event.addListener(text, "input", useragent.isIE ? onPropertyChange : onTextInput);
|
||||
event.addListener(text, "input", onTextInput);
|
||||
|
||||
if (useragent.isOldIE) {
|
||||
var keytable = { 13:1, 27:1 };
|
||||
event.addListener(text, "keyup", function (e) {
|
||||
if (inCompostion && (!text.value || keytable[e.keyCode]))
|
||||
setTimeout(onCompositionEnd, 0);
|
||||
if ((text.value.charCodeAt(0)|0) < 129) {
|
||||
return;
|
||||
}
|
||||
inCompostion ? onCompositionUpdate() : onCompositionStart();
|
||||
});
|
||||
|
||||
event.addListener(text, "propertychange", function() {
|
||||
if (text.value != PLACEHOLDER)
|
||||
setTimeout(sendText, 0);
|
||||
});
|
||||
}
|
||||
|
||||
event.addListener(text, "paste", function(e) {
|
||||
// Mark that the next input text comes from past.
|
||||
|
|
@ -206,7 +225,7 @@ var TextInput = function(parentNode, host) {
|
|||
});
|
||||
event.addListener(text, "cut", onCut); // for ie9 context menu
|
||||
}
|
||||
else if (useragent.isOpera) {
|
||||
else if (useragent.isOpera && !("KeyboardEvent" in window)) {
|
||||
event.addListener(parentNode, "keydown", function(e) {
|
||||
if ((useragent.isMac && !e.metaKey) || !e.ctrlKey)
|
||||
return;
|
||||
|
|
@ -268,11 +287,14 @@ var TextInput = function(parentNode, host) {
|
|||
tempStyle = text.style.cssText;
|
||||
|
||||
text.style.cssText =
|
||||
"position:fixed; z-index:100000;" + //"background:rgba(250, 0, 0, 0.3); opacity:1;" +
|
||||
"position:fixed; z-index:100000;" +
|
||||
(useragent.isIE ? "background:rgba(0, 0, 0, 0.03); opacity:0.1;" : "") + //"background:rgba(250, 0, 0, 0.3); opacity:1;" +
|
||||
"left:" + (e.clientX - 2) + "px; top:" + (e.clientY - 2) + "px;";
|
||||
|
||||
if (host.selection.isEmpty())
|
||||
text.value = "";
|
||||
else
|
||||
reset(true);
|
||||
|
||||
if (e.type != "mousedown")
|
||||
return;
|
||||
|
|
@ -281,7 +303,7 @@ var TextInput = function(parentNode, host) {
|
|||
host.renderer.$keepTextAreaAtCursor = null;
|
||||
|
||||
// on windows context menu is opened after mouseup
|
||||
if (useragent.isGecko && useragent.isWin)
|
||||
if (useragent.isWin && (useragent.isGecko || useragent.isIE))
|
||||
event.capture(host.container, function(e) {
|
||||
text.style.left = e.clientX - 2 + "px";
|
||||
text.style.top = e.clientY - 2 + "px";
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ var Gutter = function(parentEl) {
|
|||
breakpoints[i] ? " ace_breakpoint " : " ",
|
||||
annotation.className,
|
||||
"' title='", annotation.text.join("\n"),
|
||||
"' style='height:", this.session.getRowLength(i) * config.lineHeight, "px;'>", (i+1));
|
||||
"' style='height:", this.session.getRowLength(i) * config.lineHeight, "px;'>", (i));
|
||||
|
||||
if (foldWidgets) {
|
||||
var c = foldWidgets[i];
|
||||
|
|
@ -174,12 +174,32 @@ var Gutter = function(parentEl) {
|
|||
dom.removeCssClass(this.element, "ace_folding-enabled");
|
||||
|
||||
this.$showFoldWidgets = show;
|
||||
this.$padding = null;
|
||||
};
|
||||
|
||||
this.getShowFoldWidgets = function() {
|
||||
return this.$showFoldWidgets;
|
||||
};
|
||||
|
||||
this.$computePadding = function() {
|
||||
if (!this.element.firstChild)
|
||||
return {left: 0, right: 0};
|
||||
var style = dom.computedStyle(this.element.firstChild);
|
||||
this.$padding = {}
|
||||
this.$padding.left = parseInt(style.paddingLeft) + 1;
|
||||
this.$padding.right = parseInt(style.paddingRight);
|
||||
return this.$padding;
|
||||
};
|
||||
|
||||
this.getRegion = function(point) {
|
||||
var padding = this.$padding || this.$computePadding();
|
||||
var rect = this.element.getBoundingClientRect();
|
||||
if (point.x < padding.left + rect.left)
|
||||
return "markers";
|
||||
if (this.$showFoldWidgets && point.x > rect.right - padding.right)
|
||||
return "foldWidgets";
|
||||
};
|
||||
|
||||
}).call(Gutter.prototype);
|
||||
|
||||
exports.Gutter = Gutter;
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ var Text = function(parentEl) {
|
|||
|
||||
this.setSession = function(session) {
|
||||
this.session = session;
|
||||
this.$computeTabString();
|
||||
};
|
||||
|
||||
this.showInvisibles = false;
|
||||
|
|
@ -204,28 +205,52 @@ var Text = function(parentEl) {
|
|||
return false;
|
||||
|
||||
this.showInvisibles = showInvisibles;
|
||||
this.$computeTabString();
|
||||
return true;
|
||||
};
|
||||
|
||||
this.displayIndentGuides = true;
|
||||
this.setDisplayIndentGuides = function(display) {
|
||||
if (this.displayIndentGuides == display)
|
||||
return false;
|
||||
|
||||
this.displayIndentGuides = display;
|
||||
this.$computeTabString();
|
||||
return true;
|
||||
};
|
||||
|
||||
this.$tabStrings = [];
|
||||
this.onChangeTabSize =
|
||||
this.$computeTabString = function() {
|
||||
var tabSize = this.session.getTabSize();
|
||||
this.tabSize = tabSize;
|
||||
var tabStr = this.$tabStrings = [0];
|
||||
for (var i = 1; i < tabSize + 1; i++) {
|
||||
if (this.showInvisibles) {
|
||||
tabStr.push("<span class='ace_invisible'>"
|
||||
+ this.TAB_CHAR
|
||||
+ new Array(i).join(" ")
|
||||
+ Array(i).join(" ")
|
||||
+ "</span>");
|
||||
} else {
|
||||
tabStr.push(new Array(i+1).join(" "));
|
||||
}
|
||||
}
|
||||
if (this.displayIndentGuides) {
|
||||
this.$indentGuideRe = /\s\S| \t|\t |\s$/;
|
||||
var className = "ace_indent-guide";
|
||||
var content = Array(this.tabSize + 1).join(" ");
|
||||
var tabContent = content;
|
||||
if (this.showInvisibles) {
|
||||
className += " ace_invisible";
|
||||
tabContent = this.TAB_CHAR + content.substr(6);
|
||||
}
|
||||
|
||||
this.$tabStrings[" "] = "<span class='" + className + "'>" + content + "</span>";
|
||||
this.$tabStrings["\t"] = "<span class='" + className + "'>" + tabContent + "</span>";
|
||||
}
|
||||
};
|
||||
|
||||
this.updateLines = function(config, firstRow, lastRow) {
|
||||
this.$computeTabString();
|
||||
// Due to wrap line changes there can be new lines if e.g.
|
||||
// the line to updated wrapped in the meantime.
|
||||
if (this.config.lastRow != config.lastRow ||
|
||||
|
|
@ -253,22 +278,32 @@ var Text = function(parentEl) {
|
|||
lineElementsIdx ++;
|
||||
}
|
||||
|
||||
for (var i=first; i<=last; i++) {
|
||||
var row = first;
|
||||
var foldLine = this.session.getNextFoldLine(row);
|
||||
var foldStart = foldLine ? foldLine.start.row : Infinity;
|
||||
|
||||
while (true) {
|
||||
if (row > foldStart) {
|
||||
row = foldLine.end.row+1;
|
||||
foldLine = this.session.getNextFoldLine(row, foldLine);
|
||||
foldStart = foldLine ? foldLine.start.row :Infinity;
|
||||
}
|
||||
if (row > last)
|
||||
break;
|
||||
|
||||
var lineElement = lineElements[lineElementsIdx++];
|
||||
if (!lineElement)
|
||||
continue;
|
||||
|
||||
var html = [];
|
||||
var tokens = this.session.getTokens(i);
|
||||
this.$renderLine(html, i, tokens, !this.$useLineGroups());
|
||||
lineElement = dom.setInnerHtml(lineElement, html.join(""));
|
||||
|
||||
i = this.session.getRowFoldEnd(i);
|
||||
if (lineElement) {
|
||||
var html = [];
|
||||
this.$renderLine(
|
||||
html, row, !this.$useLineGroups(), row == foldStart ? foldLine : false
|
||||
);
|
||||
dom.setInnerHtml(lineElement, html.join(""));
|
||||
}
|
||||
row++;
|
||||
}
|
||||
};
|
||||
|
||||
this.scrollLines = function(config) {
|
||||
this.$computeTabString();
|
||||
var oldConfig = this.config;
|
||||
this.config = config;
|
||||
|
||||
|
|
@ -321,8 +356,7 @@ var Text = function(parentEl) {
|
|||
var html = [];
|
||||
// Get the tokens per line as there might be some lines in between
|
||||
// beeing folded.
|
||||
var tokens = this.session.getTokens(row);
|
||||
this.$renderLine(html, row, tokens, false);
|
||||
this.$renderLine(html, row, false, row == foldStart ? foldLine : false);
|
||||
|
||||
// don't use setInnerHtml since we are working with an empty DIV
|
||||
container.innerHTML = html.join("");
|
||||
|
|
@ -341,7 +375,6 @@ var Text = function(parentEl) {
|
|||
};
|
||||
|
||||
this.update = function(config) {
|
||||
this.$computeTabString();
|
||||
this.config = config;
|
||||
|
||||
var html = [];
|
||||
|
|
@ -363,10 +396,7 @@ var Text = function(parentEl) {
|
|||
if (this.$useLineGroups())
|
||||
html.push("<div class='ace_line_group'>")
|
||||
|
||||
// Get the tokens per line as there might be some lines in between
|
||||
// beeing folded.
|
||||
var tokens = this.session.getTokens(row);
|
||||
this.$renderLine(html, row, tokens, false);
|
||||
this.$renderLine(html, row, false, row == foldStart ? foldLine : false);
|
||||
|
||||
if (this.$useLineGroups())
|
||||
html.push("</div>"); // end the line group
|
||||
|
|
@ -429,38 +459,44 @@ var Text = function(parentEl) {
|
|||
return screenColumn + value.length;
|
||||
};
|
||||
|
||||
this.$renderLineCore = function(stringBuilder, lastRow, tokens, splits, onlyContents) {
|
||||
this.renderIndentGuide = function(stringBuilder, value) {
|
||||
var cols = value.search(this.$indentGuideRe);
|
||||
if (cols <= 0)
|
||||
return value;
|
||||
if (value[0] == " ") {
|
||||
cols -= cols % this.tabSize;
|
||||
stringBuilder.push(Array(cols/this.tabSize + 1).join(this.$tabStrings[" "]));
|
||||
return value.substr(cols);
|
||||
} else if (value[0] == "\t") {
|
||||
stringBuilder.push(Array(cols + 1).join(this.$tabStrings["\t"]));
|
||||
return value.substr(cols);
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
this.$renderWrappedLine = function(stringBuilder, tokens, splits, onlyContents) {
|
||||
var chars = 0;
|
||||
var split = 0;
|
||||
var splitChars;
|
||||
var splitChars = splits[0];
|
||||
var screenColumn = 0;
|
||||
var self = this;
|
||||
|
||||
if (!splits || splits.length == 0)
|
||||
splitChars = Number.MAX_VALUE;
|
||||
else
|
||||
splitChars = splits[0];
|
||||
|
||||
if (!onlyContents) {
|
||||
stringBuilder.push("<div class='ace_line' style='height:",
|
||||
this.config.lineHeight, "px",
|
||||
"'>"
|
||||
);
|
||||
}
|
||||
|
||||
for (var i = 0; i < tokens.length; i++) {
|
||||
var token = tokens[i];
|
||||
var value = token.value;
|
||||
if (i == 0 && this.displayIndentGuides) {
|
||||
chars = value.length;
|
||||
value = this.renderIndentGuide(stringBuilder, value);
|
||||
if (!value)
|
||||
continue;
|
||||
chars -= value.length;
|
||||
}
|
||||
|
||||
if (chars + value.length < splitChars) {
|
||||
screenColumn = self.$renderToken(
|
||||
stringBuilder, screenColumn, token, value
|
||||
);
|
||||
screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
|
||||
chars += value.length;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
while (chars + value.length >= splitChars) {
|
||||
screenColumn = self.$renderToken(
|
||||
screenColumn = this.$renderToken(
|
||||
stringBuilder, screenColumn,
|
||||
token, value.substring(0, splitChars - chars)
|
||||
);
|
||||
|
|
@ -470,8 +506,7 @@ var Text = function(parentEl) {
|
|||
if (!onlyContents) {
|
||||
stringBuilder.push("</div>",
|
||||
"<div class='ace_line' style='height:",
|
||||
this.config.lineHeight, "px",
|
||||
"'>"
|
||||
this.config.lineHeight, "px'>"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -481,37 +516,70 @@ var Text = function(parentEl) {
|
|||
}
|
||||
if (value.length != 0) {
|
||||
chars += value.length;
|
||||
screenColumn = self.$renderToken(
|
||||
screenColumn = this.$renderToken(
|
||||
stringBuilder, screenColumn, token, value
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.$renderSimpleLine = function(stringBuilder, tokens) {
|
||||
var screenColumn = 0;
|
||||
var token = tokens[0];
|
||||
var value = token.value;
|
||||
if (this.displayIndentGuides)
|
||||
value = this.renderIndentGuide(stringBuilder, value);
|
||||
if (value)
|
||||
screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
|
||||
for (var i = 1; i < tokens.length; i++) {
|
||||
token = tokens[i];
|
||||
value = token.value;
|
||||
screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
|
||||
}
|
||||
};
|
||||
|
||||
// row is either first row of foldline or not in fold
|
||||
this.$renderLine = function(stringBuilder, row, onlyContents, foldLine) {
|
||||
if (!foldLine && foldLine != false)
|
||||
foldLine = this.session.getFoldLine(row);
|
||||
|
||||
if (foldLine)
|
||||
var tokens = this.$getFoldLineTokens(row, foldLine);
|
||||
else
|
||||
var tokens = this.session.getTokens(row);
|
||||
|
||||
|
||||
if (!onlyContents) {
|
||||
stringBuilder.push(
|
||||
"<div class='ace_line' style='height:", this.config.lineHeight, "px'>"
|
||||
);
|
||||
}
|
||||
|
||||
if (tokens.length) {
|
||||
var splits = this.session.getRowSplitData(row);
|
||||
if (splits && splits.length)
|
||||
this.$renderWrappedLine(stringBuilder, tokens, splits, onlyContents);
|
||||
else
|
||||
this.$renderSimpleLine(stringBuilder, tokens);
|
||||
}
|
||||
|
||||
if (this.showInvisibles) {
|
||||
if (lastRow !== this.session.getLength() - 1)
|
||||
stringBuilder.push("<span class='ace_invisible'>" + this.EOL_CHAR + "</span>");
|
||||
else
|
||||
stringBuilder.push("<span class='ace_invisible'>" + this.EOF_CHAR + "</span>");
|
||||
if (foldLine)
|
||||
row = foldLine.end.row
|
||||
|
||||
stringBuilder.push(
|
||||
"<span class='ace_invisible'>",
|
||||
row == this.session.getLength() - 1 ? this.EOF_CHAR : this.EOL_CHAR,
|
||||
"</span>"
|
||||
);
|
||||
}
|
||||
if (!onlyContents)
|
||||
stringBuilder.push("</div>");
|
||||
};
|
||||
|
||||
this.$renderLine = function(stringBuilder, row, tokens, onlyContents) {
|
||||
// Check if the line to render is folded or not. If not, things are
|
||||
// simple, otherwise, we need to fake some things...
|
||||
if (!this.session.isRowFolded(row)) {
|
||||
var splits = this.session.getRowSplitData(row);
|
||||
this.$renderLineCore(stringBuilder, row, tokens, splits, onlyContents);
|
||||
} else {
|
||||
this.$renderFoldLine(stringBuilder, row, tokens, onlyContents);
|
||||
}
|
||||
};
|
||||
|
||||
this.$renderFoldLine = function(stringBuilder, row, tokens, onlyContents) {
|
||||
this.$getFoldLineTokens = function(row, foldLine) {
|
||||
var session = this.session;
|
||||
var foldLine = session.getFoldLine(row);
|
||||
var renderTokens = [];
|
||||
|
||||
function addTokens(tokens, from, to) {
|
||||
|
|
@ -552,6 +620,7 @@ var Text = function(parentEl) {
|
|||
}
|
||||
}
|
||||
|
||||
var tokens = session.getTokens(row);
|
||||
foldLine.walk(function(placeholder, row, column, lastColumn, isNewRow) {
|
||||
if (placeholder) {
|
||||
renderTokens.push({
|
||||
|
|
@ -567,9 +636,7 @@ var Text = function(parentEl) {
|
|||
}
|
||||
}, foldLine.end.row, this.session.getLine(foldLine.end.row).length);
|
||||
|
||||
// splits for foldline are stored at its' first row
|
||||
var splits = this.session.$useWrapMode ? this.session.$wrapData[row] : null;
|
||||
this.$renderLineCore(stringBuilder, row, renderTokens, splits, onlyContents);
|
||||
return renderTokens;
|
||||
};
|
||||
|
||||
this.$useLineGroups = function() {
|
||||
|
|
|
|||
|
|
@ -67,35 +67,61 @@ module.exports = {
|
|||
this.textLayer.$computeTabString();
|
||||
|
||||
// row with hard tabs
|
||||
var row = 0;
|
||||
var tokens = this.session.getTokens(row);
|
||||
var stringBuilder = [];
|
||||
this.textLayer.$renderLine(stringBuilder, row, tokens);
|
||||
this.textLayer.$renderLine(stringBuilder, 0);
|
||||
|
||||
// row with soft tabs
|
||||
row = 1;
|
||||
tokens = this.session.getTokens(row);
|
||||
var stringBuilder2 = [];
|
||||
this.textLayer.$renderLine(stringBuilder2, row, tokens);
|
||||
this.textLayer.$renderLine(stringBuilder2, 1);
|
||||
assert.equal(stringBuilder.join(""), stringBuilder2.join(""));
|
||||
},
|
||||
|
||||
"test rendering width of ideographic space (U+3000)" : function() {
|
||||
this.session.setValue("\u3000");
|
||||
|
||||
var tokens = this.session.getTokens(0);
|
||||
var stringBuilder = [];
|
||||
this.textLayer.$renderLine(stringBuilder, 0, tokens, true);
|
||||
this.textLayer.$renderLine(stringBuilder, 0, true);
|
||||
assert.equal(stringBuilder.join(""), "<span class='ace_cjk' style='width:20px'></span>");
|
||||
|
||||
this.textLayer.setShowInvisibles(true);
|
||||
var stringBuilder = [];
|
||||
this.textLayer.$renderLine(stringBuilder, 0, tokens, true);
|
||||
this.textLayer.$renderLine(stringBuilder, 0, true);
|
||||
assert.equal(
|
||||
stringBuilder.join(""),
|
||||
"<span class='ace_cjk ace_invisible' style='width:20px'>" + this.textLayer.SPACE_CHAR + "</span>"
|
||||
+ "<span class='ace_invisible'>\xB6</span>"
|
||||
);
|
||||
},
|
||||
|
||||
"test rendering of indent guides" : function() {
|
||||
var textLayer = this.textLayer
|
||||
var EOL = "<span class='ace_invisible'>" + textLayer.EOL_CHAR + "</span>";
|
||||
var SPACE = function(i) {return Array(i+1).join(" ")}
|
||||
var TAB = function(i) {return textLayer.TAB_CHAR + SPACE(i-1)}
|
||||
function testRender(results) {
|
||||
for (var i = results.length; i--; ) {
|
||||
var stringBuilder = [];
|
||||
textLayer.$renderLine(stringBuilder, i, true);
|
||||
assert.equal(stringBuilder.join(""), results[i]);
|
||||
}
|
||||
}
|
||||
|
||||
this.session.setValue(" \n\t\tf\n ");
|
||||
testRender([
|
||||
"<span class='ace_indent-guide'>" + SPACE(4) + "</span>" + SPACE(2),
|
||||
"<span class='ace_indent-guide'>" + SPACE(4) + "</span>" + SPACE(4) + "<span class='ace_identifier'>f</span>",
|
||||
SPACE(3)
|
||||
]);
|
||||
this.textLayer.setShowInvisibles(true);
|
||||
testRender([
|
||||
"<span class='ace_indent-guide ace_invisible'>" + SPACE(4) + "</span>" + SPACE(2) + EOL,
|
||||
"<span class='ace_indent-guide ace_invisible'>" + TAB(4) + "</span><span class='ace_invisible'>" + TAB(4) + "</span><span class='ace_identifier'>f</span>" + EOL,
|
||||
]);
|
||||
this.textLayer.setDisplayIndentGuides(false);
|
||||
testRender([
|
||||
SPACE(6) + EOL,
|
||||
"<span class='ace_invisible'>" + TAB(4) + "</span><span class='ace_invisible'>" + TAB(4) + "</span><span class='ace_identifier'>f</span>" + EOL
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -108,11 +108,6 @@ exports.getButton = function(e) {
|
|||
|
||||
if (document.documentElement.setCapture) {
|
||||
exports.capture = function(el, eventHandler, releaseCaptureHandler) {
|
||||
function onMouseMove(e) {
|
||||
eventHandler(e);
|
||||
return exports.stopPropagation(e);
|
||||
}
|
||||
|
||||
var called = false;
|
||||
function onReleaseCapture(e) {
|
||||
eventHandler(e);
|
||||
|
|
@ -137,22 +132,17 @@ if (document.documentElement.setCapture) {
|
|||
}
|
||||
else {
|
||||
exports.capture = function(el, eventHandler, releaseCaptureHandler) {
|
||||
function onMouseMove(e) {
|
||||
eventHandler(e);
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
function onMouseUp(e) {
|
||||
eventHandler && eventHandler(e);
|
||||
releaseCaptureHandler && releaseCaptureHandler(e);
|
||||
|
||||
document.removeEventListener("mousemove", onMouseMove, true);
|
||||
document.removeEventListener("mousemove", eventHandler, true);
|
||||
document.removeEventListener("mouseup", onMouseUp, true);
|
||||
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
document.addEventListener("mousemove", onMouseMove, true);
|
||||
document.addEventListener("mousemove", eventHandler, true);
|
||||
document.addEventListener("mouseup", onMouseUp, true);
|
||||
};
|
||||
}
|
||||
|
|
@ -193,7 +183,7 @@ exports.addMultiMouseDownListener = function(el, timeouts, eventHandler, callbac
|
|||
4: "quadclick"
|
||||
};
|
||||
|
||||
var listener = function(e) {
|
||||
exports.addListener(el, "mousedown", function(e) {
|
||||
if (exports.getButton(e) != 0) {
|
||||
clicks = 0;
|
||||
} else {
|
||||
|
|
@ -219,10 +209,18 @@ exports.addMultiMouseDownListener = function(el, timeouts, eventHandler, callbac
|
|||
clicks = 0;
|
||||
else if (clicks > 1)
|
||||
return eventHandler[callbackName](eventNames[clicks], e);
|
||||
};
|
||||
});
|
||||
|
||||
exports.addListener(el, "mousedown", listener);
|
||||
useragent.isOldIE && exports.addListener(el, "dblclick", listener);
|
||||
if (useragent.isOldIE) {
|
||||
exports.addListener(el, "dblclick", function(e) {
|
||||
clicks = 2;
|
||||
if (timer)
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(function() {timer = null}, timeouts[clicks - 1] || 600);
|
||||
eventHandler[callbackName]("mousedown", e);
|
||||
eventHandler[callbackName](eventNames[clicks], e);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function normalizeCommandKeys(callback, e, keyCode) {
|
||||
|
|
@ -292,7 +290,7 @@ exports.addCommandKeyListener = function(el, callback) {
|
|||
}
|
||||
};
|
||||
|
||||
if (window.postMessage) {
|
||||
if (window.postMessage && !useragent.isOldIE) {
|
||||
var postMessageId = 1;
|
||||
exports.nextTick = function(callback, win) {
|
||||
win = win || window;
|
||||
|
|
|
|||
|
|
@ -54,7 +54,8 @@ EventEmitter._dispatchEvent = function(eventName, e) {
|
|||
return;
|
||||
|
||||
e = e || {};
|
||||
e.type = eventName;
|
||||
if (!e.type)
|
||||
e.type = eventName;
|
||||
|
||||
if (!e.stopPropagation) {
|
||||
e.stopPropagation = function() {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue