| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506 | 
							- import './polyfill';
 
- import Delta from 'quill-delta';
 
- import Editor from './editor';
 
- import Emitter from './emitter';
 
- import Module from './module';
 
- import Parchment from 'parchment';
 
- import Selection, { Range } from './selection';
 
- import extend from 'extend';
 
- import logger from './logger';
 
- import Theme from './theme';
 
- let debug = logger('quill');
 
- class Quill {
 
-   static debug(limit) {
 
-     if (limit === true) {
 
-       limit = 'log';
 
-     }
 
-     logger.level(limit);
 
-   }
 
-   static find(node) {
 
-     return node.__quill || Parchment.find(node);
 
-   }
 
-   static import(name) {
 
-     if (this.imports[name] == null) {
 
-       debug.error(`Cannot import ${name}. Are you sure it was registered?`);
 
-     }
 
-     return this.imports[name];
 
-   }
 
-   static register(path, target, overwrite = false) {
 
-     if (typeof path !== 'string') {
 
-       let name = path.attrName || path.blotName;
 
-       if (typeof name === 'string') {
 
-         // register(Blot | Attributor, overwrite)
 
-         this.register('formats/' + name, path, target);
 
-       } else {
 
-         Object.keys(path).forEach((key) => {
 
-           this.register(key, path[key], target);
 
-         });
 
-       }
 
-     } else {
 
-       if (this.imports[path] != null && !overwrite) {
 
-         debug.warn(`Overwriting ${path} with`, target);
 
-       }
 
-       this.imports[path] = target;
 
-       if ((path.startsWith('blots/') || path.startsWith('formats/')) &&
 
-           target.blotName !== 'abstract') {
 
-         Parchment.register(target);
 
-       } else if (path.startsWith('modules') && typeof target.register === 'function') {
 
-         target.register();
 
-       }
 
-     }
 
-   }
 
-   constructor(container, options = {}) {
 
-     this.options = expandConfig(container, options);
 
-     this.container = this.options.container;
 
-     if (this.container == null) {
 
-       return debug.error('Invalid Quill container', container);
 
-     }
 
-     if (this.options.debug) {
 
-       Quill.debug(this.options.debug);
 
-     }
 
-     let html = this.container.innerHTML.trim();
 
-     this.container.classList.add('ql-container');
 
-     this.container.innerHTML = '';
 
-     this.container.__quill = this;
 
-     this.root = this.addContainer('ql-editor');
 
-     this.root.classList.add('ql-blank');
 
-     this.root.setAttribute('data-gramm', false);
 
-     this.scrollingContainer = this.options.scrollingContainer || this.root;
 
-     this.emitter = new Emitter();
 
-     this.scroll = Parchment.create(this.root, {
 
-       emitter: this.emitter,
 
-       whitelist: this.options.formats
 
-     });
 
-     this.editor = new Editor(this.scroll);
 
-     this.selection = new Selection(this.scroll, this.emitter);
 
-     this.theme = new this.options.theme(this, this.options);
 
-     this.keyboard = this.theme.addModule('keyboard');
 
-     this.clipboard = this.theme.addModule('clipboard');
 
-     this.history = this.theme.addModule('history');
 
-     this.theme.init();
 
-     this.emitter.on(Emitter.events.EDITOR_CHANGE, (type) => {
 
-       if (type === Emitter.events.TEXT_CHANGE) {
 
-         this.root.classList.toggle('ql-blank', this.editor.isBlank());
 
-       }
 
-     });
 
-     this.emitter.on(Emitter.events.SCROLL_UPDATE, (source, mutations) => {
 
-       let range = this.selection.lastRange;
 
-       let index = range && range.length === 0 ? range.index : undefined;
 
-       modify.call(this, () => {
 
-         return this.editor.update(null, mutations, index);
 
-       }, source);
 
-     });
 
-     let contents = this.clipboard.convert(`<div class='ql-editor' style="white-space: normal;">${html}<p><br></p></div>`);
 
-     this.setContents(contents);
 
-     this.history.clear();
 
-     if (this.options.placeholder) {
 
-       this.root.setAttribute('data-placeholder', this.options.placeholder);
 
-     }
 
-     if (this.options.readOnly) {
 
-       this.disable();
 
-     }
 
-   }
 
-   addContainer(container, refNode = null) {
 
-     if (typeof container === 'string') {
 
-       let className = container;
 
-       container = document.createElement('div');
 
-       container.classList.add(className);
 
-     }
 
-     this.container.insertBefore(container, refNode);
 
-     return container;
 
-   }
 
-   blur() {
 
-     this.selection.setRange(null);
 
-   }
 
-   deleteText(index, length, source) {
 
-     [index, length, , source] = overload(index, length, source);
 
-     return modify.call(this, () => {
 
-       return this.editor.deleteText(index, length);
 
-     }, source, index, -1*length);
 
-   }
 
-   disable() {
 
-     this.enable(false);
 
-   }
 
-   enable(enabled = true) {
 
-     this.scroll.enable(enabled);
 
-     this.container.classList.toggle('ql-disabled', !enabled);
 
-   }
 
-   focus() {
 
-     let scrollTop = this.scrollingContainer.scrollTop;
 
-     this.selection.focus();
 
-     this.scrollingContainer.scrollTop = scrollTop;
 
-     this.scrollIntoView();
 
-   }
 
-   format(name, value, source = Emitter.sources.API) {
 
-     return modify.call(this, () => {
 
-       let range = this.getSelection(true);
 
-       let change = new Delta();
 
-       if (range == null) {
 
-         return change;
 
-       } else if (Parchment.query(name, Parchment.Scope.BLOCK)) {
 
-         change = this.editor.formatLine(range.index, range.length, { [name]: value });
 
-       } else if (range.length === 0) {
 
-         this.selection.format(name, value);
 
-         return change;
 
-       } else {
 
-         change = this.editor.formatText(range.index, range.length, { [name]: value });
 
-       }
 
-       this.setSelection(range, Emitter.sources.SILENT);
 
-       return change;
 
-     }, source);
 
-   }
 
-   formatLine(index, length, name, value, source) {
 
-     let formats;
 
-     [index, length, formats, source] = overload(index, length, name, value, source);
 
-     return modify.call(this, () => {
 
-       return this.editor.formatLine(index, length, formats);
 
-     }, source, index, 0);
 
-   }
 
-   formatText(index, length, name, value, source) {
 
-     let formats;
 
-     [index, length, formats, source] = overload(index, length, name, value, source);
 
-     return modify.call(this, () => {
 
-       return this.editor.formatText(index, length, formats);
 
-     }, source, index, 0);
 
-   }
 
-   getBounds(index, length = 0) {
 
-     let bounds;
 
-     if (typeof index === 'number') {
 
-       bounds = this.selection.getBounds(index, length);
 
-     } else {
 
-       bounds = this.selection.getBounds(index.index, index.length);
 
-     }
 
-     let containerBounds = this.container.getBoundingClientRect();
 
-     return {
 
-       bottom: bounds.bottom - containerBounds.top,
 
-       height: bounds.height,
 
-       left: bounds.left - containerBounds.left,
 
-       right: bounds.right - containerBounds.left,
 
-       top: bounds.top - containerBounds.top,
 
-       width: bounds.width
 
-     };
 
-   }
 
-   getContents(index = 0, length = this.getLength() - index) {
 
-     [index, length] = overload(index, length);
 
-     return this.editor.getContents(index, length);
 
-   }
 
-   getFormat(index = this.getSelection(true), length = 0) {
 
-     if (typeof index === 'number') {
 
-       return this.editor.getFormat(index, length);
 
-     } else {
 
-       return this.editor.getFormat(index.index, index.length);
 
-     }
 
-   }
 
-   getIndex(blot) {
 
-     return blot.offset(this.scroll);
 
-   }
 
-   getLength() {
 
-     return this.scroll.length();
 
-   }
 
-   getLeaf(index) {
 
-     return this.scroll.leaf(index);
 
-   }
 
-   getLine(index) {
 
-     return this.scroll.line(index);
 
-   }
 
-   getLines(index = 0, length = Number.MAX_VALUE) {
 
-     if (typeof index !== 'number') {
 
-       return this.scroll.lines(index.index, index.length);
 
-     } else {
 
-       return this.scroll.lines(index, length);
 
-     }
 
-   }
 
-   getModule(name) {
 
-     return this.theme.modules[name];
 
-   }
 
-   getSelection(focus = false) {
 
-     if (focus) this.focus();
 
-     this.update();  // Make sure we access getRange with editor in consistent state
 
-     return this.selection.getRange()[0];
 
-   }
 
-   getText(index = 0, length = this.getLength() - index) {
 
-     [index, length] = overload(index, length);
 
-     return this.editor.getText(index, length);
 
-   }
 
-   hasFocus() {
 
-     return this.selection.hasFocus();
 
-   }
 
-   insertEmbed(index, embed, value, source = Quill.sources.API) {
 
-     return modify.call(this, () => {
 
-       return this.editor.insertEmbed(index, embed, value);
 
-     }, source, index);
 
-   }
 
-   insertText(index, text, name, value, source) {
 
-     let formats;
 
-     [index, , formats, source] = overload(index, 0, name, value, source);
 
-     return modify.call(this, () => {
 
-       return this.editor.insertText(index, text, formats);
 
-     }, source, index, text.length);
 
-   }
 
-   isEnabled() {
 
-     return !this.container.classList.contains('ql-disabled');
 
-   }
 
-   off() {
 
-     return this.emitter.off.apply(this.emitter, arguments);
 
-   }
 
-   on() {
 
-     return this.emitter.on.apply(this.emitter, arguments);
 
-   }
 
-   once() {
 
-     return this.emitter.once.apply(this.emitter, arguments);
 
-   }
 
-   pasteHTML(index, html, source) {
 
-     this.clipboard.dangerouslyPasteHTML(index, html, source);
 
-   }
 
-   removeFormat(index, length, source) {
 
-     [index, length, , source] = overload(index, length, source);
 
-     return modify.call(this, () => {
 
-       return this.editor.removeFormat(index, length);
 
-     }, source, index);
 
-   }
 
-   scrollIntoView() {
 
-     this.selection.scrollIntoView(this.scrollingContainer);
 
-   }
 
-   setContents(delta, source = Emitter.sources.API) {
 
-     return modify.call(this, () => {
 
-       delta = new Delta(delta);
 
-       let length = this.getLength();
 
-       let deleted = this.editor.deleteText(0, length);
 
-       let applied = this.editor.applyDelta(delta);
 
-       let lastOp = applied.ops[applied.ops.length - 1];
 
-       if (lastOp != null && typeof(lastOp.insert) === 'string' && lastOp.insert[lastOp.insert.length-1] === '\n') {
 
-         this.editor.deleteText(this.getLength() - 1, 1);
 
-         applied.delete(1);
 
-       }
 
-       let ret = deleted.compose(applied);
 
-       return ret;
 
-     }, source);
 
-   }
 
-   setSelection(index, length, source) {
 
-     if (index == null) {
 
-       this.selection.setRange(null, length || Quill.sources.API);
 
-     } else {
 
-       [index, length, , source] = overload(index, length, source);
 
-       this.selection.setRange(new Range(index, length), source);
 
-       if (source !== Emitter.sources.SILENT) {
 
-         this.selection.scrollIntoView(this.scrollingContainer);
 
-       }
 
-     }
 
-   }
 
-   setText(text, source = Emitter.sources.API) {
 
-     let delta = new Delta().insert(text);
 
-     return this.setContents(delta, source);
 
-   }
 
-   update(source = Emitter.sources.USER) {
 
-     let change = this.scroll.update(source);   // Will update selection before selection.update() does if text changes
 
-     this.selection.update(source);
 
-     return change;
 
-   }
 
-   updateContents(delta, source = Emitter.sources.API) {
 
-     return modify.call(this, () => {
 
-       delta = new Delta(delta);
 
-       return this.editor.applyDelta(delta, source);
 
-     }, source, true);
 
-   }
 
- }
 
