├── .gitignore ├── quilljs-source-code ├── docs │ ├── CNAME │ ├── robots.txt │ ├── assets │ │ └── images │ │ │ ├── footer.png │ │ │ ├── favicon.ico │ │ │ ├── blog │ │ │ ├── bubble.png │ │ │ ├── color.png │ │ │ ├── syntax.png │ │ │ ├── formula.png │ │ │ ├── theme-1.png │ │ │ └── theme-2.png │ │ │ ├── brand-asset.png │ │ │ └── users │ │ │ ├── asana.png │ │ │ ├── front.png │ │ │ ├── lever.png │ │ │ ├── buffer.png │ │ │ ├── gannett.png │ │ │ ├── hubspot.png │ │ │ ├── intuit.png │ │ │ ├── linkedin.png │ │ │ ├── reedsy.png │ │ │ ├── usatoday.png │ │ │ ├── voxmedia.png │ │ │ └── salesforce.png │ ├── 0.20 │ │ └── assets │ │ │ ├── images │ │ │ ├── icon.png │ │ │ ├── pen.png │ │ │ ├── cloud.png │ │ │ ├── tubes.png │ │ │ ├── browsers.png │ │ │ ├── favicon.png │ │ │ ├── cloud-large.png │ │ │ ├── quill-photo.jpg │ │ │ ├── users │ │ │ │ ├── asana.png │ │ │ │ ├── front.png │ │ │ │ ├── lever.png │ │ │ │ ├── intuit.png │ │ │ │ ├── reedsy.png │ │ │ │ ├── relateiq.png │ │ │ │ ├── voxmedia.png │ │ │ │ ├── writer.png │ │ │ │ ├── respondly.png │ │ │ │ ├── salesforce.png │ │ │ │ ├── themexpert.png │ │ │ │ └── merchantcircle.png │ │ │ └── blog │ │ │ │ ├── theme-1.png │ │ │ │ └── theme-2.png │ │ │ └── js │ │ │ └── index.js │ ├── _includes │ │ ├── basic-editor.html │ │ ├── github.html │ │ ├── open-source.html │ │ ├── sidebar.html │ │ ├── footer.html │ │ ├── svg │ │ │ ├── octocat.svg │ │ │ └── logo.svg │ │ ├── full-editor.html │ │ ├── standalone │ │ │ ├── bubble.html │ │ │ ├── snow.html │ │ │ └── full.html │ │ ├── lotr.html │ │ ├── analytics.html │ │ ├── full-toolbar.html │ │ ├── meta.html │ │ └── header.html │ ├── docs │ │ ├── standalone │ │ │ ├── full.md │ │ │ ├── snow.md │ │ │ ├── bubble.md │ │ │ └── basic.md │ │ ├── modules │ │ │ ├── formula.md │ │ │ ├── syntax.md │ │ │ ├── history.md │ │ │ └── clipboard.md │ │ ├── api.md │ │ ├── quickstart.md │ │ ├── formats.md │ │ ├── download.md │ │ ├── api │ │ │ ├── editor.md │ │ │ ├── selection.md │ │ │ └── model.md │ │ ├── modules.md │ │ └── themes.md │ ├── _layouts │ │ ├── blog.html │ │ ├── post.html │ │ ├── standalone.html │ │ ├── default.html │ │ └── v0.20.html │ ├── _posts │ │ ├── 2014-08-12-an-official-cdn-for-quill.md │ │ ├── 2016-05-03-quill-1-0-beta-release.md │ │ ├── 2016-03-14-are-we-there-yet-to-1-0.md │ │ └── 2014-11-06-quill-v0-19-no-more-iframes.md │ ├── _data │ │ ├── guides.yaml │ │ ├── api.yaml │ │ └── docs.yaml │ ├── _config.yml │ ├── blog.html │ ├── playground.html │ └── guides │ │ └── adding-quill-to-your-build-pipeline.md ├── _develop │ ├── jekyll.yml │ ├── procfile │ ├── scripts │ │ ├── webdriver.sh │ │ └── release.sh │ ├── sauce.js │ ├── wdio.config.js │ ├── proxy.js │ ├── karma.config.js │ └── browsers.js ├── assets │ ├── favicon.png │ ├── icons │ │ ├── dropdown.svg │ │ ├── mention.svg │ │ ├── comment.svg │ │ ├── undo.svg │ │ ├── redo.svg │ │ ├── attachment.svg │ │ ├── table-merge-cells.svg │ │ ├── underline.svg │ │ ├── italic.svg │ │ ├── align-center.svg │ │ ├── align-left.svg │ │ ├── align-right.svg │ │ ├── align-justify.svg │ │ ├── code.svg │ │ ├── float-full.svg │ │ ├── image.svg │ │ ├── float-center.svg │ │ ├── table-border-all.svg │ │ ├── color.svg │ │ ├── emoji.svg │ │ ├── bold.svg │ │ ├── outdent.svg │ │ ├── indent.svg │ │ ├── size-decrease.svg │ │ ├── speech.svg │ │ ├── hashtag.svg │ │ ├── blockquote.svg │ │ ├── authorship.svg │ │ ├── header-2.svg │ │ ├── clean.svg │ │ ├── direction-ltr.svg │ │ ├── direction-rtl.svg │ │ ├── size-increase.svg │ │ ├── float-left.svg │ │ ├── table-unmerge-cells.svg │ │ ├── link.svg │ │ ├── list-bullet.svg │ │ ├── float-right.svg │ │ ├── list-check.svg │ │ ├── table-insert-columns.svg │ │ ├── audio.svg │ │ ├── size.svg │ │ ├── header.svg │ │ ├── spacing.svg │ │ ├── table.svg │ │ ├── table-insert-rows.svg │ │ ├── table-delete-columns.svg │ │ ├── table-delete-rows.svg │ │ ├── strike.svg │ │ ├── superscript.svg │ │ ├── subscript.svg │ │ ├── map.svg │ │ ├── font.svg │ │ ├── list-ordered.svg │ │ ├── table-insert-cells.svg │ │ ├── table-delete-cells.svg │ │ ├── video.svg │ │ ├── formula.svg │ │ ├── table-border-none.svg │ │ ├── table-border-right.svg │ │ ├── table-border-bottom.svg │ │ ├── table-border-outside.svg │ │ ├── table-border-left.svg │ │ ├── table-border-top.svg │ │ └── background.svg │ ├── bubble │ │ ├── toolbar.styl │ │ └── tooltip.styl │ ├── snow.styl │ ├── snow │ │ ├── toolbar.styl │ │ └── tooltip.styl │ └── bubble.styl ├── blots │ ├── embed.js │ ├── text.js │ ├── container.js │ ├── break.js │ ├── table.js │ ├── table_row.js │ ├── inline.js │ ├── contain.js │ └── table_cell.js ├── formats │ ├── italic.js │ ├── strike.js │ ├── underline.js │ ├── blockquote.js │ ├── header.js │ ├── background.js │ ├── size.js │ ├── align.js │ ├── bold.js │ ├── direction.js │ ├── font.js │ ├── script.js │ ├── color.js │ ├── indent.js │ ├── link.js │ ├── video.js │ └── image.js ├── core │ ├── module.js │ ├── logger.js │ ├── theme.js │ ├── emitter.js │ └── polyfill.js ├── test │ ├── unit │ │ ├── formats │ │ │ ├── bold.js │ │ │ ├── indent.js │ │ │ ├── script.js │ │ │ ├── header.js │ │ │ ├── align.js │ │ │ ├── color.js │ │ │ └── link.js │ │ ├── blots │ │ │ ├── inline.js │ │ │ ├── block.js │ │ │ └── scroll.js │ │ └── ui │ │ │ └── picker.js │ └── unit.js ├── ui │ ├── icon-picker.js │ ├── color-picker.js │ ├── tooltip.js │ └── icons.js ├── modules │ ├── formula.js │ ├── syntax.js │ └── toolbar_extended.js ├── core.js ├── LICENSE └── package.json ├── quilljs-table └── .gitignore └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store -------------------------------------------------------------------------------- /quilljs-source-code/docs/CNAME: -------------------------------------------------------------------------------- 1 | quilljs.com -------------------------------------------------------------------------------- /quilljs-table/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store -------------------------------------------------------------------------------- /quilljs-source-code/docs/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / 3 | -------------------------------------------------------------------------------- /quilljs-source-code/_develop/jekyll.yml: -------------------------------------------------------------------------------- 1 | cdn: / 2 | quill: quill.js 3 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/assets/favicon.png -------------------------------------------------------------------------------- /quilljs-source-code/blots/embed.js: -------------------------------------------------------------------------------- 1 | import Parchment from 'parchment'; 2 | 3 | class Embed extends Parchment.Embed { } 4 | 5 | export default Embed; 6 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/footer.png -------------------------------------------------------------------------------- /quilljs-source-code/blots/text.js: -------------------------------------------------------------------------------- 1 | import Parchment from 'parchment'; 2 | 3 | class TextBlot extends Parchment.Text { } 4 | 5 | export default TextBlot; 6 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/icon.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/pen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/pen.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/_includes/basic-editor.html: -------------------------------------------------------------------------------- 1 | var basicEditor = new Quill('#basic-editor', { 2 | modules: { 'toolbar': '#basic-toolbar' } 3 | }); 4 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/favicon.ico -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/cloud.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/tubes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/tubes.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/blog/bubble.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/blog/bubble.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/blog/color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/blog/color.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/blog/syntax.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/blog/syntax.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/brand-asset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/brand-asset.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/users/asana.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/users/asana.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/users/front.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/users/front.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/users/lever.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/users/lever.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/browsers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/browsers.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/favicon.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/blog/formula.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/blog/formula.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/blog/theme-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/blog/theme-1.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/blog/theme-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/blog/theme-2.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/users/buffer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/users/buffer.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/users/gannett.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/users/gannett.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/users/hubspot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/users/hubspot.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/users/intuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/users/intuit.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/users/linkedin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/users/linkedin.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/users/reedsy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/users/reedsy.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/users/usatoday.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/users/usatoday.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/users/voxmedia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/users/voxmedia.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/cloud-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/cloud-large.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/quill-photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/quill-photo.jpg -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/users/asana.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/users/asana.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/users/front.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/users/front.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/users/lever.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/users/lever.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/assets/images/users/salesforce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/assets/images/users/salesforce.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/blog/theme-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/blog/theme-1.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/blog/theme-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/blog/theme-2.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/users/intuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/users/intuit.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/users/reedsy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/users/reedsy.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/users/relateiq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/users/relateiq.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/users/voxmedia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/users/voxmedia.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/users/writer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/users/writer.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/users/respondly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/users/respondly.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/users/salesforce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/users/salesforce.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/users/themexpert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/users/themexpert.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/docs/standalone/full.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: standalone 3 | title: Full Editor 4 | permalink: /standalone/full/ 5 | --- 6 | 7 | {% include standalone/full.html %} 8 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/docs/standalone/snow.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: standalone 3 | title: Snow Theme 4 | permalink: /standalone/snow/ 5 | --- 6 | 7 | {% include standalone/snow.html %} 8 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/images/users/merchantcircle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dost/quilljs-table/HEAD/quilljs-source-code/docs/0.20/assets/images/users/merchantcircle.png -------------------------------------------------------------------------------- /quilljs-source-code/docs/docs/standalone/bubble.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: standalone 3 | title: Bubble Theme 4 | permalink: /standalone/bubble/ 5 | --- 6 | 7 | {% include standalone/bubble.html %} 8 | -------------------------------------------------------------------------------- /quilljs-source-code/formats/italic.js: -------------------------------------------------------------------------------- 1 | import Bold from './bold'; 2 | 3 | class Italic extends Bold { } 4 | Italic.blotName = 'italic'; 5 | Italic.tagName = ['EM', 'I']; 6 | 7 | export default Italic; 8 | -------------------------------------------------------------------------------- /quilljs-source-code/formats/strike.js: -------------------------------------------------------------------------------- 1 | import Inline from '../blots/inline'; 2 | 3 | class Strike extends Inline { } 4 | Strike.blotName = 'strike'; 5 | Strike.tagName = 'S'; 6 | 7 | export default Strike; 8 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/dropdown.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/mention.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /quilljs-source-code/formats/underline.js: -------------------------------------------------------------------------------- 1 | import Inline from '../blots/inline'; 2 | 3 | class Underline extends Inline { } 4 | Underline.blotName = 'underline'; 5 | Underline.tagName = 'U'; 6 | 7 | export default Underline; 8 | -------------------------------------------------------------------------------- /quilljs-source-code/core/module.js: -------------------------------------------------------------------------------- 1 | class Module { 2 | constructor(quill, options = {}) { 3 | this.quill = quill; 4 | this.options = options; 5 | } 6 | } 7 | Module.DEFAULTS = {}; 8 | 9 | 10 | export default Module; 11 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/comment.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/undo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/redo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/attachment.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /quilljs-source-code/formats/blockquote.js: -------------------------------------------------------------------------------- 1 | import Block from '../blots/block'; 2 | 3 | 4 | class Blockquote extends Block {} 5 | Blockquote.blotName = 'blockquote'; 6 | Blockquote.tagName = 'blockquote'; 7 | 8 | 9 | export default Blockquote; 10 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/table-merge-cells.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/underline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/italic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/align-center.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/align-left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/align-right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/align-justify.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/code.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quilljs-source-code/blots/container.js: -------------------------------------------------------------------------------- 1 | import Parchment from 'parchment'; 2 | import Block, { BlockEmbed } from './block'; 3 | 4 | 5 | class Container extends Parchment.Container { } 6 | Container.allowedChildren = [Block, BlockEmbed, Container]; 7 | 8 | 9 | export default Container; 10 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/float-full.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/image.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/float-center.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/table-border-all.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/color.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/emoji.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_layouts/blog.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 | 6 | 7 | 8 |
9 |
10 | {{ content }} 11 |
12 |
13 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/bold.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /quilljs-source-code/_develop/procfile: -------------------------------------------------------------------------------- 1 | jekyll: jekyll serve -s ../docs -d ../docs/_site --port $npm_package_config_ports_jekyll -w --config ../docs/_config.yml,jekyll.yml 2 | karma: karma start karma.config.js --no-single-run --no-browsers 3 | webpack: webpack-dev-server --config webpack.config.js --env.dev 4 | proxy: node proxy.js -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/outdent.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/indent.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/size-decrease.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/speech.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/hashtag.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /quilljs-source-code/formats/header.js: -------------------------------------------------------------------------------- 1 | import Block from '../blots/block'; 2 | 3 | 4 | class Header extends Block { 5 | static formats(domNode) { 6 | return this.tagName.indexOf(domNode.tagName) + 1; 7 | } 8 | } 9 | Header.blotName = 'header'; 10 | Header.tagName = ['H1', 'H2', 'H3', 'H4', 'H5', 'H6']; 11 | 12 | 13 | export default Header; 14 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/bubble/toolbar.styl: -------------------------------------------------------------------------------- 1 | arrowWidth = 6px 2 | 3 | .ql-bubble 4 | .ql-toolbar 5 | .ql-formats 6 | margin: 8px 12px 8px 0px 7 | .ql-formats:first-child 8 | margin-left: 12px 9 | 10 | .ql-color-picker 11 | svg 12 | margin: 1px 13 | .ql-picker-item.ql-selected, .ql-picker-item:hover 14 | border-color: activeColor 15 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/blockquote.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/authorship.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/header-2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/snow.styl: -------------------------------------------------------------------------------- 1 | themeName = 'snow' 2 | activeColor = #06c 3 | borderColor = #ccc 4 | backgroundColor = #fff 5 | inactiveColor = #444 6 | shadowColor = #ddd 7 | textColor = #444 8 | 9 | @import './core' 10 | @import './base' 11 | @import './snow/*' 12 | 13 | .ql-snow 14 | a 15 | color: activeColor 16 | 17 | .ql-container.ql-snow 18 | border: 1px solid borderColor 19 | -------------------------------------------------------------------------------- /quilljs-source-code/_develop/scripts/webdriver.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | npm start & 4 | 5 | webdriver-manager start 2> /dev/null & 6 | 7 | sleep 20s 8 | wdio _develop/wdio.config.js 9 | EXIT_CODE=$? 10 | 11 | FOREMAN_PID=$(pgrep foreman) 12 | SELENIUM_PID=$(pgrep -f selenium-server-standalone) 13 | 14 | kill -s SIGINT $FOREMAN_PID 15 | kill -s SIGINT $SELENIUM_PID 16 | 17 | echo "\n" 18 | 19 | exit $EXIT_CODE 20 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/clean.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/direction-ltr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/direction-rtl.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/size-increase.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_layouts/post.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 |
6 |
7 |

{{ page.title }}

