From 99dfa6b6a1f2e63e435d217992763d0547ee7c8a Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Fri, 12 Jul 2024 16:22:24 +0400 Subject: [PATCH] Avoid default strict name escaping for Selector names #5994 --- src/css_composer/model/CssRule.ts | 18 ++++++++--------- src/selector_manager/model/Selector.ts | 20 ++++++++++++++----- .../selector_manager/model/SelectorModels.ts | 6 +++--- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/css_composer/model/CssRule.ts b/src/css_composer/model/CssRule.ts index b3cce2ae1..e9c95d88b 100644 --- a/src/css_composer/model/CssRule.ts +++ b/src/css_composer/model/CssRule.ts @@ -128,14 +128,14 @@ export default class CssRule extends StyleableModel { clone(): CssRule { const opts = { ...this.opt }; const attr = { ...this.attributes }; - attr.selectors = this.get('selectors')!.map(s => s.clone()) as Selector[]; + attr.selectors = this.get('selectors')!.map(s => s.clone() as Selector); // @ts-ignore return new this.constructor(attr, opts); } ensureSelectors(m: any, c: any, opts: any) { const { em } = this; - const sm = em?.get('SelectorManager'); + const sm = em?.Selectors; const toListen = [this, 'change:selectors', this.ensureSelectors]; let sels = this.getSelectors() as any; this.stopListening(...toListen); @@ -193,7 +193,7 @@ export default class CssRule extends StyleableModel { escape: (str: string) => (CSS && CSS.escape ? CSS.escape(str) : str), }; // @ts-ignore - const selectors = this.get('selectors').getFullString(0, selOpts); + const selectors = this.getSelectors().getFullString(0, selOpts); const stateStr = state && !opts.skipState ? `:${state}` : ''; selectors && result.push(`${selectors}${stateStr}`); addSelector && !opts.skipAdd && result.push(addSelector); @@ -235,12 +235,12 @@ export default class CssRule extends StyleableModel { getDevice() { const { em } = this; const { atRuleType, mediaText } = this.attributes; - const devices = em?.get('DeviceManager').getDevices() || []; - const deviceDefault = devices.filter((d: any) => d.getWidthMedia() === '')[0]; + const devices = em?.Devices.getDevices() || []; + const deviceDefault = devices.filter(d => d.getWidthMedia() === '')[0]; if (atRuleType !== 'media' || !mediaText) { return deviceDefault || null; } - return devices.filter((d: any) => d.getWidthMedia() === getMediaLength(mediaText))[0] || null; + return devices.filter(d => d.getWidthMedia() === getMediaLength(mediaText))[0] || null; } /** @@ -253,8 +253,8 @@ export default class CssRule extends StyleableModel { getState() { const { em } = this; const stateValue = this.get('state'); - const states = em?.get('SelectorManager').getStates() || []; - return states.filter((s: any) => s.getName() === stateValue)[0] || null; + const states = em?.Selectors.getStates() || []; + return states.filter(s => s.getName() === stateValue)[0] || null; } /** @@ -265,7 +265,7 @@ export default class CssRule extends StyleableModel { * console.log(cmp?.toHTML()); */ getComponent() { - const sel = this.getSelectors() as any; + const sel = this.getSelectors(); const sngl = sel.length == 1 && sel.at(0); const cmpId = sngl && sngl.isId() && sngl.get('name'); return (cmpId && this.em?.Components.getById(cmpId)) || null; diff --git a/src/selector_manager/model/Selector.ts b/src/selector_manager/model/Selector.ts index afc6f243d..0de65ffc7 100644 --- a/src/selector_manager/model/Selector.ts +++ b/src/selector_manager/model/Selector.ts @@ -1,6 +1,7 @@ import { result, forEach, keys } from 'underscore'; import { Model } from '../../common'; import EditorModel from '../../editor/model/Editor'; +import { SelectorManagerConfig } from '../config/config'; const TYPE_CLASS = 1; const TYPE_ID = 2; @@ -14,6 +15,15 @@ export interface SelectorProps { protected?: boolean; } +export interface SelectorPropsCustom extends SelectorProps { + [key: string]: unknown; +} + +export interface SelectorOptions { + config?: SelectorManagerConfig; + em?: EditorModel; +} + /** * @typedef Selector * @property {String} name Selector name, eg. `my-class` @@ -23,7 +33,7 @@ export interface SelectorProps { * @property {Boolean} [private=false] If true, it can't be seen by the Style Manager, but it will be rendered in the canvas and in export code. * @property {Boolean} [protected=false] If true, it can't be removed from the attached component. */ -export default class Selector extends Model { +export default class Selector extends Model { defaults() { return { name: '', @@ -40,12 +50,12 @@ export default class Selector extends Model { if (obj[key] === value) { delete obj[key]; @@ -191,7 +201,7 @@ export default class Selector extends Model { let obj: Selector; - const nameToEscape = '@Te sT:*[]().%/+#'; - const nameEscaped = '@Te-sT:-[]().%/+#'; + const nameToEscape = ' @Te sT:*[]!"£$%&/()=?^{}(). %/+#'; + const nameEscaped = '@Te-sT:*[]!"£$%&/()=?^{}().-%/+#'; beforeEach(() => { - obj = new Selector({}); + obj = new Selector({ name: '' }); }); test('Has name property', () => {