- Quill.DEFAULTS = {
 
-   bounds: null,
 
-   formats: null,
 
-   modules: {},
 
-   placeholder: '',
 
-   readOnly: false,
 
-   scrollingContainer: null,
 
-   strict: true,
 
-   theme: 'default'
 
- };
 
- Quill.events = Emitter.events;
 
- Quill.sources = Emitter.sources;
 
- // eslint-disable-next-line no-undef
 
- Quill.version = typeof(QUILL_VERSION) === 'undefined' ? 'dev' : QUILL_VERSION;
 
- Quill.imports = {
 
-   'delta'       : Delta,
 
-   'parchment'   : Parchment,
 
-   'core/module' : Module,
 
-   'core/theme'  : Theme
 
- };
 
- function expandConfig(container, userConfig) {
 
-   userConfig = extend(true, {
 
-     container: container,
 
-     modules: {
 
-       clipboard: true,
 
-       keyboard: true,
 
-       history: true
 
-     }
 
-   }, userConfig);
 
-   if (!userConfig.theme || userConfig.theme === Quill.DEFAULTS.theme) {
 
-     userConfig.theme = Theme;
 
-   } else {
 
-     userConfig.theme = Quill.import(`themes/${userConfig.theme}`);
 
-     if (userConfig.theme == null) {
 
-       throw new Error(`Invalid theme ${userConfig.theme}. Did you register it?`);
 
-     }
 
-   }
 
-   let themeConfig = extend(true, {}, userConfig.theme.DEFAULTS);
 
-   [themeConfig, userConfig].forEach(function(config) {
 
-     config.modules = config.modules || {};
 
-     Object.keys(config.modules).forEach(function(module) {
 
-       if (config.modules[module] === true) {
 
-         config.modules[module] = {};
 
-       }
 
-     });
 
-   });
 
-   let moduleNames = Object.keys(themeConfig.modules).concat(Object.keys(userConfig.modules));
 
-   let moduleConfig = moduleNames.reduce(function(config, name) {
 
-     let moduleClass = Quill.import(`modules/${name}`);
 
-     if (moduleClass == null) {
 
-       debug.error(`Cannot load ${name} module. Are you sure you registered it?`);
 
-     } else {
 
-       config[name] = moduleClass.DEFAULTS || {};
 
-     }
 
-     return config;
 
-   }, {});
 
-   // Special case toolbar shorthand
 
-   if (userConfig.modules != null && userConfig.modules.toolbar &&
 
-       userConfig.modules.toolbar.constructor !== Object) {
 
-     userConfig.modules.toolbar = {
 
-       container: userConfig.modules.toolbar
 
-     };
 
-   }
 
-   userConfig = extend(true, {}, Quill.DEFAULTS, { modules: moduleConfig }, themeConfig, userConfig);
 
-   ['bounds', 'container', 'scrollingContainer'].forEach(function(key) {
 
-     if (typeof userConfig[key] === 'string') {
 
-       userConfig[key] = document.querySelector(userConfig[key]);
 
-     }
 
-   });
 
-   userConfig.modules = Object.keys(userConfig.modules).reduce(function(config, name) {
 
-     if (userConfig.modules[name]) {
 
-       config[name] = userConfig.modules[name];
 
-     }
 
-     return config;
 
-   }, {});
 
-   return userConfig;
 
- }
 
