You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					112 lines
				
				3.5 KiB
			
		
		
			
		
	
	
					112 lines
				
				3.5 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								import extend from 'extend';
							 | 
						||
| 
								 | 
							
								import Emitter from '../core/emitter';
							 | 
						||
| 
								 | 
							
								import BaseTheme, { BaseTooltip } from './base';
							 | 
						||
| 
								 | 
							
								import { Range } from '../core/selection';
							 | 
						||
| 
								 | 
							
								import icons from '../ui/icons';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const TOOLBAR_CONFIG = [
							 | 
						||
| 
								 | 
							
								  ['bold', 'italic', 'link'],
							 | 
						||
| 
								 | 
							
								  [{ header: 1 }, { header: 2 }, 'blockquote']
							 | 
						||
| 
								 | 
							
								];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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) {
							 | 
						||
| 
								 | 
							
								    this.tooltip = new BubbleTooltip(this.quill, this.options.bounds);
							 | 
						||
| 
								 | 
							
								    this.tooltip.root.appendChild(toolbar.container);
							 | 
						||
| 
								 | 
							
								    this.buildButtons([].slice.call(toolbar.container.querySelectorAll('button')), icons);
							 | 
						||
| 
								 | 
							
								    this.buildPickers([].slice.call(toolbar.container.querySelectorAll('select')), icons);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								BubbleTheme.DEFAULTS = extend(true, {}, BaseTheme.DEFAULTS, {
							 | 
						||
| 
								 | 
							
								  modules: {
							 | 
						||
| 
								 | 
							
								    toolbar: {
							 | 
						||
| 
								 | 
							
								      handlers: {
							 | 
						||
| 
								 | 
							
								        link: function(value) {
							 | 
						||
| 
								 | 
							
								          if (!value) {
							 | 
						||
| 
								 | 
							
								            this.quill.format('link', false);
							 | 
						||
| 
								 | 
							
								          } else {
							 | 
						||
| 
								 | 
							
								            this.quill.theme.tooltip.edit();
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class BubbleTooltip extends BaseTooltip {
							 | 
						||
| 
								 | 
							
								  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';
							 | 
						||
| 
								 | 
							
								        let lines = this.quill.getLines(range.index, range.length);
							 | 
						||
| 
								 | 
							
								        if (lines.length === 1) {
							 | 
						||
| 
								 | 
							
								          this.position(this.quill.getBounds(range));
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								          let lastLine = lines[lines.length - 1];
							 | 
						||
| 
								 | 
							
								          let index = this.quill.getIndex(lastLine);
							 | 
						||
| 
								 | 
							
								          let length = Math.min(lastLine.length() - 1, range.index + range.length - index);
							 | 
						||
| 
								 | 
							
								          let bounds = this.quill.getBounds(new Range(index, length));
							 | 
						||
| 
								 | 
							
								          this.position(bounds);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      } else if (document.activeElement !== this.textbox && this.quill.hasFocus()) {
							 | 
						||
| 
								 | 
							
								        this.hide();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  listen() {
							 | 
						||
| 
								 | 
							
								    super.listen();
							 | 
						||
| 
								 | 
							
								    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;
							 | 
						||
| 
								 | 
							
								        let range = this.quill.getSelection();
							 | 
						||
| 
								 | 
							
								        if (range != null) {
							 | 
						||
| 
								 | 
							
								          this.position(this.quill.getBounds(range));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }, 1);
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  cancel() {
							 | 
						||
| 
								 | 
							
								    this.show();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  position(reference) {
							 | 
						||
| 
								 | 
							
								    let shift = super.position(reference);
							 | 
						||
| 
								 | 
							
								    let arrow = this.root.querySelector('.ql-tooltip-arrow');
							 | 
						||
| 
								 | 
							
								    arrow.style.marginLeft = '';
							 | 
						||
| 
								 | 
							
								    if (shift === 0) return shift;
							 | 
						||
| 
								 | 
							
								    arrow.style.marginLeft = (-1*shift - arrow.offsetWidth/2) + 'px';
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								BubbleTooltip.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('');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export { BubbleTooltip, BubbleTheme as default };
							 |