better way for managing options
This commit is contained in:
parent
4a252a0c3b
commit
f74185870f
11 changed files with 324 additions and 345 deletions
|
|
@ -9,14 +9,14 @@ var StatusBar = function(editor, parentNode) {
|
|||
this.element.style.cssText = "color: gray; position:absolute; right:0; border-left:1px solid";
|
||||
parentNode.appendChild(this.element);
|
||||
|
||||
var statusUpdate = lang.deferredCall(function(){
|
||||
var statusUpdate = lang.delayedCall(function(){
|
||||
this.updateStatus(editor)
|
||||
}.bind(this));
|
||||
editor.on("changeStatus", function() {
|
||||
statusUpdate.schedule(50);
|
||||
statusUpdate.schedule(100);
|
||||
});
|
||||
editor.on("changeSelection", function() {
|
||||
statusUpdate.schedule(50);
|
||||
statusUpdate.schedule(100);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -169,4 +169,93 @@ function deHyphenate(str) {
|
|||
return str.replace(/-(.)/g, function(m, m1) { return m1.toUpperCase(); });
|
||||
}
|
||||
|
||||
function capitalize(str) {
|
||||
return str[0].toUpperCase() + str.substr(1);
|
||||
}
|
||||
|
||||
|
||||
var optionsProvider = {
|
||||
setOptions: function(optList) {
|
||||
Object.keys(optList).forEach(function(key) {
|
||||
this.setOption(key, optList[key]);
|
||||
}, this);
|
||||
},
|
||||
getOptions: function(a) {
|
||||
var b = {};
|
||||
Object.keys(a).forEach(function(key) {
|
||||
b[key] = this.getOption(key);
|
||||
}, this);
|
||||
return b;
|
||||
},
|
||||
setOption: function(name, value) {
|
||||
if (this["$" + name] === value)
|
||||
return;
|
||||
var opt = this.$options[name];
|
||||
if (!opt)
|
||||
return undefined;
|
||||
if (opt.forwardTo)
|
||||
return this[opt.forwardTo] && this[opt.forwardTo].setOption(name, value);
|
||||
|
||||
if (!opt.handlesSet)
|
||||
this["$" + name] = value;
|
||||
if (opt && opt.set)
|
||||
opt.set.call(this, value);
|
||||
},
|
||||
getOption: function(name) {
|
||||
var opt = this.$options[name];
|
||||
if (!opt)
|
||||
return undefined;
|
||||
if (opt.forwardTo)
|
||||
return this[opt.forwardTo] && this[opt.forwardTo].getOption(name);
|
||||
return opt && opt.get ? opt.get.call(this) : this["$" + name];
|
||||
}
|
||||
};
|
||||
|
||||
var defaultOptions = {};
|
||||
/*
|
||||
* option {name, value, initialValue, setterName, set, get }
|
||||
*/
|
||||
exports.defineOptions = function(obj, path, options) {
|
||||
if (!obj.$options)
|
||||
defaultOptions[path] = obj.$options = {};
|
||||
|
||||
Object.keys(options).forEach(function(key) {
|
||||
var opt = options[key];
|
||||
if (typeof opt == "string")
|
||||
opt = {forwardTo: opt};
|
||||
|
||||
opt.name || (opt.name = key);
|
||||
obj.$options[opt.name] = opt;
|
||||
if ("initialValue" in opt)
|
||||
obj["$" + opt.name] = opt.initialValue;
|
||||
|
||||
opt.setterName = capitalize(opt.name)
|
||||
if (opt.setterName) {
|
||||
addSetters(obj, opt.name, opt.setterName);
|
||||
}
|
||||
});
|
||||
|
||||
// implement option provider interface
|
||||
oop.implement(obj, optionsProvider);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
function addSetters(obj, name, setterName) {
|
||||
obj["set" + setterName] = function(value) {
|
||||
return this.setOption(name, value)
|
||||
};
|
||||
obj["get" + setterName] = function() {
|
||||
return this.getOption(name)
|
||||
};
|
||||
};
|
||||
|
||||
exports.resetOptions = function(obj) {
|
||||
Object.keys(obj.$options).forEach(function(key) {
|
||||
var opt = obj.$options[key];
|
||||
if ("value" in opt)
|
||||
obj.setOption(key, opt.value);
|
||||
});
|
||||
};
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ var assert = require("./test/assertions");
|
|||
|
||||
module.exports = {
|
||||
|
||||
"test path resolution" : function() {
|
||||
"test: path resolution" : function() {
|
||||
config.set("packaged", "true");
|
||||
var url = config.moduleUrl("kr_theme", "theme");
|
||||
assert.equal(url, "theme-kr.js");
|
||||
|
|
@ -61,6 +61,53 @@ module.exports = {
|
|||
assert.equal(url, "a/b1.js");
|
||||
|
||||
assert.equal();
|
||||
},
|
||||
"test: define options" : function() {
|
||||
var o = {};
|
||||
config.defineOptions(o, "test_object", {
|
||||
opt1: {
|
||||
set: function(val) {
|
||||
this.x = val;
|
||||
},
|
||||
value: 7,
|
||||
},
|
||||
initialValue: {
|
||||
set: function(val) {
|
||||
this.x = val;
|
||||
},
|
||||
initialValue: 8,
|
||||
},
|
||||
opt2: {
|
||||
get: function(val) {
|
||||
return this.x;
|
||||
}
|
||||
},
|
||||
forwarded: "model"
|
||||
});
|
||||
o.model = {};
|
||||
config.defineOptions(o.model, "model", {
|
||||
forwarded: {value: 1}
|
||||
});
|
||||
|
||||
config.resetOptions(o);
|
||||
config.resetOptions(o.model);
|
||||
assert.equal(o.getOption("opt1"), 7);
|
||||
assert.equal(o.getOption("opt2"), 7);
|
||||
o.setOption("opt1", 8);
|
||||
assert.equal(o.getOption("opt1"), 8);
|
||||
assert.equal(o.getOption("opt2"), 8);
|
||||
|
||||
assert.equal(o.getOption("forwarded"), 1);
|
||||
|
||||
assert.equal(o.getOption("new"), undefined);
|
||||
o.setOption("new", 0);
|
||||
assert.equal(o.getOption("new"), undefined);
|
||||
|
||||
|
||||
assert.equal(o.getOption("initialValue"), 8);
|
||||
o.setOption("initialValue", 7);
|
||||
assert.equal(o.getOption("opt2"), 7);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ var Range = require("./range").Range;
|
|||
var Document = require("./document").Document;
|
||||
var BackgroundTokenizer = require("./background_tokenizer").BackgroundTokenizer;
|
||||
var SearchHighlight = require("./search_highlight").SearchHighlight;
|
||||
var config = require("./config");
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -175,6 +176,9 @@ var EditSession = function(text, mode) {
|
|||
|
||||
this.selection = new Selection(this);
|
||||
this.setMode(mode);
|
||||
|
||||
config.resetOptions(this);
|
||||
config._emit("session", this);
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -452,50 +456,26 @@ var EditSession = function(text, mode) {
|
|||
}
|
||||
};
|
||||
|
||||
this.$useSoftTabs = true;
|
||||
/**
|
||||
* Pass `true` to enable the use of soft tabs. Soft tabs means you're using spaces instead of the tab character (`'\t'`).
|
||||
* @param {Boolean} useSoftTabs Value indicating whether or not to use soft tabs
|
||||
*
|
||||
*
|
||||
*
|
||||
**/
|
||||
this.setUseSoftTabs = function(useSoftTabs) {
|
||||
if (this.$useSoftTabs === useSoftTabs) return;
|
||||
|
||||
this.$useSoftTabs = useSoftTabs;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns `true` if soft tabs are being used, `false` otherwise.
|
||||
* @returns {Boolean}
|
||||
**/
|
||||
this.getUseSoftTabs = function() {
|
||||
return this.$useSoftTabs;
|
||||
};
|
||||
|
||||
this.$tabSize = 4;
|
||||
/**
|
||||
* Set the number of spaces that define a soft tab; for example, passing in `4` transforms the soft tabs to be equivalent to four spaces. This function also emits the `changeTabSize` event.
|
||||
* @param {Number} tabSize The new tab size
|
||||
*
|
||||
*
|
||||
**/
|
||||
this.setTabSize = function(tabSize) {
|
||||
if (isNaN(tabSize) || this.$tabSize === tabSize) return;
|
||||
|
||||
this.$modified = true;
|
||||
this.$rowLengthCache = [];
|
||||
this.$tabSize = tabSize;
|
||||
this._emit("changeTabSize");
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the current tab size.
|
||||
**/
|
||||
this.getTabSize = function() {
|
||||
return this.$tabSize;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns `true` if the character at the position is a soft tab.
|
||||
|
|
@ -864,31 +844,14 @@ var EditSession = function(text, mode) {
|
|||
return this.doc.getNewLineMode();
|
||||
};
|
||||
|
||||
this.$useWorker = true;
|
||||
|
||||
/**
|
||||
* Identifies if you want to use a worker for the `EditSession`.
|
||||
* @param {Boolean} useWorker Set to `true` to use a worker
|
||||
*
|
||||
**/
|
||||
this.setUseWorker = function(useWorker) {
|
||||
if (this.$useWorker == useWorker)
|
||||
return;
|
||||
|
||||
this.$useWorker = useWorker;
|
||||
|
||||
this.$stopWorker();
|
||||
if (useWorker)
|
||||
this.$startWorker();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns `true` if workers are being used.
|
||||
**/
|
||||
this.getUseWorker = function() {
|
||||
return this.$useWorker;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reloads all the tokens on the current session. This function calls [[BackgroundTokenizer.start `BackgroundTokenizer.start ()`]] to all the rows; it also emits the `'tokenizerUpdate'` event.
|
||||
**/
|
||||
|
|
@ -2403,5 +2366,57 @@ var EditSession = function(text, mode) {
|
|||
require("./edit_session/folding").Folding.call(EditSession.prototype);
|
||||
require("./edit_session/bracket_match").BracketMatch.call(EditSession.prototype);
|
||||
|
||||
config.defineOptions(EditSession.prototype, "session", {
|
||||
wrap: {
|
||||
set: function(value) {
|
||||
if (!value || value == "off")
|
||||
value = false;
|
||||
else if (value == "free")
|
||||
value = true;
|
||||
else if (typeof value == "string")
|
||||
value = parseInt(value, 10) || false;
|
||||
|
||||
if (!value) {
|
||||
this.setUseWrapMode(false);
|
||||
} else {
|
||||
var col = typeof value == "number" && value;
|
||||
this.setUseWrapMode(true);
|
||||
this.setWrapLimitRange(value, value);
|
||||
}
|
||||
this.$wrap = value;
|
||||
},
|
||||
get: function() {
|
||||
return this.getUseWrapMode() ? this.getWrapLimitRange().min || "free" : "off";
|
||||
},
|
||||
handlesSet: true
|
||||
},
|
||||
firstLineNumber: {
|
||||
set: function() {this._emit("changeBreakpoint");},
|
||||
initialValue: 1
|
||||
},
|
||||
useWorker: {
|
||||
set: function(useWorker) {
|
||||
this.$useWorker = useWorker;
|
||||
|
||||
this.$stopWorker();
|
||||
if (useWorker)
|
||||
this.$startWorker();
|
||||
},
|
||||
initialValue: true
|
||||
},
|
||||
useSoftTabs: {initialValue: true},
|
||||
tabSize: {
|
||||
set: function(tabSize) {
|
||||
if (isNaN(tabSize) || this.$tabSize === tabSize) return;
|
||||
|
||||
this.$modified = true;
|
||||
this.$rowLengthCache = [];
|
||||
this.$tabSize = tabSize;
|
||||
this._emit("changeTabSize");
|
||||
},
|
||||
initialValue: 4
|
||||
}
|
||||
});
|
||||
|
||||
exports.EditSession = EditSession;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -88,6 +88,8 @@ var Editor = function(renderer, session) {
|
|||
});
|
||||
|
||||
this.setSession(session || new EditSession(""));
|
||||
config.resetOptions(this);
|
||||
config._emit("editor", this);
|
||||
};
|
||||
|
||||
(function(){
|
||||
|
|
@ -807,18 +809,10 @@ var Editor = function(renderer, session) {
|
|||
*
|
||||
*
|
||||
**/
|
||||
this.setScrollSpeed = function(speed) {
|
||||
this.$mouseHandler.setScrollSpeed(speed);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the value indicating how fast the mouse scroll speed is (in milliseconds).
|
||||
* @returns {Number}
|
||||
**/
|
||||
this.getScrollSpeed = function() {
|
||||
return this.$mouseHandler.getScrollSpeed();
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the delay (in milliseconds) of the mouse drag.
|
||||
* @param {Number} dragDelay A value indicating the new delay
|
||||
|
|
@ -826,19 +820,10 @@ var Editor = function(renderer, session) {
|
|||
*
|
||||
*
|
||||
**/
|
||||
this.setDragDelay = function(dragDelay) {
|
||||
this.$mouseHandler.setDragDelay(dragDelay);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the current mouse drag delay.
|
||||
* @returns {Number}
|
||||
**/
|
||||
this.getDragDelay = function() {
|
||||
return this.$mouseHandler.getDragDelay();
|
||||
};
|
||||
|
||||
this.$selectionStyle = "line";
|
||||
|
||||
/**
|
||||
* Emitted when the selection style changes, via [[Editor.setSelectionStyle]].
|
||||
|
|
@ -860,133 +845,49 @@ var Editor = function(renderer, session) {
|
|||
*
|
||||
*
|
||||
**/
|
||||
this.setSelectionStyle = function(style) {
|
||||
if (this.$selectionStyle == style) return;
|
||||
|
||||
this.$selectionStyle = style;
|
||||
this.onSelectionChange();
|
||||
this._emit("changeSelectionStyle", {data: style});
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the current selection style.
|
||||
* @returns {String}
|
||||
**/
|
||||
this.getSelectionStyle = function() {
|
||||
return this.$selectionStyle;
|
||||
};
|
||||
|
||||
this.$highlightActiveLine = true;
|
||||
|
||||
/**
|
||||
* Determines whether or not the current line should be highlighted.
|
||||
* @param {Boolean} shouldHighlight Set to `true` to highlight the current line
|
||||
*
|
||||
**/
|
||||
this.setHighlightActiveLine = function(shouldHighlight) {
|
||||
if (this.$highlightActiveLine == shouldHighlight)
|
||||
return;
|
||||
|
||||
this.$highlightActiveLine = shouldHighlight;
|
||||
this.$updateHighlightActiveLine();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns `true` if current lines are always highlighted.
|
||||
* @return {Boolean}
|
||||
**/
|
||||
this.getHighlightActiveLine = function() {
|
||||
return this.$highlightActiveLine;
|
||||
};
|
||||
|
||||
this.$highlightGutterLine = true;
|
||||
this.setHighlightGutterLine = function(shouldHighlight) {
|
||||
if (this.$highlightGutterLine == shouldHighlight)
|
||||
return;
|
||||
|
||||
this.renderer.setHighlightGutterLine(shouldHighlight);
|
||||
this.$highlightGutterLine = shouldHighlight;
|
||||
};
|
||||
|
||||
this.getHighlightGutterLine = function() {
|
||||
return this.$highlightGutterLine;
|
||||
};
|
||||
|
||||
this.$highlightSelectedWord = true;
|
||||
/**
|
||||
* Determines if the currently selected word should be highlighted.
|
||||
* @param {Boolean} shouldHighlight Set to `true` to highlight the currently selected word
|
||||
*
|
||||
*
|
||||
**/
|
||||
this.setHighlightSelectedWord = function(shouldHighlight) {
|
||||
if (this.$highlightSelectedWord == shouldHighlight)
|
||||
return;
|
||||
|
||||
this.$highlightSelectedWord = shouldHighlight;
|
||||
this.$onSelectionChange();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns `true` if currently highlighted words are to be highlighted.
|
||||
* @returns {Boolean}
|
||||
**/
|
||||
this.getHighlightSelectedWord = function() {
|
||||
return this.$highlightSelectedWord;
|
||||
};
|
||||
|
||||
this.setAnimatedScroll = function(shouldAnimate){
|
||||
this.renderer.setAnimatedScroll(shouldAnimate);
|
||||
};
|
||||
|
||||
this.getAnimatedScroll = function(){
|
||||
return this.renderer.getAnimatedScroll();
|
||||
};
|
||||
|
||||
/**
|
||||
* If `showInvisibiles` is set to `true`, invisible characters—like spaces or new lines—are show in the editor.
|
||||
* @param {Boolean} showInvisibles Specifies whether or not to show invisible characters
|
||||
*
|
||||
*
|
||||
**/
|
||||
this.setShowInvisibles = function(showInvisibles) {
|
||||
this.renderer.setShowInvisibles(showInvisibles);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns `true` if invisible characters are being shown.
|
||||
* @returns {Boolean}
|
||||
**/
|
||||
this.getShowInvisibles = function() {
|
||||
return this.renderer.getShowInvisibles();
|
||||
};
|
||||
|
||||
this.setDisplayIndentGuides = function(display) {
|
||||
this.renderer.setDisplayIndentGuides(display);
|
||||
};
|
||||
|
||||
this.getDisplayIndentGuides = function() {
|
||||
return this.renderer.getDisplayIndentGuides();
|
||||
};
|
||||
|
||||
/**
|
||||
* If `showPrintMargin` is set to `true`, the print margin is shown in the editor.
|
||||
* @param {Boolean} showPrintMargin Specifies whether or not to show the print margin
|
||||
*
|
||||
*
|
||||
**/
|
||||
this.setShowPrintMargin = function(showPrintMargin) {
|
||||
this.renderer.setShowPrintMargin(showPrintMargin);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns `true` if the print margin is being shown.
|
||||
* @returns {Boolean}
|
||||
**/
|
||||
this.getShowPrintMargin = function() {
|
||||
return this.renderer.getShowPrintMargin();
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the column defining where the print margin should be.
|
||||
* @param {Number} showPrintMargin Specifies the new print margin
|
||||
|
|
@ -994,61 +895,26 @@ var Editor = function(renderer, session) {
|
|||
*
|
||||
*
|
||||
**/
|
||||
this.setPrintMarginColumn = function(showPrintMargin) {
|
||||
this.renderer.setPrintMarginColumn(showPrintMargin);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the column number of where the print margin is.
|
||||
* @returns {Number}
|
||||
**/
|
||||
this.getPrintMarginColumn = function() {
|
||||
return this.renderer.getPrintMarginColumn();
|
||||
};
|
||||
|
||||
this.$readOnly = false;
|
||||
/**
|
||||
* If `readOnly` is true, then the editor is set to read-only mode, and none of the content can change.
|
||||
* @param {Boolean} readOnly Specifies whether the editor can be modified or not
|
||||
*
|
||||
*
|
||||
**/
|
||||
this.setReadOnly = function(readOnly) {
|
||||
this.$readOnly = readOnly;
|
||||
this.textInput.setReadOnly(readOnly);
|
||||
this.renderer.$cursorLayer.setBlinking(!readOnly);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns `true` if the editor is set to read-only mode.
|
||||
* @returns {Boolean}
|
||||
**/
|
||||
this.getReadOnly = function() {
|
||||
return this.$readOnly;
|
||||
};
|
||||
|
||||
this.$modeBehaviours = true;
|
||||
|
||||
/**
|
||||
* Specifies whether to use behaviors or not. ["Behaviors" in this case is the auto-pairing of special characters, like quotation marks, parenthesis, or brackets.]{: #BehaviorsDef}
|
||||
* @param {Boolean} enabled Enables or disables behaviors
|
||||
*
|
||||
*
|
||||
**/
|
||||
this.setBehavioursEnabled = function (enabled) {
|
||||
this.$modeBehaviours = enabled;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns `true` if the behaviors are currently enabled. {:BehaviorsDef}
|
||||
*
|
||||
* @returns {Boolean}
|
||||
**/
|
||||
this.getBehavioursEnabled = function () {
|
||||
return this.$modeBehaviours;
|
||||
};
|
||||
|
||||
this.$modeWrapBehaviours = true;
|
||||
|
||||
/**
|
||||
* Specifies whether to use wrapping behaviors or not, i.e. automatically wrapping the selection with characters such as brackets
|
||||
|
|
@ -1056,49 +922,19 @@ var Editor = function(renderer, session) {
|
|||
* @param {Boolean} enabled Enables or disables wrapping behaviors
|
||||
*
|
||||
**/
|
||||
this.setWrapBehavioursEnabled = function (enabled) {
|
||||
this.$modeWrapBehaviours = enabled;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns `true` if the wrapping behaviors are currently enabled.
|
||||
**/
|
||||
this.getWrapBehavioursEnabled = function () {
|
||||
return this.$modeWrapBehaviours;
|
||||
};
|
||||
|
||||
/**
|
||||
* Indicates whether the fold widgets are shown or not.
|
||||
* @param {Boolean} show Specifies whether the fold widgets are shown
|
||||
*
|
||||
*
|
||||
**/
|
||||
this.setShowFoldWidgets = function(show) {
|
||||
var gutter = this.renderer.$gutterLayer;
|
||||
if (gutter.getShowFoldWidgets() == show)
|
||||
return;
|
||||
|
||||
this.renderer.$gutterLayer.setShowFoldWidgets(show);
|
||||
this.$showFoldWidgets = show;
|
||||
this.renderer.updateFull();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns `true` if the fold widgets are shown.
|
||||
* @return {Boolean}
|
||||
**/
|
||||
this.getShowFoldWidgets = function() {
|
||||
return this.renderer.$gutterLayer.getShowFoldWidgets();
|
||||
};
|
||||
|
||||
this.setFadeFoldWidgets = function(show) {
|
||||
this.renderer.setFadeFoldWidgets(show);
|
||||
};
|
||||
|
||||
this.getFadeFoldWidgets = function() {
|
||||
return this.renderer.getFadeFoldWidgets();
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes words of text from the editor. A "word" is defined as a string of characters bookended by whitespace.
|
||||
* @param {String} dir The direction of the deletion to occur, either "left" or "right"
|
||||
|
|
@ -2172,5 +2008,45 @@ var Editor = function(renderer, session) {
|
|||
}).call(Editor.prototype);
|
||||
|
||||
|
||||
|
||||
config.defineOptions(Editor.prototype, "editor", {
|
||||
selectionStyle: {
|
||||
set: function(style) {
|
||||
this.onSelectionChange();
|
||||
this._emit("changeSelectionStyle", {data: style});
|
||||
},
|
||||
initialValue: "line",
|
||||
},
|
||||
highlightActiveLine: {
|
||||
set: function() {this.$updateHighlightActiveLine();},
|
||||
initialValue: true
|
||||
},
|
||||
highlightSelectedWord: {
|
||||
set: function(shouldHighlight) {this.$onSelectionChange();},
|
||||
initialValue: true
|
||||
},
|
||||
readOnly: {
|
||||
set: function(readOnly) {
|
||||
this.textInput.setReadOnly(readOnly);
|
||||
this.renderer.$cursorLayer.setBlinking(!readOnly);
|
||||
},
|
||||
initialValue: false
|
||||
},
|
||||
behavioursEnabled: {initialValue: true},
|
||||
wrapBehavioursEnabled: {initialValue: true},
|
||||
|
||||
highlightGutterLine: "renderer",
|
||||
animatedScroll: "renderer",
|
||||
showInvisibles: "renderer",
|
||||
showPrintMargin: "renderer",
|
||||
printMarginColumn: "renderer",
|
||||
fadeFoldWidgets: "renderer",
|
||||
showFoldWidgets: "renderer",
|
||||
displayIndentGuides: "renderer",
|
||||
scrollSpeed: "$mouseHandler",
|
||||
dragDelay: "$mouseHandler",
|
||||
focusTimout: "$mouseHandler"
|
||||
});
|
||||
|
||||
exports.Editor = Editor;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
define(function(require, exports, module) {
|
||||
"use strict";
|
||||
|
||||
var keyUtil = require("../lib/keys");
|
||||
var keyUtil = require("../lib/keys");
|
||||
|
||||
function HashHandler(config, platform) {
|
||||
this.platform = platform;
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ var Gutter = function(parentEl) {
|
|||
var foldWidgets = this.$showFoldWidgets && this.session.foldWidgets;
|
||||
var breakpoints = this.session.$breakpoints;
|
||||
var decorations = this.session.$decorations;
|
||||
var firstLineNumber = this.session.$firstLineNumber;
|
||||
var lastLineNumber = 0;
|
||||
|
||||
while (true) {
|
||||
|
|
@ -142,7 +143,7 @@ var Gutter = function(parentEl) {
|
|||
"<div class='ace_gutter-cell ",
|
||||
breakpoints[i] || "", decorations[i] || "", annotation.className,
|
||||
"' style='height:", this.session.getRowLength(i) * config.lineHeight, "px;'>",
|
||||
lastLineNumber = i + 1
|
||||
lastLineNumber = i + firstLineNumber
|
||||
);
|
||||
|
||||
if (foldWidgets) {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ define(function(require, exports, module) {
|
|||
var dom = require("../lib/dom");
|
||||
var useragent = require("../lib/useragent");
|
||||
|
||||
var DRAG_OFFSET = 5; // pixels
|
||||
var DRAG_OFFSET = 0; // pixels
|
||||
|
||||
function DefaultHandlers(mouseHandler) {
|
||||
mouseHandler.$clickSelection = null;
|
||||
|
|
@ -55,8 +55,6 @@ function DefaultHandlers(mouseHandler) {
|
|||
|
||||
mouseHandler.selectByLines = this.extendSelectionBy.bind(mouseHandler, "getLineRange");
|
||||
mouseHandler.selectByWords = this.extendSelectionBy.bind(mouseHandler, "getWordRange");
|
||||
|
||||
mouseHandler.$focusWaitTimout = 250;
|
||||
}
|
||||
|
||||
(function() {
|
||||
|
|
@ -86,7 +84,7 @@ function DefaultHandlers(mouseHandler) {
|
|||
// selection
|
||||
if (inSelection && !editor.isFocused()) {
|
||||
editor.focus();
|
||||
if (this.$focusWaitTimout && !this.$clickSelection) {
|
||||
if (this.$focusTimout && !this.$clickSelection) {
|
||||
this.setState("focusWait");
|
||||
this.captureMouse(ev);
|
||||
return ev.preventDefault();
|
||||
|
|
@ -205,8 +203,8 @@ function DefaultHandlers(mouseHandler) {
|
|||
var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
|
||||
var time = (new Date()).getTime();
|
||||
|
||||
if (distance > DRAG_OFFSET ||time - this.mousedownEvent.time > this.$focusWaitTimout)
|
||||
this.startSelect();
|
||||
if (distance > DRAG_OFFSET || time - this.mousedownEvent.time > this.$focusTimout)
|
||||
this.startSelect(this.mousedownEvent.getDocumentPosition());
|
||||
};
|
||||
|
||||
this.dragWait = function(e) {
|
||||
|
|
@ -216,7 +214,7 @@ function DefaultHandlers(mouseHandler) {
|
|||
|
||||
if (distance > DRAG_OFFSET) {
|
||||
this.startSelect(this.mousedownEvent.getDocumentPosition());
|
||||
} else if (time - this.mousedownEvent.time > editor.getDragDelay()) {
|
||||
} else if (time - this.mousedownEvent.time > editor.$mouseHandler.$dragDelay) {
|
||||
this.startDrag();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ var DefaultHandlers = require("./default_handlers").DefaultHandlers;
|
|||
var DefaultGutterHandler = require("./default_gutter_handler").GutterHandler;
|
||||
var MouseEvent = require("./mouse_event").MouseEvent;
|
||||
var DragdropHandler = require("./dragdrop").DragdropHandler;
|
||||
var config = require("../config");
|
||||
|
||||
var MouseHandler = function(editor) {
|
||||
this.editor = editor;
|
||||
|
|
@ -64,29 +65,10 @@ var MouseHandler = function(editor) {
|
|||
};
|
||||
|
||||
(function() {
|
||||
|
||||
this.$scrollSpeed = 1;
|
||||
this.setScrollSpeed = function(speed) {
|
||||
this.$scrollSpeed = speed;
|
||||
};
|
||||
|
||||
this.getScrollSpeed = function() {
|
||||
return this.$scrollSpeed;
|
||||
};
|
||||
|
||||
this.onMouseEvent = function(name, e) {
|
||||
this.editor._emit(name, new MouseEvent(e, this.editor));
|
||||
};
|
||||
|
||||
this.$dragDelay = 250;
|
||||
this.setDragDelay = function(dragDelay) {
|
||||
this.$dragDelay = dragDelay;
|
||||
};
|
||||
|
||||
this.getDragDelay = function() {
|
||||
return this.$dragDelay;
|
||||
};
|
||||
|
||||
this.onMouseMove = function(name, e) {
|
||||
// optimization, because mousemove doesn't have a default handler.
|
||||
var listeners = this.editor._eventRegistry && this.editor._eventRegistry.mousemove;
|
||||
|
|
@ -157,5 +139,12 @@ var MouseHandler = function(editor) {
|
|||
};
|
||||
}).call(MouseHandler.prototype);
|
||||
|
||||
config.defineOptions(MouseHandler.prototype, "mouseHandler", {
|
||||
scrollSpeed: {initialValue: 1},
|
||||
dragDelay: {initialValue: 150},
|
||||
focusTimout: {initialValue: 0}
|
||||
});
|
||||
|
||||
|
||||
exports.MouseHandler = MouseHandler;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ var testNames = [
|
|||
"ace/anchor_test",
|
||||
"ace/background_tokenizer_test",
|
||||
"ace/commands/command_manager_test",
|
||||
"ace/config_test",
|
||||
"ace/document_test",
|
||||
"ace/edit_session_test",
|
||||
"ace/editor_change_document_test",
|
||||
|
|
|
|||
|
|
@ -94,7 +94,6 @@ var VirtualRenderer = function(container, theme) {
|
|||
this.content.className = "ace_content";
|
||||
this.scroller.appendChild(this.content);
|
||||
|
||||
this.setHighlightGutterLine(true);
|
||||
this.$gutterLayer = new GutterLayer(this.$gutter);
|
||||
this.$gutterLayer.on("changeGutterWidth", this.onGutterResize.bind(this));
|
||||
|
||||
|
|
@ -111,8 +110,6 @@ var VirtualRenderer = function(container, theme) {
|
|||
this.$horizScroll = false;
|
||||
this.$horizScrollAlwaysVisible = false;
|
||||
|
||||
this.$animatedScroll = false;
|
||||
|
||||
this.scrollBar = new ScrollBar(this.container);
|
||||
this.scrollBar.addEventListener("scroll", function(e) {
|
||||
if (!_self.$inScrollAnimation)
|
||||
|
|
@ -167,10 +164,11 @@ var VirtualRenderer = function(container, theme) {
|
|||
|
||||
this.updateCharacterSize();
|
||||
this.setPadding(4);
|
||||
config.resetOptions(this);
|
||||
config._emit("renderer", this);
|
||||
};
|
||||
|
||||
(function() {
|
||||
this.showGutter = true;
|
||||
|
||||
this.CHANGE_CURSOR = 1;
|
||||
this.CHANGE_MARKER = 2;
|
||||
|
|
@ -321,7 +319,7 @@ var VirtualRenderer = function(container, theme) {
|
|||
if (width && (force || this.resizing > 1 || size.width != width)) {
|
||||
size.width = width;
|
||||
|
||||
var gutterWidth = this.showGutter ? this.$gutter.offsetWidth : 0;
|
||||
var gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
|
||||
this.scroller.style.left = gutterWidth + "px";
|
||||
size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBar.getWidth());
|
||||
this.scroller.style.right = this.scrollBar.getWidth() + "px";
|
||||
|
|
@ -341,7 +339,7 @@ var VirtualRenderer = function(container, theme) {
|
|||
|
||||
this.onGutterResize = function() {
|
||||
var width = this.$size.width;
|
||||
var gutterWidth = this.showGutter ? this.$gutter.offsetWidth : 0;
|
||||
var gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
|
||||
this.scroller.style.left = gutterWidth + "px";
|
||||
this.$size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBar.getWidth());
|
||||
|
||||
|
|
@ -366,19 +364,11 @@ var VirtualRenderer = function(container, theme) {
|
|||
*
|
||||
*
|
||||
**/
|
||||
this.setAnimatedScroll = function(shouldAnimate){
|
||||
this.$animatedScroll = shouldAnimate;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns whether an animated scroll happens or not.
|
||||
* @returns {Boolean}
|
||||
**/
|
||||
this.getAnimatedScroll = function() {
|
||||
return this.$animatedScroll;
|
||||
};
|
||||
|
||||
/**
|
||||
* Identifies whether you want to show invisible characters or not.
|
||||
* @param {Boolean} showInvisibles Set to `true` to show invisibles
|
||||
|
|
@ -386,31 +376,11 @@ var VirtualRenderer = function(container, theme) {
|
|||
*
|
||||
*
|
||||
**/
|
||||
this.setShowInvisibles = function(showInvisibles) {
|
||||
if (this.$textLayer.setShowInvisibles(showInvisibles))
|
||||
this.$loop.schedule(this.CHANGE_TEXT);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns whether invisible characters are being shown or not.
|
||||
* @returns {Boolean}
|
||||
**/
|
||||
this.getShowInvisibles = function() {
|
||||
return this.$textLayer.showInvisibles;
|
||||
};
|
||||
|
||||
this.getDisplayIndentGuides = function() {
|
||||
return this.$textLayer.displayIndentGuides;
|
||||
};
|
||||
|
||||
this.setDisplayIndentGuides = function(display) {
|
||||
if (this.$textLayer.setDisplayIndentGuides(display))
|
||||
this.$loop.schedule(this.CHANGE_TEXT);
|
||||
};
|
||||
|
||||
this.$showPrintMargin = true;
|
||||
|
||||
/**
|
||||
* Identifies whether you want to show the print margin or not.
|
||||
* @param {Boolean} showPrintMargin Set to `true` to show the print margin
|
||||
|
|
@ -418,21 +388,10 @@ var VirtualRenderer = function(container, theme) {
|
|||
*
|
||||
*
|
||||
**/
|
||||
this.setShowPrintMargin = function(showPrintMargin) {
|
||||
this.$showPrintMargin = showPrintMargin;
|
||||
this.$updatePrintMargin();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether the print margin is being shown or not.
|
||||
* @returns {Boolean}
|
||||
**/
|
||||
this.getShowPrintMargin = function() {
|
||||
return this.$showPrintMargin;
|
||||
};
|
||||
|
||||
this.$printMarginColumn = 80;
|
||||
|
||||
/**
|
||||
* Identifies whether you want to show the print margin column or not.
|
||||
* @param {Boolean} showPrintMargin Set to `true` to show the print margin column
|
||||
|
|
@ -440,77 +399,22 @@ var VirtualRenderer = function(container, theme) {
|
|||
*
|
||||
*
|
||||
**/
|
||||
this.setPrintMarginColumn = function(showPrintMargin) {
|
||||
this.$printMarginColumn = showPrintMargin;
|
||||
this.$updatePrintMargin();
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns whether the print margin column is being shown or not.
|
||||
* @returns {Boolean}
|
||||
**/
|
||||
this.getPrintMarginColumn = function() {
|
||||
return this.$printMarginColumn;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns `true` if the gutter is being shown.
|
||||
* @returns {Boolean}
|
||||
**/
|
||||
this.getShowGutter = function(){
|
||||
return this.showGutter;
|
||||
};
|
||||
|
||||
/**
|
||||
* Identifies whether you want to show the gutter or not.
|
||||
* @param {Boolean} show Set to `true` to show the gutter
|
||||
*
|
||||
*
|
||||
**/
|
||||
this.setShowGutter = function(show){
|
||||
if(this.showGutter === show)
|
||||
return;
|
||||
this.$gutter.style.display = show ? "block" : "none";
|
||||
this.showGutter = show;
|
||||
this.onResize(true);
|
||||
};
|
||||
|
||||
this.getFadeFoldWidgets = function(){
|
||||
return dom.hasCssClass(this.$gutter, "ace_fade-fold-widgets");
|
||||
};
|
||||
|
||||
this.setFadeFoldWidgets = function(show) {
|
||||
if (show)
|
||||
dom.addCssClass(this.$gutter, "ace_fade-fold-widgets");
|
||||
else
|
||||
dom.removeCssClass(this.$gutter, "ace_fade-fold-widgets");
|
||||
};
|
||||
|
||||
this.$highlightGutterLine = false;
|
||||
this.setHighlightGutterLine = function(shouldHighlight) {
|
||||
if (this.$highlightGutterLine == shouldHighlight)
|
||||
return;
|
||||
this.$highlightGutterLine = shouldHighlight;
|
||||
|
||||
if (!this.$gutterLineHighlight) {
|
||||
this.$gutterLineHighlight = dom.createElement("div");
|
||||
this.$gutterLineHighlight.className = "ace_gutter-active-line";
|
||||
this.$gutter.appendChild(this.$gutterLineHighlight);
|
||||
return;
|
||||
}
|
||||
|
||||
this.$gutterLineHighlight.style.display = shouldHighlight ? "" : "none";
|
||||
// if cursorlayer have never been updated there's nothing on screen to update
|
||||
if (this.$cursorLayer.$pixelPos)
|
||||
this.$updateGutterLineHighlight();
|
||||
};
|
||||
|
||||
this.getHighlightGutterLine = function() {
|
||||
return this.$highlightGutterLine;
|
||||
};
|
||||
|
||||
this.$updateGutterLineHighlight = function() {
|
||||
this.$gutterLineHighlight.style.top = this.$cursorLayer.$pixelPos.top - this.layerConfig.offset + "px";
|
||||
this.$gutterLineHighlight.style.height = this.layerConfig.lineHeight + "px";
|
||||
|
|
@ -706,7 +610,7 @@ var VirtualRenderer = function(container, theme) {
|
|||
// update scrollbar first to not lose scroll position when gutter calls resize
|
||||
this.$updateScrollBar();
|
||||
this.$textLayer.update(this.layerConfig);
|
||||
if (this.showGutter)
|
||||
if (this.$showGutter)
|
||||
this.$gutterLayer.update(this.layerConfig);
|
||||
this.$markerBack.update(this.layerConfig);
|
||||
this.$markerFront.update(this.layerConfig);
|
||||
|
|
@ -724,7 +628,7 @@ var VirtualRenderer = function(container, theme) {
|
|||
else
|
||||
this.$textLayer.scrollLines(this.layerConfig);
|
||||
|
||||
if (this.showGutter)
|
||||
if (this.$showGutter)
|
||||
this.$gutterLayer.update(this.layerConfig);
|
||||
this.$markerBack.update(this.layerConfig);
|
||||
this.$markerFront.update(this.layerConfig);
|
||||
|
|
@ -736,15 +640,15 @@ var VirtualRenderer = function(container, theme) {
|
|||
|
||||
if (changes & this.CHANGE_TEXT) {
|
||||
this.$textLayer.update(this.layerConfig);
|
||||
if (this.showGutter)
|
||||
if (this.$showGutter)
|
||||
this.$gutterLayer.update(this.layerConfig);
|
||||
}
|
||||
else if (changes & this.CHANGE_LINES) {
|
||||
if (this.$updateLines() || (changes & this.CHANGE_GUTTER) && this.showGutter)
|
||||
if (this.$updateLines() || (changes & this.CHANGE_GUTTER) && this.$showGutter)
|
||||
this.$gutterLayer.update(this.layerConfig);
|
||||
}
|
||||
else if (changes & this.CHANGE_TEXT || changes & this.CHANGE_GUTTER) {
|
||||
if (this.showGutter)
|
||||
if (this.$showGutter)
|
||||
this.$gutterLayer.update(this.layerConfig);
|
||||
}
|
||||
|
||||
|
|
@ -852,7 +756,7 @@ var VirtualRenderer = function(container, theme) {
|
|||
|
||||
// if the last row is unknown -> redraw everything
|
||||
if (lastRow === Infinity) {
|
||||
if (this.showGutter)
|
||||
if (this.$showGutter)
|
||||
this.$gutterLayer.update(layerConfig);
|
||||
this.$textLayer.update(layerConfig);
|
||||
return;
|
||||
|
|
@ -1374,5 +1278,64 @@ var VirtualRenderer = function(container, theme) {
|
|||
|
||||
}).call(VirtualRenderer.prototype);
|
||||
|
||||
|
||||
config.defineOptions(VirtualRenderer.prototype, "renderer", {
|
||||
animatedScroll: {initialValue: false},
|
||||
showInvisibles: {
|
||||
set: function(value) {
|
||||
if (this.$textLayer.setShowInvisibles(value))
|
||||
this.$loop.schedule(this.CHANGE_TEXT);
|
||||
},
|
||||
initialValue: false
|
||||
},
|
||||
showPrintMargin: {
|
||||
set: function() { this.$updatePrintMargin(); },
|
||||
initialValue: true
|
||||
},
|
||||
printMarginColumn: {
|
||||
set: function() { this.$updatePrintMargin(); },
|
||||
initialValue: 80
|
||||
},
|
||||
showGutter: {
|
||||
set: function(show){
|
||||
this.$gutter.style.display = show ? "block" : "none";
|
||||
this.onGutterResize();
|
||||
},
|
||||
initialValue: true
|
||||
},
|
||||
fadeFoldWidgets: {
|
||||
set: function(show) {
|
||||
dom.addCssClass(this.$gutter, "ace_fade-fold-widgets", show);
|
||||
},
|
||||
initialValue: false
|
||||
},
|
||||
showFoldWidgets: {
|
||||
set: function(show) {this.$gutterLayer.setShowFoldWidgets(show)},
|
||||
initialValue: true
|
||||
},
|
||||
displayIndentGuides: {
|
||||
set: function(show) {
|
||||
if (this.$textLayer.setDisplayIndentGuides(show))
|
||||
this.$loop.schedule(this.CHANGE_TEXT);
|
||||
},
|
||||
initialValue: true
|
||||
},
|
||||
|
||||
highlightGutterLine: {
|
||||
set: function(shouldHighlight) {
|
||||
if (!this.$gutterLineHighlight) {
|
||||
this.$gutterLineHighlight = dom.createElement("div");
|
||||
this.$gutterLineHighlight.className = "ace_gutter_active_line";
|
||||
this.$gutter.appendChild(this.$gutterLineHighlight);
|
||||
return;
|
||||
}
|
||||
|
||||
this.$gutterLineHighlight.style.display = shouldHighlight ? "" : "none";
|
||||
this.$cursorLayer.$pixelPos && this.$updateGutterLineHighlight();
|
||||
},
|
||||
initialValue: false
|
||||
}
|
||||
});
|
||||
|
||||
exports.VirtualRenderer = VirtualRenderer;
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue