It would be great to have an @Input variable to register custom modules at the Quill instance.
Implementation Possibility:
1. creating CustomModule interface
- name (e.g. 'module/custom-module')
- module object
adding @Input variable
registering all modules to quill instance
Or is there any other known way how to add a custom module to the ngx-quill component?
What would be the advantage of this? I only know the "Quill.register"
functionality and this changes the global quill object. So I think it is
cleaner to register custom modules with the "Quill" way to do it. A
component should be an encapsulated piece of code. So I would not expect
that if I pass something as input to a component to have side effects to
other quill instances. If you know a "local" way to do it.. Let me know or
create a pull request :).
Thanks for your interest in this little repo.
Am 18.02.2018 16:48 schrieb "Markus Leimer" notifications@github.com:
It would be great to have an @input https://github.com/input variable
to register custom modules at the Quill instance.Implementation Possibility:
creating CustomModule interface
name (e.g. 'module/custom-module')
module object
1.
adding @input https://github.com/input variable
2.registering all modules to quill instance
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/KillerCodeMonkey/ngx-quill/issues/114, or mute the
thread
https://github.com/notifications/unsubscribe-auth/ACKOYDPu5sNHbl9ZXswztSMNbyh1H2lXks5tWEYBgaJpZM4SJvAs
.
Thank you for your fast response,
you are right, I haven't thought about this unexpected behaviour concerning other quill instances.
The reason I opened this issue is that I can't get the Markdown Shortcuts Module to work.
I imported the js file:
import * as MarkdownShortcuts from '../../../assets/quill-markdown-shortcuts/dist/markdownShortcuts.js';
registered it in ngOnInit:
Quill.register('modules/markdownShortcuts', MarkdownShortcuts);
and added it to the editor options:
modules: {
toolbar: [...],
markdownShortcuts: {}
},
but I get an error:
quill Cannot import modules/markdownShortcuts. Are you sure it was registered?
Did I miss anything?
Thank you for your help, and this awesome repo!
I will try to check this later :)
i got it - you should not use the compiled dist file of markdown shortcut.
use the /src/index.js
so there is no npm and special support - i combined everything of markdown shortcuts:
// Quill.js Plugin - Markdown Shortcuts
// This is a module for the Quill.js WYSIWYG editor (https://quilljs.com/)
// which converts text entered as markdown to rich text.
//
// v0.0.4
//
// Author: Patrick Lee ([email protected])
//
// (c) Copyright 2017 Patrick Lee ([email protected]).
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
import Quill from 'quill'
let BlockEmbed = Quill.import('blots/block/embed')
class HorizontalRule extends BlockEmbed {}
HorizontalRule.blotName = 'hr'
HorizontalRule.tagName = 'hr'
Quill.register('formats/horizontal', HorizontalRule)
class MarkdownShortcuts {
constructor (quill, options) {
this.quill = quill
this.options = options
this.matches = [
{
name: 'header',
pattern: /^(#){1,6}\s/g,
action: (text, selection) => {
const size = text.trim().length
// Need to defer this action https://github.com/quilljs/quill/issues/1134
setTimeout(() => {
this.quill.formatLine(selection.index, 0, 'header', size)
this.quill.deleteText(selection.index - text.length, text.length)
}, 0)
}
},
{
name: 'blockquote',
pattern: /^(>)\s/g,
action: (text, selection) => {
// Need to defer this action https://github.com/quilljs/quill/issues/1134
setTimeout(() => {
this.quill.formatLine(selection.index, 1, 'blockquote', true)
this.quill.deleteText(selection.index - 2, 2)
}, 0)
}
},
{
name: 'code-block',
pattern: /^`{3}(?:\s|\n)/g,
action: (text, selection) => {
// Need to defer this action https://github.com/quilljs/quill/issues/1134
setTimeout(() => {
this.quill.formatLine(selection.index, 1, 'code-block', true)
this.quill.deleteText(selection.index - 4, 4)
}, 0)
}
},
{
name: 'bolditalic',
pattern: /(?:\*|_){3}(.+?)(?:\*|_){3}/g,
action: (text, selection, pattern, lineStart) => {
let match = pattern.exec(text)
const annotatedText = match[0]
const matchedText = match[1]
const startIndex = lineStart + match.index
if (text.match(/^([*_ \n]+)$/g)) return
setTimeout(() => {
this.quill.deleteText(startIndex, annotatedText.length)
this.quill.insertText(startIndex, matchedText, {bold: true})
this.quill.format('bold', false)
}, 0)
}
},
{
name: 'bold',
pattern: /(?:\*|_){2}(.+?)(?:\*|_){2}/g,
action: (text, selection, pattern, lineStart) => {
let match = pattern.exec(text)
const annotatedText = match[0]
const matchedText = match[1]
const startIndex = lineStart + match.index
if (text.match(/^([*_ \n]+)$/g)) return
setTimeout(() => {
this.quill.deleteText(startIndex, annotatedText.length)
this.quill.insertText(startIndex, matchedText, {bold: true})
this.quill.format('bold', false)
}, 0)
}
},
{
name: 'italic',
pattern: /(?:\*|_){1}(.+?)(?:\*|_){1}/g,
action: (text, selection, pattern, lineStart) => {
let match = pattern.exec(text)
const annotatedText = match[0]
const matchedText = match[1]
const startIndex = lineStart + match.index
if (text.match(/^([*_ \n]+)$/g)) return
setTimeout(() => {
this.quill.deleteText(startIndex, annotatedText.length)
this.quill.insertText(startIndex, matchedText, {italic: true})
this.quill.format('italic', false)
}, 0)
}
},
{
name: 'strikethrough',
pattern: /(?:~~)(.+?)(?:~~)/g,
action: (text, selection, pattern, lineStart) => {
let match = pattern.exec(text)
const annotatedText = match[0]
const matchedText = match[1]
const startIndex = lineStart + match.index
if (text.match(/^([*_ \n]+)$/g)) return
setTimeout(() => {
this.quill.deleteText(startIndex, annotatedText.length)
this.quill.insertText(startIndex, matchedText, {strike: true})
this.quill.format('strike', false)
}, 0)
}
},
{
name: 'code',
pattern: /(?:`)(.+?)(?:`)/g,
action: (text, selection, pattern, lineStart) => {
let match = pattern.exec(text)
const annotatedText = match[0]
const matchedText = match[1]
const startIndex = lineStart + match.index
if (text.match(/^([*_ \n]+)$/g)) return
setTimeout(() => {
this.quill.deleteText(startIndex, annotatedText.length)
this.quill.insertText(startIndex, matchedText, {code: true})
this.quill.format('code', false)
this.quill.insertText(this.quill.getSelection(), ' ')
}, 0)
}
},
{
name: 'hr',
pattern: /^([-*]\s?){3}/g,
action: (text, selection) => {
const startIndex = selection.index - text.length
setTimeout(() => {
this.quill.deleteText(startIndex, text.length)
this.quill.insertEmbed(startIndex + 1, 'hr', true, Quill.sources.USER)
this.quill.insertText(startIndex + 2, "\n", Quill.sources.SILENT)
this.quill.setSelection(startIndex + 2, Quill.sources.SILENT)
}, 0)
}
},
{
name: 'asterisk-ul',
pattern: /^(\*|\+)\s$/g,
action: (text, selection, pattern) => {
setTimeout(() => {
this.quill.formatLine(selection.index, 1, 'list', 'unordered')
this.quill.deleteText(selection.index - 2, 2)
}, 0)
}
},
{
name: 'image',
pattern: /(?:!\[(.+?)\])(?:\((.+?)\))/g,
action: (text, selection, pattern) => {
const startIndex = text.search(pattern)
const matchedText = text.match(pattern)[0]
// const hrefText = text.match(/(?:!\[(.*?)\])/g)[0]
const hrefLink = text.match(/(?:\((.*?)\))/g)[0]
const start = selection.index - matchedText.length - 1
if (startIndex !== -1) {
setTimeout(() => {
this.quill.deleteText(start, matchedText.length)
this.quill.insertEmbed(start, 'image', hrefLink.slice(1, hrefLink.length - 1))
}, 0)
}
}
},
{
name: 'link',
pattern: /(?:\[(.+?)\])(?:\((.+?)\))/g,
action: (text, selection, pattern) => {
const startIndex = text.search(pattern)
const matchedText = text.match(pattern)[0]
const hrefText = text.match(/(?:\[(.*?)\])/g)[0]
const hrefLink = text.match(/(?:\((.*?)\))/g)[0]
const start = selection.index - matchedText.length - 1
if (startIndex !== -1) {
setTimeout(() => {
this.quill.deleteText(start, matchedText.length)
this.quill.insertText(start, hrefText.slice(1, hrefText.length - 1), 'link', hrefLink.slice(1, hrefLink.length - 1))
}, 0)
}
}
}
]
// Handler that looks for insert deltas that match specific characters
this.quill.on('text-change', (delta, oldContents, source) => {
for (let i = 0; i < delta.ops.length; i++) {
if (delta.ops[i].hasOwnProperty('insert')) {
if (delta.ops[i].insert === ' ') {
this.onSpace()
} else if (delta.ops[i].insert === '\n') {
this.onEnter()
}
}
}
})
}
onSpace () {
const selection = this.quill.getSelection()
if (!selection) return
const [line, offset] = this.quill.getLine(selection.index)
const text = line.domNode.textContent
const lineStart = selection.index - offset
if (typeof text !== 'undefined' && text) {
for (let match of this.matches) {
const matchedText = text.match(match.pattern)
if (matchedText) {
// We need to replace only matched text not the whole line
const textToReplace = matchedText[0]
console.log('matched', match.name, textToReplace)
match.action(textToReplace, selection, match.pattern, lineStart)
return
}
}
}
}
onEnter () {
let selection = this.quill.getSelection()
if (!selection) return
const [line, offset] = this.quill.getLine(selection.index)
const text = line.domNode.textContent + ' '
const lineStart = selection.index - offset
selection.length = selection.index++
if (typeof text !== 'undefined' && text) {
for (let match of this.matches) {
const matchedText = text.match(match.pattern)
if (matchedText) {
console.log('matched', match.name, text)
match.action(text, selection, match.pattern, lineStart)
return
}
}
}
}
}
export default MarkdownShortcuts
and added it to my component:
import Quill from 'quill';
import Markdown from './quill-markdown-shortcut.js'
Quill.register('modules/markdownShortcuts', Markdown);
Awesome thank you so much!
Most helpful comment
i got it - you should not use the compiled dist file of markdown shortcut.
use the /src/index.js
so there is no npm and special support - i combined everything of markdown shortcuts:
and added it to my component: