Add editor options
(1) Add UI controls for `keyMap`, `tabSize`, `indentWithTabs`, and `lineWrapping`; `indentUnit` tracks `tabSize`. (2) Dispatch `change` events from `loadPrefs` to initialize CM options from the controls' event listener. (3) Move stock options from the `CM.fromTextArea` call into `CM.defaults`. Add `CM.setOption` method, analogous to the instance method, which updates `CM.defaults` and sets the option in all instances; add `CM.getOption` which simply returns `CM.defaults[option]`. (4) Move the new editor functions into `CM.commands` and replace the functions with commands.
This commit is contained in:
parent
d9ceb98f56
commit
284d4b8ec8
|
@ -72,6 +72,26 @@
|
|||
"message": "Checking...",
|
||||
"description": "Text to display when checking a style for an update"
|
||||
},
|
||||
"cm_indentWithTabs": {
|
||||
"message": "Use tabs with smart indentation",
|
||||
"description": "Label for the checkbox controlling tabs with smart indentation option for the style editor."
|
||||
},
|
||||
"cm_keyMap": {
|
||||
"message": "Keymap",
|
||||
"description": "Label for the drop-down list controlling the keymap for the style editor."
|
||||
},
|
||||
"cm_lineWrapping": {
|
||||
"message": "Word wrap",
|
||||
"description": "Label for the checkbox controlling word wrap option for the style editor."
|
||||
},
|
||||
"cm_smartIndent": {
|
||||
"message": "Use smart indentation",
|
||||
"description": "Label for the checkbox controlling smart indentation option for the style editor."
|
||||
},
|
||||
"cm_tabSize": {
|
||||
"message": "Tab size",
|
||||
"description": "Label for the text box controlling tab size option for the style editor."
|
||||
},
|
||||
"dbError": {
|
||||
"message": "An error has occurred using the Stylish database. Would you like to visit a web page with possible solutions?",
|
||||
"description": "Prompt when a DB error is encountered"
|
||||
|
@ -169,10 +189,6 @@
|
|||
"message": "Show number of styles active for the current site on the toolbar button",
|
||||
"description": "Label for the checkbox controlling toolbar badge text."
|
||||
},
|
||||
"prefSmartIndent": {
|
||||
"message": "Use smart indentation",
|
||||
"description": "Label for the checkbox controlling smart indentation option for the style editor."
|
||||
},
|
||||
"sectionAdd": {
|
||||
"message": "Add another section",
|
||||
"description": "Label for the button to add a section"
|
||||
|
|
39
edit.html
39
edit.html
|
@ -173,6 +173,16 @@
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
/* editor options */
|
||||
[type="number"] {
|
||||
max-width: 2.8em;
|
||||
text-align: right;
|
||||
}
|
||||
table, input, select {
|
||||
font-size: inherit;
|
||||
}
|
||||
table td:first-child {min-width: 60px}
|
||||
</style>
|
||||
<script src="storage.js"></script>
|
||||
<script src="messaging.js"></script>
|
||||
|
@ -191,7 +201,34 @@
|
|||
<a href="manage.html"><button id="cancel-button"></button></a>
|
||||
<div id="options">
|
||||
<h2 id="options-heading"></h2>
|
||||
<input id="smart-indent" type="checkbox"><label id="smart-indent-label" for="smart-indent"></label>
|
||||
<table cols="2">
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<input data-option="lineWrapping" id="editor.lineWrapping" type="checkbox">
|
||||
<label id="lineWrapping-label" for="editor.lineWrapping"></label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<input data-option="smartIndent" id="editor.smartIndent" type="checkbox">
|
||||
<label id="smartIndent-label" for="editor.smartIndent"></label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<input data-option="indentWithTabs" id="editor.indentWithTabs" type="checkbox">
|
||||
<label id="indentWithTabs-label" for="editor.indentWithTabs"></label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label id="tabSize-label" for="editor.tabSize"></label></td>
|
||||
<td><input data-option="tabSize" id="editor.tabSize" type="number" min="0"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label id="keyMap-label" for="editor.keyMap"></label></td>
|
||||
<td><select data-option="keyMap" id="editor.keyMap"></select></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<section id="sections">
|
||||
|
|
111
edit.js
111
edit.js
|
@ -12,11 +12,13 @@ appliesToEverythingTemplate.innerHTML = t("appliesToEverything") + ' <button cla
|
|||
var sectionTemplate = document.createElement("div");
|
||||
sectionTemplate.innerHTML = '<label>' + t('sectionCode') + '</label><textarea class="code"></textarea><br><div class="applies-to"><label>' + t("appliesLabel") + ' <img class="applies-to-help" src="help.png" alt="' + t('helpAlt') + '"></label><ul class="applies-to-list"></ul></div><button class="remove-section">' + t('sectionRemove') + '</button><button class="add-section">' + t('sectionAdd') + '</button>';
|
||||
|
||||
var editors = []; // array of all CodeMirror instances
|
||||
function initCodeMirror() {
|
||||
var CM = CodeMirror;
|
||||
|
||||
var editors = [] // array of all CodeMirror instances
|
||||
// replace given textarea with the CodeMirror editor
|
||||
function setupCodeMirror(textarea) {
|
||||
var cm = CodeMirror.fromTextArea(textarea, {
|
||||
// default option values
|
||||
var userOptions = prefs.getPref("editor.options");
|
||||
var stylishOptions = {
|
||||
mode: 'css',
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
|
@ -24,26 +26,70 @@ function setupCodeMirror(textarea) {
|
|||
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter", "CodeMirror-lint-markers"],
|
||||
matchBrackets: true,
|
||||
lint: CodeMirror.lint.css,
|
||||
smartIndent: prefs.getPref("smart-indent"),
|
||||
keyMap: "sublime",
|
||||
extraKeys: {"Ctrl-Space": "autocomplete"}
|
||||
};
|
||||
mergeOptions(stylishOptions, CM.defaults);
|
||||
mergeOptions(userOptions, CM.defaults);
|
||||
|
||||
function mergeOptions(source, target) {
|
||||
for (var key in source) target[key] = source[key];
|
||||
return target;
|
||||
}
|
||||
|
||||
// additional commands
|
||||
var cc = CM.commands;
|
||||
cc.jumpToLine = jumpToLine;
|
||||
cc.nextBuffer = nextBuffer;
|
||||
cc.prevBuffer = prevBuffer;
|
||||
// cc.save = save;
|
||||
|
||||
// user option values
|
||||
CM.getOption = function (o) {
|
||||
return CodeMirror.defaults[o];
|
||||
}
|
||||
CM.setOption = function (o, v) {
|
||||
CodeMirror.defaults[o] = v;
|
||||
editors.forEach(function(editor) {
|
||||
editor.setOption(o, v);
|
||||
});
|
||||
}
|
||||
|
||||
// initialize global editor controls
|
||||
document.getElementById("options").addEventListener("change", acmeEventListener, false);
|
||||
|
||||
var keymapControl = document.getElementById("editor.keyMap");
|
||||
Object.keys(CodeMirror.keyMap).sort().forEach(function(map) {
|
||||
keymapControl.appendChild(document.createElement("option")).textContent = map;
|
||||
});
|
||||
|
||||
var controlPrefs = {},
|
||||
controlOptions = ["smartIndent", "indentWithTabs", "tabSize", "keyMap", "lineWrapping"];
|
||||
controlOptions.forEach(function(option) {
|
||||
controlPrefs["editor." + option] = CM.defaults[option];
|
||||
tE(option + "-label", "cm_" + option);
|
||||
});
|
||||
loadPrefs(controlPrefs);
|
||||
|
||||
}
|
||||
initCodeMirror();
|
||||
|
||||
function acmeEventListener(event) {
|
||||
var option = event.target.dataset.option;
|
||||
console.log("acmeEventListener heard %s on %s", event.type, event.target.id);
|
||||
if (!option) console.error("acmeEventListener: no 'cm_option' %O", event.target);
|
||||
else CodeMirror.setOption(option, event.target[isCheckbox(event.target) ? "checked" : "value"]);
|
||||
|
||||
if ("tabSize" === option) CodeMirror.setOption("indentUnit", CodeMirror.getOption("tabSize"));
|
||||
}
|
||||
|
||||
// replace given textarea with the CodeMirror editor
|
||||
function setupCodeMirror(textarea) {
|
||||
var cm = CodeMirror.fromTextArea(textarea);
|
||||
cm.addKeyMap({
|
||||
"Ctrl-G": function(cm) {
|
||||
var cur = cm.getCursor();
|
||||
cm.openDialog(t('editGotoLine') + ': <input type="text" style="width: 5em"/>', function(str) {
|
||||
var m = str.match(/^\s*(\d+)(?:\s*:\s*(\d+))?\s*$/);
|
||||
if (m) {
|
||||
cm.setCursor(m[1] - 1, m[2] ? m[2] - 1 : cur.ch);
|
||||
}
|
||||
}, {value: cur.line+1});
|
||||
},
|
||||
"Alt-PageDown": function(cm) {
|
||||
editors[(editors.indexOf(cm) + 1) % editors.length].focus();
|
||||
},
|
||||
"Alt-PageUp": function(cm) {
|
||||
editors[(editors.indexOf(cm) - 1 + editors.length) % editors.length].focus();
|
||||
}
|
||||
"Ctrl-G": "jumpToLine",
|
||||
"Alt-PageDown": "nextBuffer",
|
||||
"Alt-PageUp": "prevBuffer"
|
||||
});
|
||||
cm.lastChange = cm.changeGeneration();
|
||||
cm.on("change", indicateCodeChange);
|
||||
|
@ -325,11 +371,27 @@ function setupGlobalSearch() {
|
|||
CodeMirror.commands.findPrev = function(cm) { findNext(cm, true) }
|
||||
}
|
||||
|
||||
function jumpToLine(cm) {
|
||||
var cur = cm.getCursor();
|
||||
cm.openDialog(t('editGotoLine') + ': <input type="text" style="width: 5em"/>', function(str) {
|
||||
var m = str.match(/^\s*(\d+)(?:\s*:\s*(\d+))?\s*$/);
|
||||
if (m) {
|
||||
cm.setCursor(m[1] - 1, m[2] ? m[2] - 1 : cur.ch);
|
||||
}
|
||||
}, {value: cur.line+1});
|
||||
}
|
||||
|
||||
function nextBuffer(cm) {
|
||||
editors[(editors.indexOf(cm) + 1) % editors.length].focus();
|
||||
}
|
||||
function prevBuffer(cm) {
|
||||
editors[(editors.indexOf(cm) - 1 + editors.length) % editors.length].focus();
|
||||
}
|
||||
|
||||
window.addEventListener("load", init, false);
|
||||
|
||||
function init() {
|
||||
tE("sections-help", "helpAlt", "alt");
|
||||
loadPrefs({"smart-indent": true});
|
||||
var params = getParams();
|
||||
if (!params.id) { // match should be 2 - one for the whole thing, one for the parentheses
|
||||
// This is an add
|
||||
|
@ -554,10 +616,8 @@ chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
|
|||
}
|
||||
break;
|
||||
case "prefChanged":
|
||||
if (request.prefName == "smart-indent") {
|
||||
editors.forEach(function(editor) {
|
||||
editor.setOption("smartIndent", request.value);
|
||||
});
|
||||
if (request.prefName == "editor.smartIndent") {
|
||||
CodeMirror.setOption("smartIndent", request.value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -569,7 +629,6 @@ tE("save-button", "styleSaveLabel");
|
|||
tE("cancel-button", "styleCancelEditLabel");
|
||||
tE("sections-heading", "styleSectionsTitle");
|
||||
tE("options-heading", "optionsHeading");
|
||||
tE("smart-indent-label", "prefSmartIndent");
|
||||
|
||||
document.getElementById("name").addEventListener("change", makeDirty, false);
|
||||
document.getElementById("enabled").addEventListener("change", makeDirty, false);
|
||||
|
|
10
storage.js
10
storage.js
|
@ -162,14 +162,20 @@ var prefs = {
|
|||
// defaults
|
||||
"openEditInWindow": false, // new editor opens in a own browser window
|
||||
"show-badge": true, // display text on popup menu icon
|
||||
"smart-indent": true, // CodeMirror smart indent
|
||||
|
||||
"popup.breadcrumbs": true, // display "New style" links as URL breadcrumbs
|
||||
"popup.breadcrumbs.usePath": false, // use URL path for "this URL"
|
||||
"popup.enabledFirst": true, // display enabled styles before disabled styles
|
||||
|
||||
"manage.onlyEnabled": false, // display only enabled styles
|
||||
"manage.onlyEdited": false,// display only styles created locally
|
||||
"manage.onlyEdited": false, // display only styles created locally
|
||||
|
||||
"editor.options": null, // CodeMirror.defaults.*
|
||||
"editor.lineWrapping": true, // word wrap
|
||||
"editor.smartIndent": true, // "smart" indent
|
||||
"editor.indentWithTabs": false,// smart indent with tabs
|
||||
"editor.tabSize": 4, // tab width, in spaces
|
||||
"editor.keyMap": "sublime", // keymap
|
||||
|
||||
NO_DEFAULT_PREFERENCE: "No default preference for '%s'",
|
||||
UNHANDLED_DATA_TYPE: "Default '%s' is of type '%s' - what should be done with it?",
|
||||
|
|
Loading…
Reference in New Issue
Block a user