8 | 12 | {{ content }} 13 |
14 |
15 | -------------------------------------------------------------------------------- /quilljs-source-code/formats/background.js: -------------------------------------------------------------------------------- 1 | import Parchment from 'parchment'; 2 | import { ColorAttributor } from './color'; 3 | 4 | let BackgroundClass = new Parchment.Attributor.Class('background', 'ql-bg', { 5 | scope: Parchment.Scope.INLINE 6 | }); 7 | let BackgroundStyle = new ColorAttributor('background', 'background-color', { 8 | scope: Parchment.Scope.INLINE 9 | }); 10 | 11 | export { BackgroundClass, BackgroundStyle }; 12 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_includes/github.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% include svg/octocat.svg %} 4 | Star 5 | 6 | 8,000 7 | -------------------------------------------------------------------------------- /quilljs-source-code/formats/size.js: -------------------------------------------------------------------------------- 1 | import Parchment from 'parchment'; 2 | 3 | let SizeClass = new Parchment.Attributor.Class('size', 'ql-size', { 4 | scope: Parchment.Scope.INLINE, 5 | whitelist: ['small', 'large', 'huge'] 6 | }); 7 | let SizeStyle = new Parchment.Attributor.Style('size', 'font-size', { 8 | scope: Parchment.Scope.INLINE, 9 | whitelist: ['10px', '18px', '32px'] 10 | }); 11 | 12 | export { SizeClass, SizeStyle }; 13 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/float-left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/table-unmerge-cells.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_layouts/standalone.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ page.title }} - Quill 5 | {% include meta.html %} 6 | {% assign heads = content | split: '' %} 7 | {{ heads[1] }} 8 | 9 | 10 | {{ content | split: '' | last | split: '' | first }} 11 | {% assign scripts = content | split: '' %} 12 | {{ scripts[1] }} 13 | 14 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_includes/open-source.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

An Open Source Project

