.htaccess Editor: CodeMirror fixes
This commit is contained in:
parent
367d38c549
commit
45d1cfddf6
2 changed files with 121 additions and 3 deletions
|
@ -1,4 +1,4 @@
|
||||||
CodeMirror.defineMode('shell', function() {
|
CodeMirror.defineMode('htaccess', function() {
|
||||||
|
|
||||||
var words = {};
|
var words = {};
|
||||||
function define(style, string) {
|
function define(style, string) {
|
||||||
|
@ -121,4 +121,113 @@ CodeMirror.defineMode('shell', function() {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
CodeMirror.defineMIME('text/x-sh', 'shell');
|
CodeMirror.defineMIME('text/x-htaccess', 'htaccess');
|
||||||
|
CodeMirror.defineMIME('text/x-apache-conf', 'htaccess');
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
CodeMirror.htaccessHint = function(editor, getHints, givenOptions) {
|
||||||
|
// Determine effective options based on given values and defaults.
|
||||||
|
var options = {}, defaults = CodeMirror.htaccessHint.defaults;
|
||||||
|
for (var opt in defaults)
|
||||||
|
if (defaults.hasOwnProperty(opt))
|
||||||
|
options[opt] = (givenOptions && givenOptions.hasOwnProperty(opt) ? givenOptions : defaults)[opt];
|
||||||
|
|
||||||
|
function collectHints(previousToken) {
|
||||||
|
// We want a single cursor position.
|
||||||
|
if (editor.somethingSelected()) return;
|
||||||
|
|
||||||
|
var tempToken = editor.getTokenAt(editor.getCursor());
|
||||||
|
|
||||||
|
// Don't show completions if token has changed and the option is set.
|
||||||
|
if (options.closeOnTokenChange && previousToken != null &&
|
||||||
|
(tempToken.start != previousToken.start || tempToken.type != previousToken.type)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//var result = getHints(editor, givenOptions);
|
||||||
|
var result = {
|
||||||
|
list: ['RewriteRule', 'RewriteEngine']
|
||||||
|
};
|
||||||
|
if (!result || !result.list.length) return;
|
||||||
|
var completions = result.list;
|
||||||
|
function insert(str) {
|
||||||
|
editor.replaceRange(str, result.from, result.to);
|
||||||
|
}
|
||||||
|
// When there is only one completion, use it directly.
|
||||||
|
if (options.completeSingle && completions.length == 1) {
|
||||||
|
insert(completions[0]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the select widget
|
||||||
|
var complete = document.createElement("div");
|
||||||
|
complete.className = "CodeMirror-completions";
|
||||||
|
var sel = complete.appendChild(document.createElement("select"));
|
||||||
|
// Opera doesn't move the selection when pressing up/down in a
|
||||||
|
// multi-select, but it does properly support the size property on
|
||||||
|
// single-selects, so no multi-select is necessary.
|
||||||
|
if (!window.opera) sel.multiple = true;
|
||||||
|
for (var i = 0; i < completions.length; ++i) {
|
||||||
|
var opt = sel.appendChild(document.createElement("option"));
|
||||||
|
opt.appendChild(document.createTextNode(completions[i]));
|
||||||
|
}
|
||||||
|
sel.firstChild.selected = true;
|
||||||
|
sel.size = Math.min(10, completions.length);
|
||||||
|
var pos = editor.cursorCoords(options.alignWithWord ? result.from : null);
|
||||||
|
complete.style.left = pos.left + "px";
|
||||||
|
complete.style.top = pos.bottom + "px";
|
||||||
|
document.body.appendChild(complete);
|
||||||
|
// If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
|
||||||
|
var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
|
||||||
|
if(winW - pos.left < sel.clientWidth)
|
||||||
|
complete.style.left = (pos.left - sel.clientWidth) + "px";
|
||||||
|
// Hack to hide the scrollbar.
|
||||||
|
if (completions.length <= 10)
|
||||||
|
complete.style.width = (sel.clientWidth - 1) + "px";
|
||||||
|
|
||||||
|
var done = false;
|
||||||
|
function close() {
|
||||||
|
if (done) return;
|
||||||
|
done = true;
|
||||||
|
complete.parentNode.removeChild(complete);
|
||||||
|
}
|
||||||
|
function pick() {
|
||||||
|
insert(completions[sel.selectedIndex]);
|
||||||
|
close();
|
||||||
|
setTimeout(function(){editor.focus();}, 50);
|
||||||
|
}
|
||||||
|
CodeMirror.on(sel, "blur", close);
|
||||||
|
CodeMirror.on(sel, "keydown", function(event) {
|
||||||
|
var code = event.keyCode;
|
||||||
|
// Enter
|
||||||
|
if (code == 13) {CodeMirror.e_stop(event); pick();}
|
||||||
|
// Escape
|
||||||
|
else if (code == 27) {CodeMirror.e_stop(event); close(); editor.focus();}
|
||||||
|
else if (code != 38 && code != 40 && code != 33 && code != 34 && !CodeMirror.isModifierKey(event)) {
|
||||||
|
close(); editor.focus();
|
||||||
|
// Pass the event to the CodeMirror instance so that it can handle things like backspace properly.
|
||||||
|
editor.triggerOnKeyDown(event);
|
||||||
|
// Don't show completions if the code is backspace and the option is set.
|
||||||
|
if (!options.closeOnBackspace || code != 8) {
|
||||||
|
setTimeout(function(){collectHints(tempToken);}, 50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
CodeMirror.on(sel, "dblclick", pick);
|
||||||
|
|
||||||
|
sel.focus();
|
||||||
|
// Opera sometimes ignores focusing a freshly created node
|
||||||
|
if (window.opera) setTimeout(function(){if (!done) sel.focus();}, 100);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return collectHints();
|
||||||
|
};
|
||||||
|
CodeMirror.htaccessHint.defaults = {
|
||||||
|
closeOnBackspace: true,
|
||||||
|
closeOnTokenChange: false,
|
||||||
|
completeSingle: true,
|
||||||
|
alignWithWord: true
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,17 @@ Header set Server "Apache/2.2.9 (Unix)"
|
||||||
</body>
|
</body>
|
||||||
<script src="codemirror.js"></script>
|
<script src="codemirror.js"></script>
|
||||||
<link rel="stylesheet" href="codemirror.css">
|
<link rel="stylesheet" href="codemirror.css">
|
||||||
|
<link rel="stylesheet" href="show-hint.css">
|
||||||
|
<link rel="stylesheet" href="simple-hint.css">
|
||||||
|
<script src="show-hint.js"></script>
|
||||||
<script src="htaccess.js"></script>
|
<script src="htaccess.js"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var myCodeMirror = CodeMirror.fromTextArea(document.getElementById('code'));
|
CodeMirror.commands.autocomplete = function(cm) {
|
||||||
|
CodeMirror.showHint(cm, CodeMirror.htaccessHint);
|
||||||
|
}
|
||||||
|
var myCodeMirror = CodeMirror.fromTextArea(document.getElementById('code'), {
|
||||||
|
lineNumbers: true,
|
||||||
|
extraKeys: {"Ctrl-Space": "autocomplete"}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue