| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 | 
							- import Delta from 'quill-delta';
 
- import Parchment from 'parchment';
 
- import Quill from '../core/quill';
 
- import logger from '../core/logger';
 
- import Module from '../core/module';
 
- let debug = logger('quill:toolbar');
 
- class Toolbar extends Module {
 
-   constructor(quill, options) {
 
-     super(quill, options);
 
-     if (Array.isArray(this.options.container)) {
 
-       let container = document.createElement('div');
 
-       addControls(container, this.options.container);
 
-       quill.container.parentNode.insertBefore(container, quill.container);
 
-       this.container = container;
 
-     } else if (typeof this.options.container === 'string') {
 
-       this.container = document.querySelector(this.options.container);
 
-     } else {
 
-       this.container = this.options.container;
 
-     }
 
-     if (!(this.container instanceof HTMLElement)) {
 
-       return debug.error('Container required for toolbar', this.options);
 
-     }
 
-     this.container.classList.add('ql-toolbar');
 
-     this.controls = [];
 
-     this.handlers = {};
 
-     Object.keys(this.options.handlers).forEach((format) => {
 
-       this.addHandler(format, this.options.handlers[format]);
 
-     });
 
-     [].forEach.call(this.container.querySelectorAll('button, select'), (input) => {
 
-       this.attach(input);
 
-     });
 
-     this.quill.on(Quill.events.EDITOR_CHANGE, (type, range) => {
 
-       if (type === Quill.events.SELECTION_CHANGE) {
 
-         this.update(range);
 
-       }
 
-     });
 
-     this.quill.on(Quill.events.SCROLL_OPTIMIZE, () => {
 
-       let [range, ] = this.quill.selection.getRange();  // quill.getSelection triggers update
 
-       this.update(range);
 
-     });
 
-   }
 
-   addHandler(format, handler) {
 
-     this.handlers[format] = handler;
 
-   }
 
-   attach(input) {
 
-     let format = [].find.call(input.classList, (className) => {
 
-       return className.indexOf('ql-') === 0;
 
-     });
 
-     if (!format) return;
 
-     format = format.slice('ql-'.length);
 
-     if (input.tagName === 'BUTTON') {
 
-       input.setAttribute('type', 'button');
 
-     }
 
-     if (this.handlers[format] == null) {
 
-       if (this.quill.scroll.whitelist != null && this.quill.scroll.whitelist[format] == null) {
 
-         debug.warn('ignoring attaching to disabled format', format, input);
 
-         return;
 
-       }
 
-       if (Parchment.query(format) == null) {
 
-         debug.warn('ignoring attaching to nonexistent format', format, input);
 
-         return;
 
-       }
 
-     }
 
-     let eventName = input.tagName === 'SELECT' ? 'change' : 'click';
 
-     input.addEventListener(eventName, (e) => {
 
-       let value;
 
-       if (input.tagName === 'SELECT') {
 
-         if (input.selectedIndex < 0) return;
 
-         let selected = input.options[input.selectedIndex];
 
-         if (selected.hasAttribute('selected')) {
 
-           value = false;
 
-         } else {
 
-           value = selected.value || false;
 
-         }
 
-       } else {
 
-         if (input.classList.contains('ql-active')) {
 
-           value = false;
 
-         } else {
 
-           value = input.value || !input.hasAttribute('value');
 
-         }
 
-         e.preventDefault();
 
-       }
 
-       this.quill.focus();
 
-       let [range, ] = this.quill.selection.getRange();
 
-       if (this.handlers[format] != null) {
 
-         this.handlers[format].call(this, value);
 
-       } else if (Parchment.query(format).prototype instanceof Parchment.Embed) {
 
-         value = prompt(`Enter ${format}`);
 
-         if (!value) return;
 
-         this.quill.updateContents(new Delta()
 
-           .retain(range.index)
 
-           .delete(range.length)
 
-           .insert({ [format]: value })
 
-         , Quill.sources.USER);
 
-       } else {
 
-         this.quill.format(format, value, Quill.sources.USER);
 
-       }
 
-       this.update(range);
 
-     });
 
-     // TODO use weakmap
 
-     this.controls.push([format, input]);
 
-   }
 
-   update(range) {
 
-     let formats = range == null ? {} : this.quill.getFormat(range);
 
-     this.controls.forEach(function(pair) {
 
-       let [format, input] = pair;
 
-       if (input.tagName === 'SELECT') {
 
-         let option;
 
-         if (range == null) {
 
-           option = null;
 
-         } else if (formats[format] == null) {
 
-           option = input.querySelector('option[selected]');
 
-         } else if (!Array.isArray(formats[format])) {
 
-           let value = formats[format];
 
-           if (typeof value === 'string') {
 
-             value = value.replace(/\"/g, '\\"');
 
-           }
 
-           option = input.querySelector(`option[value="${value}"]`);
 
-         }
 
-         if (option == null) {
 
-           input.value = '';   // TODO make configurable?
 
-           input.selectedIndex = -1;
 
-         } else {
 
-           option.selected = true;
 
-         }
 
-       } else {
 
-         if (range == null) {
 
-           input.classList.remove('ql-active');
 
-         } else if (input.hasAttribute('value')) {
 
-           // both being null should match (default values)
 
-           // '1' should match with 1 (headers)
 
-           let isActive = formats[format] === input.getAttribute('value') ||
 
-                          (formats[format] != null && formats[format].toString() === input.getAttribute('value')) ||
 
-                          (formats[format] == null && !input.getAttribute('value'));
 
-           input.classList.toggle('ql-active', isActive);
 
-         } else {
 
-           input.classList.toggle('ql-active', formats[format] != null);
 
-         }
 
-       }
 
-     });
 
-   }
 
- }
 
- Toolbar.DEFAULTS = {};
 
- function addButton(container, format, value) {
 
-   let input = document.createElement('button');
 
-   input.setAttribute('type', 'button');
 
-   input.classList.add('ql-' + format);
 
-   if (value != null) {
 
-     input.value = value;
 
-   }
 
-   container.appendChild(input);
 
- }
 
- function addControls(container, groups) {
 
-   if (!Array.isArray(groups[0])) {
 
-     groups = [groups];
 
-   }
 
-   groups.forEach(function(controls) {
 
-     let group = document.createElement('span');
 
-     group.classList.add('ql-formats');
 
-     controls.forEach(function(control) {
 
-       if (typeof control === 'string') {
 
-         addButton(group, control);
 
-       } else {
 
-         let format = Object.keys(control)[0];
 
-         let value = control[format];
 
-         if (Array.isArray(value)) {
 
-           addSelect(group, format, value);
 
-         } else {
 
-           addButton(group, format, value);
 
-         }
 
-       }
 
-     });
 
-     container.appendChild(group);
 
-   });
 
- }
 
- function addSelect(container, format, values) {
 
-   let input = document.createElement('select');
 
-   input.classList.add('ql-' + format);
 
-   values.forEach(function(value) {
 
-     let option = document.createElement('option');
 
-     if (value !== false) {
 
-       option.setAttribute('value', value);
 
-     } else {
 
-       option.setAttribute('selected', 'selected');
 
-     }
 
-     input.appendChild(option);
 
-   });
 
-   container.appendChild(input);
 
- }
 
- Toolbar.DEFAULTS = {
 
-   container: null,
 
-   handlers: {
 
-     clean: function() {
 
-       let range = this.quill.getSelection();
 
-       if (range == null) return;
 
-       if (range.length == 0) {
 
-         let formats = this.quill.getFormat();
 
-         Object.keys(formats).forEach((name) => {
 
-           // Clean functionality in existing apps only clean inline formats
 
-           if (Parchment.query(name, Parchment.Scope.INLINE) != null) {
 
-             this.quill.format(name, false);
 
-           }
 
-         });
 
-       } else {
 
-         this.quill.removeFormat(range, Quill.sources.USER);
 
-       }
 
-     },
 
-     direction: function(value) {
 
-       let align = this.quill.getFormat()['align'];
 
-       if (value === 'rtl' && align == null) {
 
-         this.quill.format('align', 'right', Quill.sources.USER);
 
-       } else if (!value && align === 'right') {
 
-         this.quill.format('align', false, Quill.sources.USER);
 
-       }
 
-       this.quill.format('direction', value, Quill.sources.USER);
 
-     },
 
-     indent: function(value) {
 
-       let range = this.quill.getSelection();
 
-       let formats = this.quill.getFormat(range);
 
-       let indent = parseInt(formats.indent || 0);
 
-       if (value === '+1' || value === '-1') {
 
-         let modifier = (value === '+1') ? 1 : -1;
 
-         if (formats.direction === 'rtl') modifier *= -1;
 
-         this.quill.format('indent', indent + modifier, Quill.sources.USER);
 
-       }
 
-     },
 
-     link: function(value) {
 
-       if (value === true) {
 
-         value = prompt('Enter link URL:');
 
-       }
 
-       this.quill.format('link', value, Quill.sources.USER);
 
-     },
 
-     list: function(value) {
 
-       let range = this.quill.getSelection();
 
-       let formats = this.quill.getFormat(range);
 
-       if (value === 'check') {
 
-         if (formats['list'] === 'checked' || formats['list'] === 'unchecked') {
 
-           this.quill.format('list', false, Quill.sources.USER);
 
-         } else {
 
-           this.quill.format('list', 'unchecked', Quill.sources.USER);
 
-         }
 
-       } else {
 
-         this.quill.format('list', value, Quill.sources.USER);
 
-       }
 
-     }
 
-   }
 
- }
 
- export { Toolbar as default, addControls };
 
 
  |