Merge pull request #757 from Chrissi2812/async-suggestions

Async suggestions
This commit is contained in:
Philipp Kühn
2020-08-07 14:29:21 +02:00
committed by GitHub
4 changed files with 85 additions and 80 deletions

View File

@@ -6,5 +6,6 @@ module.exports = {
], ],
plugins: [ plugins: [
'@babel/plugin-syntax-dynamic-import', '@babel/plugin-syntax-dynamic-import',
'@babel/plugin-transform-runtime',
], ],
} }

View File

@@ -63,16 +63,21 @@ export default {
new Heading({ levels: [1, 2, 3] }), new Heading({ levels: [1, 2, 3] }),
new Mention({ new Mention({
// a list of all suggested items // a list of all suggested items
items: () => [ items: async () => {
{ id: 1, name: 'Sven Adlung' }, await new Promise(resolve => {
{ id: 2, name: 'Patrick Baber' }, setTimeout(resolve, 500)
{ id: 3, name: 'Nick Hirche' }, })
{ id: 4, name: 'Philip Isik' }, return [
{ id: 5, name: 'Timo Isik' }, { id: 1, name: 'Sven Adlung' },
{ id: 6, name: 'Philipp Kühn' }, { id: 2, name: 'Patrick Baber' },
{ id: 7, name: 'Hans Pagel' }, { id: 3, name: 'Nick Hirche' },
{ id: 8, name: 'Sebastian Schrama' }, { id: 4, name: 'Philip Isik' },
], { id: 5, name: 'Timo Isik' },
{ id: 6, name: 'Philipp Kühn' },
{ id: 7, name: 'Hans Pagel' },
{ id: 8, name: 'Sebastian Schrama' },
]
},
// is called when a suggestion starts // is called when a suggestion starts
onEnter: ({ onEnter: ({
items, query, range, command, virtualNode, items, query, range, command, virtualNode,
@@ -128,11 +133,15 @@ export default {
// this function is optional because there is basic filtering built-in // this function is optional because there is basic filtering built-in
// you can overwrite it if you prefer your own filtering // you can overwrite it if you prefer your own filtering
// in this example we use fuse.js with support for fuzzy search // in this example we use fuse.js with support for fuzzy search
onFilter: (items, query) => { onFilter: async (items, query) => {
if (!query) { if (!query) {
return items return items
} }
await new Promise(resolve => {
setTimeout(resolve, 500)
})
const fuse = new Fuse(items, { const fuse = new Fuse(items, {
threshold: 0.2, threshold: 0.2,
keys: ['name'], keys: ['name'],

View File

@@ -1,80 +1,73 @@
;(function(window, document) { 'use strict';
'use strict';
var isSvg = document.createElementNS && document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' ).createSVGRect; var isSvg = document.createElementNS && document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' ).createSVGRect;
var localStorage = 'localStorage' in window && window['localStorage'] !== null ? window.localStorage : false; var localStorage = 'localStorage' in window && window['localStorage'] !== null ? window.localStorage : false;
function svgSpriteInjector(source, opts) { function svgSpriteInjector(source, opts) {
var file; var file;
opts = opts || {}; opts = opts || {};
if (source instanceof Node) { if (source instanceof Node) {
file = source.getAttribute('data-svg-sprite'); file = source.getAttribute('data-svg-sprite');
opts.revision = source.getAttribute('data-svg-sprite-revision') || opts.revision; opts.revision = source.getAttribute('data-svg-sprite-revision') || opts.revision;
} else if (typeof source === 'string') { } else if (typeof source === 'string') {
file = source; file = source;
} }
if (isSvg) { if (isSvg) {
if (file) { if (file) {
injector(file, opts); injector(file, opts);
} else {
console.error('svg-sprite-injector: undefined sprite filename!');
}
} else { } else {
console.error('svg-sprite-injector require ie9 or greater!'); console.error('svg-sprite-injector: undefined sprite filename!');
}
} else {
console.error('svg-sprite-injector require ie9 or greater!');
}
};
function injector(filepath, opts) {
var name = 'injectedSVGSprite' + filepath,
revision = opts.revision,
request;
// localStorage cache
if (revision !== undefined && localStorage && localStorage[name + 'Rev'] == revision) {
return injectOnLoad(localStorage[name]);
}
// Async load
request = new XMLHttpRequest();
request.open('GET', filepath, true);
request.onreadystatechange = function (e) {
var data;
if (request.readyState === 4 && request.status >= 200 && request.status < 400) {
injectOnLoad(data = request.responseText);
if (revision !== undefined && localStorage) {
localStorage[name] = data;
localStorage[name + 'Rev'] = revision;
}
} }
}; };
request.send();
}
function injector(filepath, opts) { function injectOnLoad(data) {
var name = 'injectedSVGSprite' + filepath, if (data) {
revision = opts.revision, if (document.body) {
request; injectData(data);
} else {
// localStorage cache document.addEventListener('DOMContentLoaded', injectData.bind(null, data));
if (revision !== undefined && localStorage && localStorage[name + 'Rev'] == revision) {
return injectOnLoad(localStorage[name]);
}
// Async load
request = new XMLHttpRequest();
request.open('GET', filepath, true);
request.onreadystatechange = function (e) {
var data;
if (request.readyState === 4 && request.status >= 200 && request.status < 400) {
injectOnLoad(data = request.responseText);
if (revision !== undefined && localStorage) {
localStorage[name] = data;
localStorage[name + 'Rev'] = revision;
}
}
};
request.send();
}
function injectOnLoad(data) {
if (data) {
if (document.body) {
injectData(data);
} else {
document.addEventListener('DOMContentLoaded', injectData.bind(null, data));
}
} }
} }
}
function injectData(data) { function injectData(data) {
var body = document.body; var body = document.body;
body.insertAdjacentHTML('afterbegin', data); body.insertAdjacentHTML('afterbegin', data);
if (body.firstChild.tagName === 'svg') { if (body.firstChild.tagName === 'svg') {
body.firstChild.style.display = 'none'; body.firstChild.style.display = 'none';
}
} }
}
if (typeof exports === 'object') { export default svgSpriteInjector;
module.exports = svgSpriteInjector;
} else {
window.svgSpriteInjector = svgSpriteInjector;
}
} (window, document));

View File

@@ -95,7 +95,7 @@ export default function SuggestionsPlugin({
view() { view() {
return { return {
update: (view, prevState) => { update: async (view, prevState) => {
const prev = this.key.getState(prevState) const prev = this.key.getState(prevState)
const next = this.key.getState(view.state) const next = this.key.getState(view.state)
@@ -133,7 +133,9 @@ export default function SuggestionsPlugin({
text: state.text, text: state.text,
decorationNode, decorationNode,
virtualNode, virtualNode,
items: onFilter(Array.isArray(items) ? items : items(), state.query), items: (handleChange || handleStart)
? await onFilter(Array.isArray(items) ? items : await items(), state.query)
: [],
command: ({ range, attrs }) => { command: ({ range, attrs }) => {
command({ command({
range, range,