Browse Source

Allow comment Components in Text. Fixes #5657

pull/5694/head
Artur Arseniev 2 years ago
parent
commit
d2c35ba337
  1. 1
      src/dom_components/model/ComponentComment.ts
  2. 7
      src/parser/config/config.ts
  3. 5
      src/parser/model/ParserHtml.ts
  4. 31
      test/specs/parser/model/ParserHtml.ts

1
src/dom_components/model/ComponentComment.ts

@ -13,7 +13,6 @@ export default class ComponentComment extends ComponentTextNode {
static isComponent(el: HTMLElement) { static isComponent(el: HTMLElement) {
if (el.nodeType == 8) { if (el.nodeType == 8) {
return { return {
tagName: 'NULL',
type: 'comment', type: 'comment',
content: el.textContent ?? '', content: el.textContent ?? '',
}; };

7
src/parser/config/config.ts

@ -46,6 +46,12 @@ export interface ParserConfig {
*/ */
textTags?: string[]; textTags?: string[];
/**
* Let the editor know which Component types should be treated as part of the text component.
* @default ['text', 'textnode', 'comment']
*/
textTypes?: string[];
/** /**
* Custom CSS parser. * Custom CSS parser.
* @see https://grapesjs.com/docs/guides/Custom-CSS-parser.html * @see https://grapesjs.com/docs/guides/Custom-CSS-parser.html
@ -71,6 +77,7 @@ export interface ParserConfig {
const config: ParserConfig = { const config: ParserConfig = {
textTags: ['br', 'b', 'i', 'u', 'a', 'ul', 'ol'], textTags: ['br', 'b', 'i', 'u', 'a', 'ul', 'ol'],
textTypes: ['text', 'textnode', 'comment'],
parserCss: undefined, parserCss: undefined,
parserHtml: undefined, parserHtml: undefined,
optionsHtml: { optionsHtml: {

5
src/parser/model/ParserHtml.ts

@ -260,6 +260,7 @@ const ParserHtml = (em?: EditorModel, config: ParserConfig & { returnArray?: boo
// be text too otherwise I'm unable to edit texnodes // be text too otherwise I'm unable to edit texnodes
const comps = model.components; const comps = model.components;
if (!model.type && comps) { if (!model.type && comps) {
const { textTypes = [], textTags = [] } = config;
let allTxt = 1; let allTxt = 1;
let foundTextNode = 0; let foundTextNode = 0;
@ -267,7 +268,7 @@ const ParserHtml = (em?: EditorModel, config: ParserConfig & { returnArray?: boo
const comp = comps[ci]; const comp = comps[ci];
const cType = comp.type; const cType = comp.type;
if (['text', 'textnode'].indexOf(cType) < 0 && config.textTags!.indexOf(comp.tagName) < 0) { if (!textTypes.includes(cType) && !textTags.includes(comp.tagName)) {
allTxt = 0; allTxt = 0;
break; break;
} }
@ -283,7 +284,7 @@ const ParserHtml = (em?: EditorModel, config: ParserConfig & { returnArray?: boo
} }
// If tagName is still empty and is not a textnode, do not push it // If tagName is still empty and is not a textnode, do not push it
if (!model.tagName && model.type != 'textnode') { if (!model.tagName && isUndefined(model.content)) {
continue; continue;
} }

31
test/specs/parser/model/ParserHtml.ts

@ -12,6 +12,7 @@ describe('ParserHtml', () => {
var dom = new DomComponents(em); var dom = new DomComponents(em);
obj = ParserHtml(em, { obj = ParserHtml(em, {
textTags: ['br', 'b', 'i', 'u'], textTags: ['br', 'b', 'i', 'u'],
textTypes: ['text', 'textnode', 'comment'],
returnArray: true, returnArray: true,
}); });
obj.compTypes = dom.componentTypes as any; obj.compTypes = dom.componentTypes as any;
@ -267,6 +268,36 @@ describe('ParserHtml', () => {
expect(obj.parse(str).html).toEqual(result); expect(obj.parse(str).html).toEqual(result);
}); });
test('Parse text with few text tags and comment', () => {
var str = '<div id="test1">Some text <br/><!-- comment --><b>Bold</b></div>';
var result = [
{
tagName: 'div',
attributes: { id: 'test1' },
type: 'text',
components: [
{
content: 'Some text ',
type: 'textnode',
tagName: '',
},
{ tagName: 'br' },
{
content: ' comment ',
type: 'comment',
tagName: '',
},
{
components: { type: 'textnode', content: 'Bold' },
type: 'text',
tagName: 'b',
},
],
},
];
expect(obj.parse(str).html).toEqual(result);
});
test('Parse nested nodes', () => { test('Parse nested nodes', () => {
var str = var str =
'<article id="test1"> <div></div> <footer id="test2"></footer> Text mid <div id="last"></div></article>'; '<article id="test1"> <div></div> <footer id="test2"></footer> Text mid <div id="last"></div></article>';

Loading…
Cancel
Save