Merge remote branch 'upstream/master' into requirejs
This commit is contained in:
commit
bfdcc1e5b4
32 changed files with 1394 additions and 696 deletions
|
|
@ -91,7 +91,7 @@ copy({
|
||||||
{
|
{
|
||||||
root: aceHome + '/lib',
|
root: aceHome + '/lib',
|
||||||
include: /.*\.js$/,
|
include: /.*\.js$/,
|
||||||
exclude: /tests?\/|theme\/|mode\/|ace\/worker\/host\.js/
|
exclude: /tests?\/|theme\/|mode\/|ace\/worker\/worker\.js/
|
||||||
},
|
},
|
||||||
{ base: aceHome + '/lib/', path: 'ace/theme/textmate.js' },
|
{ base: aceHome + '/lib/', path: 'ace/theme/textmate.js' },
|
||||||
{ base: aceHome + '/lib/', path: 'ace/mode/text.js' },
|
{ base: aceHome + '/lib/', path: 'ace/mode/text.js' },
|
||||||
|
|
@ -128,6 +128,17 @@ copy({
|
||||||
dest: data
|
dest: data
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Create the compressed and uncompressed output files
|
||||||
|
copy({
|
||||||
|
source: data,
|
||||||
|
//filter: copy.filter.uglifyjs,
|
||||||
|
dest: 'build/ace.js'
|
||||||
|
});
|
||||||
|
//copy({
|
||||||
|
// source: data,
|
||||||
|
// dest: 'build/ace-uncompressed.js'
|
||||||
|
//});
|
||||||
|
|
||||||
copy({
|
copy({
|
||||||
source: [
|
source: [
|
||||||
'build_support/editor.html'
|
'build_support/editor.html'
|
||||||
|
|
@ -135,27 +146,51 @@ copy({
|
||||||
dest: 'build/editor.html'
|
dest: 'build/editor.html'
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create the compressed and uncompressed output files
|
|
||||||
copy({
|
|
||||||
source: data,
|
|
||||||
//filter: copy.filter.uglifyjs,
|
|
||||||
dest: 'build/ace.js'
|
|
||||||
});
|
|
||||||
copy({
|
|
||||||
source: data,
|
|
||||||
dest: 'build/ace-uncompressed.js'
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create worker bootstrap code
|
// Create worker bootstrap code
|
||||||
copy({
|
copy({
|
||||||
source: "lib/ace/worker/host.js",
|
source: "lib/ace/worker/worker.js",
|
||||||
filter: [function(data) {
|
filter: [function(data) {
|
||||||
return data + "\nimportScripts('ace-uncompressed.js')";
|
return data + "\nimportScripts('ace.js')";
|
||||||
}],
|
}],
|
||||||
dest: 'build/host.js'
|
dest: 'build/worker.js'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var eclipseTheme = copy.createDataObject();
|
||||||
|
copy({
|
||||||
|
source: [{
|
||||||
|
root: aceHome + '/lib',
|
||||||
|
include: "ace/theme/eclipse.js"
|
||||||
|
}],
|
||||||
|
filter: [ copy.filter.moduleDefines ],
|
||||||
|
dest: eclipseTheme
|
||||||
|
});
|
||||||
|
copy({
|
||||||
|
source: [{
|
||||||
|
root: aceHome + '/lib',
|
||||||
|
include: "ace/theme/eclipse.css"
|
||||||
|
}],
|
||||||
|
filter: [ copy.filter.addDefines ],
|
||||||
|
dest: eclipseTheme
|
||||||
|
});
|
||||||
|
copy({
|
||||||
|
source: eclipseTheme,
|
||||||
|
dest: 'build/theme/eclipse.js'
|
||||||
|
});
|
||||||
|
|
||||||
|
[
|
||||||
|
"clouds", "clouds_midnight", "cobalt", "dawn", "idle_fingers", "kr_theme",
|
||||||
|
"mono_industrial", "monokai", "pastel_on_dark", "twilight"
|
||||||
|
].forEach(function(theme) {
|
||||||
|
copy({
|
||||||
|
source: [{
|
||||||
|
root: aceHome + '/lib',
|
||||||
|
include: "ace/theme/" + theme + ".js"
|
||||||
|
}],
|
||||||
|
filter: [ copy.filter.moduleDefines ],
|
||||||
|
dest: "build/theme/" + theme + ".js"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
function internalRequire(ignore) {
|
function internalRequire(ignore) {
|
||||||
var exports = {};
|
var exports = {};
|
||||||
|
|
|
||||||
|
|
@ -38,42 +38,47 @@
|
||||||
// don't define it in a worker.
|
// don't define it in a worker.
|
||||||
if (window.document) {
|
if (window.document) {
|
||||||
|
|
||||||
var deps = [ "pilot/fixoldbrowsers", "pilot/plugin_manager", "pilot/settings",
|
require("pilot/fixoldbrowsers");
|
||||||
"pilot/environment" ];
|
require("pilot/settings");
|
||||||
|
|
||||||
|
var Event = require("pilot/event");
|
||||||
|
var Dom = require("pilot/dom");
|
||||||
|
var EditSession = require("ace/edit_session").EditSession;
|
||||||
|
var JavaScriptMode = require("ace/mode/javascript").Mode;
|
||||||
|
var UndoManager = require("ace/undomanager").UndoManager;
|
||||||
|
var Editor = require("ace/editor").Editor;
|
||||||
|
var Renderer = require("ace/virtual_renderer").VirtualRenderer;
|
||||||
|
var Theme = require("ace/theme/textmate");
|
||||||
|
|
||||||
require(deps, function() {
|
|
||||||
var catalog = require("pilot/plugin_manager").catalog;
|
var catalog = require("pilot/plugin_manager").catalog;
|
||||||
catalog.registerPlugins([ "pilot/index" ]);
|
catalog.registerPlugins([ "pilot/index" ]);
|
||||||
});
|
|
||||||
|
|
||||||
var ace = {
|
var ace = {
|
||||||
edit: function(el) {
|
edit: function(el) {
|
||||||
if (typeof(el) == "string") {
|
if (typeof(el) == "string") {
|
||||||
el = document.getElementById(el);
|
el = document.getElementById(el);
|
||||||
}
|
}
|
||||||
var env = require("pilot/environment").create();
|
|
||||||
var catalog = require("pilot/plugin_manager").catalog;
|
|
||||||
catalog.startupPlugins({ env: env }).then(function() {
|
|
||||||
var EditSession = require("ace/edit_session").EditSession;
|
|
||||||
var JavaScriptMode = require("ace/mode/javascript").Mode;
|
|
||||||
var UndoManager = require("ace/undomanager").UndoManager;
|
|
||||||
var Editor = require("ace/editor").Editor;
|
|
||||||
var Renderer = require("ace/virtual_renderer").VirtualRenderer;
|
|
||||||
var theme = require("ace/theme/textmate");
|
|
||||||
|
|
||||||
var doc = new EditSession(el.innerHTML);
|
var doc = new EditSession(Dom.getInnerText(el));
|
||||||
el.innerHTML = '';
|
|
||||||
doc.setMode(new JavaScriptMode());
|
doc.setMode(new JavaScriptMode());
|
||||||
doc.setUndoManager(new UndoManager());
|
doc.setUndoManager(new UndoManager());
|
||||||
|
el.innerHTML = '';
|
||||||
|
|
||||||
|
var editor = new Editor(new Renderer(el, "ace/theme/textmate"));
|
||||||
|
editor.setSession(doc);
|
||||||
|
|
||||||
|
var env = require("pilot/environment").create();
|
||||||
|
catalog.startupPlugins({ env: env }).then(function() {
|
||||||
env.document = doc;
|
env.document = doc;
|
||||||
env.editor = new Editor(new Renderer(el, theme));
|
env.editor = env;
|
||||||
env.editor.setSession(doc);
|
editor.resize();
|
||||||
env.editor.resize();
|
Event.addListener(window, "resize", function() {
|
||||||
window.addEventListener("resize", function() {
|
editor.resize();
|
||||||
env.editor.resize();
|
});
|
||||||
}, false);
|
|
||||||
el.env = env;
|
el.env = env;
|
||||||
});
|
});
|
||||||
|
return editor;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -17,11 +17,13 @@
|
||||||
}
|
}
|
||||||
}</div>
|
}</div>
|
||||||
|
|
||||||
<script src="ace-uncompressed.js" type="text/javascript" charset="utf-8"></script>
|
<script src="ace.js" type="text/javascript" charset="utf-8"></script>
|
||||||
|
<script src="theme/twilight.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
ace.edit("editor");
|
var editor = ace.edit("editor");
|
||||||
}, false);
|
editor.setTheme("ace/theme/twilight");
|
||||||
|
}, false);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
210
demo/startup.js
210
demo/startup.js
|
|
@ -59,42 +59,33 @@ exports.launch = function(env) {
|
||||||
var emacs = require("ace/keyboard/keybinding/emacs").Emacs;
|
var emacs = require("ace/keyboard/keybinding/emacs").Emacs;
|
||||||
var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
|
var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
|
||||||
|
|
||||||
|
var keybindings = {
|
||||||
|
// Null = use "default" keymapping
|
||||||
|
ace: null,
|
||||||
|
vim: vim,
|
||||||
|
emacs: emacs,
|
||||||
|
// This is a way to define simple keyboard remappings
|
||||||
|
custom: new HashHandler({
|
||||||
|
"gotoright": "Tab"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
var docs = {};
|
var docs = {};
|
||||||
|
|
||||||
|
// Make the lorem ipsum text a little bit longer.
|
||||||
|
var loreIpsum = document.getElementById("plaintext").innerHTML;
|
||||||
|
for (var i = 0; i < 5; i++) {
|
||||||
|
loreIpsum += loreIpsum;
|
||||||
|
}
|
||||||
|
docs.plain = new EditSession(loreIpsum);
|
||||||
|
docs.plain.setUseWrapMode(true);
|
||||||
|
docs.plain.setMode(new TextMode());
|
||||||
|
docs.plain.setUndoManager(new UndoManager());
|
||||||
|
|
||||||
docs.js = new EditSession(document.getElementById("jstext").innerHTML);
|
docs.js = new EditSession(document.getElementById("jstext").innerHTML);
|
||||||
docs.js.setMode(new JavaScriptMode());
|
docs.js.setMode(new JavaScriptMode());
|
||||||
docs.js.setUndoManager(new UndoManager());
|
docs.js.setUndoManager(new UndoManager());
|
||||||
|
|
||||||
if (false && window.Worker) {
|
|
||||||
var worker = new WorkerClient("../..", ["ace", "pilot"], "ace/worker/mirror", "Mirror");
|
|
||||||
worker.call("setValue", [docs.js.getValue()]);
|
|
||||||
|
|
||||||
docs.js.getDocument().on("change", function(e) {
|
|
||||||
e.range = {
|
|
||||||
start: e.data.range.start,
|
|
||||||
end: e.data.range.end
|
|
||||||
};
|
|
||||||
worker.emit("change", e);
|
|
||||||
});
|
|
||||||
|
|
||||||
worker.on("jslint", function(results) {
|
|
||||||
var errors = [];
|
|
||||||
for (var i=0; i<results.data.length; i++) {
|
|
||||||
var error = results.data[i];
|
|
||||||
if (error)
|
|
||||||
errors.push({
|
|
||||||
row: error.line-1,
|
|
||||||
column: error.character-1,
|
|
||||||
text: error.reason,
|
|
||||||
type: "error",
|
|
||||||
lint: error
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
docs.js.setAnnotations(errors)
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
docs.css = new EditSession(document.getElementById("csstext").innerHTML);
|
docs.css = new EditSession(document.getElementById("csstext").innerHTML);
|
||||||
docs.css.setMode(new CssMode());
|
docs.css.setMode(new CssMode());
|
||||||
docs.css.setUndoManager(new UndoManager());
|
docs.css.setUndoManager(new UndoManager());
|
||||||
|
|
@ -129,27 +120,11 @@ exports.launch = function(env) {
|
||||||
return modes[modeEl.value];
|
return modes[modeEl.value];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var modeEl = document.getElementById("mode");
|
var modeEl = document.getElementById("mode");
|
||||||
function setMode() {
|
var wrapModeEl = document.getElementById("soft_wrap");
|
||||||
env.editor.getSession().setMode(modes[modeEl.value] || modes.text);
|
|
||||||
}
|
|
||||||
modeEl.onchange = setMode;
|
|
||||||
setMode();
|
|
||||||
|
|
||||||
// This is how you can set a custom keyboardHandler.
|
bindDropdown("doc", function(value) {
|
||||||
//
|
var doc = docs[value];
|
||||||
// Define some basic keymapping using a hash:
|
|
||||||
// env.editor.setKeyboardHandler(new HashHandler({
|
|
||||||
// "gotoright": "Tab"
|
|
||||||
// }));
|
|
||||||
//
|
|
||||||
// Use a more complex keymapping:
|
|
||||||
// env.editor.setKeyboardHandler(vim);
|
|
||||||
|
|
||||||
var docEl = document.getElementById("doc");
|
|
||||||
function onDocChange() {
|
|
||||||
var doc = docs[docEl.value];
|
|
||||||
env.editor.setSession(doc);
|
env.editor.setSession(doc);
|
||||||
|
|
||||||
var mode = doc.getMode();
|
var mode = doc.getMode();
|
||||||
|
|
@ -175,61 +150,92 @@ exports.launch = function(env) {
|
||||||
modeEl.value = "text";
|
modeEl.value = "text";
|
||||||
}
|
}
|
||||||
|
|
||||||
env.editor.focus();
|
if (!doc.getUseWrapMode()) {
|
||||||
}
|
wrapModeEl.value = "off";
|
||||||
docEl.onchange = onDocChange;
|
|
||||||
onDocChange();
|
|
||||||
|
|
||||||
|
|
||||||
var themeEl = document.getElementById("theme");
|
|
||||||
function setTheme() {
|
|
||||||
env.editor.setTheme(themeEl.value);
|
|
||||||
};
|
|
||||||
themeEl.onchange = setTheme;
|
|
||||||
setTheme();
|
|
||||||
|
|
||||||
|
|
||||||
var selectEl = document.getElementById("select_style");
|
|
||||||
function setSelectionStyle() {
|
|
||||||
if (selectEl.checked) {
|
|
||||||
env.editor.setSelectionStyle("line");
|
|
||||||
} else {
|
} else {
|
||||||
env.editor.setSelectionStyle("text");
|
wrapModeEl.value = doc.getWrapLimit();
|
||||||
}
|
}
|
||||||
|
env.editor.focus();
|
||||||
|
});
|
||||||
|
|
||||||
|
bindDropdown("mode", function(value) {
|
||||||
|
env.editor.getSession().setMode(modes[value] || modes.text);
|
||||||
|
});
|
||||||
|
|
||||||
|
bindDropdown("theme", function(value) {
|
||||||
|
env.editor.setTheme(value);
|
||||||
|
});
|
||||||
|
|
||||||
|
bindDropdown("keybinding", function(value) {
|
||||||
|
env.editor.setKeyboardHandler(keybindings[value]);
|
||||||
|
});
|
||||||
|
|
||||||
|
bindDropdown("fontsize", function(value) {
|
||||||
|
document.getElementById("editor").style.fontSize = value;
|
||||||
|
});
|
||||||
|
|
||||||
|
bindDropdown("soft_wrap", function(value) {
|
||||||
|
var session = env.editor.getSession();
|
||||||
|
var renderer = env.editor.renderer;
|
||||||
|
switch (value) {
|
||||||
|
case "off":
|
||||||
|
session.setUseWrapMode(false);
|
||||||
|
renderer.setPrintMarginColumn(80);
|
||||||
|
break;
|
||||||
|
case "40":
|
||||||
|
session.setUseWrapMode(true);
|
||||||
|
session.setWrapLimit(40);
|
||||||
|
renderer.setPrintMarginColumn(40);
|
||||||
|
break;
|
||||||
|
case "80":
|
||||||
|
session.setUseWrapMode(true);
|
||||||
|
session.setWrapLimit(80);
|
||||||
|
renderer.setPrintMarginColumn(80);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
bindCheckbox("select_style", function(checked) {
|
||||||
|
env.editor.setSelectionStyle(checked ? "line" : "text");
|
||||||
|
});
|
||||||
|
|
||||||
|
bindCheckbox("highlight_active", function(checked) {
|
||||||
|
env.editor.setHighlightActiveLine(checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
bindCheckbox("show_hidden", function(checked) {
|
||||||
|
env.editor.setShowInvisibles(checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
bindCheckbox("show_gutter", function(checked) {
|
||||||
|
env.editor.renderer.setShowGutter(checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
bindCheckbox("show_print_margin", function(checked) {
|
||||||
|
env.editor.renderer.setShowPrintMargin(checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
function bindCheckbox(id, callback) {
|
||||||
|
var el = document.getElementById(id);
|
||||||
|
var onCheck = function() {
|
||||||
|
callback(!!el.checked);
|
||||||
};
|
};
|
||||||
selectEl.onclick = setSelectionStyle;
|
el.onclick = onCheck;
|
||||||
setSelectionStyle();
|
onCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
function bindDropdown(id, callback) {
|
||||||
var activeEl = document.getElementById("highlight_active");
|
var el = document.getElementById(id);
|
||||||
function setHighlightActiveLine() {
|
var onChange = function() {
|
||||||
env.editor.setHighlightActiveLine(!!activeEl.checked);
|
callback(el.value);
|
||||||
};
|
|
||||||
activeEl.onclick = setHighlightActiveLine;
|
|
||||||
setHighlightActiveLine();
|
|
||||||
|
|
||||||
|
|
||||||
var showHiddenEl = document.getElementById("show_hidden");
|
|
||||||
function setShowInvisibles() {
|
|
||||||
env.editor.setShowInvisibles(!!showHiddenEl.checked);
|
|
||||||
};
|
|
||||||
showHiddenEl.onclick = setShowInvisibles;
|
|
||||||
setShowInvisibles();
|
|
||||||
|
|
||||||
|
|
||||||
// for debugging
|
|
||||||
window.jump = function() {
|
|
||||||
var jump = document.getElementById("jump");
|
|
||||||
var cursor = env.editor.getCursorPosition();
|
|
||||||
var pos = env.editor.renderer.textToScreenCoordinates(cursor.row, cursor.column);
|
|
||||||
jump.style.left = pos.pageX + "px";
|
|
||||||
jump.style.top = pos.pageY + "px";
|
|
||||||
jump.style.display = "block";
|
|
||||||
};
|
};
|
||||||
|
el.onchange = onChange;
|
||||||
|
onChange();
|
||||||
|
}
|
||||||
|
|
||||||
function onResize() {
|
function onResize() {
|
||||||
container.style.width = (document.documentElement.clientWidth - 4) + "px";
|
container.style.width = (document.documentElement.clientWidth) + "px";
|
||||||
container.style.height = (document.documentElement.clientHeight - 55 - 4 - 23) + "px";
|
container.style.height = (document.documentElement.clientHeight - 60 - 22) + "px";
|
||||||
env.editor.resize();
|
env.editor.resize();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -278,15 +284,7 @@ exports.launch = function(env) {
|
||||||
return event.preventDefault(e);
|
return event.preventDefault(e);
|
||||||
});
|
});
|
||||||
|
|
||||||
// gutter
|
window.env = env;
|
||||||
editor = env.editor
|
|
||||||
toggleGutter=function(){
|
|
||||||
editor.renderer.setShowGutter(!editor.renderer.showGutter)
|
|
||||||
}
|
|
||||||
//
|
|
||||||
window.ace={
|
|
||||||
editor: editor
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
html {
|
html {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
@ -16,23 +16,14 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
#editor {
|
#editor {
|
||||||
top: 55px;
|
position: absolute;
|
||||||
|
top: 60px;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
background: white;
|
background: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
#controls {
|
#controls {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 55px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#jump {
|
|
||||||
position: absolute;
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
border: 1px solid red;
|
|
||||||
z-index: 10000;
|
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#cockpitInput {
|
#cockpitInput {
|
||||||
|
|
@ -54,19 +45,3 @@ body {
|
||||||
border-top-left-radius: 4px; border-top-right-radius: 4px;
|
border-top-left-radius: 4px; border-top-right-radius: 4px;
|
||||||
background: #DDD; color: #000;
|
background: #DDD; color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
#toggleGutter{
|
|
||||||
height:8px;
|
|
||||||
width:20px;
|
|
||||||
background:lightblue;
|
|
||||||
bottom:0;
|
|
||||||
position:absolute;
|
|
||||||
z-index: 1000;
|
|
||||||
-moz-border-radius-topright: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#toggleGutter:hover{
|
|
||||||
-moz-box-shadow: 2px -1px 5px 3px #91B6D5;
|
|
||||||
border-right: 1px solid #A1A1CF;
|
|
||||||
border-top: 1px solid #A1A1CF;
|
|
||||||
}
|
|
||||||
106
editor.html
106
editor.html
|
|
@ -9,11 +9,9 @@
|
||||||
<link rel="stylesheet" href="demo/styles.css" type="text/css" media="screen" charset="utf-8">
|
<link rel="stylesheet" href="demo/styles.css" type="text/css" media="screen" charset="utf-8">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="jump"></div>
|
|
||||||
|
|
||||||
<table id="controls">
|
<table id="controls">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td align="right">
|
||||||
<label for="doc">Document:</label>
|
<label for="doc">Document:</label>
|
||||||
<select id="doc" size="1">
|
<select id="doc" size="1">
|
||||||
<option value="js">JS Document</option>
|
<option value="js">JS Document</option>
|
||||||
|
|
@ -21,9 +19,50 @@
|
||||||
<option value="css">CSS Document</option>
|
<option value="css">CSS Document</option>
|
||||||
<option value="python">Python Document</option>
|
<option value="python">Python Document</option>
|
||||||
<option value="php">PHP Document</option>
|
<option value="php">PHP Document</option>
|
||||||
|
<option value="plain">Text Document</option>
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td align="right">
|
||||||
|
<label for="theme">Theme:</label>
|
||||||
|
<select id="theme" size="1">
|
||||||
|
<option value="ace/theme/textmate">TextMate</option>
|
||||||
|
<option value="ace/theme/eclipse">Eclipse</option>
|
||||||
|
<option value="ace/theme/dawn">Dawn</option>
|
||||||
|
<option value="ace/theme/idle_fingers">idleFingers</option>
|
||||||
|
<option value="ace/theme/pastel_on_dark">Pastel on dark</option>
|
||||||
|
<option value="ace/theme/twilight">Twilight</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td align="right">
|
||||||
|
<label for="fontsize">Font Size:</label>
|
||||||
|
<select id="fontsize" size="1">
|
||||||
|
<option value="10px">10px</option>
|
||||||
|
<option value="11px">11px</option>
|
||||||
|
<option value="12px" selected="selected">12px</option>
|
||||||
|
<option value="14px">14px</option>
|
||||||
|
<option value="16px">16px</option>
|
||||||
|
<option value="20px">20px</option>
|
||||||
|
<option value="24px">24px</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td align="right">
|
||||||
|
<label for="select_style">Full Line Selection</label>
|
||||||
|
<input type="checkbox" name="select_style" id="select_style" checked>
|
||||||
|
</td>
|
||||||
|
<td align="right">
|
||||||
|
<label for="highlight_active">Highlight Active Line</label>
|
||||||
|
<input type="checkbox" name="highlight_active" id="highlight_active" checked>
|
||||||
|
</td>
|
||||||
|
<td align="right">
|
||||||
|
<label for="show_hidden">Show Invisibles</label>
|
||||||
|
<input type="checkbox" name="show_hidden" id="show_hidden">
|
||||||
|
</td>
|
||||||
|
<td align="right" rowspan="2">
|
||||||
|
<img src="demo/logo.png">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="right">
|
||||||
<label for="mode">Mode:</label>
|
<label for="mode">Mode:</label>
|
||||||
<select id="mode" size="1">
|
<select id="mode" size="1">
|
||||||
<option value="text">Plain Text</option>
|
<option value="text">Plain Text</option>
|
||||||
|
|
@ -35,45 +74,44 @@
|
||||||
<option value="php">PHP</option>
|
<option value="php">PHP</option>
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td align="right">
|
||||||
<label for="theme">Theme:</label>
|
<label for="keybinding">Key Binding:</label>
|
||||||
<select id="theme" size="1">
|
<select id="keybinding" size="1">
|
||||||
<option value="ace/theme/textmate">TextMate</option>
|
<option value="ace">Ace</option>
|
||||||
<option value="ace/theme/eclipse">Eclipse</option>
|
<option value="vim">Vim</option>
|
||||||
<option value="ace/theme/dawn">Dawn</option>
|
<option value="emacs">Emacs</option>
|
||||||
<option value="ace/theme/idle_fingers">idleFingers</option>
|
<option value="custom">Custom</option>
|
||||||
<option value="ace/theme/pastel_on_dark">Pastel on dark</option>
|
|
||||||
<option value="ace/theme/twilight">Twilight</option>
|
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td align="right">
|
||||||
<label for="select_style">Full line selections</label>
|
<label for="soft_wrap">Soft Wrap:</label>
|
||||||
<input type="checkbox" name="select_style" id="select_style" checked>
|
<select id="soft_wrap" size="1">
|
||||||
</td>
|
<option value="off">Off</option>
|
||||||
<td>
|
<option value="40">40 Chars</option>
|
||||||
<label for="highlight_active">Highlight active line</label>
|
<option value="80">80 Chars</option>
|
||||||
<input type="checkbox" name="highlight_active" id="highlight_active" checked>
|
</select>
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<label for="show_hidden">Show invisibles</label>
|
|
||||||
<input type="checkbox" name="show_hidden" id="show_hidden">
|
|
||||||
</td>
|
</td>
|
||||||
<td align="right">
|
<td align="right">
|
||||||
<img src="demo/logo.png">
|
<label for="show_gutter">Show Gutter</label>
|
||||||
|
<input type="checkbox" id="show_gutter" checked>
|
||||||
|
</td>
|
||||||
|
<td align="right">
|
||||||
|
<label for="show_print_margin">Show Print Margin</label>
|
||||||
|
<input type="checkbox" id="show_print_margin" checked>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<div id="editor">
|
<div id="editor">
|
||||||
<div id="toggleGutter" onclick='toggleGutter()'></div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<script type="text/editor" id="jstext">function foo(items) {
|
<script type="text/editor" id="jstext">function foo(items) {
|
||||||
for (var i=0; i<items.length; i++) {
|
for (var i=0; i<items.length; i++) {
|
||||||
alert(items[i] + "juhu");
|
alert(items[i] + "juhu");
|
||||||
}
|
}
|
||||||
}</script>
|
}
|
||||||
|
// A magic character: >> ぁ <<
|
||||||
|
</script>
|
||||||
|
|
||||||
<script type="text/editor" id="csstext">.text-layer {
|
<script type="text/editor" id="csstext">.text-layer {
|
||||||
font-family: Monaco, "Courier New", monospace;
|
font-family: Monaco, "Courier New", monospace;
|
||||||
|
|
@ -143,5 +181,17 @@ echo $output;
|
||||||
<script src="demo/require.js" type="text/javascript" charset="utf-8"></script>
|
<script src="demo/require.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="demo/boot.js" type="text/javascript"></script>
|
<script src="demo/boot.js" type="text/javascript"></script>
|
||||||
|
|
||||||
|
<script type="text/editor" id="plaintext">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
|
||||||
|
|
||||||
|
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
|
||||||
|
|
||||||
|
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
|
||||||
|
|
||||||
|
Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
|
||||||
|
|
||||||
|
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.
|
||||||
|
|
||||||
|
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,18 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ace_editor textarea {
|
||||||
|
position: "absolute";
|
||||||
|
z-index: -1;
|
||||||
|
opacity: 0;
|
||||||
|
width: 10px;
|
||||||
|
height: 30px;
|
||||||
|
border: none;
|
||||||
|
resize: none;
|
||||||
|
outline: none;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.ace_layer {
|
.ace_layer {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ var EditSession = function(text, mode) {
|
||||||
this.$modified = true;
|
this.$modified = true;
|
||||||
this.selection = new Selection(this);
|
this.selection = new Selection(this);
|
||||||
this.$breakpoints = [];
|
this.$breakpoints = [];
|
||||||
|
this.$wrapData = [];
|
||||||
|
|
||||||
if (text instanceof Document) {
|
if (text instanceof Document) {
|
||||||
this.setDocument(text)
|
this.setDocument(text)
|
||||||
|
|
@ -86,6 +87,8 @@ var EditSession = function(text, mode) {
|
||||||
this.$deltas.push(delta);
|
this.$deltas.push(delta);
|
||||||
this.$informUndoManager.schedule();
|
this.$informUndoManager.schedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.$updateWrapDataOnChange(e);
|
||||||
this._dispatchEvent("change", e);
|
this._dispatchEvent("change", e);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -324,8 +327,8 @@ var EditSession = function(text, mode) {
|
||||||
return this.screenWidth;
|
return this.screenWidth;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$computeWidth = function() {
|
this.$computeWidth = function(force) {
|
||||||
if (this.$modified) {
|
if (this.$modified || force) {
|
||||||
this.$modified = false;
|
this.$modified = false;
|
||||||
|
|
||||||
var lines = this.doc.getAllLines();
|
var lines = this.doc.getAllLines();
|
||||||
|
|
@ -344,8 +347,13 @@ var EditSession = function(text, mode) {
|
||||||
longestScreenLine = Math.max(longestScreenLine, len);
|
longestScreenLine = Math.max(longestScreenLine, len);
|
||||||
}
|
}
|
||||||
this.width = longestLine;
|
this.width = longestLine;
|
||||||
|
|
||||||
|
if (this.$useWrapMode) {
|
||||||
|
this.screenWidth = this.$wrapLimit;
|
||||||
|
} else {
|
||||||
this.screenWidth = longestScreenLine;
|
this.screenWidth = longestScreenLine;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -627,17 +635,200 @@ var EditSession = function(text, mode) {
|
||||||
return Math.max(0, Math.min(row, this.doc.getLength()-1));
|
return Math.max(0, Math.min(row, this.doc.getLength()-1));
|
||||||
};
|
};
|
||||||
|
|
||||||
this.documentToScreenColumn = function(row, docColumn) {
|
// WRAPMODE
|
||||||
|
this.$wrapLimit = 80;
|
||||||
|
this.$useWrapMode = false;
|
||||||
|
|
||||||
|
this.setUseWrapMode = function(useWrapMode) {
|
||||||
|
if (useWrapMode != this.$useWrapMode) {
|
||||||
|
this.$useWrapMode = useWrapMode;
|
||||||
|
this.$updateWrapData(0, this.getLength() - 1);
|
||||||
|
this.$modified = true;
|
||||||
|
this._dispatchEvent("changeWrapMode");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getUseWrapMode = function() {
|
||||||
|
return this.$useWrapMode;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.setWrapLimit = function(wrapLimit) {
|
||||||
|
if (wrapLimit != this.$wrapLimit) {
|
||||||
|
this.$wrapLimit = wrapLimit;
|
||||||
|
this.$updateWrapData(0, this.getLength() - 1);
|
||||||
|
this._dispatchEvent("changeWrapMode");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getWrapLimit = function() {
|
||||||
|
return this.$wrapLimit;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$updateWrapDataOnChange = function(e) {
|
||||||
|
if (!this.$useWrapMode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var action = e.data.action;
|
||||||
|
var firstRow = e.data.range.start.row,
|
||||||
|
lastRow = e.data.range.end.row;
|
||||||
|
|
||||||
|
if (action.indexOf("Lines") != -1) {
|
||||||
|
if (action == "insertLines") {
|
||||||
|
lastRow = firstRow + e.data.lines.length;
|
||||||
|
} else {
|
||||||
|
firstRow = lastRow - e.data.lines.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstRow != lastRow) {
|
||||||
|
var len = lastRow - firstRow;
|
||||||
|
if (action.indexOf("remove") != -1) {
|
||||||
|
this.$wrapData.splice(firstRow, len);
|
||||||
|
lastRow = firstRow;
|
||||||
|
} else {
|
||||||
|
var args = [firstRow, 0];
|
||||||
|
for (var i = 0; i < len; i++) args.push([]);
|
||||||
|
this.$wrapData.splice.apply(this.$wrapData, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$updateWrapData(firstRow, lastRow);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$updateWrapData = function(firstRow, lastRow) {
|
||||||
|
var lines = this.doc.getAllLines();
|
||||||
|
var tabSize = this.getTabSize();
|
||||||
|
var wrapData = this.$wrapData;
|
||||||
|
var wrapLimit = this.$wrapLimit;
|
||||||
|
|
||||||
|
// Remove lines that are no longer there.
|
||||||
|
wrapData.splice(lines.length, wrapData.length - lines.length);
|
||||||
|
|
||||||
|
for (var row = firstRow; row <= lastRow; row++) {
|
||||||
|
wrapData[row] =
|
||||||
|
this.$computeWrapSplits(lines[row], wrapLimit, tabSize);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// "Tokens"
|
||||||
|
var CHAR = 1,
|
||||||
|
CHAR_EXT = 2,
|
||||||
|
SPACE = 3,
|
||||||
|
TAB = 4,
|
||||||
|
TAB_SPACE = 5;
|
||||||
|
|
||||||
|
this.$computeWrapSplits = function(textLine, wrapLimit, tabSize) {
|
||||||
|
textLine = textLine.trimRight();
|
||||||
|
if (textLine.length == 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
var tabSize = this.getTabSize();
|
||||||
|
var splits = [];
|
||||||
|
var tokens = this.$getDisplayTokens(textLine);
|
||||||
|
var displayLength = tokens.length;
|
||||||
|
var lastSplit = 0, lastDocSplit = 0;
|
||||||
|
|
||||||
|
function addSplit(screenPos) {
|
||||||
|
var displayed = tokens.slice(lastSplit, screenPos);
|
||||||
|
|
||||||
|
// The document size is the current size - the extra width for tabs
|
||||||
|
// and multipleWidth characters.
|
||||||
|
var len = displayed.length;
|
||||||
|
displayed.join("").
|
||||||
|
// Get all the tabs.
|
||||||
|
replace(/4/g, function(m) {
|
||||||
|
len -= tabSize - 1;
|
||||||
|
}).
|
||||||
|
// Get all the multipleWidth characters.
|
||||||
|
replace(/2/g, function(m) {
|
||||||
|
len -= 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
lastDocSplit += len;
|
||||||
|
splits.push(lastDocSplit);
|
||||||
|
lastSplit = screenPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (displayLength - lastSplit > wrapLimit) {
|
||||||
|
// This is, where the split should be.
|
||||||
|
var split = lastSplit + wrapLimit;
|
||||||
|
|
||||||
|
// If there is a space or tab at this split position.
|
||||||
|
if (tokens[split] >= SPACE) {
|
||||||
|
// Include all following spaces + tabs in this split as well.
|
||||||
|
while (tokens[split] >= SPACE) {
|
||||||
|
split ++;
|
||||||
|
}
|
||||||
|
addSplit(split);
|
||||||
|
} else {
|
||||||
|
// Search for the first non space/tab token.
|
||||||
|
for (split; split != lastSplit - 1; split--) {
|
||||||
|
if (tokens[split] >= SPACE) {
|
||||||
|
split++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If we found one, then add the split.
|
||||||
|
if (split > lastSplit) {
|
||||||
|
addSplit(split);
|
||||||
|
}
|
||||||
|
// No space or tab around? Well, force a split then.
|
||||||
|
else {
|
||||||
|
addSplit(lastSplit + wrapLimit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return splits;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$getDisplayTokens = function(str) {
|
||||||
|
var arr = [];
|
||||||
var tabSize = this.getTabSize();
|
var tabSize = this.getTabSize();
|
||||||
|
|
||||||
var screenColumn = 0;
|
for (var i = 0; i < str.length; i++) {
|
||||||
var remaining = docColumn;
|
var c = str.charCodeAt(i);
|
||||||
var line = this.getLine(row);
|
// Tab
|
||||||
|
if (c == 9) {
|
||||||
|
arr.push(TAB);
|
||||||
|
for (var n = 1; n < tabSize; n++) {
|
||||||
|
arr.push(TAB_SPACE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Space
|
||||||
|
else if(c == 32) {
|
||||||
|
arr.push(SPACE);
|
||||||
|
}
|
||||||
|
// CJK characters
|
||||||
|
else if (
|
||||||
|
c >= 0x3040 && c <= 0x309F || // Hiragana
|
||||||
|
c >= 0x30A0 && c <= 0x30FF || // Katakana
|
||||||
|
c >= 0x4E00 && c <= 0x9FFF || // Single CJK ideographs
|
||||||
|
c >= 0xF900 && c <= 0xFAFF ||
|
||||||
|
c >= 0x3400 && c <= 0x4DBF
|
||||||
|
) {
|
||||||
|
arr.push(CHAR, CHAR_EXT);
|
||||||
|
} else {
|
||||||
|
arr.push(CHAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
for (var i=0; i<line.length; i++) {
|
/**
|
||||||
var c = line.charCodeAt(i);
|
* Calculates the width of the a string on the screen while assuming that
|
||||||
if (remaining > 0) {
|
* the string starts at the first column on the screen.
|
||||||
remaining -= 1;
|
*
|
||||||
|
* @param string str String to calculate the screen width of
|
||||||
|
* @return int number of columns for str on screen.
|
||||||
|
*/
|
||||||
|
this.$getStringScreenWidth = function(str) {
|
||||||
|
var screenColumn = 0;
|
||||||
|
var tabSize = this.getTabSize();
|
||||||
|
|
||||||
|
for (var i=0; i<str.length; i++) {
|
||||||
|
var c = str.charCodeAt(i);
|
||||||
// tab
|
// tab
|
||||||
if (c == 9) {
|
if (c == 9) {
|
||||||
screenColumn += tabSize;
|
screenColumn += tabSize;
|
||||||
|
|
@ -654,22 +845,134 @@ var EditSession = function(text, mode) {
|
||||||
} else {
|
} else {
|
||||||
screenColumn += 1;
|
screenColumn += 1;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return screenColumn;
|
return screenColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getRowHeight = function(config, row) {
|
||||||
|
var rows;
|
||||||
|
if (!this.$useWrapMode) {
|
||||||
|
rows = 1;
|
||||||
|
} else {
|
||||||
|
rows = this.$wrapData[row].length + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rows * config.lineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getScreenLastRowColumn = function(screenRow, returnDocPosition) {
|
||||||
|
if (!this.$useWrapMode) {
|
||||||
|
return this.$getStringScreenWidth(this.getLine(screenRow));
|
||||||
|
}
|
||||||
|
|
||||||
|
var rowData = this.$screenToDocumentRow(screenRow);
|
||||||
|
var docRow = rowData[0],
|
||||||
|
row = rowData[1];
|
||||||
|
|
||||||
|
var start, end;
|
||||||
|
if (this.$wrapData[docRow][row]) {
|
||||||
|
start = (this.$wrapData[docRow][row - 1] || 0);
|
||||||
|
end = this.$wrapData[docRow][row];
|
||||||
|
returnDocPosition && end--;
|
||||||
|
} else {
|
||||||
|
end = this.getLine(docRow).length;
|
||||||
|
start = (this.$wrapData[docRow][row - 1] || 0);
|
||||||
|
}
|
||||||
|
if (!returnDocPosition) {
|
||||||
|
return this.$getStringScreenWidth(this.getLine(docRow).substring(start, end));
|
||||||
|
} else {
|
||||||
|
return end;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.screenToDocumentColumn = function(row, screenColumn) {
|
this.getDocumentLastRowColumn = function(docRow, docColumn) {
|
||||||
|
if (!this.$useWrapMode) {
|
||||||
|
return this.getLine(docRow).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
var screenRow = this.documentToScreenRow(docRow, docColumn);
|
||||||
|
return this.getScreenLastRowColumn(screenRow, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getScreenFirstRowColumn = function(screenRow) {
|
||||||
|
if (!this.$useWrapMode) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var rowData = this.$screenToDocumentRow(screenRow);
|
||||||
|
var docRow = rowData[0],
|
||||||
|
row = rowData[1];
|
||||||
|
|
||||||
|
return this.$wrapData[docRow][row - 1] || 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getRowSplitData = function(row) {
|
||||||
|
if (!this.$useWrapMode) {
|
||||||
|
return undefined;
|
||||||
|
} else {
|
||||||
|
return this.$wrapData[row];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns array
|
||||||
|
* - array[0]: The documentRow aquivalent.
|
||||||
|
* - array[1]: The screenRowOffset to the first documentRow on the screen.
|
||||||
|
*/
|
||||||
|
this.$screenToDocumentRow = function(row) {
|
||||||
|
if (!this.$useWrapMode) {
|
||||||
|
return [row, 0];
|
||||||
|
}
|
||||||
|
|
||||||
|
var wrapData = this.$wrapData, linesCount = this.getLength();
|
||||||
|
var docRow = 0;
|
||||||
|
while (docRow < linesCount && row >= wrapData[docRow].length + 1) {
|
||||||
|
row -= wrapData[docRow].length + 1;
|
||||||
|
docRow ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [docRow, row];
|
||||||
|
};
|
||||||
|
|
||||||
|
this.screenToDocumentRow = function(screenRow) {
|
||||||
|
return this.$screenToDocumentRow(screenRow)[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
this.screenToDocumentColumn = function(screenRow, screenColumn) {
|
||||||
|
return this.screenToDocumentPosition(screenRow, screenColumn).column;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.screenToDocumentPosition = function(row, column) {
|
||||||
|
var line;
|
||||||
|
var docRow;
|
||||||
|
var docColumn;
|
||||||
|
var remaining = column;
|
||||||
|
if (!this.$useWrapMode) {
|
||||||
|
docRow = row;
|
||||||
|
row = 0;
|
||||||
|
docColumn = 0;
|
||||||
|
line = this.getLine(docRow);
|
||||||
|
} else {
|
||||||
|
var wrapData = this.$wrapData, linesCount = this.getLength();
|
||||||
|
|
||||||
|
var rowData = this.$screenToDocumentRow(row);
|
||||||
|
row = rowData[1];
|
||||||
|
docRow = rowData[0];
|
||||||
|
|
||||||
|
if (docRow >= linesCount) {
|
||||||
|
return {
|
||||||
|
row: docRow,
|
||||||
|
column: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
docColumn = wrapData[docRow][row - 1] || 0;
|
||||||
|
line = this.getLine(docRow).substring(docColumn);
|
||||||
|
}
|
||||||
|
|
||||||
var tabSize = this.getTabSize();
|
var tabSize = this.getTabSize();
|
||||||
|
for(var i = 0; i < line.length; i++) {
|
||||||
var docColumn = 0;
|
|
||||||
var remaining = screenColumn;
|
|
||||||
var line = this.getLine(row);
|
|
||||||
|
|
||||||
for(var i=0; i<line.length; i++) {
|
|
||||||
var c = line.charCodeAt(i);
|
var c = line.charCodeAt(i);
|
||||||
|
|
||||||
if (remaining > 0) {
|
if (remaining > 0) {
|
||||||
|
|
@ -705,8 +1008,125 @@ var EditSession = function(text, mode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return docColumn;
|
// Clamp docColumn.
|
||||||
|
if (docRow < linesCount && wrapData[docRow][row]) {
|
||||||
|
if (docColumn >= wrapData[docRow][row]) {
|
||||||
|
// We remove one character at the end such that the docColumn
|
||||||
|
// position returned is not associated to the next row on the
|
||||||
|
// screen.
|
||||||
|
docColumn = wrapData[docRow][row] - 1;
|
||||||
|
}
|
||||||
|
} else if (this.getLine(docRow)) {
|
||||||
|
docColumn = Math.min(docColumn, this.getLine(docRow).length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
row: docRow,
|
||||||
|
column: docColumn
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
this.documentToScreenColumn = function(row, docColumn) {
|
||||||
|
return this.documentToScreenPosition(row, docColumn).column;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return array[2]
|
||||||
|
* - array[0]: The number of the row on the screen (aka screenRow)
|
||||||
|
* - array[1]: The number of rows from the first docRow on the screen
|
||||||
|
* (aka screenRowOffset);
|
||||||
|
*/
|
||||||
|
this.$documentToScreenRow = function(docRow, docColumn) {
|
||||||
|
if (!this.$useWrapMode) {
|
||||||
|
return [docRow, 0];
|
||||||
|
}
|
||||||
|
|
||||||
|
var wrapData = this.$wrapData;
|
||||||
|
var screenRow = 0;
|
||||||
|
|
||||||
|
// Handle special case where the row is outside of the range of lines.
|
||||||
|
if (docRow > wrapData.length - 1) {
|
||||||
|
return [
|
||||||
|
this.getScreenLength(),
|
||||||
|
wrapData[wrapData.length - 1].length - 1
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < docRow; i++) {
|
||||||
|
screenRow += wrapData[i].length + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var screenRowOffset = 0;
|
||||||
|
while (docColumn >= wrapData[docRow][screenRowOffset]) {
|
||||||
|
screenRow ++;
|
||||||
|
screenRowOffset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [screenRow, screenRowOffset];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.documentToScreenRow = function(docRow, docColumn) {
|
||||||
|
return this.$documentToScreenRow(docRow, docColumn)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.documentToScreenPosition = function(pos, column) {
|
||||||
|
var str;
|
||||||
|
var tabSize = this.getTabSize();
|
||||||
|
|
||||||
|
// Normalize the passed in arguments.
|
||||||
|
var row;
|
||||||
|
if (column != null) {
|
||||||
|
row = pos;
|
||||||
|
} else {
|
||||||
|
row = pos.row;
|
||||||
|
column = pos.column;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.$useWrapMode) {
|
||||||
|
str = this.getLine(row).substring(0, column);
|
||||||
|
column = this.$getStringScreenWidth(str);
|
||||||
|
return {
|
||||||
|
row: row,
|
||||||
|
column: column
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (row >= this.getLength()) {
|
||||||
|
return {
|
||||||
|
row: screenRow,
|
||||||
|
column: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var split;
|
||||||
|
var wrapRowData = this.$wrapData[row];
|
||||||
|
var screenRow, screenRowOffset;
|
||||||
|
var screenColumn;
|
||||||
|
var rowData = this.$documentToScreenRow(row, column);
|
||||||
|
screenRow = rowData[0];
|
||||||
|
screenRowOffset = rowData[1];
|
||||||
|
|
||||||
|
str = this.getLine(row).substring(
|
||||||
|
wrapRowData[screenRowOffset - 1] || 0, column);
|
||||||
|
screenColumn = this.$getStringScreenWidth(str);
|
||||||
|
|
||||||
|
return {
|
||||||
|
row: screenRow,
|
||||||
|
column: screenColumn
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getScreenLength = function() {
|
||||||
|
if (!this.$useWrapMode) {
|
||||||
|
return this.getLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
var screenRows = 0;
|
||||||
|
for (var row = 0; row < this.$wrapData.length; row++) {
|
||||||
|
screenRows += this.$wrapData[row].length + 1;
|
||||||
|
}
|
||||||
|
return screenRows;
|
||||||
|
}
|
||||||
|
|
||||||
}).call(EditSession.prototype);
|
}).call(EditSession.prototype);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
* Fabian Jakobs <fabian AT ajax DOT org>
|
* Fabian Jakobs <fabian AT ajax DOT org>
|
||||||
* Irakli Gozalishvili <rfobic@gmail.com> (http://jeditoolkit.com)
|
* Irakli Gozalishvili <rfobic@gmail.com> (http://jeditoolkit.com)
|
||||||
|
* Julian Viereck <julian.viereck@gmail.com>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
|
@ -55,7 +56,7 @@ var Editor =function(renderer, session) {
|
||||||
this.container = container;
|
this.container = container;
|
||||||
this.renderer = renderer;
|
this.renderer = renderer;
|
||||||
|
|
||||||
this.textInput = new TextInput(container, this);
|
this.textInput = new TextInput(renderer.getTextAreaContainer(), this);
|
||||||
this.keyBinding = new KeyBinding(this);
|
this.keyBinding = new KeyBinding(this);
|
||||||
var self = this;
|
var self = this;
|
||||||
event.addListener(container, "mousedown", function(e) {
|
event.addListener(container, "mousedown", function(e) {
|
||||||
|
|
@ -128,6 +129,7 @@ var Editor =function(renderer, session) {
|
||||||
this.session.removeEventListener("change", this.$onDocumentChange);
|
this.session.removeEventListener("change", this.$onDocumentChange);
|
||||||
this.session.removeEventListener("changeMode", this.$onDocumentModeChange);
|
this.session.removeEventListener("changeMode", this.$onDocumentModeChange);
|
||||||
this.session.removeEventListener("changeTabSize", this.$onDocumentChangeTabSize);
|
this.session.removeEventListener("changeTabSize", this.$onDocumentChangeTabSize);
|
||||||
|
this.session.removeEventListener("changeWrapMode", this.$onDocumentChangeWrapMode);
|
||||||
this.session.removeEventListener("changeBreakpoint", this.$onDocumentChangeBreakpoint);
|
this.session.removeEventListener("changeBreakpoint", this.$onDocumentChangeBreakpoint);
|
||||||
this.session.removeEventListener("changeAnnotation", this.$onDocumentChangeAnnotation);
|
this.session.removeEventListener("changeAnnotation", this.$onDocumentChangeAnnotation);
|
||||||
|
|
||||||
|
|
@ -150,6 +152,9 @@ var Editor =function(renderer, session) {
|
||||||
this.$onDocumentChangeTabSize = this.renderer.updateText.bind(this.renderer);
|
this.$onDocumentChangeTabSize = this.renderer.updateText.bind(this.renderer);
|
||||||
session.addEventListener("changeTabSize", this.$onDocumentChangeTabSize);
|
session.addEventListener("changeTabSize", this.$onDocumentChangeTabSize);
|
||||||
|
|
||||||
|
this.$onDocumentChangeWrapMode = this.renderer.updateFull.bind(this.renderer);
|
||||||
|
session.addEventListener("changeWrapMode", this.$onDocumentChangeWrapMode);
|
||||||
|
|
||||||
this.$onDocumentChangeBreakpoint = this.onDocumentChangeBreakpoint.bind(this);
|
this.$onDocumentChangeBreakpoint = this.onDocumentChangeBreakpoint.bind(this);
|
||||||
this.session.addEventListener("changeBreakpoint", this.$onDocumentChangeBreakpoint);
|
this.session.addEventListener("changeBreakpoint", this.$onDocumentChangeBreakpoint);
|
||||||
|
|
||||||
|
|
@ -157,7 +162,6 @@ var Editor =function(renderer, session) {
|
||||||
this.session.addEventListener("changeAnnotation", this.$onDocumentChangeAnnotation);
|
this.session.addEventListener("changeAnnotation", this.$onDocumentChangeAnnotation);
|
||||||
|
|
||||||
this.selection = session.getSelection();
|
this.selection = session.getSelection();
|
||||||
this.$desiredColumn = 0;
|
|
||||||
|
|
||||||
this.$onCursorChange = this.onCursorChange.bind(this);
|
this.$onCursorChange = this.onCursorChange.bind(this);
|
||||||
this.selection.addEventListener("changeCursor", this.$onCursorChange);
|
this.selection.addEventListener("changeCursor", this.$onCursorChange);
|
||||||
|
|
@ -277,6 +281,11 @@ var Editor =function(renderer, session) {
|
||||||
|
|
||||||
this.onCursorChange = function(e) {
|
this.onCursorChange = function(e) {
|
||||||
this.$highlightBrackets();
|
this.$highlightBrackets();
|
||||||
|
|
||||||
|
// move text input over the cursor
|
||||||
|
// this is required for iOS and IME
|
||||||
|
this.renderer.moveTextAreaToCursor(this.textInput.getElement());
|
||||||
|
|
||||||
this.renderer.updateCursor(this.getCursorPosition(), this.$overwrite);
|
this.renderer.updateCursor(this.getCursorPosition(), this.$overwrite);
|
||||||
|
|
||||||
if (!this.$blockScrolling && (!e || !e.blockScrolling)) {
|
if (!this.$blockScrolling && (!e || !e.blockScrolling)) {
|
||||||
|
|
@ -414,13 +423,11 @@ var Editor =function(renderer, session) {
|
||||||
this.onMouseDoubleClick = function(e) {
|
this.onMouseDoubleClick = function(e) {
|
||||||
this.selection.selectWord();
|
this.selection.selectWord();
|
||||||
this.$clickSelection = this.getSelectionRange();
|
this.$clickSelection = this.getSelectionRange();
|
||||||
this.$updateDesiredColumn();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onMouseTripleClick = function(e) {
|
this.onMouseTripleClick = function(e) {
|
||||||
this.selection.selectLine();
|
this.selection.selectLine();
|
||||||
this.$clickSelection = this.getSelectionRange();
|
this.$clickSelection = this.getSelectionRange();
|
||||||
this.$updateDesiredColumn();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onMouseWheel = function(e) {
|
this.onMouseWheel = function(e) {
|
||||||
|
|
@ -684,7 +691,6 @@ var Editor =function(renderer, session) {
|
||||||
var range = this.session.outdentRows(selection.getRange());
|
var range = this.session.outdentRows(selection.getRange());
|
||||||
|
|
||||||
selection.setSelectionRange(range, selection.isBackwards());
|
selection.setSelectionRange(range, selection.isBackwards());
|
||||||
this.$updateDesiredColumn();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.toggleCommentLines = function() {
|
this.toggleCommentLines = function() {
|
||||||
|
|
@ -874,17 +880,14 @@ var Editor =function(renderer, session) {
|
||||||
|
|
||||||
this.clearSelection = function() {
|
this.clearSelection = function() {
|
||||||
this.selection.clearSelection();
|
this.selection.clearSelection();
|
||||||
this.$updateDesiredColumn();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.moveCursorTo = function(row, column) {
|
this.moveCursorTo = function(row, column) {
|
||||||
this.selection.moveCursorTo(row, column);
|
this.selection.moveCursorTo(row, column);
|
||||||
this.$updateDesiredColumn();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.moveCursorToPosition = function(pos) {
|
this.moveCursorToPosition = function(pos) {
|
||||||
this.selection.moveCursorToPosition(pos);
|
this.selection.moveCursorToPosition(pos);
|
||||||
this.$updateDesiredColumn();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -903,34 +906,16 @@ var Editor =function(renderer, session) {
|
||||||
this.navigateTo = function(row, column) {
|
this.navigateTo = function(row, column) {
|
||||||
this.clearSelection();
|
this.clearSelection();
|
||||||
this.moveCursorTo(row, column);
|
this.moveCursorTo(row, column);
|
||||||
this.$updateDesiredColumn(column);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.navigateUp = function(times) {
|
this.navigateUp = function(times) {
|
||||||
this.selection.clearSelection();
|
this.selection.clearSelection();
|
||||||
this.selection.moveCursorBy(-(times || 1), 0);
|
this.selection.moveCursorBy(-1, 0);
|
||||||
|
|
||||||
if (this.$desiredColumn) {
|
|
||||||
var cursor = this.getCursorPosition();
|
|
||||||
var column = this.session.screenToDocumentColumn(cursor.row, this.$desiredColumn);
|
|
||||||
this.selection.moveCursorTo(cursor.row, column);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.navigateDown = function(times) {
|
this.navigateDown = function(times) {
|
||||||
this.selection.clearSelection();
|
this.selection.clearSelection();
|
||||||
this.selection.moveCursorBy(times || 1, 0);
|
this.selection.moveCursorBy(1, 0);
|
||||||
|
|
||||||
if (this.$desiredColumn) {
|
|
||||||
var cursor = this.getCursorPosition();
|
|
||||||
var column = this.session.screenToDocumentColumn(cursor.row, this.$desiredColumn);
|
|
||||||
this.selection.moveCursorTo(cursor.row, column);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.$updateDesiredColumn = function() {
|
|
||||||
var cursor = this.getCursorPosition();
|
|
||||||
this.$desiredColumn = this.session.documentToScreenColumn(cursor.row, cursor.column);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.navigateLeft = function(times) {
|
this.navigateLeft = function(times) {
|
||||||
|
|
@ -999,7 +984,6 @@ var Editor =function(renderer, session) {
|
||||||
this.$tryReplace(range, replacement);
|
this.$tryReplace(range, replacement);
|
||||||
if (range !== null)
|
if (range !== null)
|
||||||
this.selection.setSelectionRange(range);
|
this.selection.setSelectionRange(range);
|
||||||
this.$updateDesiredColumn();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
this.replaceAll = function(replacement, options) {
|
this.replaceAll = function(replacement, options) {
|
||||||
|
|
@ -1018,7 +1002,6 @@ var Editor =function(renderer, session) {
|
||||||
this.$tryReplace(ranges[i], replacement);
|
this.$tryReplace(ranges[i], replacement);
|
||||||
if (ranges[0] !== null)
|
if (ranges[0] !== null)
|
||||||
this.selection.setSelectionRange(ranges[0]);
|
this.selection.setSelectionRange(ranges[0]);
|
||||||
this.$updateDesiredColumn();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
this.$tryReplace = function(range, replacement) {
|
this.$tryReplace = function(range, replacement) {
|
||||||
|
|
@ -1071,7 +1054,6 @@ var Editor =function(renderer, session) {
|
||||||
var range = this.$search.find(this.session);
|
var range = this.$search.find(this.session);
|
||||||
if (range) {
|
if (range) {
|
||||||
this.gotoLine(range.end.row+1, range.end.column);
|
this.gotoLine(range.end.row+1, range.end.column);
|
||||||
this.$updateDesiredColumn();
|
|
||||||
this.selection.setSelectionRange(range);
|
this.selection.setSelectionRange(range);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,7 @@ StateHandler.prototype = {
|
||||||
// If we pressed any command key but no other key, then ignore the input.
|
// If we pressed any command key but no other key, then ignore the input.
|
||||||
// Otherwise "shift-" is added to the buffer, and later on "shift-g"
|
// Otherwise "shift-" is added to the buffer, and later on "shift-g"
|
||||||
// which results in "shift-shift-g" which doesn't make senese.
|
// which results in "shift-shift-g" which doesn't make senese.
|
||||||
if (hashId != 0 && (key == "" || String.fromCharCode(0))) {
|
if (hashId != 0 && (key == "" || key == String.fromCharCode(0))) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,39 +38,13 @@
|
||||||
define(function(require, exports, module) {
|
define(function(require, exports, module) {
|
||||||
|
|
||||||
var event = require("pilot/event");
|
var event = require("pilot/event");
|
||||||
|
var useragent = require("pilot/useragent");
|
||||||
|
|
||||||
var TextInput = function(parentNode, host) {
|
var TextInput = function(parentNode, host) {
|
||||||
|
|
||||||
var text = document.createElement("textarea");
|
var text = document.createElement("textarea");
|
||||||
var style = text.style;
|
|
||||||
style.position = "fixed";
|
|
||||||
style.left = "-10000px";
|
|
||||||
style.top = "-10000px";
|
|
||||||
parentNode.appendChild(text);
|
parentNode.appendChild(text);
|
||||||
|
|
||||||
// move text input over the cursor
|
|
||||||
// this is required for iOS and IME
|
|
||||||
style.left = "0px";
|
|
||||||
style.top = "0px";
|
|
||||||
style.zIndex = -1;
|
|
||||||
style.opacity = 0;
|
|
||||||
style.width = "10px";
|
|
||||||
style.height = "30px";
|
|
||||||
|
|
||||||
var changeCursor = function() {
|
|
||||||
var cursor = host.getCursorPosition();
|
|
||||||
var pos = host.renderer.textToScreenCoordinates(cursor.row, cursor.column);
|
|
||||||
var epos = parentNode.getBoundingClientRect();
|
|
||||||
style.left = (pos.pageX - epos.left - 6) + "px";
|
|
||||||
style.top = (pos.pageY - epos.top + 52) + "px";
|
|
||||||
};
|
|
||||||
|
|
||||||
host.addEventListener("changeSession", function(e) {
|
|
||||||
if (e.oldSession)
|
|
||||||
e.oldSession.getSelection().removeEventListener("changeCursor", changeCursor);
|
|
||||||
e.session.getSelection().addEventListener("changeCursor", changeCursor);
|
|
||||||
});
|
|
||||||
|
|
||||||
var PLACEHOLDER = String.fromCharCode(0);
|
var PLACEHOLDER = String.fromCharCode(0);
|
||||||
sendText();
|
sendText();
|
||||||
|
|
||||||
|
|
@ -97,6 +71,7 @@ var TextInput = function(parentNode, host) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var onTextInput = function(e) {
|
var onTextInput = function(e) {
|
||||||
|
if (useragent.isIE && text.value.charCodeAt(0) > 128) return;
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if (!inCompostion)
|
if (!inCompostion)
|
||||||
sendText();
|
sendText();
|
||||||
|
|
@ -105,40 +80,62 @@ var TextInput = function(parentNode, host) {
|
||||||
|
|
||||||
var onCompositionStart = function(e) {
|
var onCompositionStart = function(e) {
|
||||||
inCompostion = true;
|
inCompostion = true;
|
||||||
|
if (!useragent.isIE) {
|
||||||
sendText();
|
sendText();
|
||||||
text.value = "";
|
text.value = "";
|
||||||
|
};
|
||||||
host.onCompositionStart();
|
host.onCompositionStart();
|
||||||
setTimeout(onCompositionUpdate, 0);
|
if (!useragent.isGecko) setTimeout(onCompositionUpdate, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
var onCompositionUpdate = function() {
|
var onCompositionUpdate = function() {
|
||||||
|
if (!inCompostion) return;
|
||||||
host.onCompositionUpdate(text.value);
|
host.onCompositionUpdate(text.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
var onCompositionEnd = function() {
|
var onCompositionEnd = function() {
|
||||||
inCompostion = false;
|
inCompostion = false;
|
||||||
host.onCompositionEnd();
|
host.onCompositionEnd();
|
||||||
onTextInput();
|
setTimeout(function () {
|
||||||
|
sendText();
|
||||||
|
}, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
var onCopy = function() {
|
var onCopy = function(e) {
|
||||||
copied = true;
|
copied = true;
|
||||||
text.value = host.getCopyText();
|
var copyText = host.getCopyText();
|
||||||
|
if(copyText)
|
||||||
|
text.value = copyText;
|
||||||
|
else
|
||||||
|
e.preventDefault();
|
||||||
text.select();
|
text.select();
|
||||||
copied = true;
|
|
||||||
setTimeout(sendText, 0);
|
setTimeout(sendText, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
var onCut = function() {
|
var onCut = function(e) {
|
||||||
copied = true;
|
copied = true;
|
||||||
text.value = host.getCopyText();
|
var copyText = host.getCopyText();
|
||||||
|
if(copyText) {
|
||||||
|
text.value = copyText;
|
||||||
host.onCut();
|
host.onCut();
|
||||||
|
} else
|
||||||
|
e.preventDefault();
|
||||||
text.select();
|
text.select();
|
||||||
setTimeout(sendText, 0);
|
setTimeout(sendText, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
event.addCommandKeyListener(text, host.onCommandKey.bind(host));
|
event.addCommandKeyListener(text, host.onCommandKey.bind(host));
|
||||||
event.addListener(text, "keypress", onTextInput);
|
event.addListener(text, "keypress", onTextInput);
|
||||||
|
if (useragent.isIE) {
|
||||||
|
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, "textInput", onTextInput);
|
event.addListener(text, "textInput", onTextInput);
|
||||||
event.addListener(text, "paste", function(e) {
|
event.addListener(text, "paste", function(e) {
|
||||||
// Some browsers support the event.clipboardData API. Use this to get
|
// Some browsers support the event.clipboardData API. Use this to get
|
||||||
|
|
@ -153,13 +150,20 @@ var TextInput = function(parentNode, host) {
|
||||||
onTextInput();
|
onTextInput();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (!useragent.isIE) {
|
||||||
event.addListener(text, "propertychange", onTextInput);
|
event.addListener(text, "propertychange", onTextInput);
|
||||||
|
};
|
||||||
|
|
||||||
event.addListener(text, "copy", onCopy);
|
event.addListener(text, "copy", onCopy);
|
||||||
event.addListener(text, "cut", onCut);
|
event.addListener(text, "cut", onCut);
|
||||||
|
|
||||||
event.addListener(text, "compositionstart", onCompositionStart);
|
event.addListener(text, "compositionstart", onCompositionStart);
|
||||||
event.addListener(text, "compositionupdate", onCompositionUpdate);
|
if (useragent.isGecko) {
|
||||||
|
event.addListener(text, "text", onCompositionUpdate);
|
||||||
|
};
|
||||||
|
if (useragent.isWebKit) {
|
||||||
|
event.addListener(text, "keyup", onCompositionUpdate);
|
||||||
|
};
|
||||||
event.addListener(text, "compositionend", onCompositionEnd);
|
event.addListener(text, "compositionend", onCompositionEnd);
|
||||||
|
|
||||||
event.addListener(text, "blur", function() {
|
event.addListener(text, "blur", function() {
|
||||||
|
|
@ -180,6 +184,10 @@ var TextInput = function(parentNode, host) {
|
||||||
this.blur = function() {
|
this.blur = function() {
|
||||||
text.blur();
|
text.blur();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.getElement = function() {
|
||||||
|
return text;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.TextInput = TextInput;
|
exports.TextInput = TextInput;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
* Fabian Jakobs <fabian AT ajax DOT org>
|
* Fabian Jakobs <fabian AT ajax DOT org>
|
||||||
|
* Julian Viereck <julian.viereck@gmail.com>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
|
@ -57,10 +58,9 @@ var Cursor = function(parentEl) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setCursor = function(position, overwrite) {
|
this.setCursor = function(position, overwrite) {
|
||||||
this.position = {
|
this.position =
|
||||||
row : position.row,
|
this.session.documentToScreenPosition(position);
|
||||||
column : this.session.documentToScreenColumn(position.row, position.column)
|
|
||||||
};
|
|
||||||
if (overwrite) {
|
if (overwrite) {
|
||||||
dom.addCssClass(this.cursor, "ace_overwrite");
|
dom.addCssClass(this.cursor, "ace_overwrite");
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -100,7 +100,7 @@ var Cursor = function(parentEl) {
|
||||||
}, 1000);
|
}, 1000);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getPixelPosition = function() {
|
this.getPixelPosition = function(onScreen) {
|
||||||
if (!this.config || !this.position) {
|
if (!this.config || !this.position) {
|
||||||
return {
|
return {
|
||||||
left : 0,
|
left : 0,
|
||||||
|
|
@ -108,8 +108,10 @@ var Cursor = function(parentEl) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var cursorLeft = Math.round(this.position.column * this.config.characterWidth);
|
var pos = this.position;
|
||||||
var cursorTop = this.position.row * this.config.lineHeight;
|
var cursorLeft = Math.round(pos.column * this.config.characterWidth);
|
||||||
|
var cursorTop = (pos.row - (onScreen ? this.config.firstRowScreen : 0)) *
|
||||||
|
this.config.lineHeight;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
left : cursorLeft,
|
left : cursorLeft,
|
||||||
|
|
@ -123,17 +125,10 @@ var Cursor = function(parentEl) {
|
||||||
|
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
|
||||||
var cursorLeft = Math.round(this.position.column * config.characterWidth);
|
this.pixelPos = this.getPixelPosition(true);
|
||||||
var cursorTop = this.position.row * config.lineHeight;
|
|
||||||
|
|
||||||
this.pixelPos = {
|
this.cursor.style.left = this.pixelPos.left + "px";
|
||||||
left : cursorLeft,
|
this.cursor.style.top = this.pixelPos.top + "px";
|
||||||
top : cursorTop
|
|
||||||
};
|
|
||||||
|
|
||||||
this.cursor.style.left = cursorLeft + "px";
|
|
||||||
this.cursor.style.top = (cursorTop - (config.firstRow * config.lineHeight))
|
|
||||||
+ "px";
|
|
||||||
this.cursor.style.width = config.characterWidth + "px";
|
this.cursor.style.width = config.characterWidth + "px";
|
||||||
this.cursor.style.height = config.lineHeight + "px";
|
this.cursor.style.height = config.lineHeight + "px";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
* Fabian Jakobs <fabian AT ajax DOT org>
|
* Fabian Jakobs <fabian AT ajax DOT org>
|
||||||
|
* Julian Viereck <julian.viereck@gmail.com>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
|
@ -51,6 +52,10 @@ var Gutter = function(parentEl) {
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
|
this.setSession = function(session) {
|
||||||
|
this.session = session;
|
||||||
|
};
|
||||||
|
|
||||||
this.addGutterDecoration = function(row, className){
|
this.addGutterDecoration = function(row, className){
|
||||||
if (!this.$decorations[row])
|
if (!this.$decorations[row])
|
||||||
this.$decorations[row] = "";
|
this.$decorations[row] = "";
|
||||||
|
|
@ -101,7 +106,7 @@ var Gutter = function(parentEl) {
|
||||||
this.$breakpoints[i] ? " ace_breakpoint " : " ",
|
this.$breakpoints[i] ? " ace_breakpoint " : " ",
|
||||||
annotation.className,
|
annotation.className,
|
||||||
"' title='", annotation.text.join("\n"),
|
"' title='", annotation.text.join("\n"),
|
||||||
"' style='height:", config.lineHeight, "px;'>", (i+1), "</div>");
|
"' style='height:", this.session.getRowHeight(config, i), "px;'>", (i+1), "</div>");
|
||||||
html.push("</div>");
|
html.push("</div>");
|
||||||
}
|
}
|
||||||
this.element = dom.setInnerHtml(this.element, html.join(""));
|
this.element = dom.setInnerHtml(this.element, html.join(""));
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
* Fabian Jakobs <fabian AT ajax DOT org>
|
* Fabian Jakobs <fabian AT ajax DOT org>
|
||||||
|
* Julian Viereck <julian.viereck@gmail.com>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
|
@ -87,6 +88,8 @@ var Marker = function(parentEl) {
|
||||||
var range = marker.range.clipRows(config.firstRow, config.lastRow);
|
var range = marker.range.clipRows(config.firstRow, config.lastRow);
|
||||||
if (range.isEmpty()) continue;
|
if (range.isEmpty()) continue;
|
||||||
|
|
||||||
|
range = range.toScreenRange(this.session);
|
||||||
|
|
||||||
if (range.isMultiLine()) {
|
if (range.isMultiLine()) {
|
||||||
if (marker.type == "text") {
|
if (marker.type == "text") {
|
||||||
this.drawTextMarker(html, range, marker.clazz, config);
|
this.drawTextMarker(html, range, marker.clazz, config);
|
||||||
|
|
@ -101,11 +104,16 @@ var Marker = function(parentEl) {
|
||||||
this.element = dom.setInnerHtml(this.element, html.join(""));
|
this.element = dom.setInnerHtml(this.element, html.join(""));
|
||||||
};
|
};
|
||||||
|
|
||||||
this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig) {
|
this.$getTop = function(row, layerConfig) {
|
||||||
|
return (row - layerConfig.firstRowScreen) * layerConfig.lineHeight;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig) {
|
||||||
// selection start
|
// selection start
|
||||||
var row = range.start.row;
|
var row = range.start.row;
|
||||||
var lineRange = new Range(row, range.start.column, row, this.session.getLine(row).length);
|
|
||||||
|
var lineRange = new Range(row, range.start.column,
|
||||||
|
row, this.session.getScreenLastRowColumn(row));
|
||||||
this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1);
|
this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1);
|
||||||
|
|
||||||
// selection end
|
// selection end
|
||||||
|
|
@ -116,18 +124,16 @@ var Marker = function(parentEl) {
|
||||||
for (var row = range.start.row + 1; row < range.end.row; row++) {
|
for (var row = range.start.row + 1; row < range.end.row; row++) {
|
||||||
lineRange.start.row = row;
|
lineRange.start.row = row;
|
||||||
lineRange.end.row = row;
|
lineRange.end.row = row;
|
||||||
lineRange.end.column = this.session.getLine(row).length; // account for endofline characters
|
lineRange.end.column = this.session.getScreenLastRowColumn(row);
|
||||||
this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1);
|
this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.drawMultiLineMarker = function(stringBuilder, range, clazz, layerConfig) {
|
this.drawMultiLineMarker = function(stringBuilder, range, clazz, layerConfig) {
|
||||||
var range = range.toScreenRange(this.session);
|
|
||||||
|
|
||||||
// from selection start to the end of the line
|
// from selection start to the end of the line
|
||||||
var height = layerConfig.lineHeight;
|
var height = layerConfig.lineHeight;
|
||||||
var width = Math.round(layerConfig.width - (range.start.column * layerConfig.characterWidth));
|
var width = Math.round(layerConfig.width - (range.start.column * layerConfig.characterWidth));
|
||||||
var top = (range.start.row - layerConfig.firstRow) * layerConfig.lineHeight;
|
var top = this.$getTop(range.start.row, layerConfig);
|
||||||
var left = Math.round(range.start.column * layerConfig.characterWidth);
|
var left = Math.round(range.start.column * layerConfig.characterWidth);
|
||||||
|
|
||||||
stringBuilder.push(
|
stringBuilder.push(
|
||||||
|
|
@ -139,7 +145,7 @@ var Marker = function(parentEl) {
|
||||||
);
|
);
|
||||||
|
|
||||||
// from start of the last line to the selection end
|
// from start of the last line to the selection end
|
||||||
var top = (range.end.row - layerConfig.firstRow) * layerConfig.lineHeight;
|
var top = this.$getTop(range.end.row, layerConfig);
|
||||||
var width = Math.round(range.end.column * layerConfig.characterWidth);
|
var width = Math.round(range.end.column * layerConfig.characterWidth);
|
||||||
|
|
||||||
stringBuilder.push(
|
stringBuilder.push(
|
||||||
|
|
@ -153,7 +159,7 @@ var Marker = function(parentEl) {
|
||||||
var height = (range.end.row - range.start.row - 1) * layerConfig.lineHeight;
|
var height = (range.end.row - range.start.row - 1) * layerConfig.lineHeight;
|
||||||
if (height < 0)
|
if (height < 0)
|
||||||
return;
|
return;
|
||||||
var top = (range.start.row + 1 - layerConfig.firstRow) * layerConfig.lineHeight;
|
var top = this.$getTop(range.start.row + 1, layerConfig);
|
||||||
|
|
||||||
stringBuilder.push(
|
stringBuilder.push(
|
||||||
"<div class='", clazz, "' style='",
|
"<div class='", clazz, "' style='",
|
||||||
|
|
@ -164,11 +170,9 @@ var Marker = function(parentEl) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.drawSingleLineMarker = function(stringBuilder, range, clazz, layerConfig, extraLength) {
|
this.drawSingleLineMarker = function(stringBuilder, range, clazz, layerConfig, extraLength) {
|
||||||
var range = range.toScreenRange(this.session);
|
|
||||||
|
|
||||||
var height = layerConfig.lineHeight;
|
var height = layerConfig.lineHeight;
|
||||||
var width = Math.round((range.end.column + (extraLength || 0) - range.start.column) * layerConfig.characterWidth);
|
var width = Math.round((range.end.column + (extraLength || 0) - range.start.column) * layerConfig.characterWidth);
|
||||||
var top = (range.start.row - layerConfig.firstRow) * layerConfig.lineHeight;
|
var top = this.$getTop(range.start.row, layerConfig);
|
||||||
var left = Math.round(range.start.column * layerConfig.characterWidth);
|
var left = Math.round(range.start.column * layerConfig.characterWidth);
|
||||||
|
|
||||||
stringBuilder.push(
|
stringBuilder.push(
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
* Fabian Jakobs <fabian AT ajax DOT org>
|
* Fabian Jakobs <fabian AT ajax DOT org>
|
||||||
|
* Julian Viereck <julian.viereck@gmail.com>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
|
@ -152,23 +153,31 @@ var Text = function(parentEl) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.updateLines = function(layerConfig, firstRow, lastRow) {
|
this.updateLines = function(config, firstRow, lastRow) {
|
||||||
this.$computeTabString();
|
this.$computeTabString();
|
||||||
this.config = layerConfig;
|
// 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 ||
|
||||||
|
this.config.firstRow != config.firstRow) {
|
||||||
|
this.scrollLines(config);
|
||||||
|
}
|
||||||
|
this.config = config;
|
||||||
|
|
||||||
var first = Math.max(firstRow, layerConfig.firstRow);
|
var first = Math.max(firstRow, config.firstRow);
|
||||||
var last = Math.min(lastRow, layerConfig.lastRow);
|
var last = Math.min(lastRow, config.lastRow);
|
||||||
|
|
||||||
var lineElements = this.element.childNodes;
|
var lineElements = this.element.childNodes;
|
||||||
var tokens = this.tokenizer.getTokens(first, last);
|
var tokens = this.tokenizer.getTokens(first, last);
|
||||||
for (var i=first; i<=last; i++) {
|
for (var i=first; i<=last; i++) {
|
||||||
var lineElement = lineElements[i - layerConfig.firstRow];
|
var lineElement = lineElements[i - config.firstRow];
|
||||||
if (!lineElement)
|
if (!lineElement)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var html = [];
|
var html = [];
|
||||||
this.$renderLine(html, i, tokens[i-first].tokens);
|
this.$renderLine(html, i, tokens[i-first].tokens);
|
||||||
dom.setInnerHtml(lineElement, html.join(""));
|
lineElement = dom.setInnerHtml(lineElement, html.join(""));
|
||||||
|
lineElement.style.height =
|
||||||
|
this.session.getRowHeight(config, i) + "px";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -214,7 +223,7 @@ var Text = function(parentEl) {
|
||||||
var lineEl = document.createElement("div");
|
var lineEl = document.createElement("div");
|
||||||
lineEl.className = "ace_line";
|
lineEl.className = "ace_line";
|
||||||
var style = lineEl.style;
|
var style = lineEl.style;
|
||||||
style.height = this.$characterSize.height + "px";
|
style.height = this.session.getRowHeight(config, row) + "px";
|
||||||
style.width = config.width + "px";
|
style.width = config.width + "px";
|
||||||
|
|
||||||
var html = [];
|
var html = [];
|
||||||
|
|
@ -231,14 +240,12 @@ var Text = function(parentEl) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
|
||||||
var html = [];
|
var html = [];
|
||||||
var tokens = this.tokenizer.getTokens(config.firstRow, config.lastRow);
|
var tokens = this.tokenizer.getTokens(config.firstRow, config.lastRow)
|
||||||
for (var i=config.firstRow; i<=config.lastRow; i++) {
|
var fragment = this.$renderLinesFragment(config, config.firstRow, config.lastRow);
|
||||||
html.push("<div class='ace_line' style='height:" + this.$characterSize.height + "px;", "width:",
|
|
||||||
config.width, "px'>");
|
|
||||||
this.$renderLine(html, i, tokens[i-config.firstRow].tokens), html.push("</div>");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.element = dom.setInnerHtml(this.element, html.join(""));
|
// Clear the current content of the element and add the rendered fragment.
|
||||||
|
this.element.innerHTML = "";
|
||||||
|
this.element.appendChild(fragment);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$textToken = {
|
this.$textToken = {
|
||||||
|
|
@ -266,27 +273,63 @@ var Text = function(parentEl) {
|
||||||
var spaceReplace = " ";
|
var spaceReplace = " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _self = this;
|
||||||
var characterWidth = this.config.characterWidth;
|
var characterWidth = this.config.characterWidth;
|
||||||
|
function addToken(token, value) {
|
||||||
for ( var i = 0; i < tokens.length; i++) {
|
var output = value
|
||||||
var token = tokens[i];
|
|
||||||
|
|
||||||
var output = token.value
|
|
||||||
.replace(/&/g, "&")
|
.replace(/&/g, "&")
|
||||||
.replace(/</g, "<")
|
.replace(/</g, "<")
|
||||||
.replace(spaceRe, spaceReplace)
|
.replace(spaceRe, spaceReplace)
|
||||||
.replace(/\t/g, this.$tabString)
|
.replace(/\t/g, _self.$tabString)
|
||||||
.replace(/[\u3040-\u309F]|[\u30A0-\u30FF]|[\u4E00-\u9FFF\uF900-\uFAFF\u3400-\u4DBF]/g, function(c) {
|
.replace(/[\u3040-\u309F]|[\u30A0-\u30FF]|[\u4E00-\u9FFF\uF900-\uFAFF\u3400-\u4DBF]/g, function(c) {
|
||||||
return "<span class='ace_cjk' style='width:" + (characterWidth * 2) + "px'>" + c + "</span>"
|
return "<span class='ace_cjk' style='width:" + (characterWidth * 2) + "px'>" + c + "</span>"
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!this.$textToken[token.type]) {
|
if (!_self.$textToken[token.type]) {
|
||||||
var classes = "ace_" + token.type.replace(/\./g, " ace_");
|
var classes = "ace_" + token.type.replace(/\./g, " ace_");
|
||||||
stringBuilder.push("<span class='", classes, "'>", output, "</span>");
|
stringBuilder.push("<span class='", classes, "'>", output, "</span>");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
stringBuilder.push(output);
|
stringBuilder.push(output);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var splits = this.session.getRowSplitData(row);
|
||||||
|
var chars = 0, split = 0, splitChars;
|
||||||
|
|
||||||
|
if (!splits || splits.length == 0) {
|
||||||
|
splitChars = Number.MAX_VALUE;
|
||||||
|
} else {
|
||||||
|
splitChars = splits[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
stringBuilder.push("<div style='height:",
|
||||||
|
this.config.lineHeight, "px",
|
||||||
|
"'>");
|
||||||
|
for (var i = 0; i < tokens.length; i++) {
|
||||||
|
var token = tokens[i];
|
||||||
|
var value = token.value;
|
||||||
|
|
||||||
|
if (chars + value.length < splitChars) {
|
||||||
|
addToken(token, value);
|
||||||
|
chars += value.length;
|
||||||
|
} else {
|
||||||
|
while (chars + value.length >= splitChars) {
|
||||||
|
addToken(token, value.substring(0, splitChars - chars));
|
||||||
|
value = value.substring(splitChars - chars);
|
||||||
|
chars = splitChars;
|
||||||
|
stringBuilder.push("</div>",
|
||||||
|
"<div style='height:",
|
||||||
|
this.config.lineHeight, "px",
|
||||||
|
"'>");
|
||||||
|
split ++;
|
||||||
|
splitChars = splits[split] || Number.MAX_VALUE;
|
||||||
|
}
|
||||||
|
if (value.length != 0) {
|
||||||
|
chars += value.length;
|
||||||
|
addToken(token, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.showInvisibles) {
|
if (this.showInvisibles) {
|
||||||
|
|
@ -296,6 +339,7 @@ var Text = function(parentEl) {
|
||||||
stringBuilder.push("<span class='ace_invisible'>" + this.EOF_CHAR + "</span>");
|
stringBuilder.push("<span class='ace_invisible'>" + this.EOF_CHAR + "</span>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stringBuilder.push("</div>");
|
||||||
};
|
};
|
||||||
|
|
||||||
}).call(Text.prototype);
|
}).call(Text.prototype);
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,13 @@ oop.inherits(JavaScriptWorker, Mirror);
|
||||||
this.onUpdate = function() {
|
this.onUpdate = function() {
|
||||||
var value = this.doc.getValue();
|
var value = this.doc.getValue();
|
||||||
|
|
||||||
var start = new Date();
|
// var start = new Date();
|
||||||
var parser = require("ace/narcissus/jsparse");
|
var parser = require("ace/narcissus/jsparse");
|
||||||
try {
|
try {
|
||||||
parser.parse(value);
|
parser.parse(value);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.log("narcissus")
|
// console.log("narcissus")
|
||||||
console.log(e);
|
// console.log(e);
|
||||||
sender.emit("narcissus", {
|
sender.emit("narcissus", {
|
||||||
row: e.lineno-1,
|
row: e.lineno-1,
|
||||||
column: null, // TODO convert e.cursor
|
column: null, // TODO convert e.cursor
|
||||||
|
|
@ -32,14 +32,14 @@ oop.inherits(JavaScriptWorker, Mirror);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
} finally {
|
} finally {
|
||||||
console.log("parse time: " + (new Date() - start));
|
// console.log("parse time: " + (new Date() - start));
|
||||||
}
|
}
|
||||||
|
|
||||||
var start = new Date();
|
// var start = new Date();
|
||||||
console.log("jslint")
|
// console.log("jslint")
|
||||||
lint(value, {undef: false, onevar: false, passfail: false});
|
lint(value, {undef: false, onevar: false, passfail: false});
|
||||||
this.sender.emit("jslint", lint.errors);
|
this.sender.emit("jslint", lint.errors);
|
||||||
console.log("lint time: " + (new Date() - start));
|
// console.log("lint time: " + (new Date() - start));
|
||||||
}
|
}
|
||||||
|
|
||||||
}).call(JavaScriptWorker.prototype);
|
}).call(JavaScriptWorker.prototype);
|
||||||
|
|
|
||||||
|
|
@ -145,10 +145,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
return new Range(this.start.row, 0, this.end.row, 0)
|
return new Range(this.start.row, 0, this.end.row, 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
this.toScreenRange = function(doc) {
|
this.toScreenRange = function(session) {
|
||||||
|
var screenPosStart =
|
||||||
|
session.documentToScreenPosition(this.start);
|
||||||
|
var screenPosEnd =
|
||||||
|
session.documentToScreenPosition(this.end);
|
||||||
return new Range(
|
return new Range(
|
||||||
this.start.row, doc.documentToScreenColumn(this.start.row, this.start.column),
|
screenPosStart.row, screenPosStart.column,
|
||||||
this.end.row, doc.documentToScreenColumn(this.end.row, this.end.column)
|
screenPosEnd.row, screenPosEnd.column
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
* Fabian Jakobs <fabian AT ajax DOT org>
|
* Fabian Jakobs <fabian AT ajax DOT org>
|
||||||
|
* Julian Viereck <julian.viereck@gmail.com>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
|
@ -170,6 +171,14 @@ var Selection = function(doc) {
|
||||||
this.setSelectionAnchor(range.start.row, range.start.column);
|
this.setSelectionAnchor(range.start.row, range.start.column);
|
||||||
this.selectTo(range.end.row, range.end.column);
|
this.selectTo(range.end.row, range.end.column);
|
||||||
}
|
}
|
||||||
|
this.$updateDesiredColumn();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$updateDesiredColumn = function() {
|
||||||
|
var cursor = this.getCursor();
|
||||||
|
if (cursor) {
|
||||||
|
this.$desiredColumn = this.doc.documentToScreenColumn(cursor.row, cursor.column);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$moveSelection = function(mover) {
|
this.$moveSelection = function(mover) {
|
||||||
|
|
@ -272,7 +281,7 @@ var Selection = function(doc) {
|
||||||
|
|
||||||
this.moveCursorLeft = function() {
|
this.moveCursorLeft = function() {
|
||||||
if (this.selectionLead.column == 0) {
|
if (this.selectionLead.column == 0) {
|
||||||
// cursor is a line start
|
// cursor is a line (start
|
||||||
if (this.selectionLead.row > 0) {
|
if (this.selectionLead.row > 0) {
|
||||||
this.moveCursorTo(this.selectionLead.row - 1, this.doc
|
this.moveCursorTo(this.selectionLead.row - 1, this.doc
|
||||||
.getLine(this.selectionLead.row - 1).length);
|
.getLine(this.selectionLead.row - 1).length);
|
||||||
|
|
@ -309,19 +318,27 @@ var Selection = function(doc) {
|
||||||
this.moveCursorLineStart = function() {
|
this.moveCursorLineStart = function() {
|
||||||
var row = this.selectionLead.row;
|
var row = this.selectionLead.row;
|
||||||
var column = this.selectionLead.column;
|
var column = this.selectionLead.column;
|
||||||
var beforeCursor = this.doc.getLine(row).slice(0, column);
|
var screenRow = this.doc.documentToScreenRow(row, column);
|
||||||
|
var firstRowColumn = this.doc.getScreenFirstRowColumn(screenRow);
|
||||||
|
var beforeCursor = this.doc.getLine(row).slice(firstRowColumn, column);
|
||||||
var leadingSpace = beforeCursor.match(/^\s*/);
|
var leadingSpace = beforeCursor.match(/^\s*/);
|
||||||
if (leadingSpace[0].length == 0)
|
if (leadingSpace[0].length == 0) {
|
||||||
this.moveCursorTo(row, this.doc.getLine(row).match(/^\s*/)[0].length);
|
var lastRowColumn = this.doc.getDocumentLastRowColumn(row, column);
|
||||||
else if (leadingSpace[0].length >= column)
|
leadingSpace = this.doc.getLine(row).
|
||||||
this.moveCursorTo(row, 0);
|
substring(firstRowColumn, lastRowColumn).
|
||||||
else
|
match(/^\s*/);
|
||||||
this.moveCursorTo(row, leadingSpace[0].length);
|
this.moveCursorTo(row, firstRowColumn + leadingSpace[0].length);
|
||||||
|
} else if (leadingSpace[0].length >= column) {
|
||||||
|
this.moveCursorTo(row, firstRowColumn);
|
||||||
|
} else {
|
||||||
|
this.moveCursorTo(row, firstRowColumn + leadingSpace[0].length);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.moveCursorLineEnd = function() {
|
this.moveCursorLineEnd = function() {
|
||||||
this.moveCursorTo(this.selectionLead.row,
|
var selLead = this.selectionLead;
|
||||||
this.doc.getLine(this.selectionLead.row).length);
|
this.moveCursorTo(selLead.row,
|
||||||
|
this.doc.getDocumentLastRowColumn(selLead.row, selLead.column));
|
||||||
};
|
};
|
||||||
|
|
||||||
this.moveCursorFileEnd = function() {
|
this.moveCursorFileEnd = function() {
|
||||||
|
|
@ -387,7 +404,21 @@ var Selection = function(doc) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.moveCursorBy = function(rows, chars) {
|
this.moveCursorBy = function(rows, chars) {
|
||||||
this.moveCursorTo(this.selectionLead.row + rows, this.selectionLead.column + chars);
|
if (this.doc.getUseWrapMode()) {
|
||||||
|
var screenPos = this.doc.documentToScreenPosition(
|
||||||
|
this.selectionLead.row, this.selectionLead.column);
|
||||||
|
var screenCol =
|
||||||
|
(chars == 0 && this.$desiredColumn) || screenPos.column;
|
||||||
|
|
||||||
|
var docPos = this.doc.screenToDocumentPosition(
|
||||||
|
screenPos.row + rows, screenCol);
|
||||||
|
this.moveCursorTo(docPos.row, docPos.column + chars, chars == 0);
|
||||||
|
} else {
|
||||||
|
var docColumn =
|
||||||
|
(chars == 0 && this.$desiredColumn) || this.selectionLead.column;
|
||||||
|
this.moveCursorTo(
|
||||||
|
this.selectionLead.row + rows, docColumn + chars, chars == 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -395,20 +426,17 @@ var Selection = function(doc) {
|
||||||
this.moveCursorTo(position.row, position.column);
|
this.moveCursorTo(position.row, position.column);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.moveCursorTo = function(row, column) {
|
this.moveCursorTo = function(row, column, preventUpdateDesiredColumn) {
|
||||||
var cursor = this.$clipPositionToDocument(row, column);
|
var cursor = this.$clipPositionToDocument(row, column);
|
||||||
|
|
||||||
// only dispatch change if the cursor actually changed
|
// only dispatch change if the cursor actually changed
|
||||||
if (cursor.row !== this.selectionLead.row || cursor.column !== this.selectionLead.column) {
|
if (cursor.row !== this.selectionLead.row || cursor.column !== this.selectionLead.column) {
|
||||||
this.selectionLead = cursor;
|
this.selectionLead = cursor;
|
||||||
|
!preventUpdateDesiredColumn && this.$updateDesiredColumn(column);
|
||||||
this._dispatchEvent("changeCursor", { data: this.getCursor() });
|
this._dispatchEvent("changeCursor", { data: this.getCursor() });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.moveCursorUp = function() {
|
|
||||||
this.moveCursorBy(-1, 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.$clipPositionToDocument = function(row, column) {
|
this.$clipPositionToDocument = function(row, column) {
|
||||||
var pos = {};
|
var pos = {};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
* Fabian Jakobs <fabian AT ajax DOT org>
|
* Fabian Jakobs <fabian AT ajax DOT org>
|
||||||
|
* Julian Viereck <julian.viereck@gmail.com>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
|
@ -36,6 +37,7 @@
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
var Document = require("../document").Document,
|
var Document = require("../document").Document,
|
||||||
|
EditSession = require("../edit_session").EditSession,
|
||||||
Range = require("../range").Range,
|
Range = require("../range").Range,
|
||||||
assert = require("./assertions"),
|
assert = require("./assertions"),
|
||||||
async = require("asyncjs");
|
async = require("asyncjs");
|
||||||
|
|
@ -277,6 +279,90 @@ var Test = {
|
||||||
|
|
||||||
doc.replace(new Range(0, 0, 2, 1), ["4", "5", "6"].join("\n"));
|
doc.replace(new Range(0, 0, 2, 1), ["4", "5", "6"].join("\n"));
|
||||||
assert.equal(["4", "5", "6"].join("\n"), doc.getValue());
|
assert.equal(["4", "5", "6"].join("\n"), doc.getValue());
|
||||||
|
},
|
||||||
|
|
||||||
|
"test: wrapLine split function" : function() {
|
||||||
|
var splits;
|
||||||
|
var computeWrapSplits = EditSession.prototype.$computeWrapSplits;
|
||||||
|
var c = 0;
|
||||||
|
|
||||||
|
function computeAndAssert(line, assertEqual, wrapLimit, tabSize) {
|
||||||
|
wrapLimit = wrapLimit || 12;
|
||||||
|
tabSize = tabSize || 4;
|
||||||
|
splits = computeWrapSplits.call(EditSession.prototype, line, wrapLimit, tabSize);
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Basic splitting.
|
||||||
|
computeAndAssert("foo bar foo bar", [ 12 ]);
|
||||||
|
computeAndAssert("foo bar f bar", [ 12 ]);
|
||||||
|
computeAndAssert("foo bar f r", [ 14 ]);
|
||||||
|
computeAndAssert("foo bar foo bar foo bara foo", [12, 25]);
|
||||||
|
|
||||||
|
// Don't split if there is only whitespaces/tabs at the end of the line.
|
||||||
|
computeAndAssert("foo foo foo \t \t", [ ]);
|
||||||
|
|
||||||
|
// If there is no space to split, force split.
|
||||||
|
computeAndAssert("foooooooooooooo", [ 12 ]);
|
||||||
|
computeAndAssert("fooooooooooooooooooooooooooo", [12, 24]);
|
||||||
|
computeAndAssert("foo bar fooooooooooobooooooo", [8, 20]);
|
||||||
|
|
||||||
|
// Basic splitting + tabs.
|
||||||
|
computeAndAssert("foo \t\tbar", [ 6 ]);
|
||||||
|
computeAndAssert("foo \t \tbar", [ 7 ]);
|
||||||
|
|
||||||
|
// Ignore spaces/tabs at beginning of split.
|
||||||
|
computeAndAssert("foo \t \t \t \t bar", [ 14 ]);
|
||||||
|
|
||||||
|
// Test wrapping for asian characters.
|
||||||
|
computeAndAssert("ぁぁ", [1], 2);
|
||||||
|
computeAndAssert(" ぁぁ", [1, 2], 2);
|
||||||
|
computeAndAssert(" ぁ\tぁ", [1, 3], 2);
|
||||||
|
computeAndAssert(" ぁぁ\tぁ", [1, 4], 4);
|
||||||
|
},
|
||||||
|
|
||||||
|
"test: documentToScreen": function() {
|
||||||
|
var tabSize = 4;
|
||||||
|
var wrapLimit = 12;
|
||||||
|
var session = new EditSession(["foo bar foo bar"]);
|
||||||
|
session.setUseWrapMode(true);
|
||||||
|
session.setWrapLimit(12);
|
||||||
|
|
||||||
|
assert.position(session.documentToScreenPosition(0, 11), 0, 11);
|
||||||
|
assert.position(session.documentToScreenPosition(0, 12), 1, 0);
|
||||||
|
|
||||||
|
session = new EditSession(["ぁぁa"]);
|
||||||
|
session.setUseWrapMode(true);
|
||||||
|
session.setWrapLimit(2);
|
||||||
|
assert.position(session.documentToScreenPosition(0, 1), 1, 0);
|
||||||
|
assert.position(session.documentToScreenPosition(0, 2), 2, 0);
|
||||||
|
assert.position(session.documentToScreenPosition(0, 4), 2, 1);
|
||||||
|
},
|
||||||
|
|
||||||
|
"test: screenToDocument": function() {
|
||||||
|
var tabSize = 4;
|
||||||
|
var wrapLimit = 12;
|
||||||
|
var session = new EditSession(["foo bar foo bar"]);
|
||||||
|
session.setUseWrapMode(true);
|
||||||
|
session.setWrapLimit(12);
|
||||||
|
|
||||||
|
assert.position(session.screenToDocumentPosition(1, 0), 0, 12);
|
||||||
|
assert.position(session.screenToDocumentPosition(0, 11), 0, 11);
|
||||||
|
// Check if the position is clamped the right way.
|
||||||
|
assert.position(session.screenToDocumentPosition(0, 12), 0, 11);
|
||||||
|
assert.position(session.screenToDocumentPosition(0, 20), 0, 11);
|
||||||
|
|
||||||
|
session = new EditSession(["ぁ a"]);
|
||||||
|
session.setUseWrapMode(true);
|
||||||
|
assert.position(session.screenToDocumentPosition(0, 1), 0, 0);
|
||||||
|
assert.position(session.screenToDocumentPosition(0, 2), 0, 1);
|
||||||
|
assert.position(session.screenToDocumentPosition(0, 3), 0, 2);
|
||||||
|
assert.position(session.screenToDocumentPosition(0, 4), 0, 3);
|
||||||
|
assert.position(session.screenToDocumentPosition(0, 5), 0, 3);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -257,12 +257,22 @@ var Test = {
|
||||||
|
|
||||||
session.doc.insertNewLine(0);
|
session.doc.insertNewLine(0);
|
||||||
session.doc.insertLines(1, ["\t\t"]);
|
session.doc.insertLines(1, ["\t\t"]);
|
||||||
|
|
||||||
assert.equal(session.getWidth(), 3);
|
assert.equal(session.getWidth(), 3);
|
||||||
assert.equal(session.getScreenWidth(), 8);
|
assert.equal(session.getScreenWidth(), 8);
|
||||||
|
|
||||||
session.setTabSize(2);
|
session.setTabSize(2);
|
||||||
assert.equal(session.getWidth(), 3);
|
assert.equal(session.getWidth(), 3);
|
||||||
assert.equal(session.getScreenWidth(), 4);
|
assert.equal(session.getScreenWidth(), 4);
|
||||||
|
},
|
||||||
|
|
||||||
|
"test getDisplayString": function() {
|
||||||
|
var session = new EditSession(["12"]);
|
||||||
|
session.setTabSize(4);
|
||||||
|
|
||||||
|
assert.equal(session.$getDisplayTokens("\t").length, 4);
|
||||||
|
assert.equal(session.$getDisplayTokens("abc").length, 3);
|
||||||
|
assert.equal(session.$getDisplayTokens("abc\t").length, 7);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,8 @@ MockRenderer = function(visibleRowCount) {
|
||||||
firstVisibleRow : 0,
|
firstVisibleRow : 0,
|
||||||
lastVisibleRow : this.visibleRowCount
|
lastVisibleRow : this.visibleRowCount
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.isMockRenderer = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -132,5 +134,12 @@ MockRenderer.prototype.visualizeFocus = function() {
|
||||||
MockRenderer.prototype.setAnnotations = function() {
|
MockRenderer.prototype.setAnnotations = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MockRenderer.prototype.textToScreenCoordinates = function() {
|
||||||
|
return {
|
||||||
|
pageX: 0,
|
||||||
|
pageY: 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return MockRenderer;
|
return MockRenderer;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
* Fabian Jakobs <fabian AT ajax DOT org>
|
* Fabian Jakobs <fabian AT ajax DOT org>
|
||||||
* Irakli Gozalishvili <rfobic@gmail.com> (http://jeditoolkit.com)
|
* Irakli Gozalishvili <rfobic@gmail.com> (http://jeditoolkit.com)
|
||||||
|
* Julian Viereck <julian.viereck@gmail.com>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
|
@ -115,12 +116,11 @@ var VirtualRenderer = function(container, theme) {
|
||||||
this.$loop = new RenderLoop(this.$renderChanges.bind(this));
|
this.$loop = new RenderLoop(this.$renderChanges.bind(this));
|
||||||
this.$loop.schedule(this.CHANGE_FULL);
|
this.$loop.schedule(this.CHANGE_FULL);
|
||||||
|
|
||||||
this.$updatePrintMargin();
|
|
||||||
this.setPadding(4);
|
this.setPadding(4);
|
||||||
|
this.$updatePrintMargin();
|
||||||
};
|
};
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
this.showGutter = true;
|
this.showGutter = true;
|
||||||
|
|
||||||
this.CHANGE_CURSOR = 1;
|
this.CHANGE_CURSOR = 1;
|
||||||
|
|
@ -138,8 +138,8 @@ var VirtualRenderer = function(container, theme) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.$cursorLayer.setSession(session);
|
this.$cursorLayer.setSession(session);
|
||||||
this.$markerLayer.setSession(session);
|
this.$markerLayer.setSession(session);
|
||||||
|
this.$gutterLayer.setSession(session);
|
||||||
this.$textLayer.setSession(session);
|
this.$textLayer.setSession(session);
|
||||||
|
|
||||||
this.$loop.schedule(this.CHANGE_FULL);
|
this.$loop.schedule(this.CHANGE_FULL);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -184,11 +184,11 @@ var VirtualRenderer = function(container, theme) {
|
||||||
/**
|
/**
|
||||||
* Triggers resize of the editor
|
* Triggers resize of the editor
|
||||||
*/
|
*/
|
||||||
this.onResize = function() {
|
this.onResize = function(force) {
|
||||||
var changes = this.CHANGE_SIZE;
|
var changes = this.CHANGE_SIZE;
|
||||||
|
|
||||||
var height = dom.getInnerHeight(this.container);
|
var height = dom.getInnerHeight(this.container);
|
||||||
if (this.$size.height != height) {
|
if (force || this.$size.height != height) {
|
||||||
this.$size.height = height;
|
this.$size.height = height;
|
||||||
|
|
||||||
this.scroller.style.height = height + "px";
|
this.scroller.style.height = height + "px";
|
||||||
|
|
@ -201,7 +201,7 @@ var VirtualRenderer = function(container, theme) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var width = dom.getInnerWidth(this.container);
|
var width = dom.getInnerWidth(this.container);
|
||||||
if (this.$size.width != width) {
|
if (force || this.$size.width != width) {
|
||||||
this.$size.width = width;
|
this.$size.width = width;
|
||||||
|
|
||||||
var gutterWidth = this.showGutter ? this.$gutter.offsetWidth : 0;
|
var gutterWidth = this.showGutter ? this.$gutter.offsetWidth : 0;
|
||||||
|
|
@ -264,10 +264,7 @@ var VirtualRenderer = function(container, theme) {
|
||||||
return;
|
return;
|
||||||
this.$gutter.style.display = show ? "block" : "none";
|
this.$gutter.style.display = show ? "block" : "none";
|
||||||
this.showGutter = show;
|
this.showGutter = show;
|
||||||
// set fake width to make onResize work
|
this.onResize(true);
|
||||||
this.$size.width = -1
|
|
||||||
this.onResize();
|
|
||||||
this.$gutterLayer.update(this.layerConfig)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$updatePrintMargin = function() {
|
this.$updatePrintMargin = function() {
|
||||||
|
|
@ -285,7 +282,7 @@ var VirtualRenderer = function(container, theme) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var style = this.$printMarginEl.style;
|
var style = this.$printMarginEl.style;
|
||||||
style.left = (this.characterWidth * this.$printMarginColumn) + "px";
|
style.left = ((this.characterWidth * this.$printMarginColumn) + this.$padding * 2) + "px";
|
||||||
style.visibility = this.$showPrintMargin ? "visible" : "hidden";
|
style.visibility = this.$showPrintMargin ? "visible" : "hidden";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -297,6 +294,19 @@ var VirtualRenderer = function(container, theme) {
|
||||||
return this.content;
|
return this.content;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.getTextAreaContainer = function() {
|
||||||
|
return this.scroller;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.moveTextAreaToCursor = function(textarea) {
|
||||||
|
var pos = this.$cursorLayer.getPixelPosition();
|
||||||
|
if (!pos)
|
||||||
|
return;
|
||||||
|
|
||||||
|
textarea.style.left = (pos.left + this.$padding) + "px";
|
||||||
|
textarea.style.top = pos.top + "px";
|
||||||
|
};
|
||||||
|
|
||||||
this.getFirstVisibleRow = function() {
|
this.getFirstVisibleRow = function() {
|
||||||
return (this.layerConfig || {}).firstRow || 0;
|
return (this.layerConfig || {}).firstRow || 0;
|
||||||
};
|
};
|
||||||
|
|
@ -325,6 +335,7 @@ var VirtualRenderer = function(container, theme) {
|
||||||
this.$padding = padding;
|
this.$padding = padding;
|
||||||
this.content.style.padding = "0 " + padding + "px";
|
this.content.style.padding = "0 " + padding + "px";
|
||||||
this.$loop.schedule(this.CHANGE_FULL);
|
this.$loop.schedule(this.CHANGE_FULL);
|
||||||
|
this.$updatePrintMargin();
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onScroll = function(e) {
|
this.onScroll = function(e) {
|
||||||
|
|
@ -332,7 +343,7 @@ var VirtualRenderer = function(container, theme) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$updateScrollBar = function() {
|
this.$updateScrollBar = function() {
|
||||||
this.scrollBar.setInnerHeight(this.session.getLength() * this.lineHeight);
|
this.scrollBar.setInnerHeight(this.session.getScreenLength() * this.lineHeight);
|
||||||
this.scrollBar.setScrollTop(this.scrollTop);
|
this.scrollBar.setScrollTop(this.scrollTop);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -357,6 +368,7 @@ var VirtualRenderer = function(container, theme) {
|
||||||
this.$markerLayer.update(this.layerConfig);
|
this.$markerLayer.update(this.layerConfig);
|
||||||
this.$cursorLayer.update(this.layerConfig);
|
this.$cursorLayer.update(this.layerConfig);
|
||||||
this.$updateScrollBar();
|
this.$updateScrollBar();
|
||||||
|
this.scrollCursorIntoView();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -397,20 +409,36 @@ var VirtualRenderer = function(container, theme) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$computeLayerConfig = function() {
|
this.$computeLayerConfig = function() {
|
||||||
|
var session = this.session;
|
||||||
|
|
||||||
var offset = this.scrollTop % this.lineHeight;
|
var offset = this.scrollTop % this.lineHeight;
|
||||||
var minHeight = this.$size.scrollerHeight + this.lineHeight;
|
var minHeight = this.$size.scrollerHeight + this.lineHeight;
|
||||||
|
|
||||||
var longestLine = this.$getLongestLine();
|
var longestLine = this.$getLongestLine();
|
||||||
var widthChanged = !this.layerConfig ? true : (this.layerConfig.width != longestLine);
|
var widthChanged = !this.layerConfig ? true : (this.layerConfig.width != longestLine);
|
||||||
|
|
||||||
var lineCount = Math.ceil(minHeight / this.lineHeight);
|
var lineCount = Math.ceil(minHeight / this.lineHeight) - 1;
|
||||||
var firstRow = Math.max(0, Math.round((this.scrollTop - offset) / this.lineHeight));
|
var firstRow = Math.max(0, Math.round((this.scrollTop - offset) / this.lineHeight));
|
||||||
var lastRow = Math.max(0, Math.min(this.session.getLength(), firstRow + lineCount) - 1);
|
var lastRow = firstRow + lineCount;
|
||||||
|
|
||||||
|
// Map lines on the screen to lines in the document.
|
||||||
|
var firstRowScreen, firstRowHeight;
|
||||||
|
var lineHeight = { lineHeight: this.lineHeight };
|
||||||
|
firstRow = session.screenToDocumentRow(firstRow);
|
||||||
|
firstRowScreen = session.documentToScreenRow(firstRow);
|
||||||
|
firstRowHeight = session.getRowHeight(lineHeight, firstRow);
|
||||||
|
|
||||||
|
lastRow = Math.min(session.screenToDocumentRow(lastRow), session.getLength() - 1);
|
||||||
|
minHeight = this.$size.scrollerHeight + session.getRowHeight(lineHeight, lastRow)+
|
||||||
|
firstRowHeight;
|
||||||
|
|
||||||
|
offset = this.scrollTop - firstRowScreen * this.lineHeight;
|
||||||
|
|
||||||
var layerConfig = this.layerConfig = {
|
var layerConfig = this.layerConfig = {
|
||||||
width : longestLine,
|
width : longestLine,
|
||||||
padding : this.$padding,
|
padding : this.$padding,
|
||||||
firstRow : firstRow,
|
firstRow : firstRow,
|
||||||
|
firstRowScreen: firstRowScreen,
|
||||||
lastRow : lastRow,
|
lastRow : lastRow,
|
||||||
lineHeight : this.lineHeight,
|
lineHeight : this.lineHeight,
|
||||||
characterWidth : this.characterWidth,
|
characterWidth : this.characterWidth,
|
||||||
|
|
@ -545,7 +573,7 @@ var VirtualRenderer = function(container, theme) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.scrollToY = function(scrollTop) {
|
this.scrollToY = function(scrollTop) {
|
||||||
var maxHeight = this.session.getLength() * this.lineHeight - this.$size.scrollerHeight;
|
var maxHeight = this.session.getScreenLength() * this.lineHeight - this.$size.scrollerHeight;
|
||||||
var scrollTop = Math.max(0, Math.min(maxHeight, scrollTop));
|
var scrollTop = Math.max(0, Math.min(maxHeight, scrollTop));
|
||||||
|
|
||||||
if (this.scrollTop !== scrollTop) {
|
if (this.scrollTop !== scrollTop) {
|
||||||
|
|
@ -574,17 +602,15 @@ var VirtualRenderer = function(container, theme) {
|
||||||
var row = Math.floor((pageY + this.scrollTop - canvasPos.top)
|
var row = Math.floor((pageY + this.scrollTop - canvasPos.top)
|
||||||
/ this.lineHeight);
|
/ this.lineHeight);
|
||||||
|
|
||||||
return {
|
return this.session.screenToDocumentPosition(row, Math.max(col, 0));
|
||||||
row : row,
|
|
||||||
column : this.session.screenToDocumentColumn(Math.max(0, Math.min(row, this.session.getLength()-1)), col)
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.textToScreenCoordinates = function(row, column) {
|
this.textToScreenCoordinates = function(row, column) {
|
||||||
var canvasPos = this.scroller.getBoundingClientRect();
|
var canvasPos = this.scroller.getBoundingClientRect();
|
||||||
|
var pos = this.session.documentToScreenPosition(row, column);
|
||||||
|
|
||||||
var x = this.$padding + Math.round(this.session.documentToScreenColumn(row, column) * this.characterWidth);
|
var x = this.$padding + Math.round(pos.column * this.characterWidth);
|
||||||
var y = row * this.lineHeight;
|
var y = pos.row * this.lineHeight;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pageX: canvasPos.left + x - this.getScrollLeft(),
|
pageX: canvasPos.left + x - this.getScrollLeft(),
|
||||||
|
|
@ -601,7 +627,6 @@ var VirtualRenderer = function(container, theme) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.showComposition = function(position) {
|
this.showComposition = function(position) {
|
||||||
console.log("show composition")
|
|
||||||
if (!this.$composition) {
|
if (!this.$composition) {
|
||||||
this.$composition = document.createElement("div");
|
this.$composition = document.createElement("div");
|
||||||
this.$composition.className = "ace_composition";
|
this.$composition.className = "ace_composition";
|
||||||
|
|
@ -615,13 +640,12 @@ var VirtualRenderer = function(container, theme) {
|
||||||
style.top = pos.top + "px";
|
style.top = pos.top + "px";
|
||||||
style.left = (pos.left + this.$padding) + "px";
|
style.left = (pos.left + this.$padding) + "px";
|
||||||
style.height = this.lineHeight + "px";
|
style.height = this.lineHeight + "px";
|
||||||
//style.width = this.characterWidth + "px";
|
|
||||||
|
|
||||||
this.hideCursor();
|
this.hideCursor();
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setCompositionText = function(text) {
|
this.setCompositionText = function(text) {
|
||||||
this.$composition.innerText = this.$composition.textContent = text;
|
dom.setInnerText(this.$composition, text);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.hideComposition = function() {
|
this.hideComposition = function() {
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,10 @@ var WorkerClient = function(baseUrl, topLevelNamespaces, module, classname) {
|
||||||
this.callbacks = [];
|
this.callbacks = [];
|
||||||
|
|
||||||
if (require.packaged) {
|
if (require.packaged) {
|
||||||
var worker = this.$worker = new Worker("host.js");
|
var worker = this.$worker = new Worker("worker.js");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var workerUrl = require.nameToUrl("ace/worker/host", null, "_");
|
var workerUrl = require.nameToUrl("ace/worker/worker", null, "_");
|
||||||
var worker = this.$worker = new Worker(workerUrl);
|
var worker = this.$worker = new Worker(workerUrl);
|
||||||
|
|
||||||
var tlns = {};
|
var tlns = {};
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
"asyncjs": ">=0.0.2",
|
"asyncjs": ">=0.0.2",
|
||||||
"jsdom": ">=0.1.23",
|
"jsdom": ">=0.1.23",
|
||||||
"htmlparser": ">=1.7.2",
|
"htmlparser": ">=1.7.2",
|
||||||
"dryice": ">=0.1.0"
|
"dryice": ">=0.2.1"
|
||||||
},
|
},
|
||||||
"licenses": [{
|
"licenses": [{
|
||||||
"type": "MPL",
|
"type": "MPL",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
require("./requireJS-node");
|
require("./requireJS-node");
|
||||||
require.paths.unshift(__dirname + "/../lib");
|
require.paths.unshift(__dirname + "/../lib");
|
||||||
require.paths.unshift(__dirname + "/pilot/lib");
|
require.paths.unshift(__dirname + "/pilot/lib");
|
||||||
|
require.paths.unshift(__dirname + "/async/lib");
|
||||||
|
require.paths.unshift(__dirname + "/jsdom/lib");
|
||||||
require.paths.unshift(__dirname);
|
require.paths.unshift(__dirname);
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit af90344687c8486892b44d5decc4c2181df3a6cf
|
Subproject commit 5474f1715dcc199a0c69211c89b594b9f569d9ed
|
||||||
Loading…
Add table
Add a link
Reference in a new issue