first commit
This commit is contained in:
35
public/assets/quill/themes/base.d.ts
vendored
Normal file
35
public/assets/quill/themes/base.d.ts
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
import type Quill from '../core/quill.js';
|
||||
import Theme from '../core/theme.js';
|
||||
import type { ThemeOptions } from '../core/theme.js';
|
||||
import Picker from '../ui/picker.js';
|
||||
import Tooltip from '../ui/tooltip.js';
|
||||
import type { Range } from '../core/selection.js';
|
||||
import type Clipboard from '../modules/clipboard.js';
|
||||
import type History from '../modules/history.js';
|
||||
import type Keyboard from '../modules/keyboard.js';
|
||||
import type Uploader from '../modules/uploader.js';
|
||||
import type Selection from '../core/selection.js';
|
||||
declare class BaseTheme extends Theme {
|
||||
pickers: Picker[];
|
||||
tooltip?: Tooltip;
|
||||
constructor(quill: Quill, options: ThemeOptions);
|
||||
addModule(name: 'clipboard'): Clipboard;
|
||||
addModule(name: 'keyboard'): Keyboard;
|
||||
addModule(name: 'uploader'): Uploader;
|
||||
addModule(name: 'history'): History;
|
||||
addModule(name: 'selection'): Selection;
|
||||
addModule(name: string): unknown;
|
||||
buildButtons(buttons: NodeListOf<HTMLElement>, icons: Record<string, Record<string, string> | string>): void;
|
||||
buildPickers(selects: NodeListOf<HTMLSelectElement>, icons: Record<string, string | Record<string, string>>): void;
|
||||
}
|
||||
declare class BaseTooltip extends Tooltip {
|
||||
textbox: HTMLInputElement | null;
|
||||
linkRange?: Range;
|
||||
constructor(quill: Quill, boundsContainer?: HTMLElement);
|
||||
listen(): void;
|
||||
cancel(): void;
|
||||
edit(mode?: string, preview?: string | null): void;
|
||||
restoreFocus(): void;
|
||||
save(): void;
|
||||
}
|
||||
export { BaseTooltip, BaseTheme as default };
|
||||
257
public/assets/quill/themes/base.js
Normal file
257
public/assets/quill/themes/base.js
Normal file
@@ -0,0 +1,257 @@
|
||||
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
|
||||
1
public/assets/quill/themes/base.js.map
Normal file
1
public/assets/quill/themes/base.js.map
Normal file
File diff suppressed because one or more lines are too long
18
public/assets/quill/themes/bubble.d.ts
vendored
Normal file
18
public/assets/quill/themes/bubble.d.ts
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
import BaseTheme, { BaseTooltip } from './base.js';
|
||||
import type { Bounds } from '../core/selection.js';
|
||||
import Quill from '../core/quill.js';
|
||||
import type { ThemeOptions } from '../core/theme.js';
|
||||
import type Toolbar from '../modules/toolbar.js';
|
||||
declare class BubbleTooltip extends BaseTooltip {
|
||||
static TEMPLATE: string;
|
||||
constructor(quill: Quill, bounds?: HTMLElement);
|
||||
listen(): void;
|
||||
cancel(): void;
|
||||
position(reference: Bounds): number;
|
||||
}
|
||||
declare class BubbleTheme extends BaseTheme {
|
||||
tooltip: BubbleTooltip;
|
||||
constructor(quill: Quill, options: ThemeOptions);
|
||||
extendToolbar(toolbar: Toolbar): void;
|
||||
}
|
||||
export { BubbleTooltip, BubbleTheme as default };
|
||||
114
public/assets/quill/themes/bubble.js
Normal file
114
public/assets/quill/themes/bubble.js
Normal file
@@ -0,0 +1,114 @@
|
||||
import { merge } from 'lodash-es';
|
||||
import Emitter from '../core/emitter.js';
|
||||
import BaseTheme, { BaseTooltip } from './base.js';
|
||||
import { Range } from '../core/selection.js';
|
||||
import icons from '../ui/icons.js';
|
||||
import Quill from '../core/quill.js';
|
||||
const TOOLBAR_CONFIG = [['bold', 'italic', 'link'], [{
|
||||
header: 1
|
||||
}, {
|
||||
header: 2
|
||||
}, 'blockquote']];
|
||||
class BubbleTooltip extends BaseTooltip {
|
||||
static TEMPLATE = ['<span class="ql-tooltip-arrow"></span>', '<div class="ql-tooltip-editor">', '<input type="text" data-formula="e=mc^2" data-link="https://quilljs.com" data-video="Embed URL">', '<a class="ql-close"></a>', '</div>'].join('');
|
||||
constructor(quill, bounds) {
|
||||
super(quill, bounds);
|
||||
this.quill.on(Emitter.events.EDITOR_CHANGE, (type, range, oldRange, source) => {
|
||||
if (type !== Emitter.events.SELECTION_CHANGE) return;
|
||||
if (range != null && range.length > 0 && source === Emitter.sources.USER) {
|
||||
this.show();
|
||||
// Lock our width so we will expand beyond our offsetParent boundaries
|
||||
this.root.style.left = '0px';
|
||||
this.root.style.width = '';
|
||||
this.root.style.width = `${this.root.offsetWidth}px`;
|
||||
const lines = this.quill.getLines(range.index, range.length);
|
||||
if (lines.length === 1) {
|
||||
const bounds = this.quill.getBounds(range);
|
||||
if (bounds != null) {
|
||||
this.position(bounds);
|
||||
}
|
||||
} else {
|
||||
const lastLine = lines[lines.length - 1];
|
||||
const index = this.quill.getIndex(lastLine);
|
||||
const length = Math.min(lastLine.length() - 1, range.index + range.length - index);
|
||||
const indexBounds = this.quill.getBounds(new Range(index, length));
|
||||
if (indexBounds != null) {
|
||||
this.position(indexBounds);
|
||||
}
|
||||
}
|
||||
} else if (document.activeElement !== this.textbox && this.quill.hasFocus()) {
|
||||
this.hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
listen() {
|
||||
super.listen();
|
||||
// @ts-expect-error Fix me later
|
||||
this.root.querySelector('.ql-close').addEventListener('click', () => {
|
||||
this.root.classList.remove('ql-editing');
|
||||
});
|
||||
this.quill.on(Emitter.events.SCROLL_OPTIMIZE, () => {
|
||||
// Let selection be restored by toolbar handlers before repositioning
|
||||
setTimeout(() => {
|
||||
if (this.root.classList.contains('ql-hidden')) return;
|
||||
const range = this.quill.getSelection();
|
||||
if (range != null) {
|
||||
const bounds = this.quill.getBounds(range);
|
||||
if (bounds != null) {
|
||||
this.position(bounds);
|
||||
}
|
||||
}
|
||||
}, 1);
|
||||
});
|
||||
}
|
||||
cancel() {
|
||||
this.show();
|
||||
}
|
||||
position(reference) {
|
||||
const shift = super.position(reference);
|
||||
const arrow = this.root.querySelector('.ql-tooltip-arrow');
|
||||
// @ts-expect-error
|
||||
arrow.style.marginLeft = '';
|
||||
if (shift !== 0) {
|
||||
// @ts-expect-error
|
||||
arrow.style.marginLeft = `${-1 * shift - arrow.offsetWidth / 2}px`;
|
||||
}
|
||||
return shift;
|
||||
}
|
||||
}
|
||||
class BubbleTheme extends BaseTheme {
|
||||
constructor(quill, options) {
|
||||
if (options.modules.toolbar != null && options.modules.toolbar.container == null) {
|
||||
options.modules.toolbar.container = TOOLBAR_CONFIG;
|
||||
}
|
||||
super(quill, options);
|
||||
this.quill.container.classList.add('ql-bubble');
|
||||
}
|
||||
extendToolbar(toolbar) {
|
||||
// @ts-expect-error
|
||||
this.tooltip = new BubbleTooltip(this.quill, this.options.bounds);
|
||||
if (toolbar.container != null) {
|
||||
this.tooltip.root.appendChild(toolbar.container);
|
||||
this.buildButtons(toolbar.container.querySelectorAll('button'), icons);
|
||||
this.buildPickers(toolbar.container.querySelectorAll('select'), icons);
|
||||
}
|
||||
}
|
||||
}
|
||||
BubbleTheme.DEFAULTS = merge({}, BaseTheme.DEFAULTS, {
|
||||
modules: {
|
||||
toolbar: {
|
||||
handlers: {
|
||||
link(value) {
|
||||
if (!value) {
|
||||
this.quill.format('link', false, Quill.sources.USER);
|
||||
} else {
|
||||
// @ts-expect-error
|
||||
this.quill.theme.tooltip.edit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
export { BubbleTooltip, BubbleTheme as default };
|
||||
//# sourceMappingURL=bubble.js.map
|
||||
1
public/assets/quill/themes/bubble.js.map
Normal file
1
public/assets/quill/themes/bubble.js.map
Normal file
File diff suppressed because one or more lines are too long
9
public/assets/quill/themes/snow.d.ts
vendored
Normal file
9
public/assets/quill/themes/snow.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
import BaseTheme from './base.js';
|
||||
import Quill from '../core/quill.js';
|
||||
import type Toolbar from '../modules/toolbar.js';
|
||||
import type { ThemeOptions } from '../core/theme.js';
|
||||
declare class SnowTheme extends BaseTheme {
|
||||
constructor(quill: Quill, options: ThemeOptions);
|
||||
extendToolbar(toolbar: Toolbar): void;
|
||||
}
|
||||
export default SnowTheme;
|
||||
122
public/assets/quill/themes/snow.js
Normal file
122
public/assets/quill/themes/snow.js
Normal file
@@ -0,0 +1,122 @@
|
||||
import { merge } from 'lodash-es';
|
||||
import Emitter from '../core/emitter.js';
|
||||
import BaseTheme, { BaseTooltip } from './base.js';
|
||||
import LinkBlot from '../formats/link.js';
|
||||
import { Range } from '../core/selection.js';
|
||||
import icons from '../ui/icons.js';
|
||||
import Quill from '../core/quill.js';
|
||||
const TOOLBAR_CONFIG = [[{
|
||||
header: ['1', '2', '3', false]
|
||||
}], ['bold', 'italic', 'underline', 'link'], [{
|
||||
list: 'ordered'
|
||||
}, {
|
||||
list: 'bullet'
|
||||
}], ['clean']];
|
||||
class SnowTooltip extends BaseTooltip {
|
||||
static TEMPLATE = ['<a class="ql-preview" rel="noopener noreferrer" target="_blank" href="about:blank"></a>', '<input type="text" data-formula="e=mc^2" data-link="https://quilljs.com" data-video="Embed URL">', '<a class="ql-action"></a>', '<a class="ql-remove"></a>'].join('');
|
||||
preview = this.root.querySelector('a.ql-preview');
|
||||
listen() {
|
||||
super.listen();
|
||||
// @ts-expect-error Fix me later
|
||||
this.root.querySelector('a.ql-action').addEventListener('click', event => {
|
||||
if (this.root.classList.contains('ql-editing')) {
|
||||
this.save();
|
||||
} else {
|
||||
// @ts-expect-error Fix me later
|
||||
this.edit('link', this.preview.textContent);
|
||||
}
|
||||
event.preventDefault();
|
||||
});
|
||||
// @ts-expect-error Fix me later
|
||||
this.root.querySelector('a.ql-remove').addEventListener('click', event => {
|
||||
if (this.linkRange != null) {
|
||||
const range = this.linkRange;
|
||||
this.restoreFocus();
|
||||
this.quill.formatText(range, 'link', false, Emitter.sources.USER);
|
||||
delete this.linkRange;
|
||||
}
|
||||
event.preventDefault();
|
||||
this.hide();
|
||||
});
|
||||
this.quill.on(Emitter.events.SELECTION_CHANGE, (range, oldRange, source) => {
|
||||
if (range == null) return;
|
||||
if (range.length === 0 && source === Emitter.sources.USER) {
|
||||
const [link, offset] = this.quill.scroll.descendant(LinkBlot, range.index);
|
||||
if (link != null) {
|
||||
this.linkRange = new Range(range.index - offset, link.length());
|
||||
const preview = LinkBlot.formats(link.domNode);
|
||||
// @ts-expect-error Fix me later
|
||||
this.preview.textContent = preview;
|
||||
// @ts-expect-error Fix me later
|
||||
this.preview.setAttribute('href', preview);
|
||||
this.show();
|
||||
const bounds = this.quill.getBounds(this.linkRange);
|
||||
if (bounds != null) {
|
||||
this.position(bounds);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
delete this.linkRange;
|
||||
}
|
||||
this.hide();
|
||||
});
|
||||
}
|
||||
show() {
|
||||
super.show();
|
||||
this.root.removeAttribute('data-mode');
|
||||
}
|
||||
}
|
||||
class SnowTheme extends BaseTheme {
|
||||
constructor(quill, options) {
|
||||
if (options.modules.toolbar != null && options.modules.toolbar.container == null) {
|
||||
options.modules.toolbar.container = TOOLBAR_CONFIG;
|
||||
}
|
||||
super(quill, options);
|
||||
this.quill.container.classList.add('ql-snow');
|
||||
}
|
||||
extendToolbar(toolbar) {
|
||||
if (toolbar.container != null) {
|
||||
toolbar.container.classList.add('ql-snow');
|
||||
this.buildButtons(toolbar.container.querySelectorAll('button'), icons);
|
||||
this.buildPickers(toolbar.container.querySelectorAll('select'), icons);
|
||||
// @ts-expect-error
|
||||
this.tooltip = new SnowTooltip(this.quill, this.options.bounds);
|
||||
if (toolbar.container.querySelector('.ql-link')) {
|
||||
this.quill.keyboard.addBinding({
|
||||
key: 'k',
|
||||
shortKey: true
|
||||
}, (_range, context) => {
|
||||
toolbar.handlers.link.call(toolbar, !context.format.link);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SnowTheme.DEFAULTS = merge({}, BaseTheme.DEFAULTS, {
|
||||
modules: {
|
||||
toolbar: {
|
||||
handlers: {
|
||||
link(value) {
|
||||
if (value) {
|
||||
const range = this.quill.getSelection();
|
||||
if (range == null || range.length === 0) return;
|
||||
let preview = this.quill.getText(range);
|
||||
if (/^\S+@\S+\.\S+$/.test(preview) && preview.indexOf('mailto:') !== 0) {
|
||||
preview = `mailto:${preview}`;
|
||||
}
|
||||
// @ts-expect-error
|
||||
const {
|
||||
tooltip
|
||||
} = this.quill.theme;
|
||||
tooltip.edit('link', preview);
|
||||
} else {
|
||||
this.quill.format('link', false, Quill.sources.USER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
export default SnowTheme;
|
||||
//# sourceMappingURL=snow.js.map
|
||||
1
public/assets/quill/themes/snow.js.map
Normal file
1
public/assets/quill/themes/snow.js.map
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user