- // Handle selection preservation and TEXT_CHANGE emission
 
- // common to modification APIs
 
- function modify(modifier, source, index, shift) {
 
-   if (this.options.strict && !this.isEnabled() && source === Emitter.sources.USER) {
 
-     return new Delta();
 
-   }
 
-   let range = index == null ? null : this.getSelection();
 
-   let oldDelta = this.editor.delta;
 
-   let change = modifier();
 
-   if (range != null) {
 
-     if (index === true) index = range.index;
 
-     if (shift == null) {
 
-       range = shiftRange(range, change, source);
 
-     } else if (shift !== 0) {
 
-       range = shiftRange(range, index, shift, source);
 
-     }
 
-     this.setSelection(range, Emitter.sources.SILENT);
 
-   }
 
-   if (change.length() > 0) {
 
-     let args = [Emitter.events.TEXT_CHANGE, change, oldDelta, source];
 
-     this.emitter.emit(Emitter.events.EDITOR_CHANGE, ...args);
 
-     if (source !== Emitter.sources.SILENT) {
 
-       this.emitter.emit(...args);
 
-     }
 
-   }
 
-   return change;
 
- }
 
- function overload(index, length, name, value, source) {
 
-   let formats = {};
 
-   if (typeof index.index === 'number' && typeof index.length === 'number') {
 
-     // Allow for throwaway end (used by insertText/insertEmbed)
 
-     if (typeof length !== 'number') {
 
-       source = value, value = name, name = length, length = index.length, index = index.index;
 
-     } else {
 
-       length = index.length, index = index.index;
 
-     }
 
-   } else if (typeof length !== 'number') {
 
-     source = value, value = name, name = length, length = 0;
 
-   }
 
-   // Handle format being object, two format name/value strings or excluded
 
-   if (typeof name === 'object') {
 
-     formats = name;
 
-     source = value;
 
-   } else if (typeof name === 'string') {
 
-     if (value != null) {
 
-       formats[name] = value;
 
-     } else {
 
-       source = name;
 
-     }
 
-   }
 
-   // Handle optional source
 
-   source = source || Emitter.sources.API;
 
-   return [index, length, formats, source];
 
- }
 
- function shiftRange(range, index, length, source) {
 
-   if (range == null) return null;
 
-   let start, end;
 
-   if (index instanceof Delta) {
 
-     [start, end] = [range.index, range.index + range.length].map(function(pos) {
 
-       return index.transformPosition(pos, source !== Emitter.sources.USER);
 
-     });
 
-   } else {
 
-     [start, end] = [range.index, range.index + range.length].map(function(pos) {
 
-       if (pos < index || (pos === index && source === Emitter.sources.USER)) return pos;
 
-       if (length >= 0) {
 
-         return pos + length;
 
-       } else {
 
-         return Math.max(index, pos + length);
 
-       }
 
-     });
 
-   }
 
-   return new Range(start, end - start);
 
- }
 
- export { expandConfig, overload, Quill as default };
 
 
  |