commit
8669a7d2d9
11 changed files with 130 additions and 125 deletions
|
|
@ -163,6 +163,6 @@ Continuous Integration status
|
|||
-----------------------------
|
||||
|
||||
This project is tested with [Travis CI](http://travis-ci.org)
|
||||
[](http://travis-ci.org/ajaxorg/ace)
|
||||
[](http://travis-ci.org/ajaxorg/ace)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -46,8 +46,6 @@ var theme = require("ace/theme/textmate");
|
|||
var EditSession = require("ace/edit_session").EditSession;
|
||||
var UndoManager = require("ace/undomanager").UndoManager;
|
||||
|
||||
var vim = require("ace/keyboard/vim").handler;
|
||||
var emacs = require("ace/keyboard/emacs").handler;
|
||||
var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
|
||||
|
||||
var Renderer = require("ace/virtual_renderer").VirtualRenderer;
|
||||
|
|
@ -162,11 +160,10 @@ commands.addCommand({
|
|||
exec: function() {alert("Fake Save File");}
|
||||
});
|
||||
|
||||
var keybindings = {
|
||||
// Null = use "default" keymapping
|
||||
ace: null,
|
||||
vim: vim,
|
||||
emacs: emacs,
|
||||
var keybindings = {
|
||||
ace: null, // Null = use "default" keymapping
|
||||
vim: require("ace/keyboard/vim").handler,
|
||||
emacs: "ace/keyboard/emacs",
|
||||
// This is a way to define simple keyboard remappings
|
||||
custom: new HashHandler({
|
||||
"gotoright": "Tab",
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@
|
|||
|
||||
<!--DEVEL-->
|
||||
<link rel="stylesheet" href="demo/kitchen-sink/styles.css" type="text/css" media="screen" charset="utf-8">
|
||||
<script src="http://use.edgefonts.net/source-code-pro.js"></script>
|
||||
<script async="true" src="http://use.edgefonts.net/source-code-pro.js"></script>
|
||||
<!--DEVEL-->
|
||||
|
||||
<link href="./doc/resources/ace/skeleton/images/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<!--PACKAGE
|
||||
<link rel="stylesheet" href="kitchen-sink/styles.css" type="text/css" media="screen" charset="utf-8">
|
||||
<script src="http://use.edgefonts.net/source-code-pro.js"></script>
|
||||
<script async="true" src="http://use.edgefonts.net/source-code-pro.js"></script>
|
||||
PACKAGE-->
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -280,4 +280,4 @@
|
|||
PACKAGE-->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ define(function(require, exports, module) {
|
|||
"no use strict";
|
||||
|
||||
var lang = require("./lib/lang");
|
||||
var oop = require("./lib/oop");
|
||||
var EventEmitter = require("./lib/event_emitter").EventEmitter;
|
||||
|
||||
var global = (function() {
|
||||
return this;
|
||||
|
|
@ -65,6 +67,9 @@ exports.all = function() {
|
|||
return lang.copyObject(options);
|
||||
};
|
||||
|
||||
// module loading
|
||||
oop.implement(exports, EventEmitter);
|
||||
|
||||
exports.moduleUrl = function(name, component) {
|
||||
if (options.$moduleUrls[name])
|
||||
return options.$moduleUrls[name];
|
||||
|
|
@ -87,6 +92,32 @@ exports.setModuleUrl = function(name, subst) {
|
|||
return options.$moduleUrls[name] = subst;
|
||||
};
|
||||
|
||||
exports.loadModule = function(moduleName, onLoad) {
|
||||
var module, moduleType;
|
||||
if (Array.isArray(moduleName)) {
|
||||
moduleType = moduleName[0];
|
||||
moduleName = moduleName[1];
|
||||
}
|
||||
try {
|
||||
module = require(moduleName);
|
||||
} catch (e) {};
|
||||
if (module)
|
||||
return onLoad(module);
|
||||
|
||||
var afterLoad = function() {
|
||||
require([moduleName], function(module) {
|
||||
exports._emit("load.module", {name: moduleName, module: module});
|
||||
onLoad(module);
|
||||
});
|
||||
};
|
||||
|
||||
if (!exports.get("packaged"))
|
||||
return afterLoad();
|
||||
net.loadScript(exports.moduleUrl(moduleName, moduleType), afterLoad);
|
||||
};
|
||||
|
||||
|
||||
// initialization
|
||||
exports.init = function() {
|
||||
options.packaged = require.packaged || module.packaged || (global.define && define.packaged);
|
||||
|
||||
|
|
|
|||
|
|
@ -898,69 +898,6 @@ var EditSession = function(text, mode) {
|
|||
};
|
||||
|
||||
this.$modes = {};
|
||||
this._loadMode = function(mode, callback) {
|
||||
if (!this.$modes["null"])
|
||||
this.$modes["null"] = this.$modes["ace/mode/text"] = new TextMode();
|
||||
|
||||
if (this.$modes[mode])
|
||||
return callback(this.$modes[mode]);
|
||||
|
||||
var _self = this;
|
||||
var module;
|
||||
try {
|
||||
module = require(mode);
|
||||
} catch (e) {};
|
||||
// sometimes require returns empty object (this bug is present in requirejs 2 as well)
|
||||
if (module && module.Mode)
|
||||
return done(module);
|
||||
|
||||
// set mode to text until loading is finished
|
||||
if (!this.$mode)
|
||||
this.$setModePlaceholder();
|
||||
|
||||
fetch(mode, function() {
|
||||
require([mode], done);
|
||||
});
|
||||
|
||||
function done(module) {
|
||||
if (_self.$modes[mode])
|
||||
return callback(_self.$modes[mode]);
|
||||
|
||||
_self.$modes[mode] = new module.Mode();
|
||||
_self.$modes[mode].$id = mode;
|
||||
_self._emit("loadmode", {
|
||||
name: mode,
|
||||
mode: _self.$modes[mode]
|
||||
});
|
||||
callback(_self.$modes[mode]);
|
||||
}
|
||||
|
||||
function fetch(name, callback) {
|
||||
if (!config.get("packaged"))
|
||||
return callback();
|
||||
|
||||
net.loadScript(config.moduleUrl(name, "mode"), callback);
|
||||
}
|
||||
};
|
||||
|
||||
this.$setModePlaceholder = function() {
|
||||
this.$mode = this.$modes["null"];
|
||||
var tokenizer = this.$mode.getTokenizer();
|
||||
|
||||
if (!this.bgTokenizer) {
|
||||
this.bgTokenizer = new BackgroundTokenizer(tokenizer);
|
||||
var _self = this;
|
||||
this.bgTokenizer.addEventListener("update", function(e) {
|
||||
_self._emit("tokenizerUpdate", e);
|
||||
});
|
||||
} else {
|
||||
this.bgTokenizer.setTokenizer(tokenizer);
|
||||
}
|
||||
this.bgTokenizer.setDocument(this.getDocument());
|
||||
|
||||
this.tokenRe = this.$mode.tokenRe;
|
||||
this.nonTokenRe = this.$mode.nonTokenRe;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets a new text mode for the `EditSession`. This method also emits the `'changeMode'` event. If a [[BackgroundTokenizer `BackgroundTokenizer`]] is set, the `'tokenizerUpdate'` event is also emitted.
|
||||
|
|
@ -970,23 +907,45 @@ var EditSession = function(text, mode) {
|
|||
this.$mode = null;
|
||||
this.$modeId = null;
|
||||
this.setMode = function(mode) {
|
||||
mode = mode || "null";
|
||||
// load on demand
|
||||
if (typeof mode === "string") {
|
||||
if (this.$modeId == mode)
|
||||
return;
|
||||
|
||||
this.$modeId = mode;
|
||||
var _self = this;
|
||||
this._loadMode(mode, function(module) {
|
||||
if (_self.$modeId !== mode)
|
||||
return;
|
||||
|
||||
_self.setMode(module);
|
||||
});
|
||||
return;
|
||||
if (mode && typeof mode === "object") {
|
||||
if (mode.getTokenizer)
|
||||
return this.$onChangeMode(mode);
|
||||
var options = mode;
|
||||
var path = options.path;
|
||||
} else {
|
||||
path = mode || "ace/mode/text";
|
||||
}
|
||||
|
||||
// this is needed if ace isn't on require path (e.g tests in node)
|
||||
if (!this.$modes["ace/mode/text"])
|
||||
this.$modes["ace/mode/text"] = new TextMode();
|
||||
|
||||
if (this.$modes[path] && !options)
|
||||
return this.$onChangeMode(this.$modes[path]);
|
||||
|
||||
// load on demand
|
||||
this.$modeId = path;
|
||||
config.loadModule(["mode", path], function(m) {
|
||||
if (this.$modeId !== path)
|
||||
return;
|
||||
if (this.$modes[path] && !options)
|
||||
return this.$onChangeMode(this.$modes[path]);
|
||||
if (m && m.Mode) {
|
||||
m = new m.Mode(options);
|
||||
if (!options) {
|
||||
this.$modes[path] = m;
|
||||
m.$id = path;
|
||||
}
|
||||
this.$onChangeMode(m)
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
// set mode to text until loading is finished
|
||||
if (!this.$mode)
|
||||
this.$onChangeMode(this.$modes["ace/mode/text"], true);
|
||||
};
|
||||
|
||||
this.$onChangeMode = function(mode, $isPlaceholder) {
|
||||
if (this.$mode === mode) return;
|
||||
this.$mode = mode;
|
||||
this.$modeId = mode.$id;
|
||||
|
|
@ -1014,14 +973,16 @@ var EditSession = function(text, mode) {
|
|||
}
|
||||
|
||||
this.bgTokenizer.setDocument(this.getDocument());
|
||||
this.bgTokenizer.start(0);
|
||||
|
||||
this.tokenRe = mode.tokenRe;
|
||||
this.nonTokenRe = mode.nonTokenRe;
|
||||
|
||||
this.$setFolding(mode.foldingRules);
|
||||
|
||||
this._emit("changeMode");
|
||||
if (!$isPlaceholder) {
|
||||
this.$setFolding(mode.foldingRules);
|
||||
this._emit("changeMode");
|
||||
this.bgTokenizer.start(0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ var Range = require("./range").Range;
|
|||
var EventEmitter = require("./lib/event_emitter").EventEmitter;
|
||||
var CommandManager = require("./commands/command_manager").CommandManager;
|
||||
var defaultCommands = require("./commands/default_commands").commands;
|
||||
var config = require("./config");
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -100,7 +101,17 @@ var Editor = function(renderer, session) {
|
|||
*
|
||||
**/
|
||||
this.setKeyboardHandler = function(keyboardHandler) {
|
||||
this.keyBinding.setKeyboardHandler(keyboardHandler);
|
||||
if (typeof keyboardHandler == "string" && keyboardHandler) {
|
||||
this.$keybindingId = keyboardHandler;
|
||||
var _self = this;
|
||||
config.loadModule(["keybinding", keyboardHandler], function(module) {
|
||||
if (_self.$keybindingId == keyboardHandler)
|
||||
_self.keyBinding.setKeyboardHandler(module && module.handler);
|
||||
});
|
||||
} else {
|
||||
delete this.$keybindingId;
|
||||
this.keyBinding.setKeyboardHandler(keyboardHandler);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2149,4 +2160,4 @@ var Editor = function(renderer, session) {
|
|||
|
||||
|
||||
exports.Editor = Editor;
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -324,6 +324,19 @@ function setupApi(editor, editorDiv, settingDiv, ace, options, loader) {
|
|||
editorDiv.style.fontSize = value;
|
||||
break;
|
||||
|
||||
case "keybindings":
|
||||
switch (value) {
|
||||
case "vim":
|
||||
editor.setKeyboardHandler("ace/keyboard/vim");
|
||||
break;
|
||||
case "emacs":
|
||||
editor.setKeyboardHandler("ace/keyboard/emacs");
|
||||
break;
|
||||
default:
|
||||
editor.setKeyboardHandler(null);
|
||||
}
|
||||
break;
|
||||
|
||||
case "softWrap":
|
||||
switch (value) {
|
||||
case "off":
|
||||
|
|
@ -391,6 +404,7 @@ function setupSettingPanel(settingDiv, settingOpener, editor, options) {
|
|||
theme: "Theme:",
|
||||
fontSize: "Font Size:",
|
||||
softWrap: "Soft Wrap:",
|
||||
keybindings: "Keyboard",
|
||||
showPrintMargin: "Show Print Margin:",
|
||||
useSoftTabs: "Use Soft Tabs:",
|
||||
showInvisibles: "Show Invisibles"
|
||||
|
|
@ -456,6 +470,11 @@ function setupSettingPanel(settingDiv, settingOpener, editor, options) {
|
|||
80: "80",
|
||||
free: "Free"
|
||||
},
|
||||
keybindings: {
|
||||
ace: "ace",
|
||||
vim: "vim",
|
||||
emacs: "emacs"
|
||||
},
|
||||
showPrintMargin: BOOL,
|
||||
useSoftTabs: BOOL,
|
||||
showInvisibles: BOOL
|
||||
|
|
@ -518,6 +537,7 @@ exports.options = {
|
|||
gutter: "false",
|
||||
fontSize: "12px",
|
||||
softWrap: "off",
|
||||
keybindings: "ace",
|
||||
showPrintMargin: "false",
|
||||
useSoftTabs: "true",
|
||||
showInvisibles: "true"
|
||||
|
|
|
|||
|
|
@ -33,14 +33,14 @@ define(function(require, exports, module) {
|
|||
|
||||
var dom = require("../lib/dom");
|
||||
|
||||
var screenToTextBlockCoordinates = function(pageX, pageY) {
|
||||
var screenToTextBlockCoordinates = function(x, y) {
|
||||
var canvasPos = this.scroller.getBoundingClientRect();
|
||||
|
||||
var col = Math.floor(
|
||||
(pageX + this.scrollLeft - canvasPos.left - this.$padding - dom.getPageScrollLeft()) / this.characterWidth
|
||||
(x + this.scrollLeft - canvasPos.left - this.$padding) / this.characterWidth
|
||||
);
|
||||
var row = Math.floor(
|
||||
(pageY + this.scrollTop - canvasPos.top - dom.getPageScrollTop()) / this.lineHeight
|
||||
(y + this.scrollTop - canvasPos.top) / this.lineHeight
|
||||
);
|
||||
|
||||
return this.session.screenToDocumentPosition(row, col);
|
||||
|
|
|
|||
|
|
@ -35,14 +35,17 @@ var oop = require("../lib/oop");
|
|||
var TextMode = require("./text").Mode;
|
||||
var Tokenizer = require("../tokenizer").Tokenizer;
|
||||
var PhpHighlightRules = require("./php_highlight_rules").PhpHighlightRules;
|
||||
var PhpLangHighlightRules = require("./php_highlight_rules").PhpLangHighlightRules;
|
||||
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
|
||||
var Range = require("../range").Range;
|
||||
var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
|
||||
var CStyleFoldMode = require("./folding/cstyle").FoldMode;
|
||||
var unicode = require("../unicode");
|
||||
|
||||
var Mode = function() {
|
||||
this.$tokenizer = new Tokenizer(new PhpHighlightRules().getRules());
|
||||
var Mode = function(opts) {
|
||||
var inline = opts && opts.inline;
|
||||
var HighlightRules = inline ? PhpLangHighlightRules : PhpHighlightRules;
|
||||
this.$tokenizer = new Tokenizer(new HighlightRules().getRules());
|
||||
this.$outdent = new MatchingBraceOutdent();
|
||||
this.$behaviour = new CstyleBehaviour();
|
||||
this.foldingRules = new CStyleFoldMode();
|
||||
|
|
|
|||
|
|
@ -1062,4 +1062,5 @@ var PhpHighlightRules = function() {
|
|||
oop.inherits(PhpHighlightRules, HtmlHighlightRules);
|
||||
|
||||
exports.PhpHighlightRules = PhpHighlightRules;
|
||||
exports.PhpLangHighlightRules = PhpLangHighlightRules;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -69,16 +69,16 @@ dom.importCssString(editorCss, "ace_editor");
|
|||
var VirtualRenderer = function(container, theme) {
|
||||
var _self = this;
|
||||
|
||||
this.container = container;
|
||||
this.container = container || dom.createElement("div");
|
||||
|
||||
// TODO: this breaks rendering in Cloud9 with multiple ace instances
|
||||
// // Imports CSS once per DOM document ('ace_editor' serves as an identifier).
|
||||
// dom.importCssString(editorCss, "ace_editor", container.ownerDocument);
|
||||
// // Imports CSS once per DOM document ('ace_editor' serves as an identifier).
|
||||
// dom.importCssString(editorCss, "ace_editor", container.ownerDocument);
|
||||
|
||||
// in IE <= 9 the native cursor always shines through
|
||||
this.$keepTextAreaAtCursor = !useragent.isIE;
|
||||
|
||||
dom.addCssClass(container, "ace_editor");
|
||||
dom.addCssClass(this.container, "ace_editor");
|
||||
|
||||
this.setTheme(theme);
|
||||
|
||||
|
|
@ -113,7 +113,7 @@ var VirtualRenderer = function(container, theme) {
|
|||
|
||||
this.$animatedScroll = false;
|
||||
|
||||
this.scrollBar = new ScrollBar(container);
|
||||
this.scrollBar = new ScrollBar(this.container);
|
||||
this.scrollBar.addEventListener("scroll", function(e) {
|
||||
if (!_self.$inScrollAnimation)
|
||||
_self.session.setScrollTop(e.data);
|
||||
|
|
@ -1278,10 +1278,7 @@ var VirtualRenderer = function(container, theme) {
|
|||
};
|
||||
|
||||
this._loadTheme = function(name, callback) {
|
||||
if (!config.get("packaged"))
|
||||
return callback();
|
||||
|
||||
net.loadScript(config.moduleUrl(name, "theme"), callback);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1292,28 +1289,12 @@ var VirtualRenderer = function(container, theme) {
|
|||
**/
|
||||
this.setTheme = function(theme) {
|
||||
var _self = this;
|
||||
|
||||
this.$themeValue = theme;
|
||||
_self._dispatchEvent('themeChange',{theme:theme});
|
||||
|
||||
if (!theme || typeof theme == "string") {
|
||||
var moduleName = theme || "ace/theme/textmate";
|
||||
|
||||
var module;
|
||||
try {
|
||||
module = require(moduleName);
|
||||
} catch (e) {};
|
||||
if (module)
|
||||
return afterLoad(module);
|
||||
|
||||
_self._loadTheme(moduleName, function() {
|
||||
require([moduleName], function(module) {
|
||||
if (_self.$themeValue !== theme)
|
||||
return;
|
||||
|
||||
afterLoad(module);
|
||||
});
|
||||
});
|
||||
config.loadModule(["theme", moduleName], afterLoad);
|
||||
} else {
|
||||
afterLoad(theme);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue