Mimic customRTE behavior when parsing content
Question
Hi @artf,
I'd like to replicate this behavior when calling editor.setComponents("<div>This is a text component. <span style='font-size: 20px;'>This is a nested element that I don't want get parsed out.</span></div>"). In that example, I would want the nested span to not get parsed as its own component so that I cannot select it or interact with it in any way (much the same as if I had enabled/disabled a customRTE on the div).
I'm seeing 2 options here:
- After calling
editor.setComponents, programmatically enable and disable RTE on outer div so that the child elements & text are treated ascontenton thediv. I'm pretty sure this would work without making any changes to grapesjs core...haven't tested it out just yet. - Modify the behavior of
ParseHtml.parseNodeto somehow identify that thedivshould not parse out its child elements/text. Maybe something like this using a a new property returned fromisComponent:
var defaultType = editor.DomComponents.getType("default");
editor.DomComponents.addType('some-custom-component-type', {
model: defaultType.model.extend(
{
},
{
isComponent: function(el) {
if(el.hasAttribute && el.hasAttribute("data-some-custom-component-type")){
return {
type: 'some-custom-component-type',
parseChildContent: false // new property that will tell the parser not to bother with parsing the children
};
}
}
}
),
view: defaultType.view
});
... // changes to ParseHtml.parseNode() below
if (nodeChild === 1 && firstChild.nodeType === 3) {
!model.type && (model.type = 'text');
model.content = firstChild.nodeValue;
} else if (model.hasOwnProperty("parseChildContent") && !model.parseChildContent) { // check for the new property to prevent the default node parsing behavior
model.content = node.innerHTML;
} else {
model.components = this.parseNode(node);
}
...
editor.setComponents("<div data-some-custom-component-type>This is a text component. <span style='font-size: 20px;'>This is a nested element that I don't want get parsed out.</span></div>")
Any thoughts on exploring option 2? Would you consider accepting a pull request that adds that new functionality to the parser? It wouldn't necessarily need to be driven by a custom component...I think a property like data-parse-child-content="false" could also be an option, or perhaps simply recognizing that a customRTE is being used and just check for model.type === "text" instead of parseChildContent.
My use case for this is that I'm going to be using a customRTE, but there's a good chance that the content that initially gets set into the editor will have a lot of nested text components which I'd like to treat as a single component.
Answers (3)
Now that I think through this a bit more, option 1 wouldn't really work for me since I want to prevent any inline styles from getting removed, as well as preventing any id's/classes/attributes from getting added to the child elements. So I guess that leaves option 2 or maybe another solution that I haven't thought of.
Hey Ryan what about this custom component
const domc = editor.DomComponents;
const textType = domc.getType('text');
domc.addType('raw-text', {
model: textType.model.extend({
},{
isComponent: function(el) {
if (el.hasAttribute && el.hasAttribute('data-raw-text')) {
return {
type: 'raw-text',
content: el.innerHTML,
components: [] // this will avoid parsing children
};
}
}
}
),
view: textType.view.extend({
disableEditing() {
const model = this.model;
const rte = this.rte;
if (rte && model.get('editable')) {
rte.disable(this, this.activeRte);
model.set('content', this.getChildrenContainer().innerHTML)
.trigger('change:content', model);
}
this.rteEnabled = 0;
this.toggleEvents();
},
})
});
Thanks @artf! I bet your suggestion will work for me - I'll test it out in the next few hours.
Related Questions and Answers
Continue research with similar issue discussions.
Issue #792
Script property using function don't work with blocks
In Components & JS docs there's this example: This works perfectly. But I couldn't use a function instead of a string in script, as is said...
Issue #1421
[Bug]: "disabled" instead of "active" class for Panel Button View
Hello I assume there is a bug with class when Panel Button is disabled https://github.com/artf/grapesjs/blob/dev/src/panels/view/ButtonView...
Issue #1846
[Question]: Using ngModel on component that contains groups of tagName
I have tried this solution https://github.com/artf/grapesjs/issues/1819#event-2158016066 But on custom components Let's say, i have a mixtu...
Issue #1688
on set model content property image and text written in content is not editable in grapejs canvas.
WARNING READ and FOLLOW next 5 steps, then REMOVE them before posting the issueFollow CONTRIBUTING Guidelines https://github.com/artf/grape...
Paid Plugins That Match This Issue
Curated by issue keywords and label relevance to help you ship faster.
Loading paid plugin recommendations...
Browse Plugin Categories
Jump directly to plugin category pages on the marketplace.