Hi @julian , @PitaJ
Finally got nodebb-plugin-emoji working on Quill.
As an added bonus, the emojis can be used inside the post AND in the title bar.
In emoji-dialog.js make the following changes, allowing quill to work side by side with composer.
- Top of file, add import:
import { active as activeComposer } from 'composer';
- In toggle, update opener if quill is available:
export function toggle(
opener: HTMLElement,
onClick: (e: JQuery.Event, name: string, dialog: JQuery) => void,
) {
function after(dialog: JQuery) {
if (dialog.hasClass('open')) {
dialogActions.close(dialog);
return;
}
dialog.off('click').on('click', '.emoji-link', (e) => {
e.preventDefault();
const name = (e.currentTarget as HTMLAnchorElement).name;
onClick(e, name, dialog);
});
//If Quill
if($('[data-uuid="' + activeComposer + '"] .ql-container.ql-snow'))
opener = (<HTMLScriptElement[]><any>document.querySelectorAll('button.ql-emoji-add-emoji'))[0];
- Update toggleForInsert as follows. Note the changes allowing emojis in title bar:
export function toggleForInsert(textarea: HTMLTextAreaElement) {
toggle($('[data-format="emoji-add-emoji"]').filter(':visible')[0], (e, name) => {
var quill = $('[data-uuid="' + activeComposer + '"] .ql-container.ql-snow').data("quill");
if(quill) {
var range = quill.getSelection();
if (range) {
if (range.length == 0) {
//User cursor is at index
} else {
//User has highlighted text - deleting and replacing with emoji
quill.deleteText(range.index, range.length);
}
quill.clipboard.dangerouslyPasteHTML(range.index, (<HTMLElement>(<HTMLInputElement>e.currentTarget).children[0]).outerHTML);
return;
}
//User cursor is not in editor (range is null) -> change focus to the title's textarea
textarea = <HTMLTextAreaElement>(<any>(<HTMLScriptElement>document.querySelectorAll('.composer.resizable[data-uuid="' + activeComposer + '"] input.title.form-control')[0]));
var text = <string>(<any>(<HTMLInputElement>e.currentTarget).children[0]).alt;
var selectionStart = <number>(<any>(<HTMLScriptElement>document.querySelectorAll('.composer.resizable[data-uuid="' + activeComposer + '"] input.title.form-control')[0])).selectionStart;
var selectionEnd = <number>(<any>(<HTMLScriptElement>document.querySelectorAll('.composer.resizable[data-uuid="' + activeComposer + '"] input.title.form-control')[0])).selectionStart;
} else {
var text = `:${name}: `;
var {selectionStart, selectionEnd} = textarea;
}
var end = selectionEnd + text.length;
var start = selectionStart === selectionEnd ? end : selectionStart;
insertIntoTextarea(textarea, text);
updateTextareaSelection(textarea, start, end);
$(textarea).trigger('input');
});
}
Note I am using dangerouslyPasteHTML that slightly changes the link/img html of the emoji element (for example, removes emoji classes). We can use the quill converter from quill-delta-to-html, perhaps it will make a slightly better job, or hardcode ourselves, that is, if these classes means anything...
As for dangerouslyPaste, using the converter above will not make it any safer. We have to sanitize the delta in the server. Any attempts to sanitize in the client are futile, as someone can just take over the client code and push whatever he wants to the server...
JJ.