UNPKG

@print-one/grapesjs

Version:

Free and Open Source Web Builder Framework

187 lines (159 loc) 4.3 kB
import { result, forEach, keys } from 'underscore'; import { Model } from '../../common'; import EditorModel from '../../editor/model/Editor'; const TYPE_CLASS = 1; const TYPE_ID = 2; export interface SelectorProps { name: string; label?: string; type?: number; active?: boolean; private?: boolean; protected?: boolean; } /** * @typedef Selector * @property {String} name Selector name, eg. `my-class` * @property {String} label Selector label, eg. `My Class` * @property {Number} [type=1] Type of the selector. 1 (class) | 2 (id) * @property {Boolean} [active=true] If not active, it's not selectable by the Style Manager. * @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 { defaults() { return { name: '', label: '', type: TYPE_CLASS, active: true, private: false, protected: false, _undo: true, }; } // Type selectors: https://developer.mozilla.org/it/docs/Web/CSS/CSS_Selectors static readonly TYPE_CLASS = TYPE_CLASS; static readonly TYPE_ID = TYPE_ID; em: EditorModel; /** * @hideconstructor */ constructor(props: any, opts: any = {}) { super(props, opts); const { config = {} } = opts; const name = this.get('name'); const label = this.get('label'); if (!name) { this.set('name', label); } else if (!label) { this.set('label', name); } const namePreEsc = this.get('name'); const { escapeName } = config; const nameEsc = escapeName ? escapeName(namePreEsc) : Selector.escapeName(namePreEsc); this.set('name', nameEsc); this.em = opts.em; } isId() { return this.get('type') === TYPE_ID; } isClass() { return this.get('type') === TYPE_CLASS; } getFullName(opts: any = {}) { const { escape } = opts; const name = this.get('name'); let pfx = ''; switch (this.get('type')) { case TYPE_CLASS: pfx = '.'; break; case TYPE_ID: pfx = '#'; break; } return pfx + (escape ? escape(name) : name); } /** * Get selector as a string. * @returns {String} * @example * // Given such selector: { name: 'my-selector', type: 2 } * console.log(selector.toString()); * // -> `#my-selector` */ toString() { return this.getFullName(); } /** * Get selector label. * @returns {String} * @example * // Given such selector: { name: 'my-selector', label: 'My selector' } * console.log(selector.getLabel()); * // -> `My selector` */ getLabel() { return this.get('label'); } /** * Update selector label. * @param {String} label New label * @example * // Given such selector: { name: 'my-selector', label: 'My selector' } * selector.setLabel('New Label') * console.log(selector.getLabel()); * // -> `New Label` */ setLabel(label: string) { return this.set('label', label); } /** * Get selector active state. * @returns {Boolean} */ getActive(): boolean { return this.get('active'); } /** * Update selector active state. * @param {Boolean} value New active state */ setActive(value: boolean) { return this.set('active', value); } toJSON(opts = {}) { const { em } = this; let obj = Model.prototype.toJSON.call(this, [opts]); const defaults = result(this, 'defaults'); if (em && em.getConfig().avoidDefaults) { forEach(defaults, (value, key) => { if (obj[key] === value) { delete obj[key]; } }); if (obj.label === obj.name) { delete obj.label; } const objLen = keys(obj).length; if (objLen === 1 && obj.name) { obj = obj.name; } if (objLen === 2 && obj.name && obj.type) { obj = this.getFullName(); } } return obj; } /** * Escape string * @param {string} name * @return {string} * @private */ static escapeName(name: string) { return `${name}`.trim().replace(/([^a-z0-9\w-\:@]+)/gi, '-'); } } Selector.prototype.idAttribute = 'name';