Sanitize settings are corrupted if multiple inline tools specify the same tag
If you create more than one inline tool that uses the same tag, the settings from one seem to overwrite the other.
I have a font and font size inline tool. Both use a SPAN tag and have a unique classes and data settings. Which ever is included last overwrites the other settings.
In Font, I have a sanitize config of:
static get sanitize() {
return {
span: {
class: true,
'data-font-setting': true
}
};
}
And in FontSize, I have a sanitize config of:
static get sanitize() {
return {
span: {
class: true,
'data-font-size-setting': true
}
};
}
Depending on inclusion order, I will only get one or the other "data" settings in the save results. Since sanitization bubbles up to the block, I think the issue is that the block is improperly merging these rules together. It needs to be doing a deep, recursive merge I would think.
That said, it also raises the question of how that should even be handled properly. I would not want to allow a span with a class of "font-size" to keep a "font" setting and vice versa. I think in that case, we'd need a more granular selector than just a tag name.
Steps to reproduce:
- Create 2 inline tools that both use the same tag but have different settings for the sanitize
- Use both inline tools in the editor
- Generate the save data
- Note the results will have removed one of the inline tools valid data settings, but kept the other
Expected behavior: At the very least, all allowed attributes should be kept. Perhaps the easiest solution is doing a deeper merge of the sanitization rules.
Device, Browser, OS: PC, Latest Google Chrome, Windows 10
Editor.js version: 2.28.0
Plugins you use with their versions: Nothing beyond the 2 custom tools discussed here.
Workaround: I have a nice workaround in place. I defined a central SPAN Sanitization function that returns the proper config based on the class. Now, both tools have a sanitize config of:
static get sanitize() {
return {
span: SpanSanitizer.sanitize
};
}
And SpanSanitizer.sanitize is a standlone class and static getter that simply returns the function.
class SpanSanitizer {
static get sanitize() {
return function (el) {
if (el.classList.contains('ejs--textsize')) {
return {
class: true,
'data-size-setting': true,
'data-custom-size': true
}
} else if (el.classList.contains('ejs--font')) {
return {
class: true,
'data-font-setting': true
}
}
};
}
}
I think this is the best way to get that sort of granular selection and sanitization, but it makes distributing the plugins by themselves much less simple.
Definitely open to being wrong about this all. I'm still a bit new to EditorJS, so maybe I am missing something. Otherwise, I feel this needs some attention, but the workaround works fine for my direct needs.
I have the same exact issue. If I create 2 inline tools with the same tag, only the one which gets included later will get its class, the other won't.