@anywhichway/nerd-editor
Version:
A JavaScript rich text editor based on and with support for custom elements.
76 lines (74 loc) • 3.39 kB
JavaScript
import {createElement} from "../create-element.js";
const typeAhead = {
mentions: [],
match: /\s(@.*\+?)/s,
template(item) {
if(item.href) {
return createElement({tagName:"div",innerHTML:`${item.icon} ${item.name}`});
}
const gravatar = item.gravatar || createElement({tagName:"gravatar-display",attributes:{username:item.name,style:{display:"none"}},innerHTML:` ${item.name} (Gravatar)`});
if(!item.gravatar) {
item.gravatar = gravatar;
gravatar.addEventListener("loaded", () => {
if (gravatar.style.display === "none") gravatar.style.display = "block";
})
setTimeout(() => {
if (gravatar.style.display === "none") {
gravatar.remove();
const index = this.mentions.findIndex((mention) => mention.name === item.name);
if (index >= 0) {
this.mentions.splice(index, 1);
}
}
}, 2000);
}
return gravatar;
},
options(keyword, callback) {
if(keyword==="@") {
callback([]);
return;
}
keyword = keyword.substring(1); // remove at
let profile;
if(keyword.endsWith("+")) {
keyword = keyword.substring(0,keyword.length-1);
profile = true;
}
this.mentions.forEach((mention) => {
mention.profile = profile;
})
if(!this.mentions.find((mention) => mention.name===keyword)) {
this.mentions.unshift({name:keyword,profile})
}
const sites = [{name:keyword,href:`https://www.facebook.com/${keyword}`,icon:'<i class="fa-brands fa-facebook"></i>'},
{name:keyword,href:`https://www.github.com/${keyword}`,icon:'<i class="fa-brands fa-github">'},
{name:keyword,href:`https://www.instagram.com/${keyword}`,icon:'<i class="fa-brands fa-instagram">'},
{name:keyword,href:`https://www.linkedin.com/in/${keyword}`,icon:'<i class="fa-brands fa-linkedin"></i>'},
{name:keyword,href:`https://www.twitter.com/${keyword}`,icon:'<i class="fa-brands fa-twitter"></i>'}
];
callback([...sites,...this.mentions.filter((item) => keyword.startsWith(item.name))]);
},
content(item) {
if(item.href) {
return createElement({tagName:"a",attributes:{href:item.href,target:"_tab"},innerHTML:`${item.icon} ${item.name}`});
}
const gravatar = item.gravatar.cloneNode(true);
if(item.profile) {
gravatar.setAttribute("showprofile","true");
gravatar.innerHTML = '<div style="float:right">${name.formatted}<br>\n${displayName}</div>';
} else {
gravatar.setAttribute("showprofile","false");
gravatar.innerHTML = `<div style="float:right;"> ${item.name}</div>`;
}
gravatar.style.display = "inline-block";
gravatar.render();
requestAnimationFrame(() => {
if(!gravatar.nextSibling || gravatar.nextSibling.textContent.length===0) {
gravatar.insertAdjacentHTML("afterend"," ");
}
});
return gravatar;
}
}
export {typeAhead as mentionTypeAhead}