347 lines
11 KiB
JavaScript
Executable File
347 lines
11 KiB
JavaScript
Executable File
define(function(require, exports, module) {
|
|
"use strict";
|
|
var overlayPage = require('./menu_tools/overlay_page').overlayPage;
|
|
|
|
|
|
var dom = require("../lib/dom");
|
|
var oop = require("../lib/oop");
|
|
var EventEmitter = require("../lib/event_emitter").EventEmitter;
|
|
var buildDom = dom.buildDom;
|
|
|
|
var modelist = require("./modelist");
|
|
var themelist = require("./themelist");
|
|
|
|
var themes = { Bright: [], Dark: [] };
|
|
themelist.themes.forEach(function(x) {
|
|
themes[x.isDark ? "Dark" : "Bright"].push({ caption: x.caption, value: x.theme });
|
|
});
|
|
|
|
var modes = modelist.modes.map(function(x){
|
|
return { caption: x.caption, value: x.mode };
|
|
});
|
|
|
|
|
|
var optionGroups = {
|
|
Main: {
|
|
Mode: {
|
|
path: "mode",
|
|
type: "select",
|
|
items: modes
|
|
},
|
|
Theme: {
|
|
path: "theme",
|
|
type: "select",
|
|
items: themes
|
|
},
|
|
"Keybinding": {
|
|
type: "buttonBar",
|
|
path: "keyboardHandler",
|
|
items: [
|
|
{ caption : "Ace", value : null },
|
|
{ caption : "Vim", value : "ace/keyboard/vim" },
|
|
{ caption : "Emacs", value : "ace/keyboard/emacs" },
|
|
{ caption : "Sublime", value : "ace/keyboard/sublime" }
|
|
]
|
|
},
|
|
"Font Size": {
|
|
path: "fontSize",
|
|
type: "number",
|
|
defaultValue: 12,
|
|
defaults: [
|
|
{caption: "12px", value: 12},
|
|
{caption: "24px", value: 24}
|
|
]
|
|
},
|
|
"Soft Wrap": {
|
|
type: "buttonBar",
|
|
path: "wrap",
|
|
items: [
|
|
{ caption : "Off", value : "off" },
|
|
{ caption : "View", value : "free" },
|
|
{ caption : "margin", value : "printMargin" },
|
|
{ caption : "40", value : "40" }
|
|
]
|
|
},
|
|
"Cursor Style": {
|
|
path: "cursorStyle",
|
|
items: [
|
|
{ caption : "Ace", value : "ace" },
|
|
{ caption : "Slim", value : "slim" },
|
|
{ caption : "Smooth", value : "smooth" },
|
|
{ caption : "Smooth And Slim", value : "smooth slim" },
|
|
{ caption : "Wide", value : "wide" }
|
|
]
|
|
},
|
|
"Folding": {
|
|
path: "foldStyle",
|
|
items: [
|
|
{ caption : "Manual", value : "manual" },
|
|
{ caption : "Mark begin", value : "markbegin" },
|
|
{ caption : "Mark begin and end", value : "markbeginend" }
|
|
]
|
|
},
|
|
"Soft Tabs": [{
|
|
path: "useSoftTabs"
|
|
}, {
|
|
path: "tabSize",
|
|
type: "number",
|
|
values: [2, 3, 4, 8, 16]
|
|
}],
|
|
"Overscroll": {
|
|
type: "buttonBar",
|
|
path: "scrollPastEnd",
|
|
items: [
|
|
{ caption : "None", value : 0 },
|
|
{ caption : "Half", value : 0.5 },
|
|
{ caption : "Full", value : 1 }
|
|
]
|
|
}
|
|
},
|
|
More: {
|
|
"Atomic soft tabs": {
|
|
path: "navigateWithinSoftTabs"
|
|
},
|
|
"Enable Behaviours": {
|
|
path: "behavioursEnabled"
|
|
},
|
|
"Full Line Selection": {
|
|
type: "checkbox",
|
|
values: "text|line",
|
|
path: "selectionStyle"
|
|
},
|
|
"Highlight Active Line": {
|
|
path: "highlightActiveLine"
|
|
},
|
|
"Show Invisibles": {
|
|
path: "showInvisibles"
|
|
},
|
|
"Show Indent Guides": {
|
|
path: "displayIndentGuides"
|
|
},
|
|
"Persistent Scrollbar": [{
|
|
path: "hScrollBarAlwaysVisible"
|
|
}, {
|
|
path: "vScrollBarAlwaysVisible"
|
|
}],
|
|
"Animate scrolling": {
|
|
path: "animatedScroll"
|
|
},
|
|
"Show Gutter": {
|
|
path: "showGutter"
|
|
},
|
|
"Show Line Numbers": {
|
|
path: "showLineNumbers"
|
|
},
|
|
"Relative Line Numbers": {
|
|
path: "relativeLineNumbers"
|
|
},
|
|
"Fixed Gutter Width": {
|
|
path: "fixedWidthGutter"
|
|
},
|
|
"Show Print Margin": [{
|
|
path: "showPrintMargin"
|
|
}, {
|
|
type: "number",
|
|
path: "printMarginColumn"
|
|
}],
|
|
"Indented Soft Wrap": {
|
|
path: "indentedSoftWrap"
|
|
},
|
|
"Highlight selected word": {
|
|
path: "highlightSelectedWord"
|
|
},
|
|
"Fade Fold Widgets": {
|
|
path: "fadeFoldWidgets"
|
|
},
|
|
"Use textarea for IME": {
|
|
path: "useTextareaForIME"
|
|
},
|
|
"Merge Undo Deltas": {
|
|
path: "mergeUndoDeltas",
|
|
items: [
|
|
{ caption : "Always", value : "always" },
|
|
{ caption : "Never", value : "false" },
|
|
{ caption : "Timed", value : "true" }
|
|
]
|
|
},
|
|
"Elastic Tabstops": {
|
|
path: "useElasticTabstops"
|
|
},
|
|
"Incremental Search": {
|
|
path: "useIncrementalSearch"
|
|
},
|
|
"Read-only": {
|
|
path: "readOnly"
|
|
},
|
|
"Copy without selection": {
|
|
path: "copyWithEmptySelection"
|
|
},
|
|
"Live Autocompletion": {
|
|
path: "enableLiveAutocompletion"
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
var OptionPanel = function(editor, element) {
|
|
this.editor = editor;
|
|
this.container = element || document.createElement("div");
|
|
this.groups = [];
|
|
this.options = {};
|
|
};
|
|
|
|
(function() {
|
|
|
|
oop.implement(this, EventEmitter);
|
|
|
|
this.add = function(config) {
|
|
if (config.Main)
|
|
oop.mixin(optionGroups.Main, config.Main);
|
|
if (config.More)
|
|
oop.mixin(optionGroups.More, config.More);
|
|
};
|
|
|
|
this.render = function() {
|
|
this.container.innerHTML = "";
|
|
buildDom(["table", {id: "controls"},
|
|
this.renderOptionGroup(optionGroups.Main),
|
|
["tr", null, ["td", {colspan: 2},
|
|
["table", {id: "more-controls"},
|
|
this.renderOptionGroup(optionGroups.More)
|
|
]
|
|
]]
|
|
], this.container);
|
|
};
|
|
|
|
this.renderOptionGroup = function(group) {
|
|
return Object.keys(group).map(function(key, i) {
|
|
var item = group[key];
|
|
if (!item.position)
|
|
item.position = i / 10000;
|
|
if (!item.label)
|
|
item.label = key;
|
|
return item;
|
|
}).sort(function(a, b) {
|
|
return a.position - b.position;
|
|
}).map(function(item) {
|
|
return this.renderOption(item.label, item);
|
|
}, this);
|
|
};
|
|
|
|
this.renderOptionControl = function(key, option) {
|
|
var self = this;
|
|
if (Array.isArray(option)) {
|
|
return option.map(function(x) {
|
|
return self.renderOptionControl(key, x);
|
|
});
|
|
}
|
|
var control;
|
|
|
|
var value = self.getOption(option);
|
|
|
|
if (option.values && option.type != "checkbox") {
|
|
if (typeof option.values == "string")
|
|
option.values = option.values.split("|");
|
|
option.items = option.values.map(function(v) {
|
|
return { value: v, name: v };
|
|
});
|
|
}
|
|
|
|
if (option.type == "buttonBar") {
|
|
control = ["div", option.items.map(function(item) {
|
|
return ["button", {
|
|
value: item.value,
|
|
ace_selected_button: value == item.value,
|
|
onclick: function() {
|
|
self.setOption(option, item.value);
|
|
var nodes = this.parentNode.querySelectorAll("[ace_selected_button]");
|
|
for (var i = 0; i < nodes.length; i++) {
|
|
nodes[i].removeAttribute("ace_selected_button");
|
|
}
|
|
this.setAttribute("ace_selected_button", true);
|
|
}
|
|
}, item.desc || item.caption || item.name];
|
|
})];
|
|
} else if (option.type == "number") {
|
|
control = ["input", {type: "number", value: value || option.defaultValue, style:"width:3em", oninput: function() {
|
|
self.setOption(option, parseInt(this.value));
|
|
}}];
|
|
if (option.defaults) {
|
|
control = [control, option.defaults.map(function(item) {
|
|
return ["button", {onclick: function() {
|
|
var input = this.parentNode.firstChild;
|
|
input.value = item.value;
|
|
input.oninput();
|
|
}}, item.caption];
|
|
})];
|
|
}
|
|
} else if (option.items) {
|
|
var buildItems = function(items) {
|
|
return items.map(function(item) {
|
|
return ["option", { value: item.value || item.name }, item.desc || item.caption || item.name];
|
|
});
|
|
};
|
|
|
|
var items = Array.isArray(option.items)
|
|
? buildItems(option.items)
|
|
: Object.keys(option.items).map(function(key) {
|
|
return ["optgroup", {"label": key}, buildItems(option.items[key])];
|
|
});
|
|
control = ["select", { id: key, value: value, onchange: function() {
|
|
self.setOption(option, this.value);
|
|
} }, items];
|
|
} else {
|
|
if (typeof option.values == "string")
|
|
option.values = option.values.split("|");
|
|
if (option.values) value = value == option.values[1];
|
|
control = ["input", { type: "checkbox", id: key, checked: value || null, onchange: function() {
|
|
var value = this.checked;
|
|
if (option.values) value = option.values[value ? 1 : 0];
|
|
self.setOption(option, value);
|
|
}}];
|
|
if (option.type == "checkedNumber") {
|
|
control = [control, []];
|
|
}
|
|
}
|
|
return control;
|
|
};
|
|
|
|
this.renderOption = function(key, option) {
|
|
if (option.path && !option.onchange && !this.editor.$options[option.path])
|
|
return;
|
|
this.options[option.path] = option;
|
|
var safeKey = "-" + option.path;
|
|
var control = this.renderOptionControl(safeKey, option);
|
|
return ["tr", {class: "ace_optionsMenuEntry"}, ["td",
|
|
["label", {for: safeKey}, key]
|
|
], ["td", control]];
|
|
};
|
|
|
|
this.setOption = function(option, value) {
|
|
if (typeof option == "string")
|
|
option = this.options[option];
|
|
if (value == "false") value = false;
|
|
if (value == "true") value = true;
|
|
if (value == "null") value = null;
|
|
if (value == "undefined") value = undefined;
|
|
if (typeof value == "string" && parseFloat(value).toString() == value)
|
|
value = parseFloat(value);
|
|
if (option.onchange)
|
|
option.onchange(value);
|
|
else if (option.path)
|
|
this.editor.setOption(option.path, value);
|
|
this._signal("setOption", {name: option.path, value: value});
|
|
};
|
|
|
|
this.getOption = function(option) {
|
|
if (option.getValue)
|
|
return option.getValue();
|
|
return this.editor.getOption(option.path);
|
|
};
|
|
|
|
}).call(OptionPanel.prototype);
|
|
|
|
exports.OptionPanel = OptionPanel;
|
|
|
|
});
|