UNPKG

3.87 kBJavaScriptView Raw
1import extend from 'extend';
2import Emitter from '../core/emitter';
3import BaseTheme, { BaseTooltip } from './base';
4import LinkBlot from '../formats/link';
5import { Range } from '../core/selection';
6import icons from '../ui/icons';
7
8
9const TOOLBAR_CONFIG = [
10 [{ header: ['1', '2', '3', false] }],
11 ['bold', 'italic', 'underline', 'link'],
12 [{ list: 'ordered' }, { list: 'bullet' }],
13 ['clean']
14];
15
16class SnowTheme extends BaseTheme {
17 constructor(quill, options) {
18 if (options.modules.toolbar != null && options.modules.toolbar.container == null) {
19 options.modules.toolbar.container = TOOLBAR_CONFIG;
20 }
21 super(quill, options);
22 this.quill.container.classList.add('ql-snow');
23 }
24
25 extendToolbar(toolbar) {
26 toolbar.container.classList.add('ql-snow');
27 this.buildButtons([].slice.call(toolbar.container.querySelectorAll('button')), icons);
28 this.buildPickers([].slice.call(toolbar.container.querySelectorAll('select')), icons);
29 this.tooltip = new SnowTooltip(this.quill, this.options.bounds);
30 if (toolbar.container.querySelector('.ql-link')) {
31 this.quill.keyboard.addBinding({ key: 'K', shortKey: true }, function(range, context) {
32 toolbar.handlers['link'].call(toolbar, !context.format.link);
33 });
34 }
35 }
36}
37SnowTheme.DEFAULTS = extend(true, {}, BaseTheme.DEFAULTS, {
38 modules: {
39 toolbar: {
40 handlers: {
41 link: function(value) {
42 if (value) {
43 let range = this.quill.getSelection();
44 if (range == null || range.length == 0) return;
45 let preview = this.quill.getText(range);
46 if (/^\S+@\S+\.\S+$/.test(preview) && preview.indexOf('mailto:') !== 0) {
47 preview = 'mailto:' + preview;
48 }
49 let tooltip = this.quill.theme.tooltip;
50 tooltip.edit('link', preview);
51 } else {
52 this.quill.format('link', false);
53 }
54 }
55 }
56 }
57 }
58});
59
60
61class SnowTooltip extends BaseTooltip {
62 constructor(quill, bounds) {
63 super(quill, bounds);
64 this.preview = this.root.querySelector('a.ql-preview');
65 }
66
67 listen() {
68 super.listen();
69 this.root.querySelector('a.ql-action').addEventListener('click', (event) => {
70 if (this.root.classList.contains('ql-editing')) {
71 this.save();
72 } else {
73 this.edit('link', this.preview.textContent);
74 }
75 event.preventDefault();
76 });
77 this.root.querySelector('a.ql-remove').addEventListener('click', (event) => {
78 if (this.linkRange != null) {
79 let range = this.linkRange;
80 this.restoreFocus();
81 this.quill.formatText(range, 'link', false, Emitter.sources.USER);
82 delete this.linkRange;
83 }
84 event.preventDefault();
85 this.hide();
86 });
87 this.quill.on(Emitter.events.SELECTION_CHANGE, (range, oldRange, source) => {
88 if (range == null) return;
89 if (range.length === 0 && source === Emitter.sources.USER) {
90 let [link, offset] = this.quill.scroll.descendant(LinkBlot, range.index);
91 if (link != null) {
92 this.linkRange = new Range(range.index - offset, link.length());
93 let preview = LinkBlot.formats(link.domNode);
94 this.preview.textContent = preview;
95 this.preview.setAttribute('href', preview);
96 this.show();
97 this.position(this.quill.getBounds(this.linkRange));
98 return;
99 }
100 } else {
101 delete this.linkRange;
102 }
103 this.hide();
104 });
105 }
106
107 show() {
108 super.show();
109 this.root.removeAttribute('data-mode');
110 }
111}
112SnowTooltip.TEMPLATE = [
113 '<a class="ql-preview" target="_blank" href="about:blank"></a>',
114 '<input type="text" data-formula="e=mc^2" data-link="https://quilljs.com" data-video="Embed URL">',
115 '<a class="ql-action"></a>',
116 '<a class="ql-remove"></a>'
117].join('');
118
119
120export default SnowTheme;