Add tag input autocomplete when editing pages.

Thanks to Awesomplete by @LeaVerou :D
This commit is contained in:
Starbeamrainbowlabs 2020-01-26 21:04:39 +00:00
parent adc42fc806
commit 83bf9acd86
Signed by: sbrl
GPG Key ID: 1BE5172E637709C2
6 changed files with 57 additions and 6 deletions

View File

@ -14,6 +14,10 @@ This file holds the changelog for Pepperminty Wiki. This is the master list of t
- Added dark theme to the [downloader](https://starbeamrainbowlabs.com/labs/peppermint/download.php) (will be updated at the next stable release)
- Added initial mobile theme support to the default theme
- There's still a bunch of work to do in this department, but it's a bit of a challenge to do so without breaking desktop support
- Added autocomplete for tags when editing pages, powered by [Awesomplete](https://leaverou.github.io/awesomplete/)
- The new `editing_tags_autocomplete` setting - enabled by default - toggles it, but why would you want to turn it off? :P
- It should be reasonably accessible, judging from all the aria tags I'm seeing
- Get in touch if you experience performance issues with fetching tag lists from your wiki
### Fixed
- Fixed weighted word support on search query analysis debug page

View File

@ -6,7 +6,9 @@ register_module([
"description" => "Allows you to edit pages by adding the edit and save actions. You should probably include this one.",
"id" => "page-edit",
"extra_data" => [
"diff.min.js" => "https://cdnjs.cloudflare.com/ajax/libs/jsdiff/2.2.2/diff.min.js"
"diff.min.js" => "https://cdnjs.cloudflare.com/ajax/libs/jsdiff/2.2.2/diff.min.js",
"awesomplete.min.js" => "https://cdnjs.cloudflare.com/ajax/libs/awesomplete/1.1.5/awesomplete.min.js",
"awesomplete.min.css" => "https://cdnjs.cloudflare.com/ajax/libs/awesomplete/1.1.5/awesomplete.min.css"
],
"code" => function() {
@ -33,7 +35,7 @@ register_module([
* %edit%
*/
add_action("edit", function() {
global $pageindex, $settings, $env;
global $pageindex, $settings, $env, $paths;
$filename = "$env->storage_prefix$env->page.md";
$creatingpage = !isset($pageindex->{$env->page});
@ -194,6 +196,41 @@ window.addEventListener("load", function(event) {
smartsave_restore();
});
});');
// Why would anyone want this disabled?
if($settings->editing_tags_autocomplete) {
page_renderer::add_js_link("$paths->extra_data_directory/page-edit/awesomplete.min.js");
page_renderer::add_js_snippet('window.addEventListener("load", async (event) => {
// FUTURE: Optionally cache this?
let response = await fetch("?action=list-tags&format=text");
if(!response.ok) {
console.warn(`Warning: Failed to fetch tags list with status code ${response.status} ${response.statusText}`);
return;
}
let tags = (await response.text()).split("\n");
console.log(tags);
window.input_tags_completer = new Awesomplete(
document.querySelector("#tags"), {
list: tags,
filter: function(text, input) {
console.log(arguments);
// Avoid suggesting tags that are already present
if(input.split(/,\s*/).includes(text.value)) return false;
return Awesomplete.FILTER_CONTAINS(text, input.match(/[^,]*$/)[0]);
},
item: function(text, input) {
return Awesomplete.ITEM(text, input.match(/[^,]*$/)[0]);
},
replace: function(text) {
var before = this.input.value.match(/^.+,\s*|/)[0];
this.input.value = before + text + ", ";
}
}
);
});
');
$content .= "<link rel=\"stylesheet\" href=\"$paths->extra_data_directory/page-edit/awesomplete.min.css\" />";
}
exit(page_renderer::render_main("$title - $settings->sitename", $content));
});
@ -413,7 +450,7 @@ window.addEventListener("load", function(event) {
</form>";
// Insert a reference to jsdiff to generate the diffs
$diffScript = <<<'DIFFSCRIPT'
$diff_script = <<<'DIFFSCRIPT'
window.addEventListener("load", function(event) {
var destination = document.getElementById("highlighted-diff"),
diff = JsDiff.diffWords(document.getElementById("original-content").value, document.getElementById("new-content").value),
@ -427,9 +464,9 @@ window.addEventListener("load", function(event) {
destination.innerHTML = output;
});
DIFFSCRIPT;
// diff.min.js is downloaded above
$content .= "\n<script src='$paths->extra_data_dir/page-edit/diff.min.js'></script>
<script>$diffScript</script>\n";
page_renderer::add_js_link("$paths->extra_data_directory/page-edit/diff.min.js");
page_renderer::add_js_snippet($diff_script);
header("x-failure-reason: edit-conflict");
exit(page_renderer::render_main("Edit Conflict - $env->page - $settings->sitename", $content));

View File

@ -13,6 +13,7 @@
"random_page_exclude_redirects": { "type": "checkbox", "description": "Causes the random action to avoid sending the user to a redirect page.", "default": true },
"footer_message": { "type": "textarea", "description": "A message that will appear at the bottom of every page. May contain HTML.", "default": "All content is under <a href='?page=License' target='_blank'>this license</a>. Please make sure that you read and understand the license, especially if you are thinking about copying some (or all) of this site's content, as it may restrict you from doing so." },
"editing_message": { "type": "textarea", "description": "A message that will appear just before the submit button on the editing page. May contain HTML.", "default": "<a href='?action=help#20-parser-default' target='_blank'>Formatting help</a> (<a href='https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet' target='_blank'>Markdown Cheatsheet</a>)<br />\nBy submitting your edit or uploading your file, you are agreeing to release your changes under <a href='?action=view&page=License' target='_blank'>this license</a>. Also note that if you don't want your work to be edited by other users of this site, please don't submit it here!" },
"editing_tags_autocomplete": { "type": "checkbox", "description": "Whether to enable autocomplete for the tags box in the page editor.", "default": true },
"admindisplaychar": { "type": "text", "description": "The string that is prepended before an admin's name on the nav bar. Defaults to a diamond shape (&#9670;).", "default": "&#9670;" },
"protectedpagechar": { "type": "text", "description": "The string that is prepended a page's name in the page title if it is protected. Defaults to a lock symbol. (&#128274;)", "default": "&#128274;" },
"editing": { "type": "checkbox", "description": "Whether editing is enabled.", "default": true},

View File

@ -283,6 +283,7 @@ main label:not(.link-display-label){
display:inline-block;
min-width:16rem;
}
.awesomplete { width: 100%; }
input[type=text]:not(.link-display), input[type=password], input[type=url], input[type=email], input[type=number], textarea{
margin:0.5rem 0;
}

View File

@ -196,6 +196,13 @@ a.interwiki_link:active { color: var(--accent-d3); }
.editform { position: relative; }
textarea[name=content] { resize: none; }
.fit-text-mirror { position: absolute; top: 0; left: -10000vw; word-wrap: break-word; white-space: pre-wrap; }
.awesomplete { width: 100%; color: var(--text-dark); }
.awesomplete > ul::before { display: none; }
/* Overly specific to override library css */
.awesomplete > ul[role=listbox] { top: 2.5em; background: var(--accent-a2); }
main label:not(.link-display-label) { display: inline-block; min-width: 16rem; }
input[type=text]:not(.link-display), input[type=password], input[type=url], input[type=email], input[type=number], textarea { margin: 0.5rem 0; }
input[type=text], input[type=password], input[type=url], input[type=email], input[type=number], textarea, textarea[name=content] + pre, #search-box { padding: 0.5rem 0.8rem; background: var(--accent-a4); border: 0; border-radius: 0.3rem; font-size: 1rem; color: var(--text-bright); }

View File

@ -121,6 +121,7 @@ textarea, #tags, #search-box {
}
.fit-text-mirror { position: absolute; left: -1000000px; }
.awesomplete { width: 100%; }
textarea, input:not([type=submit]):not([type=button]) {
font-family: "Ubuntu", sans-serif;