4 | Quill is permissively licensed under BSD. Use it freely in personal or commercial projects. Join the growing community on Github! 5 |
6 | {% include github.html %} 7 |
8 |
9 | 10 |
-------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/list-bullet.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/float-right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/list-check.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/table-insert-columns.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /quilljs-source-code/formats/align.js: -------------------------------------------------------------------------------- 1 | import Parchment from 'parchment'; 2 | 3 | let config = { 4 | scope: Parchment.Scope.BLOCK, 5 | whitelist: ['right', 'center', 'justify'] 6 | }; 7 | 8 | let AlignAttribute = new Parchment.Attributor.Attribute('align', 'align', config); 9 | let AlignClass = new Parchment.Attributor.Class('align', 'ql-align', config); 10 | let AlignStyle = new Parchment.Attributor.Style('align', 'text-align', config); 11 | 12 | export { AlignAttribute, AlignClass, AlignStyle }; 13 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/audio.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/size.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_includes/sidebar.html: -------------------------------------------------------------------------------- 1 | {% for parent in include.items %} 2 | 3 | {{ parent.title }} 4 | {% if parent.children != null %} 5 | 12 | {% endif %} 13 | 14 | {% endfor %} -------------------------------------------------------------------------------- /quilljs-source-code/formats/bold.js: -------------------------------------------------------------------------------- 1 | import Inline from '../blots/inline'; 2 | 3 | class Bold extends Inline { 4 | static create() { 5 | return super.create(); 6 | } 7 | 8 | static formats() { 9 | return true; 10 | } 11 | 12 | optimize() { 13 | super.optimize(); 14 | if (this.domNode.tagName !== this.statics.tagName[0]) { 15 | this.replaceWith(this.statics.blotName); 16 | } 17 | } 18 | } 19 | Bold.blotName = 'bold'; 20 | Bold.tagName = ['STRONG', 'B']; 21 | 22 | export default Bold; 23 | -------------------------------------------------------------------------------- /quilljs-source-code/formats/direction.js: -------------------------------------------------------------------------------- 1 | import Parchment from 'parchment'; 2 | 3 | let config = { 4 | scope: Parchment.Scope.BLOCK, 5 | whitelist: ['rtl'] 6 | }; 7 | 8 | let DirectionAttribute = new Parchment.Attributor.Attribute('direction', 'dir', config); 9 | let DirectionClass = new Parchment.Attributor.Class('direction', 'ql-direction', config); 10 | let DirectionStyle = new Parchment.Attributor.Style('direction', 'direction', config); 11 | 12 | export { DirectionAttribute, DirectionClass, DirectionStyle }; 13 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/header.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /quilljs-source-code/blots/break.js: -------------------------------------------------------------------------------- 1 | import Embed from './embed'; 2 | 3 | 4 | class Break extends Embed { 5 | static value() { 6 | return undefined; 7 | } 8 | 9 | insertInto(parent, ref) { 10 | if (parent.children.length === 0) { 11 | super.insertInto(parent, ref); 12 | } else { 13 | this.remove(); 14 | } 15 | } 16 | 17 | length() { 18 | return 0; 19 | } 20 | 21 | value() { 22 | return ''; 23 | } 24 | } 25 | Break.blotName = 'break'; 26 | Break.tagName = 'BR'; 27 | 28 | 29 | export default Break; 30 | -------------------------------------------------------------------------------- /quilljs-source-code/formats/font.js: -------------------------------------------------------------------------------- 1 | import Parchment from 'parchment'; 2 | 3 | let config = { 4 | scope: Parchment.Scope.INLINE, 5 | whitelist: ['serif', 'monospace'] 6 | }; 7 | 8 | let FontClass = new Parchment.Attributor.Class('font', 'ql-font', config); 9 | 10 | class FontStyleAttributor extends Parchment.Attributor.Style { 11 | value(node) { 12 | return super.value(node).replace(/["']/g, ''); 13 | } 14 | } 15 | 16 | let FontStyle = new FontStyleAttributor('font', 'font-family', config); 17 | 18 | export { FontStyle, FontClass }; 19 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/spacing.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/table.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/table-insert-rows.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_includes/footer.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/table-delete-columns.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/table-delete-rows.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/strike.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quilljs-source-code/test/unit/formats/bold.js: -------------------------------------------------------------------------------- 1 | import Scroll from '../../../blots/scroll'; 2 | 3 | 4 | describe('Bold', function() { 5 | it('optimize and merge', function() { 6 | let scroll = this.initialize(Scroll, '

abc

'); 7 | let bold = document.createElement('b'); 8 | bold.appendChild(scroll.domNode.firstChild.childNodes[1]); 9 | scroll.domNode.firstChild.insertBefore(bold, scroll.domNode.firstChild.lastChild); 10 | scroll.update(); 11 | expect(scroll.domNode).toEqualHTML('

abc

'); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/superscript.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /quilljs-source-code/_develop/sauce.js: -------------------------------------------------------------------------------- 1 | var _ = require('lodash'); 2 | var os = require('os'); 3 | 4 | var options = { 5 | username: process.env.SAUCE_USER || 'quill', 6 | accessKey: process.env.SAUCE_KEY || 'adc0c0cf-221b-46f1-81b9-a4429b722c2e' 7 | }; 8 | 9 | if (process.env.TRAVIS) { 10 | module.exports = { 11 | build: process.env.TRAVIS_BUILD_ID, 12 | tunnel: process.env.TRAVIS_JOB_NUMBER 13 | }; 14 | } else { 15 | var id = _.random(16*16*16*16).toString(16); 16 | module.exports = { 17 | build: os.hostname() + '-' + id, 18 | tunnel: os.hostname() + '-tunnel-' + id 19 | }; 20 | } 21 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_includes/svg/octocat.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /quilljs-source-code/core/logger.js: -------------------------------------------------------------------------------- 1 | let levels = ['error', 'warn', 'log', 'info']; 2 | let level = 'warn'; 3 | 4 | function debug(method, ...args) { 5 | if (levels.indexOf(method) <= levels.indexOf(level)) { 6 | console[method].apply(console, args); // eslint-disable-line no-console 7 | } 8 | } 9 | 10 | function namespace(ns) { 11 | return levels.reduce(function(logger, method) { 12 | logger[method] = debug.bind(console, method, ns); 13 | return logger; 14 | }, {}); 15 | } 16 | 17 | debug.level = namespace.level = function(newLevel) { 18 | level = newLevel; 19 | }; 20 | 21 | 22 | export default namespace; 23 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_posts/2014-08-12-an-official-cdn-for-quill.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | permalink: /blog/an-official-cdn-for-quill/ 4 | title: An Offical CDN for Quill 5 | --- 6 | 7 | Quill now has an offical Content Distribution Network so you can have access to a reliable, high-speed host for the library. To include a file: 8 | 9 | ```html 10 | 11 | ``` 12 | ```html 13 | 14 | ``` 15 | 16 | You can also use "latest" as the version: 17 | 18 | ```html 19 | 20 | ``` 21 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_includes/full-editor.html: -------------------------------------------------------------------------------- 1 | // Initialize editor with custom theme and modules 2 | var fullEditor = new Quill('#full-editor', { 3 | modules: { 4 | 'toolbar': { container: '#full-toolbar' }, 5 | }, 6 | theme: 'snow' 7 | }); 8 | 9 | // Update basic editor's content with ours 10 | fullEditor.on('text-change', function(delta, oldDelta, source) { 11 | if (source === 'user') { 12 | basicEditor.updateContents(delta); 13 | } 14 | }); 15 | 16 | // Update our content with basic editor's 17 | basicEditor.on('text-change', function(delta, oldDelta, source) { 18 | if (source === 'user') { 19 | fullEditor.updateContents(delta); 20 | } 21 | }); -------------------------------------------------------------------------------- /quilljs-source-code/formats/script.js: -------------------------------------------------------------------------------- 1 | import Inline from '../blots/inline'; 2 | 3 | class Script extends Inline { 4 | static create(value) { 5 | if (value === 'super') { 6 | return document.createElement('sup'); 7 | } else if (value === 'sub') { 8 | return document.createElement('sub'); 9 | } else { 10 | return super.create(value); 11 | } 12 | } 13 | 14 | static formats(domNode) { 15 | if (domNode.tagName === 'SUB') return 'sub'; 16 | if (domNode.tagName === 'SUP') return 'super'; 17 | return undefined; 18 | } 19 | } 20 | Script.blotName = 'script'; 21 | Script.tagName = ['SUB', 'SUP']; 22 | 23 | export default Script; 24 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_data/guides.yaml: -------------------------------------------------------------------------------- 1 | - title: Why Quill 2 | url: /guides/why-quill/ 3 | - title: How to Customize Quill 4 | url: /guides/how-to-customize-quill/ 5 | - title: Adding Quill to Your Build Pipeline 6 | url: /guides/adding-quill-to-your-build-pipeline/ 7 | - title: Building a Custom Module 8 | url: /guides/building-a-custom-module/ 9 | - title: Cloning Medium with Parchment 10 | url: /guides/cloning-medium-with-parchment/ 11 | - title: Designing the Delta Format 12 | url: /guides/designing-the-delta-format/ 13 | - title: Comparison with Other Rich Text Editors 14 | url: /guides/comparison-with-other-rich-text-editors/ 15 | - title: Upgrading to 1.0 16 | url: /guides/upgrading-to-1-0/ 17 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/subscript.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_includes/standalone/bubble.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 |
14 |
15 |
16 | 17 | 18 | 24 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_config.yml: -------------------------------------------------------------------------------- 1 | name: Quill - Your powerful, rich text editor 2 | description: Quill is a free, open source WYSIWYG editor built for the modern web. With its modular architecture and expressive API, it is completely customizable to fit any need. 3 | timezone: America/Los_Angeles 4 | markdown: kramdown 5 | highlighter: rouge 6 | kramdown: 7 | input: GFM 8 | gems: 9 | - jekyll-sitemap 10 | - jekyll-redirect-from 11 | - jekyll-feed 12 | version: 1.2.0 13 | cdn: //cdn.quilljs.com/ 14 | github: https://github.com/quilljs/quill/tree/develop/docs 15 | quill: quill.min.js 16 | highlightjs: //cdnjs.cloudflare.com/ajax/libs/highlight.js/9.3.0 17 | katex: //cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0 18 | url: https://quilljs.com 19 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/map.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_includes/lotr.html: -------------------------------------------------------------------------------- 1 |

One Ring to Rule Them All

2 |

http://en.wikipedia.org/wiki/One_Ring

3 |


4 |

Three Rings for the Elven-kings under the sky,

5 |

Seven for the Dwarf-lords in halls of stone,

6 |

Nine for Mortal Men, doomed to die,

7 |

One for the Dark Lord on his dark throne.

8 |


9 |

In the Land of Mordor where the Shadows lie.

10 |

One Ring to rule them all, One Ring to find them,

11 |

One Ring to bring them all and in the darkness bind them.

12 |

In the Land of Mordor where the Shadows lie.

-------------------------------------------------------------------------------- /quilljs-source-code/ui/icon-picker.js: -------------------------------------------------------------------------------- 1 | import Picker from './picker'; 2 | 3 | 4 | class IconPicker extends Picker { 5 | constructor(select, icons) { 6 | super(select); 7 | this.container.classList.add('ql-icon-picker'); 8 | [].forEach.call(this.container.querySelectorAll('.ql-picker-item'), (item) => { 9 | item.innerHTML = icons[item.getAttribute('data-value') || '']; 10 | }); 11 | this.defaultItem = this.container.querySelector('.ql-selected'); 12 | this.selectItem(this.defaultItem); 13 | } 14 | 15 | selectItem(item, trigger) { 16 | super.selectItem(item, trigger); 17 | item = item || this.defaultItem; 18 | this.label.innerHTML = item.innerHTML; 19 | } 20 | } 21 | 22 | 23 | export default IconPicker; 24 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/font.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quilljs-source-code/core/theme.js: -------------------------------------------------------------------------------- 1 | class Theme { 2 | constructor(quill, options) { 3 | this.quill = quill; 4 | this.options = options; 5 | this.modules = {}; 6 | } 7 | 8 | init() { 9 | Object.keys(this.options.modules).forEach((name) => { 10 | if (this.modules[name] == null) { 11 | this.addModule(name); 12 | } 13 | }); 14 | } 15 | 16 | addModule(name) { 17 | let moduleClass = this.quill.constructor.import(`modules/${name}`); 18 | this.modules[name] = new moduleClass(this.quill, this.options.modules[name] || {}); 19 | return this.modules[name]; 20 | } 21 | } 22 | Theme.DEFAULTS = { 23 | modules: {} 24 | }; 25 | Theme.themes = { 26 | 'default': Theme 27 | }; 28 | 29 | 30 | export default Theme; 31 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/docs/modules/formula.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docs 3 | title: Formula Module 4 | permalink: /docs/modules/formula/ 5 | --- 6 | 7 | The Formula Module adds beautifully rendered formulas into Quill documents, powered by [KaTeX](https://khan.github.io/KaTeX/). 8 | 9 | 10 | ### Example 11 | 12 | ```html 13 | 14 | 15 | 16 | 17 | 18 | 19 | 28 | ``` 29 | -------------------------------------------------------------------------------- /quilljs-source-code/formats/color.js: -------------------------------------------------------------------------------- 1 | import Parchment from 'parchment'; 2 | 3 | class ColorAttributor extends Parchment.Attributor.Style { 4 | value(domNode) { 5 | let value = super.value(domNode); 6 | if (!value.startsWith('rgb(')) return value; 7 | value = value.replace(/^[^\d]+/, '').replace(/[^\d]+$/, ''); 8 | return '#' + value.split(',').map(function(component) { 9 | return ('00' + parseInt(component).toString(16)).slice(-2); 10 | }).join(''); 11 | } 12 | } 13 | 14 | let ColorClass = new Parchment.Attributor.Class('color', 'ql-color', { 15 | scope: Parchment.Scope.INLINE 16 | }); 17 | let ColorStyle = new ColorAttributor('color', 'color', { 18 | scope: Parchment.Scope.INLINE 19 | }); 20 | 21 | export { ColorAttributor, ColorClass, ColorStyle }; 22 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/snow/toolbar.styl: -------------------------------------------------------------------------------- 1 | .ql-toolbar.ql-snow 2 | border: 1px solid borderColor 3 | box-sizing: border-box 4 | font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif 5 | padding: 8px 6 | 7 | .ql-formats 8 | margin-right: 15px 9 | 10 | .ql-picker-label 11 | border: 1px solid transparent 12 | .ql-picker-options 13 | border: 1px solid transparent 14 | box-shadow: rgba(0,0,0,0.2) 0 2px 8px 15 | .ql-picker.ql-expanded 16 | .ql-picker-label 17 | border-color: borderColor 18 | .ql-picker-options 19 | border-color: borderColor 20 | 21 | .ql-color-picker 22 | .ql-picker-item.ql-selected, .ql-picker-item:hover 23 | border-color: #000 24 | 25 | .ql-toolbar.ql-snow + .ql-container.ql-snow 26 | border-top: 0px; 27 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/list-ordered.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /quilljs-source-code/_develop/wdio.config.js: -------------------------------------------------------------------------------- 1 | exports.config = { 2 | specs: [ 3 | './test/functional/epic.js' 4 | ], 5 | exclude: [], 6 | 7 | reporters: ['spec'], 8 | 9 | maxInstances: 10, 10 | capabilities: [{ 11 | browserName: 'chrome' 12 | }], 13 | 14 | sync: true, 15 | logLevel: 'error', 16 | coloredLogs: true, 17 | 18 | baseUrl: 'http://localhost:' + process.env.npm_package_config_ports_proxy, 19 | 20 | waitforTimeout: 10000, 21 | connectionRetryTimeout: 90000, 22 | connectionRetryCount: 3, 23 | 24 | framework: 'jasmine', 25 | jasmineNodeOpts: { 26 | defaultTimeoutInterval: 10000, 27 | expectationResultHandler: function(passed, assertion) { 28 | if (passed) return; 29 | this.saveScreenshot('./wd-' + this.desiredCapabilities.browserName + '-error.png'); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/table-insert-cells.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/table-delete-cells.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /quilljs-source-code/core/emitter.js: -------------------------------------------------------------------------------- 1 | import EventEmitter from 'eventemitter3'; 2 | import logger from './logger'; 3 | 4 | let debug = logger('quill:events'); 5 | 6 | 7 | class Emitter extends EventEmitter { 8 | constructor() { 9 | super(); 10 | this.on('error', debug.error); 11 | } 12 | 13 | emit() { 14 | debug.log.apply(debug, arguments); 15 | super.emit.apply(this, arguments); 16 | } 17 | } 18 | 19 | Emitter.events = { 20 | EDITOR_CHANGE : 'editor-change', 21 | SCROLL_BEFORE_UPDATE : 'scroll-before-update', 22 | SCROLL_OPTIMIZE : 'scroll-optimize', 23 | SCROLL_UPDATE : 'scroll-update', 24 | SELECTION_CHANGE : 'selection-change', 25 | TEXT_CHANGE : 'text-change' 26 | }; 27 | Emitter.sources = { 28 | API : 'api', 29 | SILENT : 'silent', 30 | USER : 'user' 31 | }; 32 | 33 | 34 | export default Emitter; 35 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/blog.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: blog 3 | title: Blog 4 | permalink: /blog/ 5 | --- 6 | 7 | {% for post in site.posts %} 8 | {% unless post.draft %} 9 |
10 |

{{ post.title }}

11 | 15 | {% if post.content contains '' %} 16 | {{ post.content | split: '' | first }} 17 | Read more 18 | {% else %} 19 | {{ post.content }} 20 | {% endif %} 21 | {% if forloop.last == false %} 22 |
23 | {% endif %} 24 |
25 | {% endunless %} 26 | {% endfor %} 27 | -------------------------------------------------------------------------------- /quilljs-source-code/test/unit.js: -------------------------------------------------------------------------------- 1 | import Quill from '../quill.js'; 2 | 3 | import './helpers/unit.js'; 4 | 5 | import './unit/blots/scroll.js'; 6 | import './unit/blots/block.js'; 7 | import './unit/blots/block-embed.js'; 8 | import './unit/blots/inline.js'; 9 | 10 | import './unit/core/editor'; 11 | import './unit/core/selection'; 12 | import './unit/core/quill'; 13 | 14 | import './unit/formats/color'; 15 | import './unit/formats/link'; 16 | import './unit/formats/script'; 17 | import './unit/formats/align'; 18 | import './unit/formats/code'; 19 | import './unit/formats/header'; 20 | import './unit/formats/indent'; 21 | import './unit/formats/list'; 22 | import './unit/formats/bold'; 23 | 24 | import './unit/modules/clipboard'; 25 | import './unit/modules/history'; 26 | import './unit/modules/toolbar'; 27 | 28 | import './unit/ui/picker'; 29 | 30 | 31 | export default Quill; 32 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/video.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /quilljs-source-code/test/unit/formats/indent.js: -------------------------------------------------------------------------------- 1 | import Delta from 'quill-delta'; 2 | import Editor from '../../../core/editor'; 3 | 4 | 5 | describe('Indent', function() { 6 | it('+1', function() { 7 | let editor = this.initialize(Editor, ''); 8 | editor.formatText(4, 1, { 'indent': '+1' }); 9 | expect(editor.getDelta()).toEqual(new Delta().insert('0123').insert('\n', { list: 'bullet', indent: 1 })); 10 | expect(editor.scroll.domNode).toEqualHTML(''); 11 | }); 12 | 13 | it('-1', function() { 14 | let editor = this.initialize(Editor, ''); 15 | editor.formatText(4, 1, { 'indent': '-1' }); 16 | expect(editor.getDelta()).toEqual(new Delta().insert('0123').insert('\n', { list: 'bullet' })); 17 | expect(editor.scroll.domNode).toEqualHTML(''); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_data/api.yaml: -------------------------------------------------------------------------------- 1 | - Content: 2 | - deleteText 3 | - getContents 4 | - getLength 5 | - getText 6 | - insertEmbed 7 | - insertText 8 | - pasteHTML 9 | - setContents 10 | - setText 11 | - updateContents 12 | - Formatting: 13 | - format 14 | - formatLine 15 | - formatText 16 | - getFormat 17 | - removeFormat 18 | - Selection: 19 | - getBounds 20 | - getSelection 21 | - setSelection 22 | - Editor: 23 | - blur 24 | - focus 25 | - disable 26 | - enable 27 | - hasFocus 28 | - update 29 | - Events: 30 | - text-change 31 | - selection-change 32 | - editor-change 33 | - "off" 34 | - "on" 35 | - once 36 | - Model: 37 | - find-experimental 38 | - getIndex-experimental 39 | - getLeaf-experimental 40 | - getLine-experimental 41 | - getLines-experimental 42 | - Extension: 43 | - debug 44 | - import 45 | - register 46 | - addContainer 47 | - getModule -------------------------------------------------------------------------------- /quilljs-source-code/docs/docs/api.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docs 3 | title: API 4 | permalink: /docs/api/ 5 | redirect_from: 6 | - /docs/api/events/ 7 | - /docs/api/manipulation/ 8 | - /docs/editor/ 9 | - /docs/editor/api/ 10 | - /docs/events/ 11 | --- 12 | 13 |
14 | {% for hash in site.data.api %} 15 | 23 | {% endfor %} 24 |
25 | 26 | {% include_relative api/contents.md %} 27 | {% include_relative api/formatting.md %} 28 | {% include_relative api/selection.md %} 29 | {% include_relative api/editor.md %} 30 | {% include_relative api/events.md %} 31 | {% include_relative api/model.md %} 32 | {% include_relative api/extension.md %} 33 | -------------------------------------------------------------------------------- /quilljs-source-code/formats/indent.js: -------------------------------------------------------------------------------- 1 | import Parchment from 'parchment'; 2 | 3 | class IdentAttributor extends Parchment.Attributor.Class { 4 | add(node, value) { 5 | if (value === '+1' || value === '-1') { 6 | let indent = this.value(node) || 0; 7 | value = (value === '+1' ? (indent + 1) : (indent - 1)); 8 | } 9 | if (value === 0) { 10 | this.remove(node); 11 | return true; 12 | } else { 13 | return super.add(node, value); 14 | } 15 | } 16 | 17 | canAdd(node, value) { 18 | return super.canAdd(node, value) || super.canAdd(node, parseInt(value)); 19 | } 20 | 21 | value(node) { 22 | return parseInt(super.value(node)) || undefined; // Don't return NaN 23 | } 24 | } 25 | 26 | let IndentClass = new IdentAttributor('indent', 'ql-indent', { 27 | scope: Parchment.Scope.BLOCK, 28 | whitelist: [1, 2, 3, 4, 5, 6, 7, 8] 29 | }); 30 | 31 | export { IndentClass }; 32 | -------------------------------------------------------------------------------- /quilljs-source-code/modules/formula.js: -------------------------------------------------------------------------------- 1 | import Embed from '../blots/embed'; 2 | import Quill from '../core/quill'; 3 | 4 | 5 | class FormulaBlot extends Embed { 6 | static create(value) { 7 | let node = super.create(value); 8 | if (typeof value === 'string') { 9 | window.katex.render(value, node); 10 | node.setAttribute('data-value', value); 11 | } 12 | node.setAttribute('contenteditable', false); 13 | return node; 14 | } 15 | 16 | static value(domNode) { 17 | return domNode.getAttribute('data-value'); 18 | } 19 | 20 | index() { 21 | return 1; 22 | } 23 | } 24 | FormulaBlot.blotName = 'formula'; 25 | FormulaBlot.className = 'ql-formula'; 26 | FormulaBlot.tagName = 'SPAN'; 27 | 28 | 29 | function Formula() { 30 | if (window.katex == null) { 31 | throw new Error('Formula module requires KaTeX.'); 32 | } 33 | Quill.register(FormulaBlot, true); 34 | } 35 | 36 | 37 | export { FormulaBlot, Formula as default }; 38 | -------------------------------------------------------------------------------- /quilljs-source-code/test/unit/formats/script.js: -------------------------------------------------------------------------------- 1 | import Editor from '../../../core/editor'; 2 | 3 | 4 | describe('Script', function() { 5 | it('add', function() { 6 | let editor = this.initialize(Editor, '

a2 + b2 = c2

'); 7 | editor.formatText(6, 1, { script: 'super' }); 8 | expect(editor.scroll.domNode).toEqualHTML('

a2 + b2 = c2

'); 9 | }); 10 | 11 | it('remove', function() { 12 | let editor = this.initialize(Editor, '

a2 + b2

'); 13 | editor.formatText(1, 1, { script: false }); 14 | expect(editor.scroll.domNode).toEqualHTML('

a2 + b2

'); 15 | }); 16 | 17 | it('replace', function() { 18 | let editor = this.initialize(Editor, '

a2 + b2

'); 19 | editor.formatText(1, 1, { script: 'sub' }); 20 | expect(editor.scroll.domNode).toEqualHTML('

a2 + b2

'); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_includes/svg/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /quilljs-source-code/blots/table.js: -------------------------------------------------------------------------------- 1 | import Parchment from 'parchment'; 2 | import Container from './container'; 3 | import TableRow from './table_row'; 4 | 5 | 6 | class Table extends Container { 7 | 8 | static create(value) { 9 | let tagName = 'table'; 10 | let node = super.create(tagName); 11 | node.setAttribute('table_id', value); 12 | return node; 13 | } 14 | 15 | optimize() { 16 | super.optimize(); 17 | let next = this.next; 18 | if (next != null && next.prev === this && 19 | next.statics.blotName === this.statics.blotName && 20 | next.domNode.tagName === this.domNode.tagName && 21 | next.domNode.getAttribute('table_id') === this.domNode.getAttribute('table_id')) { 22 | next.moveChildren(this); 23 | next.remove(); 24 | } 25 | } 26 | 27 | } 28 | 29 | Table.blotName = 'table'; 30 | Table.tagName = 'table'; 31 | Table.scope = Parchment.Scope.BLOCK_BLOT; 32 | Table.defaultChild = 'tr'; 33 | Table.allowedChildren = [TableRow]; 34 | 35 | 36 | export default Table; 37 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_includes/standalone/snow.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 14 | 15 |
16 |
17 |
18 | 19 | 20 | 21 | 22 | 28 | -------------------------------------------------------------------------------- /quilljs-source-code/blots/table_row.js: -------------------------------------------------------------------------------- 1 | import Parchment from 'parchment'; 2 | import Container from './container'; 3 | import TableCell from './table_cell'; 4 | 5 | 6 | class TableRow extends Container { 7 | 8 | static create(value) { 9 | let tagName = 'tr'; 10 | let node = super.create(tagName); 11 | node.setAttribute('row_id', value); 12 | return node; 13 | } 14 | 15 | optimize() { 16 | super.optimize(); 17 | let next = this.next; 18 | if (next != null && next.prev === this && 19 | next.statics.blotName === this.statics.blotName && 20 | next.domNode.tagName === this.domNode.tagName && 21 | next.domNode.getAttribute('row_id') === this.domNode.getAttribute('row_id')) { 22 | next.moveChildren(this); 23 | next.remove(); 24 | } 25 | } 26 | 27 | } 28 | 29 | TableRow.blotName = 'tr'; 30 | TableRow.tagName = 'tr'; 31 | TableRow.scope = Parchment.Scope.BLOCK_BLOT; 32 | TableRow.defaultChild = 'td'; 33 | TableRow.allowedChildren = [TableCell]; 34 | 35 | 36 | export default TableRow 37 | -------------------------------------------------------------------------------- /quilljs-source-code/ui/color-picker.js: -------------------------------------------------------------------------------- 1 | import Picker from './picker'; 2 | 3 | 4 | class ColorPicker extends Picker { 5 | constructor(select, label) { 6 | super(select); 7 | this.label.innerHTML = label; 8 | this.container.classList.add('ql-color-picker'); 9 | [].slice.call(this.container.querySelectorAll('.ql-picker-item'), 0, 7).forEach(function(item) { 10 | item.classList.add('ql-primary'); 11 | }); 12 | } 13 | 14 | buildItem(option) { 15 | let item = super.buildItem(option); 16 | item.style.backgroundColor = option.getAttribute('value') || ''; 17 | return item; 18 | } 19 | 20 | selectItem(item, trigger) { 21 | super.selectItem(item, trigger); 22 | let colorLabel = this.label.querySelector('.ql-color-label'); 23 | let value = item ? item.getAttribute('data-value') || '' : ''; 24 | if (colorLabel) { 25 | if (colorLabel.tagName === 'line') { 26 | colorLabel.style.stroke = value; 27 | } else { 28 | colorLabel.style.fill = value; 29 | } 30 | } 31 | } 32 | } 33 | 34 | 35 | export default ColorPicker; 36 | -------------------------------------------------------------------------------- /quilljs-source-code/test/unit/blots/inline.js: -------------------------------------------------------------------------------- 1 | import Scroll from '../../../blots/scroll'; 2 | 3 | 4 | describe('Inline', function() { 5 | it('format order', function() { 6 | let scroll = this.initialize(Scroll, '

Hello World!

'); 7 | scroll.formatAt(0, 1, 'bold', true); 8 | scroll.formatAt(0, 1, 'italic', true); 9 | scroll.formatAt(2, 1, 'italic', true); 10 | scroll.formatAt(2, 1, 'bold', true); 11 | expect(scroll.domNode).toEqualHTML( 12 | '

Hello World!

' 13 | ); 14 | }); 15 | 16 | it('reorder', function() { 17 | let scroll = this.initialize(Scroll, '

0123

'); 18 | let p = scroll.domNode.firstChild; 19 | let em = document.createElement('em'); 20 | [].slice.call(p.childNodes).forEach(function(node) { 21 | em.appendChild(node); 22 | }); 23 | p.appendChild(em); 24 | expect(scroll.domNode).toEqualHTML('

0123

'); 25 | scroll.update(); 26 | expect(scroll.domNode).toEqualHTML( 27 | '

0123

' 28 | ); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/bubble.styl: -------------------------------------------------------------------------------- 1 | themeName = 'bubble' 2 | activeColor = #fff 3 | borderColor = #777 4 | backgroundColor = #444 5 | inactiveColor = #ccc 6 | shadowColor = #ddd 7 | textColor = #fff 8 | 9 | @import './core' 10 | @import './base' 11 | @import './bubble/*' 12 | 13 | .ql-container.ql-bubble:not(.ql-disabled) 14 | a 15 | position: relative 16 | white-space: nowrap 17 | a::before 18 | background-color: #444 19 | border-radius: 15px 20 | top: -5px 21 | font-size: 12px 22 | color: #fff 23 | content: attr(href) 24 | font-weight: normal 25 | overflow: hidden 26 | padding: 5px 15px 27 | text-decoration: none 28 | z-index: 1 29 | a::after 30 | border-top: 6px solid #444 31 | border-left: 6px solid transparent 32 | border-right: 6px solid transparent 33 | top: 0 34 | content: " " 35 | height: 0 36 | width: 0 37 | a::before, a::after 38 | left: 0 39 | margin-left: 50% 40 | position: absolute 41 | transform: translate(-50%, -100%) 42 | transition: visibility 0s ease 200ms 43 | visibility: hidden 44 | a:hover::before, a:hover::after 45 | visibility: visible 46 | -------------------------------------------------------------------------------- /quilljs-source-code/formats/link.js: -------------------------------------------------------------------------------- 1 | import Inline from '../blots/inline'; 2 | 3 | 4 | class Link extends Inline { 5 | static create(value) { 6 | let node = super.create(value); 7 | value = this.sanitize(value); 8 | node.setAttribute('href', value); 9 | node.setAttribute('target', '_blank'); 10 | return node; 11 | } 12 | 13 | static formats(domNode) { 14 | return domNode.getAttribute('href'); 15 | } 16 | 17 | static sanitize(url) { 18 | return sanitize(url, ['http', 'https', 'mailto']) ? url : this.SANITIZED_URL; 19 | } 20 | 21 | format(name, value) { 22 | if (name !== this.statics.blotName || !value) return super.format(name, value); 23 | value = this.constructor.sanitize(value); 24 | this.domNode.setAttribute('href', value); 25 | } 26 | } 27 | Link.blotName = 'link'; 28 | Link.tagName = 'A'; 29 | Link.SANITIZED_URL = 'about:blank'; 30 | 31 | 32 | function sanitize(url, protocols) { 33 | let anchor = document.createElement('a'); 34 | anchor.href = url; 35 | let protocol = anchor.href.slice(0, anchor.href.indexOf(':')); 36 | return protocols.indexOf(protocol) > -1; 37 | } 38 | 39 | 40 | export { Link as default, sanitize }; 41 | -------------------------------------------------------------------------------- /quilljs-source-code/core.js: -------------------------------------------------------------------------------- 1 | import Parchment from 'parchment'; 2 | import Quill from './core/quill'; 3 | 4 | import Block, { BlockEmbed } from './blots/block'; 5 | import Break from './blots/break'; 6 | import Container from './blots/container'; 7 | import Cursor from './blots/cursor'; 8 | import Embed from './blots/embed'; 9 | import Inline from './blots/inline'; 10 | import Scroll from './blots/scroll'; 11 | import TextBlot from './blots/text'; 12 | 13 | import Clipboard from './modules/clipboard'; 14 | import History from './modules/history'; 15 | import Keyboard from './modules/keyboard'; 16 | 17 | 18 | Quill.register({ 19 | 'blots/block' : Block, 20 | 'blots/block/embed' : BlockEmbed, 21 | 'blots/break' : Break, 22 | 'blots/container' : Container, 23 | 'blots/cursor' : Cursor, 24 | 'blots/embed' : Embed, 25 | 'blots/inline' : Inline, 26 | 'blots/scroll' : Scroll, 27 | 'blots/text' : TextBlot, 28 | 29 | 'modules/clipboard' : Clipboard, 30 | 'modules/history' : History, 31 | 'modules/keyboard' : Keyboard, 32 | }); 33 | 34 | Parchment.register(Block, Break, Cursor, Inline, Scroll, TextBlot); 35 | 36 | 37 | module.exports = Quill; 38 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_includes/analytics.html: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_data/docs.yaml: -------------------------------------------------------------------------------- 1 | - title: Quickstart 2 | url: /docs/quickstart/ 3 | - title: Download 4 | url: /docs/download/ 5 | - title: Configuration 6 | url: /docs/configuration/ 7 | - title: Formats 8 | url: /docs/formats/ 9 | - title: API 10 | url: /docs/api/ 11 | children: 12 | - title: Content 13 | url: /docs/api/#content 14 | - title: Formatting 15 | url: /docs/api/#formatting 16 | - title: Selection 17 | url: /docs/api/#selection 18 | - title: Editor 19 | url: /docs/api/#editor 20 | - title: Events 21 | url: /docs/api/#events 22 | - title: Model 23 | url: /docs/api/#model 24 | - title: Extension 25 | url: /docs/api/#extension 26 | - title: Delta 27 | url: /docs/delta/ 28 | - title: Modules 29 | url: /docs/modules/ 30 | children: 31 | - title: Toolbar 32 | url: /docs/modules/toolbar/ 33 | - title: Keyboard 34 | url: /docs/modules/keyboard/ 35 | - title: History 36 | url: /docs/modules/history/ 37 | - title: Clipboard 38 | url: /docs/modules/clipboard/ 39 | - title: Formula 40 | url: /docs/modules/formula/ 41 | - title: Syntax 42 | url: /docs/modules/syntax/ 43 | - title: Themes 44 | url: /docs/themes/ 45 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_includes/full-toolbar.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_posts/2016-05-03-quill-1-0-beta-release.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | permalink: /blog/quill-1-0-beta-release/ 4 | title: Quill 1.0 Beta Release 5 | --- 6 | 7 | Today Quill is ready for its first beta preview of 1.0. This is the biggest rewrite to Quill since its inception and enables many new possibilities not available in previous versions of Quill, nor any other editor. The code is as always available on Github and through npm: 8 | 9 | ``` 10 | npm install quill@1.0.0-beta.0 11 | ``` 12 | 13 | The skeleton of a new documentation site is also being built out at [beta.quilljs.com](http://beta.quilljs.com). Whereas the current site focuses on being a referential resource, the new site will also be a guide to provide insight on approaching different customization goals. There is also an [interactive playground](http://beta.quilljs.com/playground/) to try out various configurations and explore the API. 14 | 15 | 16 | 17 | The goal now is of course an official 1.0 release. To get there, Quill will now enter a weekly cadence of beta releases, so you can expect rapid interations on stability and bug fixes each week. Github is still the center of all development so please do report [Issues](https://github.com/quilljs/quill/issues) as you encounter them in the beta preview. 18 | -------------------------------------------------------------------------------- /quilljs-source-code/test/unit/formats/header.js: -------------------------------------------------------------------------------- 1 | import Delta from 'quill-delta'; 2 | import Editor from '../../../core/editor'; 3 | 4 | 5 | describe('Header', function() { 6 | it('add', function() { 7 | let editor = this.initialize(Editor, '

0123

'); 8 | editor.formatText(4, 1, { header: 1 }); 9 | expect(editor.getDelta()).toEqual(new Delta() 10 | .insert('0123', { italic: true }) 11 | .insert('\n', { header: 1 }) 12 | ); 13 | expect(editor.scroll.domNode).toEqualHTML('

0123

'); 14 | }); 15 | 16 | it('remove', function() { 17 | let editor = this.initialize(Editor, '

0123

'); 18 | editor.formatText(4, 1, { header: false }); 19 | expect(editor.getDelta()).toEqual(new Delta() 20 | .insert('0123', { italic: true }) 21 | .insert('\n') 22 | ); 23 | expect(editor.scroll.domNode).toEqualHTML('

0123

'); 24 | }); 25 | 26 | it('change', function() { 27 | let editor = this.initialize(Editor, '

0123

'); 28 | editor.formatText(4, 1, { header: 2 }); 29 | expect(editor.getDelta()).toEqual(new Delta() 30 | .insert('0123', { italic: true }) 31 | .insert('\n', { header: 2 }) 32 | ); 33 | expect(editor.scroll.domNode).toEqualHTML('

0123

'); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /quilljs-source-code/test/unit/ui/picker.js: -------------------------------------------------------------------------------- 1 | import Picker from '../../../ui/picker'; 2 | 3 | describe('Picker', function() { 4 | it('initialization', function() { 5 | this.container.innerHTML = ''; 6 | let picker = new Picker(this.container.firstChild); // eslint-disable-line no-unused-vars 7 | expect(this.container.querySelector('.ql-picker')).toBeTruthy(); 8 | expect(this.container.querySelector('.ql-active')).toBeFalsy(); 9 | expect(this.container.querySelector('.ql-picker-item.ql-selected').outerHTML).toEqualHTML(''); 10 | expect(this.container.querySelector('.ql-picker-item:not(.ql-selected)').outerHTML).toEqualHTML(''); 11 | }); 12 | 13 | it('escape charcters', function() { 14 | let select = document.createElement('select'); 15 | let option = document.createElement('option'); 16 | this.container.appendChild(select); 17 | select.appendChild(option); 18 | let value = '"Helvetica Neue", \'Helvetica\', sans-serif'; 19 | option.value = value; 20 | value = value.replace(/\"/g, '\\"'); 21 | expect(select.querySelector(`option[value="${value}"]`)).toEqual(option); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/docs/modules/syntax.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docs 3 | title: Syntax Highlighter Module 4 | permalink: /docs/modules/syntax/ 5 | redirect_from: 6 | - /docs/modules/code-highlighter/ 7 | --- 8 | 9 | The Syntax Module enhances the Code Block format by automatically detecting and applying syntax highlighting. The excellent [highlight.js](https://highlightjs.org/) library is used as a dependency to parse and tokenize code blocks. 10 | 11 | In general, you may [configure](http://highlightjs.readthedocs.io/en/latest/api.html#configure-options) highlight.js as needed. However, Quill expects and requires the `useBR` option to be `false`. 12 | 13 | 14 | ### Example 15 | 16 | ```html 17 | 18 | 19 | 20 | 21 | 22 | 23 | 36 | ``` 37 | -------------------------------------------------------------------------------- /quilljs-source-code/_develop/proxy.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var httpProxy = require('http-proxy'); 3 | 4 | var proxy = httpProxy.createProxyServer({}); 5 | var ports = { 6 | proxy: parseInt(process.env.npm_package_config_ports_proxy), 7 | jekyll: parseInt(process.env.npm_package_config_ports_jekyll), 8 | karma: parseInt(process.env.npm_package_config_ports_karma), 9 | webpack: parseInt(process.env.npm_package_config_ports_webpack) 10 | }; 11 | 12 | var server = http.createServer(function(req, res) { 13 | if (/\/\d+\.\d+\.\d+/.test(req.url) || req.url.startsWith('/karma/base/dist')) { 14 | var target = 'http://localhost:' + ports.webpack + '/' + req.url.split('/').pop(); 15 | proxy.web(req, res, { 16 | ignorePath: true, 17 | target: target 18 | }); 19 | } else if (req.url.startsWith('/karma') || req.url === '/assets/favicon.png') { 20 | proxy.web(req, res, { ignorePath: false, target: { port: ports.karma } }); 21 | } else { 22 | proxy.web(req, res, { ignorePath: false, target: { port: ports.jekyll } }); 23 | } 24 | }); 25 | 26 | server.on('upgrade', function (req, socket, head) { 27 | proxy.ws(req, socket, head); 28 | }); 29 | 30 | proxy.on('error', function(e) { 31 | console.error(e); 32 | }); 33 | 34 | console.log('Proxy listening on ' + ports.proxy); 35 | server.listen(ports.proxy); 36 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/docs/quickstart.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docs 3 | title: Quickstart 4 | permalink: /docs/quickstart/ 5 | redirect_from: /docs/ 6 | --- 7 | 8 | The best way to get started is try a simple example. Quill is initialized with a DOM element to contain the editor. The contents of that element will become the initial contents of Quill. 9 | 10 | ```html 11 | 12 | 13 | 14 | 15 |
16 |

Hello World!

17 |

Some initial bold text

18 |


19 |
20 | 21 | 22 | 23 | 24 | 25 | 30 | ``` 31 | 32 | And that's all there is to it! 33 | 34 | 35 | ### Next Steps ### 36 | 37 | The real magic of Quill comes in its flexibility and extensibility. You can get an idea of what is possible by playing around with the demos throughout this site or head straight to the [Interactive Playground](/playground/). For an in-depth walkthrough, take a look at [How to Customize Quill](/guides/how-to-customize-quill/). 38 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/docs/formats.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docs 3 | title: Formats 4 | permalink: /docs/formats/ 5 | --- 6 | 7 | Quill supports a number of formats, both in UI controls and API calls. 8 | 9 | By default all formats are enabled and allowed to exist within a Quill editor and can be configured with the [formats](/docs/configuration/#formats) option. This is separate from adding a control in the [Toolbar](/docs/modules/toolbar/). For example, you can configure Quill to allow bolded content to be pasted into an editor that has no bold button in the toolbar. 10 | 11 | {% include standalone/full.html %} 12 | 13 | Standalone 14 | 15 | #### Inline 16 | 17 | - Background Color - `background` 18 | - Bold - `bold` 19 | - Color - `color` 20 | - Font - `font` 21 | - Inline Code - `code` 22 | - Italic - `italic` 23 | - Link - `link` 24 | - Size - `size` 25 | - Strikethrough - `strike` 26 | - Superscript/Subscript - `script` 27 | - Underline - `underline` 28 | 29 | #### Block 30 | 31 | - Blockquote - `blockquote` 32 | - Header - `header` 33 | - Indent - `indent` 34 | - List - `list` 35 | - Text Alignment - `align` 36 | - Text Direction - `direction` 37 | - Code Block - `code-block` 38 | 39 | #### Embeds 40 | 41 | - Formula - `formula` 42 | - Image - `image` 43 | - Video - `video` 44 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_includes/meta.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {% if page.description %} 6 | 7 | {% else %} 8 | 9 | {% endif %} 10 | 11 | 12 | {% if page.path != "index.html" %} 13 | 14 | {% else %} 15 | 16 | {% endif %} 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | {% feed_meta %} -------------------------------------------------------------------------------- /quilljs-source-code/formats/video.js: -------------------------------------------------------------------------------- 1 | import { BlockEmbed } from '../blots/block'; 2 | import Link from '../formats/link'; 3 | 4 | const ATTRIBUTES = [ 5 | 'height', 6 | 'width' 7 | ]; 8 | 9 | 10 | class Video extends BlockEmbed { 11 | static create(value) { 12 | let node = super.create(value); 13 | node.setAttribute('frameborder', '0'); 14 | node.setAttribute('allowfullscreen', true); 15 | node.setAttribute('src', this.sanitize(value)); 16 | return node; 17 | } 18 | 19 | static formats(domNode) { 20 | return ATTRIBUTES.reduce(function(formats, attribute) { 21 | if (domNode.hasAttribute(attribute)) { 22 | formats[attribute] = domNode.getAttribute(attribute); 23 | } 24 | return formats; 25 | }, {}); 26 | } 27 | 28 | static sanitize(url) { 29 | return Link.sanitize(url); 30 | } 31 | 32 | static value(domNode) { 33 | return domNode.getAttribute('src'); 34 | } 35 | 36 | format(name, value) { 37 | if (ATTRIBUTES.indexOf(name) > -1) { 38 | if (value) { 39 | this.domNode.setAttribute(name, value); 40 | } else { 41 | this.domNode.removeAttribute(name); 42 | } 43 | } else { 44 | super.format(name, value); 45 | } 46 | } 47 | } 48 | Video.blotName = 'video'; 49 | Video.className = 'ql-video'; 50 | Video.tagName = 'IFRAME'; 51 | 52 | 53 | export default Video; 54 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/bubble/tooltip.styl: -------------------------------------------------------------------------------- 1 | arrowWidth = 6px 2 | 3 | .ql-bubble 4 | .ql-tooltip 5 | background-color: backgroundColor 6 | border-radius: 25px 7 | color: textColor 8 | .ql-tooltip-arrow 9 | border-left: arrowWidth solid transparent 10 | border-right: arrowWidth solid transparent 11 | content: " " 12 | display: block 13 | left: 50% 14 | margin-left: -1 * arrowWidth 15 | position: absolute 16 | .ql-tooltip:not(.ql-flip) .ql-tooltip-arrow 17 | border-bottom: arrowWidth solid backgroundColor 18 | top: -1 * arrowWidth 19 | .ql-tooltip.ql-flip .ql-tooltip-arrow 20 | border-top: arrowWidth solid backgroundColor 21 | bottom: -1 * arrowWidth 22 | 23 | .ql-tooltip.ql-editing 24 | .ql-tooltip-editor 25 | display: block 26 | .ql-formats 27 | visibility: hidden 28 | 29 | .ql-tooltip-editor 30 | display: none 31 | input[type=text] 32 | background: transparent 33 | border: none 34 | color: textColor 35 | font-size: 13px 36 | height: 100% 37 | outline: none 38 | padding: 10px 20px 39 | position: absolute 40 | width: 100% 41 | a 42 | &:before 43 | color: inactiveColor 44 | content: "\00D7" 45 | font-size: 16px 46 | font-weight: bold 47 | top: 10px 48 | position: absolute 49 | right: 20px 50 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/formula.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quilljs-source-code/formats/image.js: -------------------------------------------------------------------------------- 1 | import Embed from '../blots/embed'; 2 | import { sanitize } from '../formats/link'; 3 | 4 | const ATTRIBUTES = [ 5 | 'alt', 6 | 'height', 7 | 'width' 8 | ]; 9 | 10 | 11 | class Image extends Embed { 12 | static create(value) { 13 | let node = super.create(value); 14 | if (typeof value === 'string') { 15 | node.setAttribute('src', this.sanitize(value)); 16 | } 17 | return node; 18 | } 19 | 20 | static formats(domNode) { 21 | return ATTRIBUTES.reduce(function(formats, attribute) { 22 | if (domNode.hasAttribute(attribute)) { 23 | formats[attribute] = domNode.getAttribute(attribute); 24 | } 25 | return formats; 26 | }, {}); 27 | } 28 | 29 | static match(url) { 30 | return /\.(jpe?g|gif|png)$/.test(url) || /^data:image\/.+;base64/.test(url); 31 | } 32 | 33 | static sanitize(url) { 34 | return sanitize(url, ['http', 'https', 'data']) ? url : '//:0'; 35 | } 36 | 37 | static value(domNode) { 38 | return domNode.getAttribute('src'); 39 | } 40 | 41 | format(name, value) { 42 | if (ATTRIBUTES.indexOf(name) > -1) { 43 | if (value) { 44 | this.domNode.setAttribute(name, value); 45 | } else { 46 | this.domNode.removeAttribute(name); 47 | } 48 | } else { 49 | super.format(name, value); 50 | } 51 | } 52 | } 53 | Image.blotName = 'image'; 54 | Image.tagName = 'IMG'; 55 | 56 | 57 | export default Image; 58 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/snow/tooltip.styl: -------------------------------------------------------------------------------- 1 | tooltipMargin = 8px 2 | 3 | .ql-snow 4 | .ql-tooltip 5 | background-color: #fff 6 | border: 1px solid borderColor 7 | box-shadow: 0px 0px 5px shadowColor 8 | color: textColor 9 | padding: 5px 12px 10 | white-space: nowrap 11 | &::before 12 | content: "Visit URL:" 13 | line-height: 26px 14 | margin-right: tooltipMargin 15 | input[type=text] 16 | display: none 17 | border: 1px solid borderColor 18 | font-size: 13px 19 | height: 26px 20 | margin: 0px 21 | padding: 3px 5px 22 | width: 170px 23 | a.ql-preview 24 | display: inline-block 25 | max-width: 200px 26 | overflow-x: hidden 27 | text-overflow: ellipsis 28 | vertical-align: top 29 | a.ql-action::after 30 | border-right: 1px solid borderColor 31 | content: 'Edit' 32 | margin-left: tooltipMargin*2 33 | padding-right: tooltipMargin 34 | a.ql-remove::before 35 | content: 'Remove' 36 | margin-left: tooltipMargin 37 | a 38 | line-height: 26px 39 | .ql-tooltip.ql-editing 40 | a.ql-preview, a.ql-remove 41 | display: none 42 | input[type=text] 43 | display: inline-block 44 | a.ql-action::after 45 | border-right: 0px 46 | content: 'Save' 47 | padding-right: 0px 48 | .ql-tooltip[data-mode=link]::before 49 | content: "Enter link:" 50 | .ql-tooltip[data-mode=formula]::before 51 | content: "Enter formula:" 52 | .ql-tooltip[data-mode=video]::before 53 | content: "Enter video:" 54 | -------------------------------------------------------------------------------- /quilljs-source-code/test/unit/formats/align.js: -------------------------------------------------------------------------------- 1 | import Delta from 'quill-delta'; 2 | import Editor from '../../../core/editor'; 3 | 4 | 5 | describe('Align', function() { 6 | it('add', function() { 7 | let editor = this.initialize(Editor, '

0123

'); 8 | editor.formatText(4, 1, { align: 'center' }); 9 | expect(editor.getDelta()).toEqual(new Delta().insert('0123').insert('\n', { align: 'center' })); 10 | expect(editor.scroll.domNode).toEqualHTML('

0123

'); 11 | }); 12 | 13 | it('remove', function() { 14 | let editor = this.initialize(Editor, '

0123

'); 15 | editor.formatText(4, 1, { align: false }); 16 | expect(editor.getDelta()).toEqual(new Delta().insert('0123\n')); 17 | expect(editor.scroll.domNode).toEqualHTML('

0123

'); 18 | }); 19 | 20 | it('whitelist', function() { 21 | let editor = this.initialize(Editor, '

0123

') 22 | let initial = editor.scroll.domNode.innerHTML; 23 | editor.formatText(4, 1, { align: 'middle' }); 24 | expect(editor.getDelta()).toEqual(new Delta().insert('0123').insert('\n', { align: 'center' })); 25 | expect(editor.scroll.domNode).toEqualHTML(initial); 26 | }); 27 | 28 | it('invalid scope', function() { 29 | let editor = this.initialize(Editor, '

0123

'); 30 | let initial = editor.scroll.domNode.innerHTML; 31 | editor.formatText(1, 2, { align: 'center' }); 32 | expect(editor.getDelta()).toEqual(new Delta().insert('0123\n')); 33 | expect(editor.scroll.domNode).toEqualHTML(initial); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /quilljs-source-code/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Jason Chen 2 | Copyright (c) 2013, salesforce.com 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 21 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 23 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/table-border-none.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /quilljs-source-code/blots/inline.js: -------------------------------------------------------------------------------- 1 | import Embed from './embed'; 2 | import Text from './text'; 3 | import Parchment from 'parchment'; 4 | 5 | 6 | class Inline extends Parchment.Inline { 7 | static compare(self, other) { 8 | let selfIndex = Inline.order.indexOf(self); 9 | let otherIndex = Inline.order.indexOf(other); 10 | if (selfIndex >= 0 || otherIndex >= 0) { 11 | return selfIndex - otherIndex; 12 | } else if (self === other) { 13 | return 0; 14 | } else if (self < other) { 15 | return -1; 16 | } else { 17 | return 1; 18 | } 19 | } 20 | 21 | formatAt(index, length, name, value) { 22 | if (Inline.compare(this.statics.blotName, name) < 0 && Parchment.query(name, Parchment.Scope.BLOT)) { 23 | let blot = this.isolate(index, length); 24 | if (value) { 25 | blot.wrap(name, value); 26 | } 27 | } else { 28 | super.formatAt(index, length, name, value); 29 | } 30 | } 31 | 32 | optimize() { 33 | super.optimize(); 34 | if (this.parent instanceof Inline && 35 | Inline.compare(this.statics.blotName, this.parent.statics.blotName) > 0) { 36 | let parent = this.parent.isolate(this.offset(), this.length()); 37 | this.moveChildren(parent); 38 | parent.wrap(this); 39 | } 40 | } 41 | } 42 | Inline.allowedChildren = [Inline, Embed, Text]; 43 | // Lower index means deeper in the DOM tree, since not found (-1) is for embeds 44 | Inline.order = [ 45 | 'cursor', 'inline', // Must be lower 46 | 'code', 'underline', 'strike', 'italic', 'bold', 'script', 47 | 'link' // Must be higher 48 | ]; 49 | 50 | 51 | export default Inline; 52 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/docs/download.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docs 3 | title: Download 4 | permalink: /docs/download/ 5 | --- 6 | 7 | Quill comes ready to use in several convenient forms. 8 | 9 | 10 | ### CDN 11 | 12 | A globally distributed and available CDN is provided, backed by [Amazon Cloudfront](https://aws.amazon.com/cloudfront/). 13 | 14 | ```html 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | ``` 27 | 28 | 29 | ### NPM 30 | 31 | Add Quill as an [NPM](//www.npmjs.org/) dependency and add it your own build workflow, or use the included built options. Compiled stylesheets are also included in `dist/` folder. 32 | 33 | ```bash 34 | npm install quill@{{site.version}} 35 | ``` 36 | 37 | 38 | ### Direct Download 39 | 40 | Quill builds are also available for direct download on every [release](https://github.com/quilljs/quill/releases/tag/v{{site.version}}). 41 | 42 | 43 | ### Source 44 | 45 | And of course the complete source code is always available on [Github](https://github.com/quilljs/quill). 46 | 47 | ```bash 48 | git clone git@github.com:quilljs/quill.git 49 | ``` 50 | -------------------------------------------------------------------------------- /quilljs-source-code/test/unit/formats/color.js: -------------------------------------------------------------------------------- 1 | import Delta from 'quill-delta'; 2 | import Editor from '../../../core/editor'; 3 | 4 | 5 | describe('Color', function() { 6 | it('add', function() { 7 | let editor = this.initialize(Editor, '

0123

'); 8 | editor.formatText(1, 2, { color: 'red' }); 9 | expect(editor.getDelta()).toEqual(new Delta() 10 | .insert('0') 11 | .insert('12', { color: 'red' }) 12 | .insert('3\n') 13 | ); 14 | expect(editor.scroll.domNode).toEqualHTML('

0123

'); 15 | }); 16 | 17 | it('remove', function() { 18 | let editor = this.initialize(Editor, '

0123

'); 19 | editor.formatText(1, 2, { color: false }); 20 | let delta = new Delta().insert('0').insert('12', { bold: true }).insert('3\n'); 21 | expect(editor.getDelta()).toEqual(delta); 22 | expect(editor.scroll.domNode).toEqualHTML('

0123

'); 23 | }); 24 | 25 | it('remove unwrap', function() { 26 | let editor = this.initialize(Editor, '

0123

'); 27 | editor.formatText(1, 2, { color: false }); 28 | expect(editor.getDelta()).toEqual(new Delta().insert('0123\n')); 29 | expect(editor.scroll.domNode).toEqualHTML('

0123

'); 30 | }); 31 | 32 | it('invalid scope', function() { 33 | let editor = this.initialize(Editor, '

0123

'); 34 | let initial = editor.scroll.domNode.innerHTML; 35 | editor.formatText(4, 1, { color: 'red' }); 36 | expect(editor.getDelta()).toEqual(new Delta().insert('0123\n')); 37 | expect(editor.scroll.domNode).toEqualHTML(initial); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/docs/api/editor.md: -------------------------------------------------------------------------------- 1 | ## Editor 2 | 3 | ### blur 4 | 5 | Removes focus from the editor. 6 | 7 | **Methods** 8 | 9 | ```javascript 10 | blur() 11 | ``` 12 | 13 | **Examples** 14 | 15 | ```javascript 16 | quill.blur(); 17 | ``` 18 | 19 | ### disable 20 | 21 | Shorthand for [`enable(false)`](#enable). 22 | 23 | ### enable 24 | 25 | Set ability for user to edit, via input devices like the mouse or keyboard. Does not affect capabilities of API calls, when the `source` is `"api"` or `"silent". 26 | 27 | **Methods** 28 | 29 | ```javascript 30 | enable(enabled: boolean = true) 31 | ``` 32 | 33 | **Examples** 34 | 35 | ```javascript 36 | quill.enable(); 37 | quill.enable(false); // Disables user input 38 | ``` 39 | 40 | ### focus 41 | 42 | Focuses the editor and restores its last range. 43 | 44 | **Methods** 45 | 46 | ```javascript 47 | focus() 48 | ``` 49 | 50 | **Examples** 51 | 52 | ```javascript 53 | quill.focus(); 54 | ``` 55 | 56 | ### hasFocus 57 | 58 | Checks if editor has focus. Note focus on toolbar, tooltips, does not count as the editor. 59 | 60 | **Methods** 61 | 62 | ```javascript 63 | hasFocus(): Boolean 64 | ``` 65 | 66 | **Examples** 67 | 68 | ```javascript 69 | quill.hasFocus(); 70 | ``` 71 | 72 | ### update 73 | 74 | Synchronously check editor for user updates and fires events, if changes have occurred. Useful for collaborative use cases during conflict resolution requiring the latest up to date state. [Source](/docs/api/#events) may be `"user"`, `"api"`, or `"silent"`. 75 | 76 | **Methods** 77 | 78 | ```javascript 79 | update(source: String = 'user') 80 | ``` 81 | 82 | **Examples** 83 | 84 | ```javascript 85 | quill.update(); 86 | ``` 87 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/table-border-right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /quilljs-source-code/blots/contain.js: -------------------------------------------------------------------------------- 1 | import Parchment from 'parchment'; 2 | import Container from './container'; 3 | import Block, { BlockEmbed } from './block'; 4 | 5 | 6 | class ContainBlot extends Container { 7 | 8 | static randomId() { 9 | return Math.random().toString(36).slice(2) 10 | } 11 | 12 | static create(value) { 13 | let tagName = 'contain'; 14 | let node = super.create(tagName); 15 | if(value == true) { 16 | value = this.randomId(); 17 | } 18 | node.setAttribute('id', value); 19 | return node; 20 | } 21 | 22 | insertBefore(blot, ref) { 23 | if (blot.statics.blotName == this.statics.blotName) { 24 | // console.log('############################ Not sure this is clean:') // eslint-disable-line 25 | // console.log(blot) // eslint-disable-line 26 | // console.log(blot.children.head) // eslint-disable-line 27 | super.insertBefore(blot.children.head, ref); 28 | } else { 29 | super.insertBefore(blot, ref); 30 | } 31 | } 32 | 33 | static formats(domNode) { 34 | return domNode.getAttribute('id'); 35 | } 36 | 37 | formats() { 38 | // We don't inherit from FormatBlot 39 | return { [this.statics.blotName]: this.statics.formats(this.domNode) } 40 | } 41 | 42 | replace(target) { 43 | if (target.statics.blotName !== this.statics.blotName) { 44 | let item = Parchment.create(this.statics.defaultChild); 45 | target.moveChildren(item); 46 | this.appendChild(item); 47 | } 48 | if (target.parent == null) return; 49 | super.replace(target) 50 | } 51 | 52 | } 53 | 54 | ContainBlot.blotName = 'contain'; 55 | ContainBlot.tagName = 'contain'; 56 | ContainBlot.scope = Parchment.Scope.BLOCK_BLOT; 57 | ContainBlot.defaultChild = 'block'; 58 | ContainBlot.allowedChildren = [Block, BlockEmbed, Container]; 59 | 60 | 61 | export default ContainBlot; 62 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/table-border-bottom.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /quilljs-source-code/ui/tooltip.js: -------------------------------------------------------------------------------- 1 | class Tooltip { 2 | constructor(quill, boundsContainer) { 3 | this.quill = quill; 4 | this.boundsContainer = boundsContainer || document.body; 5 | this.root = quill.addContainer('ql-tooltip'); 6 | this.root.innerHTML = this.constructor.TEMPLATE; 7 | this.quill.root.addEventListener('scroll', () => { 8 | this.root.style.marginTop = (-1*this.quill.root.scrollTop) + 'px'; 9 | }); 10 | this.hide(); 11 | } 12 | 13 | hide() { 14 | this.root.classList.add('ql-hidden'); 15 | } 16 | 17 | position(reference) { 18 | let left = reference.left + reference.width/2 - this.root.offsetWidth/2; 19 | let top = reference.bottom + this.quill.root.scrollTop; 20 | this.root.style.left = left + 'px'; 21 | this.root.style.top = top + 'px'; 22 | this.root.classList.remove('ql-flip'); 23 | let containerBounds = this.boundsContainer.getBoundingClientRect(); 24 | let rootBounds = this.root.getBoundingClientRect(); 25 | let shift = 0; 26 | if (rootBounds.right > containerBounds.right) { 27 | shift = containerBounds.right - rootBounds.right; 28 | this.root.style.left = (left + shift) + 'px'; 29 | } 30 | if (rootBounds.left < containerBounds.left) { 31 | shift = containerBounds.left - rootBounds.left; 32 | this.root.style.left = (left + shift) + 'px'; 33 | } 34 | if (rootBounds.bottom > containerBounds.bottom) { 35 | let height = rootBounds.bottom - rootBounds.top; 36 | let verticalShift = containerBounds.bottom - rootBounds.bottom - height; 37 | this.root.style.top = (top + verticalShift) + 'px'; 38 | this.root.classList.add('ql-flip'); 39 | } 40 | return shift; 41 | } 42 | 43 | show() { 44 | this.root.classList.remove('ql-editing'); 45 | this.root.classList.remove('ql-hidden'); 46 | } 47 | } 48 | 49 | 50 | export default Tooltip; 51 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/docs/api/selection.md: -------------------------------------------------------------------------------- 1 | ## Selection 2 | 3 | ### getBounds 4 | 5 | Retrieves the pixel position (relative to the editor container) and dimensions of a selection at a given location. The user's current selection need not be at that index. Useful for calculating where to place tooltips. 6 | 7 | **Methods** 8 | 9 | ```javascript 10 | getBounds(index: Number, length: Number = 0): 11 | { left: Number, top: Number, height: Number, width: Number } 12 | ``` 13 | 14 | **Examples** 15 | 16 | ```javascript 17 | quill.setText('Hello\nWorld\n'); 18 | quill.getBounds(7); // Returns { height: 15, width: 0, left: 27, top: 31 } 19 | ``` 20 | 21 | ### getSelection 22 | 23 | Retrieves the user's selection range, optionally to focus the editor first. Otherwise `null` may be returned if editor does not have focus. 24 | 25 | **Methods** 26 | 27 | ```javascript 28 | getSelection(focus = false): { index: Number, length: Number } 29 | ``` 30 | 31 | **Examples** 32 | 33 | ```javascript 34 | var range = quill.getSelection(); 35 | if (range) { 36 | if (range.length == 0) { 37 | console.log('User cursor is at index', range.index); 38 | } else { 39 | var text = quill.getText(range.index, range.length); 40 | console.log('User has highlighted: ', text); 41 | } 42 | } else { 43 | console.log('User cursor is not in editor'); 44 | } 45 | ``` 46 | 47 | ### setSelection 48 | 49 | Sets user selection to given range, which will also focus the editor. Providing `null` as the selection range will blur the editor. [Source](/docs/api/#events) may be `"user"`, `"api"`, or `"silent"`. 50 | 51 | **Methods** 52 | 53 | ```javascript 54 | setSelection(index: Number, length: Number, source: String = 'api') 55 | setSelection(range: { index: Number, length: Number }, 56 | souce: String = 'api') 57 | ``` 58 | 59 | **Examples** 60 | 61 | ```javascript 62 | quill.setSelection(0, 5); 63 | ``` 64 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_includes/header.html: -------------------------------------------------------------------------------- 1 |
2 | 22 | 44 | 49 |
-------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/table-border-outside.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /quilljs-source-code/test/unit/formats/link.js: -------------------------------------------------------------------------------- 1 | import Delta from 'quill-delta'; 2 | import Editor from '../../../core/editor'; 3 | import Link from '../../../formats/link'; 4 | 5 | 6 | describe('Link', function() { 7 | it('add', function() { 8 | let editor = this.initialize(Editor, '

0123

'); 9 | editor.formatText(1, 2, { link: 'https://quilljs.com' }); 10 | expect(editor.getDelta()).toEqual(new Delta() 11 | .insert('0') 12 | .insert('12', { link: 'https://quilljs.com' }) 13 | .insert('3\n') 14 | ); 15 | expect(editor.scroll.domNode).toEqualHTML('

0123

'); 16 | }); 17 | 18 | it('add invalid', function() { 19 | let editor = this.initialize(Editor, '

0123

'); 20 | editor.formatText(1, 2, { link: 'javascript:alert(0);' }); // eslint-disable-line no-script-url 21 | expect(editor.getDelta()).toEqual(new Delta() 22 | .insert('0') 23 | .insert('12', { link: Link.SANITIZED_URL }) 24 | .insert('3\n') 25 | ); 26 | }); 27 | 28 | it('change', function() { 29 | let editor = this.initialize(Editor, '

0123

'); 30 | editor.formatText(1, 2, { link: 'https://quilljs.com' }); 31 | expect(editor.getDelta()).toEqual(new Delta() 32 | .insert('0') 33 | .insert('12', { link: 'https://quilljs.com' }) 34 | .insert('3\n') 35 | ); 36 | expect(editor.scroll.domNode).toEqualHTML('

0123

'); 37 | }); 38 | 39 | it('remove', function() { 40 | let editor = this.initialize(Editor, '

0123

'); 41 | editor.formatText(1, 2, { link: false }); 42 | let delta = new Delta().insert('0').insert('12', { size: 'large' }).insert('3\n'); 43 | expect(editor.getDelta()).toEqual(delta); 44 | expect(editor.scroll.domNode).toEqualHTML('

0123

'); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /quilljs-source-code/_develop/karma.config.js: -------------------------------------------------------------------------------- 1 | var browsers = require('./browsers'); 2 | var sauce = require('./sauce'); 3 | 4 | 5 | module.exports = function(config) { 6 | config.set({ 7 | basePath: '../', 8 | urlRoot: '/karma/', 9 | port: process.env.npm_package_config_ports_karma, 10 | 11 | files: [ 12 | { pattern: 'dist/quill.snow.css', nocache: true }, 13 | { pattern: 'dist/unit.js', nocache: true }, 14 | { pattern: 'dist/*.map', included: false, served: true, nocache: true }, 15 | { pattern: 'assets/favicon.png', included: false, served: true } 16 | ], 17 | proxies: { 18 | '/assets/': '/karma/base/assets/' 19 | }, 20 | 21 | frameworks: ['jasmine'], 22 | reporters: ['progress'], 23 | colors: true, 24 | autoWatch: false, 25 | singleRun: true, 26 | browsers: ['Chrome'], 27 | 28 | client: { 29 | useIframe: false 30 | }, 31 | 32 | coverageReporter: { 33 | dir: '.coverage', 34 | reporters: [ 35 | { type: 'text' }, 36 | { type: 'html' } 37 | ] 38 | }, 39 | sauceLabs: { 40 | testName: 'quill-unit', 41 | options: { 42 | 'public': 'public', 43 | 'record-screenshots': false 44 | }, 45 | build: sauce.build, 46 | username: sauce.username, 47 | accessKey: sauce.accessKey, 48 | tunnelIdentifier: sauce.tunnel 49 | }, 50 | customLaunchers: browsers 51 | }); 52 | 53 | if (process.env.TRAVIS) { 54 | config.sauceLabs.startConnect = false; 55 | config.transports = ['polling']; 56 | config.browsers = [process.env.BROWSER]; 57 | config.browserDisconnectTimeout = 10000; 58 | config.browserDisconnectTolerance = 3; 59 | config.browserNoActivityTimeout = 60000; 60 | config.captureTimeout = 120000; 61 | // MS Edge does not work in an iframe 62 | if (process.env.BROWSER.indexOf('ios') > -1 || 63 | process.env.BROWSER.indexOf('android') > -1 || 64 | process.env.BROWSER.indexOf('firefox') > -1) { 65 | config.client.useIframe = true; 66 | } 67 | } 68 | }; 69 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/docs/modules.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docs 3 | title: Modules 4 | permalink: /docs/modules/ 5 | redirect_from: 6 | - /docs/modules/authorship/ 7 | - /docs/modules/multi-cursors/ 8 | --- 9 | 10 | Modules allow Quill's behavior and functionality to be customized. Several officially supported modules are available to pick and choose from, some with additional configuration options and APIs. Refer to their respective documentation pages for more details. 11 | 12 | To enable a module, simply include it in Quill's configuration. 13 | 14 | ```javascript 15 | var quill = new Quill('#editor', { 16 | modules: { 17 | 'history': { // Enable with custom configurations 18 | 'delay': 2500, 19 | 'userOnly': true 20 | }, 21 | 'syntax': true // Enable with default configuration 22 | } 23 | }); 24 | ``` 25 | 26 | The [Clipboard](/docs/modules/clipboard/), [Keyboard](/docs/modules/keyboard/), and [History](/docs/modules/history/) modules are required by Quill and do not need to be included explictly, but may be configured like any other module. 27 | 28 | 29 | ## Extending 30 | 31 | Modules may also be extended and re-registered, replacing the original module. Even required modules may be re-registered and replaced. 32 | 33 | ```javascript 34 | var Clipboard = Quill.import('modules/clipboard'); 35 | var Delta = Quill.import('delta'); 36 | 37 | class PlainClipboard extends Clipboard { 38 | convert(html = null) { 39 | if (typeof html === 'string') { 40 | this.container.innerHTML = html; 41 | } 42 | return new Delta().insert(this.container.innerText); 43 | } 44 | } 45 | 46 | Quill.register('modules/clipboard', PlainClipboard, true); 47 | 48 | // Will be created with instance of PlainClipboard 49 | var quill = new Quill('#editor'); 50 | ``` 51 | 52 | *Note: This particular example was selected to show what is possible. It is often easier to just use an API or configuration the existing module exposes. In this example, the existing Clipboard's [addMatcher](/docs/modules/clipboard/#addmatcher) API is suitable for most paste customization scenarios.* 53 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_posts/2016-03-14-are-we-there-yet-to-1-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | permalink: /blog/are-we-there-yet-to-1-0/ 4 | title: Are We There Yet (to 1.0)? 5 | --- 6 | 7 | When Quill laid out its [1.0 roadmap](/blog/the-road-to-1-0/), core to its journey was the development of a new document model called Parchment. Today a beta release of Parchment is being made available on [Github](https://github.com/quilljs/parchment) and [NPM](https://www.npmjs.com/package/parchment). 8 | 9 | What this means is its design and API is reasonably stable and the adventurous can now take an early look. The latest Quill source is already using Parchment to implement its formatting and content capabilities, and its [integration](https://github.com/quilljs/quill/tree/develop/formats) would be a helpful example of Parchment in action. Of course, this is in addition to Parchment’s own [documentation](https://github.com/quilljs/parchment/blob/master/README.md). 10 | 11 | 12 | 13 | 14 | ### New Formats 15 | 16 | Parchment enables Quill to scalably support many formats and many are being added in 1.0. The list includes headers, blockquotes, code, superscript, subscript, text direction, nested lists, and video embeds. Syntax highlighted code and formulas will also be available through externally supported modules. In addition, formats that previously relied on style attributes are reimplemented to optionally use classes instead. By default, fonts, sizes, and text alignment will use classes, while foreground and background colors will still use style attributes, since there are so many possible color values. 17 | 18 | 19 | ### Quill 1.0 Beta 20 | 21 | With Parchment out of the way, Quill is nearing its own 1.0 release. This will also be prefaced with a beta period, optimistically planned for early April. You can also set up the [local development](https://github.com/quilljs/quill/blob/develop/.github/CONTRIBUTING.md#local-development) environment to follow along with the latest changes and progress. 22 | 23 | If you are currently using Quill at your company or project, we'd love to hear about your use case [hello@quilljs.com](mailto:hello@quilljs.com)! 24 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/docs/modules/history.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docs 3 | title: History Module 4 | permalink: /docs/modules/history/ 5 | --- 6 | 7 | The History module is responsible for handling undo and redo for Quill. It can be configured with the following options: 8 | 9 | ## Configuration 10 | 11 | #### delay 12 | 13 | - Default: `1000` 14 | 15 | Changes occuring within the `delay` number of milliseconds is merged into a single change. 16 | 17 | For example, with delay set to `0`, nearly every character is recorded as one change and so undo would undo one character at a time. With delay set to `1000`, undo would undo all changes that occured within the last 1000 milliseconds. 18 | 19 | 20 | #### maxStack 21 | 22 | - Default: `100` 23 | 24 | Maximum size of the history's undo/redo stack. Merged changes with the `delay` option counts as a singular change. 25 | 26 | 27 | #### userOnly 28 | 29 | - Default: `false` 30 | 31 | By default all changes, whether originating from user input or programmatically through the API, are treated the same and change be undone or redone by the history module. If `userOnly` is set to `true`, only user changes will be undone or redone. 32 | 33 | 34 | ### Example 35 | 36 | ```javascript 37 | var quill = new Quill('#editor', { 38 | modules: { 39 | history: { 40 | delay: 2000, 41 | maxStack: 500, 42 | userOnly: true 43 | } 44 | }, 45 | theme: 'snow' 46 | }); 47 | ``` 48 | 49 | ## API 50 | 51 | #### clear 52 | 53 | Clears the history stack. 54 | 55 | **Methods** 56 | 57 | ```js 58 | clear() 59 | ``` 60 | 61 | **Examples** 62 | 63 | ```js 64 | quill.history.clear(); 65 | ``` 66 | 67 | 68 | #### undo 69 | 70 | Undo last change. 71 | 72 | **Methods** 73 | 74 | ```js 75 | undo() 76 | ``` 77 | 78 | **Examples** 79 | 80 | ```js 81 | quill.history.undo(); 82 | ``` 83 | 84 | 85 | #### redo 86 | 87 | If last change was an undo, redo this undo. Otherwise does nothing. 88 | 89 | **Methods** 90 | 91 | ```js 92 | redo() 93 | ``` 94 | 95 | **Examples** 96 | 97 | ```js 98 | quill.history.redo(); 99 | ``` 100 | -------------------------------------------------------------------------------- /quilljs-source-code/core/polyfill.js: -------------------------------------------------------------------------------- 1 | let elem = document.createElement('div'); 2 | elem.classList.toggle('test-class', false); 3 | if (elem.classList.contains('test-class')) { 4 | let _toggle = DOMTokenList.prototype.toggle; 5 | DOMTokenList.prototype.toggle = function(token, force) { 6 | if (arguments.length > 1 && !this.contains(token) === !force) { 7 | return force; 8 | } else { 9 | return _toggle.call(this, token); 10 | } 11 | }; 12 | } 13 | 14 | if (!String.prototype.startsWith) { 15 | String.prototype.startsWith = function(searchString, position){ 16 | position = position || 0; 17 | return this.substr(position, searchString.length) === searchString; 18 | }; 19 | } 20 | 21 | if (!String.prototype.endsWith) { 22 | String.prototype.endsWith = function(searchString, position) { 23 | var subjectString = this.toString(); 24 | if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) { 25 | position = subjectString.length; 26 | } 27 | position -= searchString.length; 28 | var lastIndex = subjectString.indexOf(searchString, position); 29 | return lastIndex !== -1 && lastIndex === position; 30 | }; 31 | } 32 | 33 | if (!Array.prototype.find) { 34 | Object.defineProperty(Array.prototype, "find", { 35 | value: function(predicate) { 36 | if (this === null) { 37 | throw new TypeError('Array.prototype.find called on null or undefined'); 38 | } 39 | if (typeof predicate !== 'function') { 40 | throw new TypeError('predicate must be a function'); 41 | } 42 | var list = Object(this); 43 | var length = list.length >>> 0; 44 | var thisArg = arguments[1]; 45 | var value; 46 | 47 | for (var i = 0; i < length; i++) { 48 | value = list[i]; 49 | if (predicate.call(thisArg, value, i, list)) { 50 | return value; 51 | } 52 | } 53 | return undefined; 54 | } 55 | }); 56 | } 57 | 58 | // Disable resizing in Firefox 59 | document.addEventListener("DOMContentLoaded", function() { 60 | document.execCommand("enableObjectResizing", false, false); 61 | }); 62 | -------------------------------------------------------------------------------- /quilljs-source-code/_develop/browsers.js: -------------------------------------------------------------------------------- 1 | var desktop = { 2 | 'mac-chrome-latest' : ['OS X 10.11', 'chrome', '54.0'], 3 | 'mac-firefox-latest' : ['OS X 10.11', 'firefox', '50.0'], 4 | 'mac-safari-latest' : ['OS X 10.11', 'safari', '10.0'], 5 | 'mac-chrome-previous' : ['OS X 10.10', 'chrome', '53.0'], 6 | 'mac-firefox-previous' : ['OS X 10.10', 'firefox', '49.0'], 7 | 'mac-safari-previous' : ['OS X 10.10', 'safari', '9.0'], 8 | 9 | 'windows-chrome-latest' : ['Windows 10', 'chrome', '54.0'], 10 | 'windows-firefox-latest' : ['Windows 10', 'firefox', '50.0'], 11 | 'windows-edge-latest' : ['Windows 10', 'microsoftedge', '14.14393'], 12 | 'windows-ie-latest' : ['Windows 8.1', 'internet explorer', '11.0'], 13 | 'windows-chrome-previous' : ['Windows 8.1', 'chrome', '53.0'], 14 | 'windows-firefox-previous': ['Windows 8.1', 'firefox', '49.0'], 15 | 'windows-edge-previous' : ['Windows 10', 'microsoftedge', '13.10586'], 16 | 17 | 'linux-chrome-latest' : ['Linux', 'chrome', '48.0'], 18 | 'linux-firefox-latest' : ['Linux', 'firefox', '45.0'], 19 | 'linux-chrome-previous' : ['Linux', 'chrome', '47.0'], 20 | 'linux-firefox-previous' : ['Linux', 'firefox', '44.0'] 21 | }; 22 | 23 | var mobile = { 24 | 'ios-latest' : ['iPhone 7 Plus', 'iOS', '10.0', 'Safari'], 25 | 'ios-previous' : ['iPhone 6 Plus', 'iOS', '9.3', 'Safari'], 26 | 27 | 'android-latest' : ['Android Emulator', 'Android', '5.1', 'Browser'], 28 | 'android-previous' : ['Android Emulator', 'Android', '5.0', 'Browser'] 29 | }; 30 | 31 | Object.keys(desktop).forEach(function(key) { 32 | module.exports[key] = { 33 | base: 'SauceLabs', 34 | browserName: desktop[key][1], 35 | version: desktop[key][2], 36 | platform: desktop[key][0] 37 | }; 38 | }); 39 | 40 | Object.keys(mobile).forEach(function(key) { 41 | var appiumVersion = key.startsWith('ios') ? '1.6.3' : '1.5.3'; 42 | module.exports[key] = { 43 | base: 'SauceLabs', 44 | browserName: mobile[key][3], 45 | appiumVersion: appiumVersion, 46 | deviceName: mobile[key][0], 47 | deviceOrientation: 'portrait', 48 | platformVersion: mobile[key][2], 49 | platformName: mobile[key][1] 50 | }; 51 | }); 52 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/table-border-left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /quilljs-source-code/ui/icons.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'align': { 3 | '' : require('../assets/icons/align-left.svg'), 4 | 'center' : require('../assets/icons/align-center.svg'), 5 | 'right' : require('../assets/icons/align-right.svg'), 6 | 'justify' : require('../assets/icons/align-justify.svg') 7 | }, 8 | 'background': require('../assets/icons/background.svg'), 9 | 'blockquote': require('../assets/icons/blockquote.svg'), 10 | 'bold' : require('../assets/icons/bold.svg'), 11 | 'clean' : require('../assets/icons/clean.svg'), 12 | 'code' : require('../assets/icons/code.svg'), 13 | 'code-block': require('../assets/icons/code.svg'), 14 | 'color' : require('../assets/icons/color.svg'), 15 | 'direction' : { 16 | '' : require('../assets/icons/direction-ltr.svg'), 17 | 'rtl' : require('../assets/icons/direction-rtl.svg') 18 | }, 19 | 'float': { 20 | 'center' : require('../assets/icons/float-center.svg'), 21 | 'full' : require('../assets/icons/float-full.svg'), 22 | 'left' : require('../assets/icons/float-left.svg'), 23 | 'right' : require('../assets/icons/float-right.svg') 24 | }, 25 | 'formula' : require('../assets/icons/formula.svg'), 26 | 'header': { 27 | '1' : require('../assets/icons/header.svg'), 28 | '2' : require('../assets/icons/header-2.svg') 29 | }, 30 | 'italic' : require('../assets/icons/italic.svg'), 31 | 'image' : require('../assets/icons/image.svg'), 32 | 'indent': { 33 | '+1' : require('../assets/icons/indent.svg'), 34 | '-1' : require('../assets/icons/outdent.svg') 35 | }, 36 | 'link' : require('../assets/icons/link.svg'), 37 | 'list': { 38 | 'ordered' : require('../assets/icons/list-ordered.svg'), 39 | 'bullet' : require('../assets/icons/list-bullet.svg'), 40 | 'check' : require('../assets/icons/list-check.svg') 41 | }, 42 | 'script': { 43 | 'sub' : require('../assets/icons/subscript.svg'), 44 | 'super' : require('../assets/icons/superscript.svg'), 45 | }, 46 | 'strike' : require('../assets/icons/strike.svg'), 47 | 'underline' : require('../assets/icons/underline.svg'), 48 | 'video' : require('../assets/icons/video.svg') 49 | }; 50 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/table-border-top.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/playground.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Interactive Playground 4 | permalink: /playground/ 5 | redirect_from: 6 | - /examples/ 7 | pens: 8 | - title: Autosave 9 | slug: RRYBEP 10 | - title: Class vs Inline Style 11 | slug: jAvpQL 12 | - title: Form Submit 13 | slug: kXRjQJ 14 | - title: Snow Toolbar Tooltips 15 | slug: ozYEro 16 | - title: Autogrow Height 17 | slug: dOqrVm 18 | - title: Custom Fonts 19 | slug: gLBYam 20 | - title: Quill Playground 21 | slug: KzZqZx 22 | --- 23 | 24 |
25 |
26 |

Interactive Playground

27 | 28 |
29 | 39 | 40 | {% include open-source.html %} 41 |
42 | 43 | 65 | 66 | -------------------------------------------------------------------------------- /quilljs-source-code/modules/syntax.js: -------------------------------------------------------------------------------- 1 | import Parchment from 'parchment'; 2 | import Quill from '../core/quill'; 3 | import Module from '../core/module'; 4 | import CodeBlock from '../formats/code'; 5 | 6 | 7 | class SyntaxCodeBlock extends CodeBlock { 8 | replaceWith(block) { 9 | this.domNode.textContent = this.domNode.textContent; 10 | this.attach(); 11 | super.replaceWith(block); 12 | } 13 | 14 | highlight(highlight) { 15 | if (this.cachedHTML !== this.domNode.innerHTML) { 16 | let text = this.domNode.textContent; 17 | if (text.trim().length > 0 || this.cachedHTML == null) { 18 | this.domNode.innerHTML = highlight(text); 19 | this.attach(); 20 | } 21 | this.cachedHTML = this.domNode.innerHTML; 22 | } 23 | } 24 | } 25 | SyntaxCodeBlock.className = 'ql-syntax'; 26 | 27 | 28 | let CodeToken = new Parchment.Attributor.Class('token', 'hljs', { 29 | scope: Parchment.Scope.INLINE 30 | }); 31 | 32 | 33 | class Syntax extends Module { 34 | constructor(quill, options) { 35 | super(quill, options); 36 | if (typeof this.options.highlight !== 'function') { 37 | throw new Error('Syntax module requires highlight.js. Please include the library on the page before Quill.'); 38 | } 39 | Quill.register(CodeToken, true); 40 | Quill.register(SyntaxCodeBlock, true); 41 | let timer = null; 42 | this.quill.on(Quill.events.SCROLL_OPTIMIZE, () => { 43 | if (timer != null) return; 44 | timer = setTimeout(() => { 45 | this.highlight(); 46 | timer = null; 47 | }, 100); 48 | }); 49 | this.highlight(); 50 | } 51 | 52 | highlight() { 53 | if (this.quill.selection.composing) return; 54 | let range = this.quill.getSelection(); 55 | this.quill.scroll.descendants(SyntaxCodeBlock).forEach((code) => { 56 | code.highlight(this.options.highlight); 57 | }); 58 | this.quill.update(Quill.sources.SILENT); 59 | if (range != null) { 60 | this.quill.setSelection(range, Quill.sources.SILENT); 61 | } 62 | } 63 | } 64 | Syntax.DEFAULTS = { 65 | highlight: (function() { 66 | if (window.hljs == null) return null; 67 | return function(text) { 68 | let result = window.hljs.highlightAuto(text); 69 | return result.value; 70 | }; 71 | })() 72 | }; 73 | 74 | 75 | export { SyntaxCodeBlock as CodeBlock, CodeToken, Syntax as default}; 76 | -------------------------------------------------------------------------------- /quilljs-source-code/modules/toolbar_extended.js: -------------------------------------------------------------------------------- 1 | import Toolbar from './toolbar'; 2 | 3 | 4 | function defaultToolbarOptions() { 5 | return [ 6 | // Extended toolbar buttons 7 | ['contain'], 8 | ['td'], // new table (cursor needs to be out of table) 9 | [{ 'table': 'append-row' }], // cursor needs to be in the table 10 | [{ 'table': 'append-col' }], // cursor needs to be in the table 11 | [{ 'table': 'remove-row' }], // cursor needs to be in the table 12 | [{ 'table': 'remove-col' }], // cursor needs to be in the table 13 | [{ 'table': 'remove-table' }], // cursor needs to be in the table 14 | [{ 'table': 'cell-background' }], // cursor needs to be in the table 15 | 16 | // Default toolbar buttons 17 | ['bold', 'italic', 'underline', 'strike'], 18 | ['blockquote', 'code-block'], 19 | 20 | [{ 'header': 1 }, { 'header': 2 }], 21 | [{ 'list': 'ordered'}, { 'list': 'bullet' }], 22 | [{ 'script': 'sub'}, { 'script': 'super' }], 23 | [{ 'indent': '-1'}, { 'indent': '+1' }], 24 | [{ 'direction': 'rtl' }], 25 | 26 | [{ 'size': ['small', false, 'large', 'huge'] }], 27 | [{ 'header': [1, 2, 3, 4, 5, 6, false] }], 28 | 29 | [{ 'color': [] }, { 'background': [] }], 30 | [{ 'align': [] }], 31 | 32 | ['link', 'image', 'code-block'], 33 | 34 | ['clean'] 35 | ]; 36 | } 37 | 38 | 39 | Toolbar.DEFAULTS = Object.assign(Toolbar.DEFAULTS, { 40 | container: defaultToolbarOptions(), 41 | handlers: { 42 | table: function(value) { 43 | if(value == 'append-row') { 44 | this.quill.getModule('table_handler').appendRow(); 45 | } else if(value == 'append-col') { 46 | this.quill.getModule('table_handler').appendCol(); 47 | } else if(value == 'remove-row') { 48 | this.quill.getModule('table_handler').removeRow(); 49 | } else if(value == 'remove-col') { 50 | this.quill.getModule('table_handler').removeCol(); 51 | } else if(value == 'remove-table') { 52 | this.quill.getModule('table_handler').removeTable(); 53 | } else if(value == 'cell-background') { 54 | let bgColor = prompt('Background color?'); 55 | if(bgColor != null) { 56 | this.quill.getModule('table_handler').cellBackground(bgColor); 57 | } 58 | } else { 59 | this.quill.format('table', value); 60 | } 61 | } 62 | } 63 | }); 64 | 65 | 66 | export default Toolbar; 67 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/0.20/assets/js/index.js: -------------------------------------------------------------------------------- 1 | var quill; // Expose as global so people can easily try out the API 2 | 3 | $(document).ready(function() { 4 | quill = new Quill('#editor', { 5 | modules: { 6 | 'toolbar': { container: '#toolbar' }, 7 | 'image-tooltip': true, 8 | 'link-tooltip': true 9 | }, 10 | theme: 'snow' 11 | }); 12 | 13 | // Bootstrap Toolbar has positioning but when showing manually when tooltip is offscreen 14 | $('.quill-wrapper').tooltip({ trigger: 'manual', animation: false }).tooltip('show'); 15 | $('.quill-wrapper + .tooltip').hide(); 16 | var tooltipTimer = setTimeout(function() { 17 | $('.quill-wrapper + .tooltip').fadeIn(1000); 18 | }, 2500); 19 | 20 | quill.once('selection-change', function(hasFocus) { 21 | $('#editor').toggleClass('focus', hasFocus); 22 | // Hack for inability to scroll on mobile 23 | if (/mobile/i.test(navigator.userAgent)) { 24 | $('#editor').css('height', quill.root.scrollHeight + 30) // 30 for padding 25 | } 26 | $('.quill-wrapper').tooltip('destroy'); 27 | clearTimeout(tooltipTimer); 28 | }); 29 | 30 | var users = { 31 | 'Asana': 'https://asana.com/', 32 | 'Front': 'https://frontapp.com/', 33 | 'Intuit': 'https://www.intuit.com/', 34 | 'Lever': 'https://www.lever.co/', 35 | 'MerchantCircle': 'http://www.merchantcircle.com/', 36 | 'Reedsy': 'https://reedsy.com/', 37 | 'RelateIQ': 'https://www.relateiq.com/', 38 | 'Respondly': 'https://respond.ly/', 39 | 'Salesforce': 'http://www.salesforce.com/', 40 | 'ThemeXpert': 'https://www.themexpert.com/', 41 | 'Vox Media': 'http://www.voxmedia.com/', 42 | 'Writer': 'https://chrome.google.com/webstore/detail/writer/hlddiopdeghmcmdjjmpdegemnojihpib?hl=en' 43 | }; 44 | 45 | var keys = Object.keys(users); 46 | // Show users randomly 47 | $('#users-container a').each(function(i, link) { 48 | var index = Math.floor(Math.random() * keys.length); 49 | var key = keys[index]; 50 | keys.splice(index, 1); 51 | $(link).attr({ href: users[key], title: key }); 52 | $('img', link).attr({ 53 | src: '/0.20/assets/images/users/' + (key.toLowerCase().replace(/\s/g, '')) + '.png', 54 | alt: key 55 | }); 56 | }); 57 | 58 | console.log("Welcome to Quill!\n\nThe editor on this page is available via `quill`. Give the API a try:\n\n\tquill.formatText(6, 10, 'bold', true);\n\nVisit the API documenation page to learn more: http://quilljs.com/docs/api/\n"); 59 | }); 60 | -------------------------------------------------------------------------------- /quilljs-source-code/_develop/scripts/release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | VERSION="$1" 4 | 5 | if [ -z "$VERSION" ]; then 6 | echo "Version required." 7 | exit 8 | else 9 | echo "Releasing $VERSION" 10 | fi 11 | 12 | rm -r .release 13 | rm -r dist 14 | mkdir .release 15 | mkdir .release/quill 16 | 17 | npm run build 18 | webpack --config _develop/webpack.config.js --env.minimize 19 | cp dist/quill.core.css dist/quill.bubble.css dist/quill.snow.css dist/quill.js dist/quill.core.js dist/quill.min.js dist/quill.min.js.map .release/quill/ 20 | 21 | cd .release 22 | 23 | printf "cdn: .\nversion: ." > jekyll.yml 24 | jekyll build -s ../docs -d _site --config ../docs/_config.yml,jekyll.yml 25 | 26 | mkdir quill/examples 27 | mv _site/standalone/bubble/index.html quill/examples/bubble.html 28 | mv _site/standalone/snow/index.html quill/examples/snow.html 29 | mv _site/standalone/full/index.html quill/examples/full.html 30 | find quill/examples -type f -exec sed -i "" 's/\/ /g' {} \; 31 | find quill/examples -type f -exec sed -i "" 's/href="\/\//href="https:\/\//g' {} \; 32 | find quill/examples -type f -exec sed -i "" 's/src="\/\//src="https:\/\//g' {} \; 33 | 34 | tar -czf quill.tar.gz quill 35 | 36 | aws s3 cp quill/quill.js s3://cdn.quilljs.com/$VERSION/ --cache-control max-age=604800 --content-type "application/javascript; charset=utf-8" --profile quill 37 | aws s3 cp quill/quill.min.js s3://cdn.quilljs.com/$VERSION/ --cache-control max-age=604800 --content-type "application/javascript; charset=utf-8" --profile quill 38 | aws s3 cp quill/quill.core.js s3://cdn.quilljs.com/$VERSION/ --cache-control max-age=604800 --content-type "application/javascript; charset=utf-8" --profile quill 39 | aws s3 cp quill/quill.bubble.css s3://cdn.quilljs.com/$VERSION/ --cache-control max-age=604800 --content-type "text/css; charset=utf-8" --profile quill 40 | aws s3 cp quill/quill.core.css s3://cdn.quilljs.com/$VERSION/ --cache-control max-age=604800 --content-type "text/css; charset=utf-8" --profile quill 41 | aws s3 cp quill/quill.snow.css s3://cdn.quilljs.com/$VERSION/ --cache-control max-age=604800 --content-type "text/css; charset=utf-8" --profile quill 42 | aws s3 cp quill/quill.min.js.map s3://cdn.quilljs.com/$VERSION/ --cache-control max-age=604800 --content-type "application/json; charset=utf-8" --profile quill 43 | aws s3 sync s3://cdn.quilljs.com/$VERSION/ s3://cdn.quilljs.com/latest/ --profile quill 44 | 45 | cd .. 46 | git tag v$VERSION -m "Version $VERSION" 47 | git push origin v$VERSION 48 | git push origin master 49 | 50 | npm publish 51 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ page.title }}{% if page.path != "index.html" %} - Quill{% endif %} 5 | {% include meta.html %} 6 | 7 | {% assign sections = content | split: '' %} 8 | {% for section in sections %} 9 | {% assign mod = forloop.index | modulo: 2 %} 10 | {% if mod == 0 %} 11 | {{ section | strip }} 12 | {% endif %} 13 | {% endfor %} 14 | 15 | {% include analytics.html %} 16 | 17 | 18 | {% include header.html %} 19 | {% assign heads = content | split: '' %} 20 | {% for head in heads %} 21 | {% if forloop.last != true %} 22 | {% assign headMod = forloop.index | modulo: 2 %} 23 | {% if headMod == 1 %} 24 | {{ head | strip }} 25 | {% endif %} 26 | {% else %} 27 | {% assign scripts = head | split: '' %} 28 | {% for script in scripts %} 29 | {% assign scriptMod = forloop.index | modulo: 2 %} 30 | {% if scriptMod == 1 %} 31 | {{ script | strip }} 32 | {% endif %} 33 | {% endfor %} 34 | {% endif %} 35 | {% endfor %} 36 | {% include footer.html %} 37 | 38 | {% assign sections = content | split: '' %} 39 | {% for section in sections %} 40 | {% assign mod = forloop.index | modulo: 2 %} 41 | {% if mod == 0 %} 42 | {{ section | strip }} 43 | {% endif %} 44 | {% endfor %} 45 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | :bangbang: | This repository is not maintained. It served as a testing platform only. It is recommended you don't use it in production environments. 2 | :---: | :--- 3 | 4 | # QuillJS table 5 | 6 | Test lab for creating `TABLE` functionality in QuillJS using Containers. 7 | 8 | Code of quill is included in project so we can easily play with it in our tests. 9 | 10 | ## Run 11 | 12 | Try by opening `quilljs-table/index.html` in a browser. 13 | 14 | ## Aim of this project 15 | 16 | While the code is at this point more or less hacked together, 17 | long term goal is to provide enough material to understand table behavior 18 | so we end up with stable working solution for quill. 19 | 20 | Please feel free to add your own files and directories to play with the concept. 21 | 22 | ## Progress so far 23 | * `TABLE`, `TR` and `TD` are containers - it is possible to have multiple block blots in `TD`. 24 | * all tables, rows and cells are identified by random strings and optimize merge only those with the same id. 25 | * It is possible to add tables by defining rows and cols count in grid. 26 | * It is possible to add rows and columns to existing tables (accessible by buttons in toolbar). 27 | * it is possible to copy & paste table from Word. Works ok. Needs to test edge cases. 28 | 29 | ## Known issues 30 | It is early stage so there is a lot of issues with current state. 31 | Still there are some worth to mention which should be dealt with. 32 | 33 | * Lists (number or bullet) in cell upon enter loose list format on previous line but keeps it on actual. 34 | * Delete and backspace behavior on tables should be either disabled or should have some well defined behavior. Now it is pretty easy to destroy table in ugly way. 35 | * Definition of TableTrick is hacked in just to test if adding of rows and cols is easily possible - which is. Should be done differently so quill doesn't throw exception (it continues to work). 36 | * Undo/History breaks badly with cell deletions (disabled backspace could solve this). 37 | * When loading delta of nested container in table cell, nested container loose format. 38 | * Pressing enter in table cell leads to inserting container into the container. It is hacked in ContainBlot insertBefore function by striping parent container and optimize then merges it fine. But it should be resolved earlier on MutationRecord creation or probably somewhere on update at `Scroll` or `Container` level. 39 | * Containers need order similar to Inline.order. Otherwise delta is not canonical. 40 | * Organization of code is hectic as it was not refactored even once from our first attempts to put this all to work. 41 | * ... 42 | -------------------------------------------------------------------------------- /quilljs-source-code/blots/table_cell.js: -------------------------------------------------------------------------------- 1 | import Parchment from 'parchment'; 2 | import Container from './container'; 3 | import ContainBlot from './contain'; 4 | import Block, { BlockEmbed } from './block'; 5 | 6 | 7 | class TableCell extends ContainBlot { 8 | 9 | static randomId() { 10 | return Math.random().toString(36).slice(2) 11 | } 12 | 13 | static create(value) { 14 | // console.log(value) // eslint-disable-line 15 | if(value == true) { 16 | value = this.randomId() + '|' + 17 | this.randomId() + '|' + 18 | this.randomId(); 19 | } 20 | let tagName = 'td'; 21 | let node = super.create(tagName); 22 | let ids = value.split('|') 23 | node.setAttribute('table_id', ids[0]); 24 | node.setAttribute('row_id', ids[1]); 25 | node.setAttribute('cell_id', ids[2]); 26 | node.setAttribute('style', ids[3] ? ids[3] : null); 27 | return node; 28 | } 29 | 30 | format(name, value) { 31 | // console.log('name: ' + name + ' value: ' + value); 32 | if (name != null) { 33 | if(value) { 34 | this.domNode.setAttribute(name, value); 35 | } else { 36 | this.domNode.removeAttribute(name); 37 | } 38 | } 39 | } 40 | 41 | formats() { 42 | // We don't inherit from FormatBlot 43 | return { [this.statics.blotName]: 44 | this.domNode.getAttribute('table_id') + '|' + 45 | this.domNode.getAttribute('row_id') + '|' + 46 | this.domNode.getAttribute('cell_id') + '|' + 47 | this.domNode.getAttribute('style') 48 | } 49 | } 50 | 51 | optimize() { 52 | super.optimize(); 53 | 54 | // Add parent TR and TABLE when missing 55 | let parent = this.parent; 56 | if (parent != null && parent.statics.blotName != 'tr') { 57 | // we will mark td position, put in table and replace mark 58 | let mark = Parchment.create('block'); 59 | this.parent.insertBefore(mark, this.next); 60 | let table = Parchment.create('table', this.domNode.getAttribute('table_id')); 61 | let tr = Parchment.create('tr', this.domNode.getAttribute('row_id')); 62 | table.appendChild(tr); 63 | tr.appendChild(this); 64 | table.replace(mark) 65 | } 66 | 67 | // merge same TD id 68 | let next = this.next; 69 | if (next != null && next.prev === this && 70 | next.statics.blotName === this.statics.blotName && 71 | next.domNode.tagName === this.domNode.tagName && 72 | next.domNode.getAttribute('cell_id') === this.domNode.getAttribute('cell_id')) { 73 | next.moveChildren(this); 74 | next.remove(); 75 | } 76 | } 77 | 78 | } 79 | 80 | TableCell.blotName = 'td'; 81 | TableCell.tagName = 'td'; 82 | TableCell.scope = Parchment.Scope.BLOCK_BLOT; 83 | TableCell.defaultChild = 'block'; 84 | TableCell.allowedChildren = [Block, BlockEmbed, Container]; 85 | 86 | 87 | export default TableCell 88 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_includes/standalone/full.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 14 | 15 |
16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 |
61 |
62 |
63 | 64 | 65 | 66 | 67 | 78 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/docs/standalone/basic.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: standalone 3 | title: Basic Example 4 | permalink: /standalone/basic/ 5 | --- 6 | 7 | 8 | 23 | 24 |
25 | 30 | 36 | 46 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |
71 |
72 | 73 | 74 | 82 | 83 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/docs/themes.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docs 3 | title: Themes 4 | permalink: /docs/themes/ 5 | redirect_from: 6 | - /docs/themes/bubble/ 7 | - /docs/themes/snow/ 8 | --- 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 | 24 | Themes allow you to easily make your editor look good with minimal effort. Quill features two offically supported themes: [Snow](#snow) and [Bubble](#bubble). 25 | 26 | ### Usage 27 | 28 | ```html 29 | 30 | 31 | 32 | 33 | 38 | ``` 39 | 40 | ## Bubble 41 | 42 | Bubble is a simple tooltip based theme. 43 | 44 |
45 |
46 |
47 | Standalone 48 | 49 | ## Snow 50 | 51 | Snow is a clean, flat toolbar theme. 52 | 53 |
54 |
55 |
56 | Standalone 57 | 58 | 59 | ### Customization 60 | 61 | Themes primarily control the visual look of Quill through its CSS stylesheet, and many changes can easily be made by overriding these rules. This is easiest to do, as with any other web application, by simply using your browser developer console to inspect the elements to view the rules affecting them. 62 | 63 | Many other customizations can be done through the respective modules. For example, the toolbar is perhaps the most visible user interface, but much of the customization is done through the [Toolbar module](/docs/modules/toolbar/). 64 | 65 | 66 | 67 | 68 | 69 | 70 | 89 | 90 | -------------------------------------------------------------------------------- /quilljs-source-code/assets/icons/background.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /quilljs-source-code/test/unit/blots/block.js: -------------------------------------------------------------------------------- 1 | import Parchment from 'parchment'; 2 | import Scroll from '../../../blots/scroll'; 3 | 4 | 5 | describe('Block', function() { 6 | it('childless', function() { 7 | let block = Parchment.create('block'); 8 | block.optimize(); 9 | expect(block.domNode).toEqualHTML('
'); 10 | }); 11 | 12 | it('insert into empty', function() { 13 | let block = Parchment.create('block'); 14 | block.insertAt(0, 'Test'); 15 | expect(block.domNode).toEqualHTML('Test'); 16 | }); 17 | 18 | it('insert newlines', function() { 19 | let scroll = this.initialize(Scroll, '


'); 20 | scroll.insertAt(0, '\n\n\n'); 21 | expect(scroll.domNode).toEqualHTML('





'); 22 | }); 23 | 24 | it('insert multiline', function() { 25 | let scroll = this.initialize(Scroll, '

Hello World!

'); 26 | scroll.insertAt(6, 'pardon\nthis\n\ninterruption\n'); 27 | expect(scroll.domNode).toEqualHTML(` 28 |

Hello pardon

29 |

this

30 |


31 |

interruption

32 |

World!

33 | `); 34 | }); 35 | 36 | it('insert into formatted', function() { 37 | let scroll = this.initialize(Scroll, '

Welcome

'); 38 | scroll.insertAt(3, 'l\n'); 39 | expect(scroll.domNode.firstChild.outerHTML).toEqualHTML('

Well

'); 40 | expect(scroll.domNode.childNodes[1].outerHTML).toEqualHTML('

come

'); 41 | }); 42 | 43 | it('delete line contents', function() { 44 | let scroll = this.initialize(Scroll, '

Hello

World!

'); 45 | scroll.deleteAt(0, 5); 46 | expect(scroll.domNode).toEqualHTML('


World!

'); 47 | }); 48 | 49 | it('join lines', function() { 50 | let scroll = this.initialize(Scroll, '

Hello

World!

'); 51 | scroll.deleteAt(5, 1); 52 | expect(scroll.domNode).toEqualHTML('

HelloWorld!

'); 53 | }); 54 | 55 | it('join line with empty', function() { 56 | let scroll = this.initialize(Scroll, '

HelloWorld


'); 57 | scroll.deleteAt(10, 1); 58 | expect(scroll.domNode).toEqualHTML('

HelloWorld

'); 59 | }); 60 | 61 | it('join empty lines', function() { 62 | let scroll = this.initialize(Scroll, '



'); 63 | scroll.deleteAt(1, 1); 64 | expect(scroll.domNode).toEqualHTML('


'); 65 | }); 66 | 67 | it('format empty', function() { 68 | let scroll = this.initialize(Scroll, '


'); 69 | scroll.formatAt(0, 1, 'header', 1); 70 | expect(scroll.domNode).toEqualHTML('


'); 71 | }); 72 | 73 | it('format newline', function() { 74 | let scroll = this.initialize(Scroll, '

Hello

'); 75 | scroll.formatAt(5, 1, 'header', 2); 76 | expect(scroll.domNode).toEqualHTML('

Hello

'); 77 | }); 78 | 79 | it('remove unnecessary break', function() { 80 | let scroll = this.initialize(Scroll, '

Test

'); 81 | scroll.children.head.domNode.appendChild(document.createElement('br')); 82 | scroll.update(); 83 | expect(scroll.domNode).toEqualHTML('

Test

'); 84 | }); 85 | }); 86 | -------------------------------------------------------------------------------- /quilljs-source-code/test/unit/blots/scroll.js: -------------------------------------------------------------------------------- 1 | import Parchment from 'parchment'; 2 | import Emitter from '../../../core/emitter'; 3 | import Selection, { Range } from '../../../core/selection'; 4 | import Cursor from '../../../blots/cursor'; 5 | import Scroll from '../../../blots/scroll'; 6 | 7 | 8 | describe('Scroll', function() { 9 | it('initialize empty document', function() { 10 | let scroll = this.initialize(Scroll, ''); 11 | expect(scroll.domNode).toEqualHTML('


'); 12 | }); 13 | 14 | it('api change', function() { 15 | let scroll = this.initialize(Scroll, '

Hello World!

'); 16 | spyOn(scroll.emitter, 'emit').and.callThrough(); 17 | scroll.insertAt(5, '!'); 18 | expect(scroll.emitter.emit).toHaveBeenCalledWith(Emitter.events.SCROLL_OPTIMIZE, jasmine.any(Array)); 19 | }); 20 | 21 | it('user change', function(done) { 22 | let scroll = this.initialize(Scroll, '

Hello World!

'); 23 | spyOn(scroll.emitter, 'emit').and.callThrough(); 24 | scroll.domNode.firstChild.appendChild(document.createTextNode('!')); 25 | setTimeout(function() { 26 | expect(scroll.emitter.emit).toHaveBeenCalledWith(Emitter.events.SCROLL_OPTIMIZE, jasmine.any(Array)); 27 | expect(scroll.emitter.emit).toHaveBeenCalledWith(Emitter.events.SCROLL_UPDATE, Emitter.sources.USER, jasmine.any(Array)); 28 | done(); 29 | }, 1); 30 | }); 31 | 32 | it('whitelist', function() { 33 | let scroll = Parchment.create('scroll', { emitter: new Emitter(), whitelist: ['bold'] }); 34 | scroll.insertAt(0, 'Hello World!'); 35 | scroll.formatAt(0, 5, 'bold', true); 36 | scroll.formatAt(6, 5, 'italic', true); 37 | expect(scroll.domNode.firstChild).toEqualHTML('Hello World!'); 38 | }); 39 | 40 | describe('leaf()', function() { 41 | it('text', function() { 42 | let scroll = this.initialize(Scroll, '

Tests

'); 43 | let [leaf, offset] = scroll.leaf(2); 44 | expect(leaf.value()).toEqual('Tests'); 45 | expect(offset).toEqual(2); 46 | }); 47 | 48 | it('precise', function() { 49 | let scroll = this.initialize(Scroll, '

01234

'); 50 | let [leaf, offset] = scroll.leaf(3); 51 | expect(leaf.value()).toEqual('2'); 52 | expect(offset).toEqual(1); 53 | }); 54 | 55 | it('newline', function() { 56 | let scroll = this.initialize(Scroll, '

0123

5678

'); 57 | let [leaf, offset] = scroll.leaf(4); 58 | expect(leaf.value()).toEqual('0123'); 59 | expect(offset).toEqual(4); 60 | }); 61 | 62 | it('cursor', function() { 63 | let selection = this.initialize(Selection, '

012

'); 64 | selection.setRange(new Range(2)); 65 | selection.format('strike', true); 66 | let [leaf, offset] = selection.scroll.leaf(2); 67 | expect(leaf instanceof Cursor).toBe(true); 68 | expect(offset).toEqual(0); 69 | }); 70 | 71 | it('beyond document', function() { 72 | let scroll = this.initialize(Scroll, '

Test

'); 73 | let [leaf, offset] = scroll.leaf(10); 74 | expect(leaf).toEqual(null); 75 | expect(offset).toEqual(-1); 76 | }); 77 | }); 78 | }); 79 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/docs/api/model.md: -------------------------------------------------------------------------------- 1 | ## Model 2 | 3 | ### find experimental {#find-experimental} 4 | 5 | Static method returning the Quill or [Blot](https://github.com/quilljs/parchment) instance for the given DOM node. In the latter case, passing in true for the `bubble` parameter will search up the given DOM's ancestors until it finds a corresponding [Blot](https://github.com/quilljs/parchment). 6 | 7 | **Methods** 8 | 9 | ```javascript 10 | Quill.find(domNode: Node, bubble: boolean = false): Blot | Quill 11 | ``` 12 | 13 | **Examples** 14 | 15 | ```javascript 16 | var container = document.querySelector("#container"); 17 | var quill = new Quill(container); 18 | console.log(Quill.find(container) === quill); // Should be true 19 | 20 | quill.insertText(0, 'Hello', 'link', 'https://world.com'); 21 | var linkNode = document.querySelector('#container a'); 22 | var linkBlot = Quill.find(linkNode); 23 | ``` 24 | 25 | ### getIndex experimental {#getindex-experimental} 26 | 27 | Returns the distance between the beginning of document to the occurance of the given [Blot](https://github.com/quilljs/parchment). 28 | 29 | **Methods** 30 | 31 | ```javascript 32 | getIndex(blot: Blot): Number 33 | ``` 34 | 35 | **Examples** 36 | 37 | ```javascript 38 | let [line, offset] = quill.getLine(10); 39 | let index = quill.getIndex(line); // index + offset should == 10 40 | ``` 41 | 42 | ### getLeaf experimental {#getleaf-experimental} 43 | 44 | Returns the leaf [Blot](https://github.com/quilljs/parchment) at the specified index within the document. 45 | 46 | **Methods** 47 | 48 | ```javascript 49 | getLeaf(index: Number): Blot 50 | ``` 51 | 52 | **Examples** 53 | 54 | ```javascript 55 | quill.setText('Hello Good World!'); 56 | quill.formatText(6, 4, "bold", true); 57 | 58 | let [leaf, offset] = quill.getLeaf(7); 59 | // leaf should be a Text Blot with value "Good" 60 | // offset should be 1, since the returned leaf started at index 6 61 | ``` 62 | 63 | ### getLine experimental {#getline-experimental} 64 | 65 | Returns the line [Blot](https://github.com/quilljs/parchment) at the specified index within the document. 66 | 67 | **Methods** 68 | 69 | ```javascript 70 | getLine(index: Number): Blot 71 | ``` 72 | 73 | 74 | **Examples** 75 | 76 | ```javascript 77 | quill.setText('Hello\nWorld!'); 78 | 79 | let [line, offset] = quill.getLine(7); 80 | // line should be a Block Blot representing the 2nd "World!" line 81 | // offset should be 1, since the returned line started at index 6 82 | ``` 83 | 84 | ### getLines experimental {#getlines-experimental} 85 | 86 | Returns the lines contained within the specified location. 87 | 88 | **Methods** 89 | 90 | ```javascript 91 | getLines(index: Number = 0, length: Number = remaining): Blot[] 92 | getLines(range: Range): Blot[] 93 | ``` 94 | 95 | **Examples** 96 | 97 | ```javascript 98 | quill.setText('Hello\nGood\nWorld!'); 99 | quill.formatLine(1, 1, 'list', 'bullet'); 100 | 101 | let lines = quill.getLines(2, 5); 102 | // array witha a ListItem and Block Blot, 103 | // representing the first two lines 104 | ``` 105 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_layouts/v0.20.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ page.title }} 5 | 6 | {% include meta.html %} 7 | 8 | 9 | 10 | 11 | {% include analytics.html %} 12 | 13 | 14 | Yeaaah! A newer version Quill {{ site.version | split: '.' | slice: 0,2 | join: '.' }} is out! You are viewing docs for v0.20. 15 | 41 | {{ content }} 42 |
43 |
44 | 48 |
49 | Quill is open source under 50 | BSD. 51 | The latest version is currently 52 | v{{site.version}} 53 |
54 |
55 |
56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /quilljs-source-code/docs/_posts/2014-11-06-quill-v0-19-no-more-iframes.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | permalink: /blog/quill-v0-19-no-more-iframes/ 4 | title: Quill v0.19 - No More Iframes 5 | --- 6 | 7 | Customizability is core to Quill's ethos and the new [v0.19 release](https://github.com/quilljs/quill/releases/tag/v0.19.0) is a big step towards fulfilling that mission. In previous versions Quill utilized an iframe to contain the editor. This unfortunately prevented expected browser behaviors and made it difficult for developers to access and extend Quill[^1]. Its removal is the biggest change in v0.19 and some rippling effects are expected. They, and other changes for v0.19, are summarized here. 8 | 9 | 10 | ### Styles 11 | 12 | With iframes gone it is now much easier to customize the styling of the Quill editor and unecessary for Quill to do so on your behalf in most cases. This leads to a few changes: 13 | 14 | You can now pass `false` into the [style config](/docs/configuration#styles) to prevent Quill from injecting any `