123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- import { merge } from 'lodash-es';
- import Emitter from '../core/emitter.js';
- import Theme from '../core/theme.js';
- import ColorPicker from '../ui/color-picker.js';
- import IconPicker from '../ui/icon-picker.js';
- import Picker from '../ui/picker.js';
- import Tooltip from '../ui/tooltip.js';
- const ALIGNS = [false, 'center', 'right', 'justify'];
- const COLORS = ['#000000', '#e60000', '#ff9900', '#ffff00', '#008a00', '#0066cc', '#9933ff', '#ffffff', '#facccc', '#ffebcc', '#ffffcc', '#cce8cc', '#cce0f5', '#ebd6ff', '#bbbbbb', '#f06666', '#ffc266', '#ffff66', '#66b966', '#66a3e0', '#c285ff', '#888888', '#a10000', '#b26b00', '#b2b200', '#006100', '#0047b2', '#6b24b2', '#444444', '#5c0000', '#663d00', '#666600', '#003700', '#002966', '#3d1466'];
- const FONTS = [false, 'serif', 'monospace'];
- const HEADERS = ['1', '2', '3', false];
- const SIZES = ['small', false, 'large', 'huge'];
- class BaseTheme extends Theme {
- constructor(quill, options) {
- super(quill, options);
- const listener = e => {
- if (!document.body.contains(quill.root)) {
- document.body.removeEventListener('click', listener);
- return;
- }
- if (this.tooltip != null &&
- // @ts-expect-error
- !this.tooltip.root.contains(e.target) &&
- // @ts-expect-error
- document.activeElement !== this.tooltip.textbox && !this.quill.hasFocus()) {
- this.tooltip.hide();
- }
- if (this.pickers != null) {
- this.pickers.forEach(picker => {
- // @ts-expect-error
- if (!picker.container.contains(e.target)) {
- picker.close();
- }
- });
- }
- };
- quill.emitter.listenDOM('click', document.body, listener);
- }
- addModule(name) {
- const module = super.addModule(name);
- if (name === 'toolbar') {
- // @ts-expect-error
- this.extendToolbar(module);
- }
- return module;
- }
- buildButtons(buttons, icons) {
- Array.from(buttons).forEach(button => {
- const className = button.getAttribute('class') || '';
- className.split(/\s+/).forEach(name => {
- if (!name.startsWith('ql-')) return;
- name = name.slice('ql-'.length);
- if (icons[name] == null) return;
- if (name === 'direction') {
- // @ts-expect-error
- button.innerHTML = icons[name][''] + icons[name].rtl;
- } else if (typeof icons[name] === 'string') {
- // @ts-expect-error
- button.innerHTML = icons[name];
- } else {
- // @ts-expect-error
- const value = button.value || '';
- // @ts-expect-error
- if (value != null && icons[name][value]) {
- // @ts-expect-error
- button.innerHTML = icons[name][value];
- }
- }
- });
- });
- }
- buildPickers(selects, icons) {
- this.pickers = Array.from(selects).map(select => {
- if (select.classList.contains('ql-align')) {
- if (select.querySelector('option') == null) {
- fillSelect(select, ALIGNS);
- }
- if (typeof icons.align === 'object') {
- return new IconPicker(select, icons.align);
- }
- }
- if (select.classList.contains('ql-background') || select.classList.contains('ql-color')) {
- const format = select.classList.contains('ql-background') ? 'background' : 'color';
- if (select.querySelector('option') == null) {
- fillSelect(select, COLORS, format === 'background' ? '#ffffff' : '#000000');
- }
- return new ColorPicker(select, icons[format]);
- }
- if (select.querySelector('option') == null) {
- if (select.classList.contains('ql-font')) {
- fillSelect(select, FONTS);
- } else if (select.classList.contains('ql-header')) {
- fillSelect(select, HEADERS);
- } else if (select.classList.contains('ql-size')) {
- fillSelect(select, SIZES);
- }
- }
- return new Picker(select);
- });
- const update = () => {
- this.pickers.forEach(picker => {
- picker.update();
- });
- };
- this.quill.on(Emitter.events.EDITOR_CHANGE, update);
- }
- }
- BaseTheme.DEFAULTS = merge({}, Theme.DEFAULTS, {
- modules: {
- toolbar: {
- handlers: {
- formula() {
- this.quill.theme.tooltip.edit('formula');
- },
- image() {
- let fileInput = this.container.querySelector('input.ql-image[type=file]');
- if (fileInput == null) {
- fileInput = document.createElement('input');
- fileInput.setAttribute('type', 'file');
- fileInput.setAttribute('accept', this.quill.uploader.options.mimetypes.join(', '));
- fileInput.classList.add('ql-image');
- fileInput.addEventListener('change', () => {
- const range = this.quill.getSelection(true);
- this.quill.uploader.upload(range, fileInput.files);
- fileInput.value = '';
- });
- this.container.appendChild(fileInput);
- }
- fileInput.click();
- },
- video() {
- this.quill.theme.tooltip.edit('video');
- }
- }
- }
- }
- });
- class BaseTooltip extends Tooltip {
- constructor(quill, boundsContainer) {
- super(quill, boundsContainer);
- this.textbox = this.root.querySelector('input[type="text"]');
- this.listen();
- }
- listen() {
- // @ts-expect-error Fix me later
- this.textbox.addEventListener('keydown', event => {
- if (event.key === 'Enter') {
- this.save();
- event.preventDefault();
- } else if (event.key === 'Escape') {
- this.cancel();
- event.preventDefault();
- }
- });
- }
- cancel() {
- this.hide();
- this.restoreFocus();
- }
- edit() {
- let mode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'link';
- let preview = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
- this.root.classList.remove('ql-hidden');
- this.root.classList.add('ql-editing');
- if (this.textbox == null) return;
- if (preview != null) {
- this.textbox.value = preview;
- } else if (mode !== this.root.getAttribute('data-mode')) {
- this.textbox.value = '';
- }
- const bounds = this.quill.getBounds(this.quill.selection.savedRange);
- if (bounds != null) {
- this.position(bounds);
- }
- this.textbox.select();
- this.textbox.setAttribute('placeholder', this.textbox.getAttribute(`data-${mode}`) || '');
- this.root.setAttribute('data-mode', mode);
- }
- restoreFocus() {
- this.quill.focus({
- preventScroll: true
- });
- }
- save() {
- // @ts-expect-error Fix me later
- let {
- value
- } = this.textbox;
- switch (this.root.getAttribute('data-mode')) {
- case 'link':
- {
- const {
- scrollTop
- } = this.quill.root;
- if (this.linkRange) {
- this.quill.formatText(this.linkRange, 'link', value, Emitter.sources.USER);
- delete this.linkRange;
- } else {
- this.restoreFocus();
- this.quill.format('link', value, Emitter.sources.USER);
- }
- this.quill.root.scrollTop = scrollTop;
- break;
- }
- case 'video':
- {
- value = extractVideoUrl(value);
- }
- // eslint-disable-next-line no-fallthrough
- case 'formula':
- {
- if (!value) break;
- const range = this.quill.getSelection(true);
- if (range != null) {
- const index = range.index + range.length;
- this.quill.insertEmbed(index,
- // @ts-expect-error Fix me later
- this.root.getAttribute('data-mode'), value, Emitter.sources.USER);
- if (this.root.getAttribute('data-mode') === 'formula') {
- this.quill.insertText(index + 1, ' ', Emitter.sources.USER);
- }
- this.quill.setSelection(index + 2, Emitter.sources.USER);
- }
- break;
- }
- default:
- }
- // @ts-expect-error Fix me later
- this.textbox.value = '';
- this.hide();
- }
- }
- function extractVideoUrl(url) {
- let match = url.match(/^(?:(https?):\/\/)?(?:(?:www|m)\.)?youtube\.com\/watch.*v=([a-zA-Z0-9_-]+)/) || url.match(/^(?:(https?):\/\/)?(?:(?:www|m)\.)?youtu\.be\/([a-zA-Z0-9_-]+)/);
- if (match) {
- return `${match[1] || 'https'}://www.youtube.com/embed/${match[2]}?showinfo=0`;
- }
- // eslint-disable-next-line no-cond-assign
- if (match = url.match(/^(?:(https?):\/\/)?(?:www\.)?vimeo\.com\/(\d+)/)) {
- return `${match[1] || 'https'}://player.vimeo.com/video/${match[2]}/`;
- }
- return url;
- }
- function fillSelect(select, values) {
- let defaultValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
- values.forEach(value => {
- const option = document.createElement('option');
- if (value === defaultValue) {
- option.setAttribute('selected', 'selected');
- } else {
- option.setAttribute('value', String(value));
- }
- select.appendChild(option);
- });
- }
- export { BaseTooltip, BaseTheme as default };
- //# sourceMappingURL=base.js.map
|