问题
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? :(
回答1:
EDIT (Dec 18, 2019)
So... After hours of research, I was finally able to make the editor a little more correct. In this whole story I ended up creating a blot that is capable of formatting text with different styles depending on the value passed to formatting. You can even remove formatting by providing or omitting a value.
I was finally able to get an answer for item 2 and, as I thought, found it within the toolbar module. Regarding the formats methods and their differences, I think I could better understand it. I still don't understand why formats are called so often. I think I'll find the answer looking at quill core, but... The quill source code is very large as it involves multiple files.
I am putting here a more updated version of the code shown earlier. It is all commented, favoring anyone who wants to learn more about how to:
- Define custom blots/formats,
- Define blots that accept values, and behave in different ways depending on the configured value.
- Define custom toolbar buttons that respond and reflect the state of the editor content.
I hope that this will enable people to better understand how this tool can be used, and to create greater interest and contribution with it.
Full Example on GitHub
ORIGINAL ANSWER
It seems that I somehow managed to get the desired result. I am putting an answer here, but I do not consider it correct yet, as it is not complete. The desired result is obtained, but I'm still unable to understood how or why things work. Understanding the process becomes something fundamental, especially if and when the code needs to be changed in the future. Below you can check the code of the whole project. To test, just run it.
My remaining questions are:
- What are the differences between
formats
andstatic formats(domNode)
? If you observe code execution, they are called a few times, andstatic formats(domNode)
are called twice. Is this normal? I do not know, that's why I am asking. - Within function
highlightSelectedText(hl)
, why does hl appear with a false value? How does this happen? - When formatting is applied, the
create
is used. When it is removed,format(format, value)
is called. There are snippets of code (inside format) that are never reached. Shouldn't applying and removing formats be aformat
-only job? Why do I have to change the DOM element in two different locations?
I think I can find the answer to number 2 by looking at the toolbar module source code. But I'm not quite sure. If I can figure it all out, I'll be back here to edit this answer, okay? I know others may also have the same questions.
来源:https://stackoverflow.com/questions/59366868/what-how-and-when-to-use-static-formats-formats-and-format-on-custom-blot