Browse Source

Fix: `"TypeError: this.parseStyle is not a function"` when `setStyles` is called internally (bug introduced in GrapesJS v19.5) (#4520)

* wrap `ParserHtml().parseStyle` around a class method

currently when the model is extended via the `.extend` method, the `parseStyle`
property is "hoisted" from the parent to the child. ideally, it should
be be located on the parent which is the `prototype` of the child. the
consequence of this is that when you run:
`Object.hasOwnProperty.call(child, 'parseStyle')`, you get `true`.
this is problematic as `parseStyle` is required by `setStyle` of
`Dom_Components::Model::Component` which expects `parseStyle` to exist
on its prototype (`StyleableModel`). But `parseStyle` is "hoisted" to be the property
of any component that extends `Dom_Components::Model::Component`, thus, `this.parseStyle` will always be
`undefined` when its called by any method that exists in objects that
are lower in the prototypal
chain than the topmost object (where `parseStyle` is defined).
If `setStyle` is called further down the prototypal chain, it throws the
following error: `"this.parseStyle is not a function"`

* fix: prevent requesting a new parser on each parse
pull/4535/head
Collins Lagat 4 years ago
committed by GitHub
parent
commit
d3abac15ef
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 11
      src/domain_abstract/model/StyleableModel.js
  2. 23
      test/specs/dom_components/model/Component.js

11
src/domain_abstract/model/StyleableModel.js

@ -3,8 +3,17 @@ import { shallowDiff } from '../../utils/mixins';
import ParserHtml from '../../parser/model/ParserHtml';
import { Model } from '../../common';
const parserHtml = ParserHtml();
export default class StyleableModel extends Model {
parseStyle = ParserHtml().parseStyle;
/**
* Forward style string to `parseStyle` to be parse to an object
* @param {string} str
* @returns
*/
parseStyle(str) {
return parserHtml.parseStyle(str);
}
/**
* To trigger the style change event on models I have to

23
test/specs/dom_components/model/Component.js

@ -417,6 +417,29 @@ describe('Component', () => {
};
newObj.components().each(model => inhereted(model));
});
test('setStyle parses styles correctly', () => {
const styles = 'padding: 12px;height:auto;';
const expectedObj = {
padding: '12px',
height: 'auto',
};
const c = new Component();
expect(c.setStyle(styles)).toEqual(expectedObj);
});
test('setStyle should be called successfully when invoked internally', () => {
const ExtendedComponent = Component.extend({
init() {
const styles = 'padding: 12px;height:auto;';
this.setStyle(styles);
},
});
expect(() => new ExtendedComponent()).not.toThrowError();
});
});
describe('Image Component', () => {

Loading…
Cancel
Save