DESCRIPTION
I am trying to create an inline blot for text highlighting. I know this feature is already present in quill. But in my implementation I would like to assign a different value to the html element depending on the type of highlighting that was assigned. Here's what I got:
let Inline = Quill.import('blots/inline');
class TextHighlight extends Inline {
static create(value) {
let node = super.create();
if(!value || value < 1) return node;
if(value == 5){
node.style.color = 'rgb(225, 225, 225)';
}
else {
node.style.borderRadius = '2px';
node.style.padding = '2px';
if(value == 1){ node.style.background = 'rgb(254, 255, 171)'; }
if(value == 2){ node.style.background = 'rgb(255, 171, 171)'; }
if(value == 3){ node.style.background = 'rgb(171, 207, 255)'; }
if(value == 4){ node.style.background = 'rgb(178, 255, 171)'; }
}
node.setAttribute('data-value' , value);
return node;
}
formats() {
console.log('#formats()');
let result = this.domNode.getAttribute('data-value');
return result ? result : 0;
}
}
TextHighlight.blotName = 'texthighlight';
TextHighlight.tagName = 'span';
My remove/add function:
function highlightSelectedText(value) {
if (value < 0 || value > 5) return false;
var range = quill.getSelection();
if (range && range.length > 0) {
if (value > 0) {
quill.formatText(
range.index,
range.length,
'texthighlight',
value,
true);
}
else {
quill.formatText(range.index, range.length, 'texthighlight', false, false);
}
}
}
And finally the creation of the Quill instance:
var toolbarOptions = {
container: '#toolbar-container',
handlers: {
'texthighlight': function (value) {
highlightSelectedText(value);
}
}
};
var quill = new Quill('#editor', {
theme: 'bubble',
modules: {
toolbar: toolbarOptions
}
});
The problems
- Highlighted text snippets have the following Delta:
...
{
"attributes": {
"0": "3"
},
"insert": "highlighted text"
},
...
"texthighlight" should appear instead of 0, like:
...
{
"attributes": {
"texthighlight": "3"
},
"insert": "highlighted text"
},
...
- If I apply formatting more than once, it starts accumulating, putting markup inside markup. For example:
<span class="texthighlight"><span class="texthighlight"><span class="texthighlight"><span class="texthighlight"></span></span></span></span>
The expected behavior is that only one highlight is present.
- I cannot remove the formatting.
CONCLUSION
There is no doubt that I lack knowledge about how to properly implement this. I was able to create simpler blots in other situations, but now I'm really getting confused about overriding certain blot methods. For example, the following list shows which methods I mean, and what I understand about each:
static formats(node)
: Returns formats represented by domNode. Called on selection events when index is within formatted range.formats()
: Returns formats represented by this Blot. It is used for Delta generation. Called on selection events when index is within formatted range.format(format , value)
: Applies formatting to this blot.
In the highlight implementation demonstrated, only formats()
and create(value)
are being called. I know there is an example of how each of these methods is implemented, but I am not getting the desired behavior. I think it's because I don't know how to exactly implement them. Could someone answer me what they really do, when they are called, and how they should behave (be implemented)?
Can somebody help me, please? :(