Editor: showHelp() as html, add help for hotkeys

This commit is contained in:
tophf 2015-04-26 15:34:59 +03:00
parent 9ae6382469
commit e707a08a84
2 changed files with 138 additions and 12 deletions

View File

@ -61,11 +61,16 @@
.aligned { .aligned {
display: table-row; display: table-row;
} }
.aligned > * { .aligned > *:not(img) {
display: table-cell; display: table-cell;
margin-top: 0.1rem; margin-top: 0.1rem;
min-height: 1.4rem; min-height: 1.4rem;
} }
img[src="help.png"] {
cursor: pointer;
vertical-align: middle;
margin-left: 0.2rem;
}
input[type="checkbox"] { input[type="checkbox"] {
margin-left: 0.1rem; margin-left: 0.1rem;
} }
@ -88,11 +93,6 @@
margin-right: 0.5rem; margin-right: 0.5rem;
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
} }
#actions img {
margin-left: 0.2rem;
position: relative;
top: 0.2rem;
}
/* options */ /* options */
#options [type="number"] { #options [type="number"] {
max-width: 2.5rem; max-width: 2.5rem;
@ -202,6 +202,55 @@
.applies-to img { .applies-to img {
vertical-align: bottom; vertical-align: bottom;
} }
/************ help popup ************/
#help-popup {
top: 3rem;
right: 3rem;
max-width: 50vw;
position: fixed;
display: none;
background-color: white;
box-shadow: 3px 3px 30px rgba(0, 0, 0, 0.5);
padding: 0.5rem;
z-index: 9999;
}
#help-popup .title {
font-weight: bold;
background-color: rgba(0,0,0,0.05);
margin: -0.5rem -0.5rem 0.5rem;
padding: 0.5rem;
}
#help-popup .contents {
max-height: calc(100vh - 8rem);
overflow-y: auto;
}
#help-popup .close-icon {
cursor: pointer;
width: 8px;
height: 8px;
position: absolute;
right: 0.5rem;
top: 0.75rem;
background: linear-gradient(-45deg, transparent 5px, black 5px, black 6px, transparent 6.5px), linear-gradient(45deg, transparent 5px, black 5px, black 6px, transparent 6.5px);
}
.keymap-list {
font-size: 85%;
line-height: 1.0;
border-spacing: 0;
word-break: break-all;
}
.keymap-list input {
width: 100%;
}
.keymap-list tr:nth-child(odd) {
background-color: rgba(0, 0, 0, 0.07);
}
.keymap-list td:first-child {
white-space: nowrap;
font-family: monospace;
padding-right: 0.5rem;
}
/************ reponsive layouts ************/ /************ reponsive layouts ************/
@media(max-width:737px) { @media(max-width:737px) {
@ -248,7 +297,7 @@
#options { #options {
-webkit-column-count: 2; -webkit-column-count: 2;
} }
#options .aligned > * { #options .aligned > *:not(img) {
margin: 1px 0 0 0; /* workaround the flowing-padding column bug in webkit */ margin: 1px 0 0 0; /* workaround the flowing-padding column bug in webkit */
padding-right: 0.4rem; padding-right: 0.4rem;
vertical-align: baseline; vertical-align: baseline;
@ -336,6 +385,7 @@
<div class="option aligned"> <div class="option aligned">
<label id="keyMap-label" for="editor.keyMap" i18n-text="cm_keyMap"></label> <label id="keyMap-label" for="editor.keyMap" i18n-text="cm_keyMap"></label>
<select data-option="keyMap" id="editor.keyMap"></select> <select data-option="keyMap" id="editor.keyMap"></select>
<img id="keyMap-help" src="help.png" i18n-alt="helpAlt">
</div> </div>
<div class="option aligned"> <div class="option aligned">
<label id="theme-label" for="editor.theme" i18n-text="cm_theme"></label> <label id="theme-label" for="editor.theme" i18n-text="cm_theme"></label>
@ -346,5 +396,9 @@
<section id="sections"> <section id="sections">
<h2><span id="sections-heading" i18n-text="styleSectionsTitle"></span><img id="sections-help" src="help.png" i18n-alt="helpAlt"></h2> <h2><span id="sections-heading" i18n-text="styleSectionsTitle"></span><img id="sections-help" src="help.png" i18n-alt="helpAlt"></h2>
</section> </section>
<div id="help-popup">
<div class="title"></div><div class="close-icon"></div>
<div class="contents"></div>
</div>
</body> </body>
</html> </html>

82
edit.js
View File

