text editor link autocomplete
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -18,6 +18,7 @@
|
|||||||
var codeMirrorContainer = document.querySelector("[data-codemirror-mount]");
|
var codeMirrorContainer = document.querySelector("[data-codemirror-mount]");
|
||||||
var codeMirrorReadyPromise = null;
|
var codeMirrorReadyPromise = null;
|
||||||
var codeMirrorModules = null;
|
var codeMirrorModules = null;
|
||||||
|
var documentCompletionOptionsPromise = null;
|
||||||
|
|
||||||
if (!form || !textarea || statusNodes.length === 0) {
|
if (!form || !textarea || statusNodes.length === 0) {
|
||||||
return;
|
return;
|
||||||
@@ -507,6 +508,105 @@
|
|||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeCompletionPath(doc) {
|
||||||
|
var docPath = doc && doc.path ? String(doc.path) : "";
|
||||||
|
return docPath.replace(/\.md$/, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildDocumentCompletionOptions(documents) {
|
||||||
|
var seen = new Set();
|
||||||
|
|
||||||
|
return (documents || [])
|
||||||
|
.map(function (doc) {
|
||||||
|
var label = normalizeCompletionPath(doc);
|
||||||
|
if (!label || seen.has(label) || label === path.replace(/\.md$/, "")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
seen.add(label);
|
||||||
|
|
||||||
|
return {
|
||||||
|
label: label,
|
||||||
|
detail: doc.title && doc.title !== label ? doc.title : doc.path,
|
||||||
|
type: "file",
|
||||||
|
apply: function (view, completion, from, to) {
|
||||||
|
var insert = completion.label;
|
||||||
|
var after = view.state.doc.sliceString(to, Math.min(view.state.doc.length, to + 2));
|
||||||
|
if (after !== "]]") {
|
||||||
|
insert += "]]";
|
||||||
|
}
|
||||||
|
view.dispatch({
|
||||||
|
changes: { from: from, to: to, insert: insert },
|
||||||
|
selection: { anchor: from + insert.length },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.filter(Boolean)
|
||||||
|
.sort(function (a, b) {
|
||||||
|
return a.label.localeCompare(b.label);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchDocumentCompletionOptions() {
|
||||||
|
return fetch("/api/documents", { credentials: "same-origin" })
|
||||||
|
.then(function (response) {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Could not load documents");
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(function (data) {
|
||||||
|
var documents = data.documents || [];
|
||||||
|
if (window.MDHubCache && window.MDHubCache.cacheDocuments) {
|
||||||
|
window.MDHubCache.cacheDocuments(documents).catch(function () {});
|
||||||
|
}
|
||||||
|
return buildDocumentCompletionOptions(documents);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadDocumentCompletionOptions() {
|
||||||
|
if (documentCompletionOptionsPromise) {
|
||||||
|
return documentCompletionOptionsPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
documentCompletionOptionsPromise = Promise.resolve()
|
||||||
|
.then(function () {
|
||||||
|
if (window.MDHubCache && window.MDHubCache.getCachedDocuments) {
|
||||||
|
return window.MDHubCache.getCachedDocuments().then(function (documents) {
|
||||||
|
if (documents && documents.length > 0) {
|
||||||
|
return buildDocumentCompletionOptions(documents);
|
||||||
|
}
|
||||||
|
return fetchDocumentCompletionOptions();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return fetchDocumentCompletionOptions();
|
||||||
|
})
|
||||||
|
.catch(function () {
|
||||||
|
return [];
|
||||||
|
});
|
||||||
|
|
||||||
|
return documentCompletionOptionsPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
function wikiLinkCompletions(context) {
|
||||||
|
var before = context.matchBefore(/\[\[([^\]\n]*)$/);
|
||||||
|
if (!before) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return loadDocumentCompletionOptions().then(function (options) {
|
||||||
|
if (!options.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
from: before.from + 2,
|
||||||
|
to: before.to,
|
||||||
|
options: options,
|
||||||
|
validFor: /^[^\]\n]*$/,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function createCodeMirrorEditor(mount, initialValue, options) {
|
function createCodeMirrorEditor(mount, initialValue, options) {
|
||||||
var cm = codeMirrorModules.cm;
|
var cm = codeMirrorModules.cm;
|
||||||
var markdownModule = codeMirrorModules.markdown;
|
var markdownModule = codeMirrorModules.markdown;
|
||||||
@@ -521,6 +621,10 @@
|
|||||||
cm.EditorView.lineWrapping,
|
cm.EditorView.lineWrapping,
|
||||||
codeMirrorTheme(),
|
codeMirrorTheme(),
|
||||||
codeMirrorHighlighting(),
|
codeMirrorHighlighting(),
|
||||||
|
cm.autocompletion({
|
||||||
|
override: [wikiLinkCompletions],
|
||||||
|
activateOnTyping: true,
|
||||||
|
}),
|
||||||
cm.EditorView.updateListener.of(function (update) {
|
cm.EditorView.updateListener.of(function (update) {
|
||||||
if (update.docChanged) {
|
if (update.docChanged) {
|
||||||
onChange(update.state.doc.toString());
|
onChange(update.state.doc.toString());
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const STATIC_CACHE = "md-hub-static-v6";
|
const STATIC_CACHE = "md-hub-static-v7";
|
||||||
const DB_NAME = "md-hub-cache";
|
const DB_NAME = "md-hub-cache";
|
||||||
const DB_VERSION = 3;
|
const DB_VERSION = 3;
|
||||||
const STORE_PAGES = "pages";
|
const STORE_PAGES = "pages";
|
||||||
|
|||||||
Reference in New Issue
Block a user