Browse Source

Prevent crash if block category id is an object builtin method name. Closes #5478

pull/5504/head
Artur Arseniev 3 years ago
parent
commit
561ee08591
  1. 19
      src/block_manager/model/Categories.ts
  2. 11
      src/block_manager/view/BlocksView.ts
  3. 8
      src/utils/mixins.ts

19
src/block_manager/model/Categories.ts

@ -1,6 +1,19 @@
import { Collection } from '../../common'; import { isArray, isString } from 'underscore';
import Category from './Category'; import { AddOptions, Collection } from '../../common';
import { normalizeKey } from '../../utils/mixins';
import Category, { BlockCategoryProperties } from './Category';
export default class Categories extends Collection<Category> {} export default class Categories extends Collection<Category> {
/** @ts-ignore */
add(model: (BlockCategoryProperties | Category)[] | BlockCategoryProperties | Category, opts?: AddOptions) {
const models = isArray(model) ? model : [model];
models.forEach(md => md && (md.id = normalizeKey(`${md.id}`)));
return super.add(model, opts);
}
get(id: string | Category) {
return super.get(isString(id) ? normalizeKey(id) : id);
}
}
Categories.prototype.model = Category; Categories.prototype.model = Category;

11
src/block_manager/view/BlocksView.ts

@ -19,7 +19,7 @@ export default class BlocksView extends View {
em: EditorModel; em: EditorModel;
config: BlocksViewConfig; config: BlocksViewConfig;
categories: Categories; categories: Categories;
renderedCategories: Record<string, CategoryView>; renderedCategories = new Map<string, CategoryView>();
ppfx: string; ppfx: string;
noCatClass: string; noCatClass: string;
blockContClass: string; blockContClass: string;
@ -34,7 +34,6 @@ export default class BlocksView extends View {
bindAll(this, 'getSorter', 'onDrag', 'onDrop', 'onMove'); bindAll(this, 'getSorter', 'onDrag', 'onDrop', 'onMove');
this.config = config || {}; this.config = config || {};
this.categories = opts.categories || ''; this.categories = opts.categories || '';
this.renderedCategories = {};
const ppfx = this.config.pStylePrefix || ''; const ppfx = this.config.pStylePrefix || '';
this.ppfx = ppfx; this.ppfx = ppfx;
this.noCatClass = `${ppfx}blocks-no-cat`; this.noCatClass = `${ppfx}blocks-no-cat`;
@ -126,7 +125,7 @@ export default class BlocksView extends View {
* @private * @private
* */ * */
add(model: Block, fragment?: DocumentFragment) { add(model: Block, fragment?: DocumentFragment) {
const { config } = this; const { config, renderedCategories } = this;
const view = new BlockView( const view = new BlockView(
{ {
model, model,
@ -148,13 +147,13 @@ export default class BlocksView extends View {
const catModel = this.categories.add(category); const catModel = this.categories.add(category);
const catId = catModel.get('id')!; const catId = catModel.get('id')!;
const categories = this.getCategoriesEl(); const categories = this.getCategoriesEl();
let catView = this.renderedCategories[catId]; let catView = renderedCategories.get(catId);
// @ts-ignore // @ts-ignore
model.set('category', catModel, { silent: true }); model.set('category', catModel, { silent: true });
if (!catView && categories) { if (!catView && categories) {
catView = new CategoryView({ model: catModel }, config).render(); catView = new CategoryView({ model: catModel }, config).render();
this.renderedCategories[catId] = catView; renderedCategories.set(catId, catView);
categories.appendChild(catView.el); categories.appendChild(catView.el);
} }
@ -191,7 +190,7 @@ export default class BlocksView extends View {
const frag = document.createDocumentFragment(); const frag = document.createDocumentFragment();
delete this.catsEl; delete this.catsEl;
delete this.blocksEl; delete this.blocksEl;
this.renderedCategories = {}; this.renderedCategories = new Map();
this.el.innerHTML = ` this.el.innerHTML = `
<div class="${this.catsClass}"></div> <div class="${this.catsClass}"></div>
<div class="${this.noCatClass}"> <div class="${this.noCatClass}">

8
src/utils/mixins.ts

@ -1,10 +1,16 @@
import { isArray, isElement, isUndefined, keys } from 'underscore'; import { isArray, isElement, isFunction, isUndefined, keys } from 'underscore';
import ComponentView from '../dom_components/view/ComponentView'; import ComponentView from '../dom_components/view/ComponentView';
import EditorModel from '../editor/model/Editor'; import EditorModel from '../editor/model/Editor';
import { isTextNode } from './dom'; import { isTextNode } from './dom';
import Component from '../dom_components/model/Component'; import Component from '../dom_components/model/Component';
import { ObjectAny } from '../common'; import { ObjectAny } from '../common';
const obj: ObjectAny = {};
export const isBultInMethod = (key: string) => isFunction(obj[key]);
export const normalizeKey = (key: string) => (isBultInMethod(key) ? `_${key}` : key);
export const wait = (mls: number = 0) => new Promise(res => setTimeout(res, mls)); export const wait = (mls: number = 0) => new Promise(res => setTimeout(res, mls));
export const isDef = (value: any) => typeof value !== 'undefined'; export const isDef = (value: any) => typeof value !== 'undefined';

Loading…
Cancel
Save