@ -703,6 +703,7 @@ function initHooks() {
document.getElementById("to-mozilla-help").addEventListener("click", showToMozillaHelp, false); document.getElementById("to-mozilla-help").addEventListener("click", showToMozillaHelp, false);
document.getElementById("save-button").addEventListener("click", save, false); document.getElementById("save-button").addEventListener("click", save, false);
document.getElementById("sections-help").addEventListener("click", showSectionHelp, false); document.getElementById("sections-help").addEventListener("click", showSectionHelp, false);
document.getElementById("keyMap-help").addEventListener("click", showKeyMapHelp, false);
setupGlobalSearch(); setupGlobalSearch();
setCleanGlobal(); setCleanGlobal();
@ -835,19 +836,90 @@ function toMozillaFormat() {
} }
function showSectionHelp() { function showSectionHelp() {
showHelp(t("sectionHelp")); showHelp(t("styleSectionsTitle"), t("sectionHelp"));
} }
function showAppliesToHelp() { function showAppliesToHelp() {
showHelp(t("appliesHelp")); showHelp(t("appliesLabel"), t("appliesHelp"));
} }
function showToMozillaHelp() { function showToMozillaHelp() {
showHelp(t("styleToMozillaFormatHelp")); showHelp(t("styleToMozillaFormat"), t("styleToMozillaFormatHelp"));
} }
function showHelp(text) { function showKeyMapHelp() {
alert(text); var keyMap = mergeKeyMaps({}, prefs.getPref("editor.keyMap"), CodeMirror.defaults.extraKeys);
var keyMapSorted = Object.keys(keyMap)
.map(function(key) { return {key: key, cmd: keyMap[key]} })
.sort(function(a, b) { return a.cmd < b.cmd || (a.cmd == b.cmd && a.key < b.key) ? -1 : 1 });
showHelp(t("cm_keyMap") + ": " + prefs.getPref("editor.keyMap"),
'<table class="keymap-list">' +
"<thead><tr><th><input></th><th><input></th></tr></thead>" +
"<tbody>" + keyMapSorted.map(function(value) {
return "<tr><td>" + value.key + "</td><td>" + value.cmd + "</td></tr>";
}).join("") +
"</tbody>" +
"</table>");
document.querySelector("#help-popup table").addEventListener("input", function(event) {
var input = event.target;
var query = new RegExp(input.value.replace(/([{}()\[\]\/\\.+?^$:=*!|])/g, "\\$1"), "gi");
var col = input.parentNode.cellIndex;
this.tBodies[0].childNodes.forEach(function(row) {
var cell = row.children[col];
if (query.test(cell.textContent)) {
row.style.display = "";
cell.innerHTML = cell.textContent.replace(query, "<mark>$&</mark>");
} else {
row.style.display = "none";
}
});
});
function mergeKeyMaps(merged) {
[].slice.call(arguments, 1).forEach(function(keyMap) {
if (typeof keyMap == "string") {
keyMap = CodeMirror.keyMap[keyMap];
}
Object.keys(keyMap).forEach(function(key) {
var cmd = keyMap[key];
// filter out '...', 'attach', etc. (hotkeys start with an uppercase letter)
if (!merged[key] && !key.match(/^[a-z]/) && cmd != "...") {
if (typeof cmd == "function") {
// for 'emacs' keymap: provide at least something meaningful (hotkeys and the function body)
// for 'vim*' keymaps: almost nothing as it doesn't rely on CM keymap mechanism
cmd = cmd.toString().replace(/^function.*?\{[\s\r\n]*([\s\S]+?)[\s\r\n]*\}$/, "$1");
merged[key] = cmd.length <= 200 ? cmd : cmd.substr(0, 200) + "...";
} else {
merged[key] = cmd;
}
}
});
if (keyMap.fallthrough) {
merged = mergeKeyMaps(merged, keyMap.fallthrough);
}
});
return merged;
}
}
function showHelp(title, text) {
var div = document.getElementById("help-popup");
div.querySelector(".contents").innerHTML = text;
div.querySelector(".title").innerHTML = title;
if (getComputedStyle(div).display == "none") {
document.addEventListener("keydown", closeHelp);
div.querySelector(".close-icon").onclick = closeHelp; // avoid chaining on multiple showHelp() calls
}
div.style.display = "block";
function closeHelp(e) {
if (e.type == "click" || (e.keyCode == 27 && !e.altKey && !e.ctrlKey && !e.shiftKey && !e.metaKey)) {
div.style.display = "";
document.removeEventListener("keydown", closeHelp);
}
}
} }
function getParams() { function getParams() {