diff --git a/frappe/public/js/frappe/form/controls/comment.js b/frappe/public/js/frappe/form/controls/comment.js index 9ca61135b7..6ce9defa3b 100644 --- a/frappe/public/js/frappe/form/controls/comment.js +++ b/frappe/public/js/frappe/form/controls/comment.js @@ -68,9 +68,9 @@ frappe.ui.form.ControlComment = frappe.ui.form.ControlTextEditor.extend({ const options = this._super(); return Object.assign(options, { theme: 'bubble', - modules: Object.assign(options.modules, { - mention: this.get_mention_options() - }) + // modules: Object.assign(options.modules, { + // mention: this.get_mention_options() + // }) }); }, diff --git a/frappe/public/js/frappe/form/controls/text_editor.js b/frappe/public/js/frappe/form/controls/text_editor.js index 0e00ae5294..39d433f2bf 100644 --- a/frappe/public/js/frappe/form/controls/text_editor.js +++ b/frappe/public/js/frappe/form/controls/text_editor.js @@ -8,6 +8,25 @@ const Block = Quill.import('blots/block'); Block.tagName = 'DIV'; Quill.register(Block, true); +// table +const Table = Quill.import('formats/table-container'); +Table.className = 'table'; +Quill.register(Table, true); + +// inline style +const BackgroundStyle = Quill.import('attributors/style/background'); +const ColorStyle = Quill.import('attributors/style/color'); +const SizeStyle = Quill.import('attributors/style/size'); +const FontStyle = Quill.import('attributors/style/font'); +const AlignStyle = Quill.import('attributors/style/align'); +const DirectionStyle = Quill.import('attributors/style/direction'); +Quill.register(BackgroundStyle, true); +Quill.register(ColorStyle, true); +Quill.register(SizeStyle, true); +Quill.register(FontStyle, true); +Quill.register(AlignStyle, true); +Quill.register(DirectionStyle, true); + frappe.ui.form.ControlTextEditor = frappe.ui.form.ControlCode.extend({ make_input() { this.has_input = true; @@ -63,6 +82,38 @@ frappe.ui.form.ControlTextEditor = frappe.ui.form.ControlCode.extend({ }); } }); + + // table commands + this.$wrapper.on('click', '.ql-table .ql-picker-item', (e) => { + const $target = $(e.currentTarget); + const action = $target.data().value; + e.preventDefault(); + + const table = this.quill.getModule('table'); + if (action === 'insert-table') { + table.insertTable(2, 2); + } else if (action === 'insert-row-above') { + table.insertRowAbove(); + } else if (action === 'insert-row-below') { + table.insertRowBelow(); + } else if (action === 'insert-column-left') { + table.insertColumnLeft(); + } else if (action === 'insert-column-right') { + table.insertColumnRight(); + } else if (action === 'delete-row') { + table.deleteRow(); + } else if (action === 'delete-column') { + table.deleteColumn(); + } else if (action === 'delete-table') { + table.deleteTable(); + } + + if (action !== 'delete-row') { + table.balanceTables(); + } + + e.preventDefault(); + }); }, is_quill_dirty(source) { @@ -75,7 +126,8 @@ frappe.ui.form.ControlTextEditor = frappe.ui.form.ControlCode.extend({ return { modules: { toolbar: this.get_toolbar_options(), - imageDrop: true + imageDrop: true, + table: true }, theme: 'snow' }; @@ -90,6 +142,16 @@ frappe.ui.form.ControlTextEditor = frappe.ui.form.ControlCode.extend({ [{ 'list': 'ordered' }, { 'list': 'bullet' }], [{ 'align': [] }], [{ 'indent': '-1'}, { 'indent': '+1' }], + [{'table': [ + 'insert-table', + 'insert-row-above', + 'insert-row-below', + 'insert-column-right', + 'insert-column-left', + 'delete-row', + 'delete-column', + 'delete-table', + ]}], ['clean'] ]; }, diff --git a/frappe/public/less/quill.less b/frappe/public/less/quill.less index ae23f34e85..7379dc769f 100644 --- a/frappe/public/less/quill.less +++ b/frappe/public/less/quill.less @@ -70,4 +70,45 @@ border: 1px solid @light-border-color; padding: 2px 3px; background-color: @btn-bg; +} + +// table + +.ql-table { + width: 66px; + + .ql-picker-label::before { + content: 'Table'; + } + + .ql-picker-options { + [data-value='insert-table']::before { + content: 'Insert Table'; + } + [data-value='insert-row-above']::before { + content: 'Insert Row Above'; + } + [data-value='insert-row-below']::before { + content: 'Insert Row Below'; + } + [data-value='insert-column-right']::before { + content: 'Insert Column Right'; + } + [data-value='insert-column-left']::before { + content: 'Insert Column Left'; + } + [data-value='delete-row']::before { + content: 'Delete Row'; + } + [data-value='delete-column']::before { + content: 'Delete Column'; + } + [data-value='delete-table']::before { + content: 'Delete Table'; + } + } +} + +.ql-editor td { + border: 1px solid @border-color; } \ No newline at end of file diff --git a/package.json b/package.json index b797453053..02156fc126 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "jsbarcode": "^3.9.0", "moment": "^2.20.1", "moment-timezone": "^0.5.21", - "quill": "^1.3.6", + "quill": "2.0.0-dev.2", "quill-image-drop-module": "^1.0.3", "quill-mention": "^2.0.2", "redis": "^2.8.0", diff --git a/yarn.lock b/yarn.lock index 6352f5a0bb..15d65acf5d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1006,6 +1006,11 @@ eventemitter3@^2.0.3: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-2.0.3.tgz#b5e1079b59fb5e1ba2771c0a993be060a58c99ba" integrity sha1-teEHm1n7XhuidxwKmTvgYKWMmbo= +eventemitter3@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" + integrity sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA== + execa@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" @@ -2459,6 +2464,10 @@ parchment@^1.1.4: resolved "https://registry.yarnpkg.com/parchment/-/parchment-1.1.4.tgz#aeded7ab938fe921d4c34bc339ce1168bc2ffde5" integrity sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg== +parchment@quilljs/parchment#487850f7eb030a6c4e750ba809e58b09444e0bdb: + version "2.0.0-dev" + resolved "https://codeload.github.com/quilljs/parchment/tar.gz/487850f7eb030a6c4e750ba809e58b09444e0bdb" + parse-glob@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" @@ -3034,7 +3043,19 @@ quill-mention@^2.0.2: dependencies: quill "^1.3.4" -quill@^1.2.2, quill@^1.3.4, quill@^1.3.6: +quill@2.0.0-dev.2: + version "2.0.0-dev.2" + resolved "https://registry.yarnpkg.com/quill/-/quill-2.0.0-dev.2.tgz#0f8bc962da28e3ebbb856f246200e7d32e39fc9f" + integrity sha512-jqP2ar0EaPZLLyeYmyJ01l07+l3NKjUiq79i7OQiYv7Rm3wHTaejgq2oIqmXUCZjGQd2f5jlFUABkf8quZVcIw== + dependencies: + clone "^2.1.1" + deep-equal "^1.0.1" + eventemitter3 "^3.1.0" + extend "^3.0.1" + parchment quilljs/parchment#487850f7eb030a6c4e750ba809e58b09444e0bdb + quill-delta "^3.6.2" + +quill@^1.2.2, quill@^1.3.4: version "1.3.6" resolved "https://registry.yarnpkg.com/quill/-/quill-1.3.6.tgz#99f4de1fee85925a0d7d4163b6d8328f23317a4d" integrity sha512-K0mvhimWZN6s+9OQ249CH2IEPZ9JmkFuCQeHAOQax3EZ2nDJ3wfGh59mnlQaZV2i7u8eFarx6wAtvQKgShojug==