'use strict';
import './register';
import Quill from 'quill';
import inJectEditor from './inject';
const checker = {
youtube: text => {
const regex = /^https:\/\/www.youtube.com\/embed\/(.*?)$/;
const result = regex.exec(text);
if (!result) return null;
return result[1];
},
twitter: text => {
const pathMatch = /twitter.com\/(.*?)\?/.exec(text);
if (!pathMatch) return null;
return pathMatch[1];
},
};
class QuillEditor extends inJectEditor {
_quill = null;
_element = '';
_isModify = false;
_html = '';
_text = '';
constructor(element, options, title, isModify, initialHtml) {
super();
this._element = element;
if (isModify) {
this._isModify = isModify;
this._html = initialHtml;
}
const isOption = options && Object.keys(options).length > 0;
if (isOption) {
$(this._element).before('<div id="editor-header"></div>');
$(this._element).after('<div id="editor-footer"></div>');
$('#editor-header').after(`<h3 class="custom-h3 pb-2">${title || '๋ด์ฉ'}</h3>`);
// opinion, eventTime, postTime, using, version, title
const keys = Object.keys(options);
keys.forEach(key => {
const property = options[key];
const { use, injectEle, required } = property;
if (use) {
const option = {
injectEle,
required,
};
this.injectFn(key, option);
}
return property;
});
} else {
$(this._element).before(`<h3 class="custom-h3 pb-2">${title || '๋ด์ฉ'}</h3>`);
}
this.created();
}
created() {
const bindings = {
removeCodeBlock: {
key: 'backspace',
empty: true,
format: ['code-block'],
handler: () => {
this._quill.format('code-block', false);
},
},
removeQuote: {
key: 'enter',
empty: true,
format: ['blockquote'],
handler: () => {
this._quill.format('blockquote', false);
},
},
removeQuoteWithBackspace: {
key: 'backspace',
empty: true,
format: ['blockquote'],
handler: () => {
this._quill.format('blockquote', false);
},
},
};
this._quill = new Quill(this._element, {
theme: 'snow',
modules: {
keyboard: {
bindings,
},
toolbar: [
[{ font: [] }, { size: [] }],
['bold', 'italic', 'underline', 'strike'],
[{ color: [] }, { background: [] }],
[{ header: [false, 1, 2, 3, 4, 5, 6] }, 'blockquote'],
[{ list: 'ordered' }, { list: 'bullet' }, { indent: '-1' }, { indent: '+1' }],
['link', 'image'],
['tweet', 'youtube']
],
clipboard: {
// https://quilljs.com/docs/modules/clipboard/#matchvisual
matchVisual: false,
},
},
bounds: document.querySelector('#quill-editor'),
placeholder: '๋ด์ฉ์ ์์ฑํด์ฃผ์ธ์.',
});
this.applyEventListeners();
if (this._isModify) {
this._quill.root.innerHTML = this._html;
}
}
addImageToEditor = image => {
if (!this._quill) return false;
this._quill.focus();
const range = this._quill.getSelection();
if (!range) return false;
this._quill.insertEmbed(range.index, 'image', image);
this._quill.insertText(range.index + 2, '');
this._quill.setSelection(range.index + 2, 0);
this._quill.focus();
return true;
};
addYoutubeToEditor = (url) => {
if (!this._quill) return false;
this._quill.focus();
const range = this._quill.getSelection(true);
if (!range) return false;
// 'https://www.youtube.com/embed/QHH3iSeDBLo?showinfo=0';
this._quill.insertText(range.index, '\n', Quill.sources.USER);
this._quill.insertEmbed(range.index + 1, 'video', url, Quill.sources.USER);
this._quill.formatText(range.index + 1, 1, { height: '400', width: '500' });
this._quill.setSelection(range.index + 2, Quill.sources.SILENT);
this._quill.focus();
return true;
};
addTwitterToEditor = (id) => {
if (!this._quill) return false;
this._quill.focus();
const range = this._quill.getSelection(true);
if (!range) return false;
// '464454167226904576';
this._quill.insertText(range.index, '\n', Quill.sources.USER);
this._quill.insertEmbed(range.index + 1, 'tweet', id, Quill.sources.USER);
this._quill.setSelection(range.index + 2, Quill.sources.SILENT);
this._quill.focus();
return true;
};
applyEventListeners = () => {
const that = this;
this._quill.on('text-change', () => {
that._html = that._quill.root.innerHTML;
that._text = that._quill.getText();
console.log(that._html);
});
this._quill.getModule('toolbar').addHandler('image', () => {
const input = document.createElement('input');
input.type = 'file';
input.onchange = () => {
if (!input.files) return;
const file = input.files[0];
console.log(file);
// TODO: ์ถํ ์
๋ก๋ํ๋ api์ถ๊ฐ
const image =
'https://images.velog.io/post-images/velopert/8bd63950-b353-11e8-b01f-598f1220d1c8/mobx.png';
that.addImageToEditor(image);
};
input.click();
});
this._quill.getModule('toolbar').addHandler('tweet', () => {
const value = prompt('Enter URL:');
const checked = checker.twitter(value);
if (value && checked) {
const splitValue = checked.split('/');
const id = splitValue[splitValue.length - 1];
that.addTwitterToEditor(id);
}
});
this._quill.getModule('toolbar').addHandler('youtube', () => {
const value = prompt('Enter URL:');
if (value && checker.youtube(value)) {
that.addYoutubeToEditor(value);
}
});
};
injectFn = (key, option) => {
switch (key) {
case 'opinion':
this.injectOpinionOption(option);
break;
case 'eventTime':
this.injectEventTimeOption(option);
break;
case 'postTime':
this.injectPostTimeOption(option);
break;
case 'using':
this.injectUsingOption(option);
break;
case 'version':
this.injectVersionOption(option);
break;
case 'title':
this.injectTitleOption(option);
break;
case 'classification':
this.inJectClassificationOption(option);
break;
case 'template':
this.injectTemplateOption(option);
break;
default:
console.log('์ ํจํ์ง ์๋ injectํ์
::', key);
break;
}
};
}
export default QuillEditor;