Browse Source

Convert ClassTagsView to ts

pull/4306/head
Alex 4 years ago
parent
commit
4ff9b07efd
  1. 3
      src/dom_components/model/Component.js
  2. 8
      src/domain_abstract/model/StyleableModel.js
  3. 367
      src/editor/model/Editor.ts
  4. 6
      src/editor/model/Selected.ts
  5. 7
      src/selector_manager/config/config.ts
  6. 104
      src/selector_manager/index.ts
  7. 93
      src/selector_manager/view/ClassTagsView.ts

3
src/dom_components/model/Component.js

@ -12,7 +12,7 @@ import {
keys, keys,
} from 'underscore'; } from 'underscore';
import { shallowDiff, capitalize, isEmptyObj, isObject, toLowerCase } from 'utils/mixins'; import { shallowDiff, capitalize, isEmptyObj, isObject, toLowerCase } from 'utils/mixins';
import StyleableModel from 'domain_abstract/model/StyleableModel'; import StyleableModel from '../../domain_abstract/model/StyleableModel';
import { Model } from 'backbone'; import { Model } from 'backbone';
import Components from './Components'; import Components from './Components';
import Selector from 'selector_manager/model/Selector'; import Selector from 'selector_manager/model/Selector';
@ -49,7 +49,6 @@ export const keyUpdateInside = `${keyUpdate}-inside`;
* *
* [Component]: component.html * [Component]: component.html
* *
* @typedef Component
* @property {String} [type=''] Component type, eg. `text`, `image`, `video`, etc. * @property {String} [type=''] Component type, eg. `text`, `image`, `video`, etc.
* @property {String} [tagName='div'] HTML tag of the component, eg. `span`. Default: `div` * @property {String} [tagName='div'] HTML tag of the component, eg. `span`. Default: `div`
* @property {Object} [attributes={}] Key-value object of the component's attributes, eg. `{ title: 'Hello' }` Default: `{}` * @property {Object} [attributes={}] Key-value object of the component's attributes, eg. `{ title: 'Hello' }` Default: `{}`

8
src/domain_abstract/model/StyleableModel.js

@ -1,12 +1,10 @@
import { isString, isArray, keys, isUndefined } from 'underscore'; import { isString, isArray, keys, isUndefined } from 'underscore';
import { shallowDiff } from '../../utils/mixins'; import { shallowDiff } from '../../utils/mixins';
import ParserHtml from '../../parser/model/ParserHtml'; import ParserHtml from '../../parser/model/ParserHtml';
import { Model } from 'common'; import { Model } from '../../common';
const parseStyle = ParserHtml().parseStyle;
export default class StyleableModel extends Model { export default class StyleableModel extends Model {
parseStyle; parseStyle = ParserHtml().parseStyle;
/** /**
* To trigger the style change event on models I have to * To trigger the style change event on models I have to
@ -36,7 +34,7 @@ export default class StyleableModel extends Model {
*/ */
setStyle(prop = {}, opts = {}) { setStyle(prop = {}, opts = {}) {
if (isString(prop)) { if (isString(prop)) {
prop = parseStyle(prop); prop = this.parseStyle(prop);
} }
const propOrig = this.getStyle(opts); const propOrig = this.getStyle(opts);

367
src/editor/model/Editor.ts

@ -1,48 +1,41 @@
import { import { isUndefined, isArray, contains, toArray, keys, bindAll } from 'underscore';
isUndefined, import Backbone from 'backbone';
isArray, import $ from '../../utils/cash-dom';
contains, import Extender from '../../utils/extender';
toArray, import { getModel, hasWin, isEmptyObj } from '../../utils/mixins';
keys, import { Model } from '../../common';
bindAll, import Selected from './Selected';
} from "underscore"; import FrameView from '../../canvas/view/FrameView';
import Backbone from "backbone"; import EditorModule from '..';
import $ from "../../utils/cash-dom"; import EditorView from '../view/EditorView';
import Extender from "../../utils/extender"; import { IModule } from '../../abstract/Module';
import { getModel, hasWin, isEmptyObj } from "../../utils/mixins";
import { Model } from "../../common";
import Selected from "./Selected";
import FrameView from "../../canvas/view/FrameView";
import EditorModule from "..";
import EditorView from "../view/EditorView";
import { IModule } from "../../abstract/Module";
//@ts-ignore //@ts-ignore
Backbone.$ = $; Backbone.$ = $;
const deps = [ const deps = [
require("utils"), require('utils'),
require("i18n"), require('i18n'),
require("keymaps"), require('keymaps'),
require("undo_manager"), require('undo_manager'),
require("storage_manager"), require('storage_manager'),
require("device_manager"), require('device_manager'),
require("parser"), require('parser'),
require("style_manager"), require('style_manager'),
require("selector_manager"), require('selector_manager'),
require("modal_dialog"), require('modal_dialog'),
require("code_manager"), require('code_manager'),
require("panels"), require('panels'),
require("rich_text_editor"), require('rich_text_editor'),
require("asset_manager"), require('asset_manager'),
require("css_composer"), require('css_composer'),
require("pages"), require('pages'),
require("trait_manager"), require('trait_manager'),
require("dom_components"), require('dom_components'),
require("navigator"), require('navigator'),
require("canvas"), require('canvas'),
require("commands"), require('commands'),
require("block_manager"), require('block_manager'),
]; ];
const ts_deps: any[] = []; const ts_deps: any[] = [];
@ -74,7 +67,7 @@ export default class EditorModel extends Model {
modules: [], modules: [],
toLoad: [], toLoad: [],
opened: {}, opened: {},
device: "", device: '',
}; };
} }
@ -88,30 +81,33 @@ export default class EditorModel extends Model {
view?: EditorView; view?: EditorView;
get storables(): any[] { get storables(): any[] {
return this.get("storables"); return this.get('storables');
} }
get modules(): IModule[] { get modules(): IModule[] {
return this.get("modules"); return this.get('modules');
} }
get toLoad(): any[] { get toLoad(): any[] {
return this.get("toLoad"); return this.get('toLoad');
}
get selected(): Selected {
return this.get('selected');
} }
constructor(conf = {}) { constructor(conf = {}) {
super(); super();
this._config = conf; this._config = conf;
const { config } = this; const { config } = this;
this.set("Config", conf); this.set('Config', conf);
this.set("modules", []); this.set('modules', []);
this.set("toLoad", []); this.set('toLoad', []);
this.set("storables", []); this.set('storables', []);
this.set("selected", new Selected()); this.set('selected', new Selected());
this.set("dmode", config.dragMode); this.set('dmode', config.dragMode);
const { el, log } = config; const { el, log } = config;
const toLog = log === true ? keys(logs) : isArray(log) ? log : []; const toLog = log === true ? keys(logs) : isArray(log) ? log : [];
bindAll(this, "initBaseColorPicker"); bindAll(this, 'initBaseColorPicker');
if (el && config.fromElement) { if (el && config.fromElement) {
config.components = el.innerHTML; config.components = el.innerHTML;
@ -122,7 +118,7 @@ export default class EditorModel extends Model {
res[next.nodeName] = next.nodeValue; res[next.nodeName] = next.nodeValue;
return res; return res;
}, {}) }, {})
: ""; : '';
// Move components to pages // Move components to pages
if (config.components && !config.pageManager) { if (config.components && !config.pageManager) {
@ -130,35 +126,27 @@ export default class EditorModel extends Model {
} }
// Load modules // Load modules
deps.forEach((name) => this.loadModule(name)); deps.forEach(name => this.loadModule(name));
ts_deps.forEach((name) => this.tsLoadModule(name)); ts_deps.forEach(name => this.tsLoadModule(name));
this.on("change:componentHovered", this.componentHovered, this); this.on('change:componentHovered', this.componentHovered, this);
this.on("change:changesCount", this.updateChanges, this); this.on('change:changesCount', this.updateChanges, this);
this.on("change:readyLoad change:readyCanvas", this._checkReady, this); this.on('change:readyLoad change:readyCanvas', this._checkReady, this);
toLog.forEach((e) => this.listenLog(e)); toLog.forEach(e => this.listenLog(e));
// Deprecations // Deprecations
[{ from: "change:selectedComponent", to: "component:toggled" }].forEach( [{ from: 'change:selectedComponent', to: 'component:toggled' }].forEach(event => {
(event) => { const eventFrom = event.from;
const eventFrom = event.from; const eventTo = event.to;
const eventTo = event.to; this.listenTo(this, eventFrom, (...args) => {
this.listenTo(this, eventFrom, (...args) => { this.trigger(eventTo, ...args);
this.trigger(eventTo, ...args); this.logWarning(`The event '${eventFrom}' is deprecated, replace it with '${eventTo}'`);
this.logWarning( });
`The event '${eventFrom}' is deprecated, replace it with '${eventTo}'` });
);
});
}
);
} }
_checkReady() { _checkReady() {
if ( if (this.get('readyLoad') && this.get('readyCanvas') && !this.get('ready')) {
this.get("readyLoad") && this.set('ready', true);
this.get("readyCanvas") &&
!this.get("ready")
) {
this.set("ready", true);
} }
} }
@ -192,15 +180,15 @@ export default class EditorModel extends Model {
*/ */
loadOnStart() { loadOnStart() {
const { projectData, headless } = this.config; const { projectData, headless } = this.config;
const sm = this.get("StorageManager"); const sm = this.get('StorageManager');
// In `onLoad`, the module will try to load the data from its configurations. // In `onLoad`, the module will try to load the data from its configurations.
this.toLoad.forEach((mdl) => mdl.onLoad()); this.toLoad.forEach(mdl => mdl.onLoad());
// Stuff to do post load // Stuff to do post load
const postLoad = () => { const postLoad = () => {
this.modules.forEach((mdl) => mdl.postLoad && mdl.postLoad(this)); this.modules.forEach(mdl => mdl.postLoad && mdl.postLoad(this));
this.set("readyLoad", 1); this.set('readyLoad', 1);
}; };
if (headless) { if (headless) {
@ -230,8 +218,8 @@ export default class EditorModel extends Model {
undoManager: false, undoManager: false,
}); });
// We only need to load a few modules // We only need to load a few modules
["PageManager", "Canvas"].forEach((key) => shallow.get(key).onLoad()); ['PageManager', 'Canvas'].forEach(key => shallow.get(key).onLoad());
this.set("shallow", shallow); this.set('shallow', shallow);
} }
/** /**
@ -240,18 +228,18 @@ export default class EditorModel extends Model {
* @private * @private
*/ */
updateChanges() { updateChanges() {
const stm = this.get("StorageManager"); const stm = this.get('StorageManager');
const changes = this.getDirtyCount(); const changes = this.getDirtyCount();
this.updateItr && clearTimeout(this.updateItr); this.updateItr && clearTimeout(this.updateItr);
//@ts-ignore //@ts-ignore
this.updateItr = setTimeout(() => this.trigger("update")); this.updateItr = setTimeout(() => this.trigger('update'));
if (this.config.noticeOnUnload) { if (this.config.noticeOnUnload) {
window.onbeforeunload = changes ? () => true : null; window.onbeforeunload = changes ? () => true : null;
} }
if (stm.isAutosave() && changes >= stm.getStepsBeforeSave()) { if (stm.isAutosave() && changes >= stm.getStepsBeforeSave()) {
this.store().catch((err) => this.logError(err)); this.store().catch(err => this.logError(err));
} }
} }
@ -266,11 +254,9 @@ export default class EditorModel extends Model {
const Module = moduleName.default || moduleName; const Module = moduleName.default || moduleName;
const Mod = new Module(); const Mod = new Module();
const name = Mod.name.charAt(0).toLowerCase() + Mod.name.slice(1); const name = Mod.name.charAt(0).toLowerCase() + Mod.name.slice(1);
const cfgParent = !isUndefined(config[name]) const cfgParent = !isUndefined(config[name]) ? config[name] : config[Mod.name];
? config[name]
: config[Mod.name];
const cfg = cfgParent === true ? {} : cfgParent || {}; const cfg = cfgParent === true ? {} : cfgParent || {};
cfg.pStylePrefix = config.pStylePrefix || ""; cfg.pStylePrefix = config.pStylePrefix || '';
if (!isUndefined(cfgParent) && !cfgParent) { if (!isUndefined(cfgParent) && !cfgParent) {
cfg._disable = 1; cfg._disable = 1;
@ -321,11 +307,11 @@ export default class EditorModel extends Model {
this.initialize(opts); this.initialize(opts);
this.destroyed = false; this.destroyed = false;
} }
this.set("Editor", editor); this.set('Editor', editor);
} }
getEditor() { getEditor() {
return this.get("Editor"); return this.get('Editor');
} }
/** /**
@ -338,13 +324,7 @@ export default class EditorModel extends Model {
* */ * */
handleUpdates(model: any, val: any, opt: any = {}) { handleUpdates(model: any, val: any, opt: any = {}) {
// Component has been added temporarily - do not update storage or record changes // Component has been added temporarily - do not update storage or record changes
if ( if (this.__skip || opt.temporary || opt.noCount || opt.avoidStore || !this.get('ready')) {
this.__skip ||
opt.temporary ||
opt.noCount ||
opt.avoidStore ||
!this.get("ready")
) {
return; return;
} }
@ -353,7 +333,7 @@ export default class EditorModel extends Model {
this.timedInterval = setTimeout(() => { this.timedInterval = setTimeout(() => {
const curr = this.getDirtyCount() || 0; const curr = this.getDirtyCount() || 0;
const { unset, ...opts } = opt; const { unset, ...opts } = opt;
this.set("changesCount", curr + 1, opts); this.set('changesCount', curr + 1, opts);
}, 0); }, 0);
} }
@ -369,9 +349,9 @@ export default class EditorModel extends Model {
* @private * @private
* */ * */
componentHovered(editor: any, component: any, options: any) { componentHovered(editor: any, component: any, options: any) {
const prev = this.previous("componentHovered"); const prev = this.previous('componentHovered');
prev && this.trigger("component:unhovered", prev, options); prev && this.trigger('component:unhovered', prev, options);
component && this.trigger("component:hovered", component, options); component && this.trigger('component:hovered', component, options);
} }
/** /**
@ -380,7 +360,7 @@ export default class EditorModel extends Model {
* @public * @public
*/ */
getSelected() { getSelected() {
return this.get("selected").lastComponent(); return this.selected.lastComponent();
} }
/** /**
@ -388,8 +368,8 @@ export default class EditorModel extends Model {
* @return {Array} * @return {Array}
* @public * @public
*/ */
getSelectedAll(): any[] { getSelectedAll() {
return this.get("selected").allComponents(); return this.selected.allComponents();
} }
/** /**
@ -402,7 +382,7 @@ export default class EditorModel extends Model {
const { event } = opts; const { event } = opts;
const ctrlKey = event && (event.ctrlKey || event.metaKey); const ctrlKey = event && (event.ctrlKey || event.metaKey);
const { shiftKey } = event || {}; const { shiftKey } = event || {};
const els = (isArray(el) ? el : [el]).map((el) => getModel(el, $)); const els = (isArray(el) ? el : [el]).map(el => getModel(el, $));
const selected = this.getSelectedAll(); const selected = this.getSelectedAll();
const mltSel = this.getConfig().multipleSelection; const mltSel = this.getConfig().multipleSelection;
let added; let added;
@ -410,20 +390,19 @@ export default class EditorModel extends Model {
// If an array is passed remove all selected // If an array is passed remove all selected
// expect those yet to be selected // expect those yet to be selected
const multiple = isArray(el); const multiple = isArray(el);
multiple && this.removeSelected(selected.filter((s) => !contains(els, s))); multiple && this.removeSelected(selected.filter(s => !contains(els, s)));
els.forEach((el) => { els.forEach(el => {
let model = getModel(el, undefined); let model = getModel(el, undefined);
if (model) { if (model) {
this.trigger("component:select:before", model, opts); this.trigger('component:select:before', model, opts);
// Check for valid selectable // Check for valid selectable
if (!model.get("selectable") || opts.abort) { if (!model.get('selectable') || opts.abort) {
if (opts.useValid) { if (opts.useValid) {
let parent = model.parent(); let parent = model.parent();
while (parent && !parent.get("selectable")) while (parent && !parent.get('selectable')) parent = parent.parent();
parent = parent.parent();
model = parent; model = parent;
} else { } else {
return; return;
@ -435,13 +414,13 @@ export default class EditorModel extends Model {
if (ctrlKey && mltSel) { if (ctrlKey && mltSel) {
return this.toggleSelected(model); return this.toggleSelected(model);
} else if (shiftKey && mltSel) { } else if (shiftKey && mltSel) {
this.clearSelection(this.get("Canvas").getWindow()); this.clearSelection(this.get('Canvas').getWindow());
const coll = model.collection; const coll = model.collection;
const index = model.index(); const index = model.index();
let min: number | undefined, max: number | undefined; let min: number | undefined, max: number | undefined;
// Fin min and max siblings // Fin min and max siblings
this.getSelectedAll().forEach((sel) => { this.getSelectedAll().forEach(sel => {
const selColl = sel.collection; const selColl = sel.collection;
const selIndex = sel.index(); const selIndex = sel.index();
if (selColl === coll) { if (selColl === coll) {
@ -472,7 +451,7 @@ export default class EditorModel extends Model {
return this.addSelected(model); return this.addSelected(model);
} }
!multiple && this.removeSelected(selected.filter((s) => s !== model)); !multiple && this.removeSelected(selected.filter(s => s !== model));
this.addSelected(model, opts); this.addSelected(model, opts);
added = model; added = model;
}); });
@ -488,12 +467,12 @@ export default class EditorModel extends Model {
const model = getModel(el, $); const model = getModel(el, $);
const models = isArray(model) ? model : [model]; const models = isArray(model) ? model : [model];
models.forEach((model) => { models.forEach(model => {
if (model && !model.get("selectable")) return; if (model && !model.get('selectable')) return;
const selected = this.get("selected"); const { selected } = this;
opts.forceChange && this.removeSelected(model, opts); opts.forceChange && this.removeSelected(model, opts);
selected.addComponent(model, opts); selected.addComponent(model, opts);
model && this.trigger("component:select", model, opts); model && this.trigger('component:select', model, opts);
}); });
} }
@ -504,7 +483,7 @@ export default class EditorModel extends Model {
* @public * @public
*/ */
removeSelected(el: any, opts = {}) { removeSelected(el: any, opts = {}) {
this.get("selected").removeComponent(getModel(el, $), opts); this.selected.removeComponent(getModel(el, $), opts);
} }
/** /**
@ -517,8 +496,8 @@ export default class EditorModel extends Model {
const model = getModel(el, $); const model = getModel(el, $);
const models = isArray(model) ? model : [model]; const models = isArray(model) ? model : [model];
models.forEach((model) => { models.forEach(model => {
if (this.get("selected").hasComponent(model)) { if (this.selected.hasComponent(model)) {
this.removeSelected(model, opts); this.removeSelected(model, opts);
} else { } else {
this.addSelected(model, opts); this.addSelected(model, opts);
@ -533,21 +512,21 @@ export default class EditorModel extends Model {
* @private * @private
*/ */
setHovered(el: any, opts: any = {}) { setHovered(el: any, opts: any = {}) {
if (!el) return this.set("componentHovered", ""); if (!el) return this.set('componentHovered', '');
const ev = "component:hover"; const ev = 'component:hover';
let model = getModel(el, undefined); let model = getModel(el, undefined);
if (!model) return; if (!model) return;
opts.forceChange && this.set("componentHovered", ""); opts.forceChange && this.set('componentHovered', '');
this.trigger(`${ev}:before`, model, opts); this.trigger(`${ev}:before`, model, opts);
// Check for valid hoverable // Check for valid hoverable
if (!model.get("hoverable")) { if (!model.get('hoverable')) {
if (opts.useValid && !opts.abort) { if (opts.useValid && !opts.abort) {
let parent = model && model.parent(); let parent = model && model.parent();
while (parent && !parent.get("hoverable")) parent = parent.parent(); while (parent && !parent.get('hoverable')) parent = parent.parent();
model = parent; model = parent;
} else { } else {
return; return;
@ -555,13 +534,13 @@ export default class EditorModel extends Model {
} }
if (!opts.abort) { if (!opts.abort) {
this.set("componentHovered", model, opts); this.set('componentHovered', model, opts);
this.trigger(ev, model, opts); this.trigger(ev, model, opts);
} }
} }
getHovered() { getHovered() {
return this.get("componentHovered"); return this.get('componentHovered');
} }
/** /**
@ -572,7 +551,7 @@ export default class EditorModel extends Model {
* @public * @public
*/ */
setComponents(components: any, opt = {}) { setComponents(components: any, opt = {}) {
return this.get("DomComponents").setComponents(components, opt); return this.get('DomComponents').setComponents(components, opt);
} }
/** /**
@ -581,13 +560,13 @@ export default class EditorModel extends Model {
* @private * @private
*/ */
getComponents() { getComponents() {
var cmp = this.get("DomComponents"); var cmp = this.get('DomComponents');
var cm = this.get("CodeManager"); var cm = this.get('CodeManager');
if (!cmp || !cm) return; if (!cmp || !cm) return;
var wrp = cmp.getComponents(); var wrp = cmp.getComponents();
return cm.getCode(wrp, "json"); return cm.getCode(wrp, 'json');
} }
/** /**
@ -598,7 +577,7 @@ export default class EditorModel extends Model {
* @public * @public
*/ */
setStyle(style: any, opt = {}) { setStyle(style: any, opt = {}) {
const cssc = this.get("CssComposer"); const cssc = this.get('CssComposer');
cssc.clear(opt); cssc.clear(opt);
cssc.getAll().add(style, opt); cssc.getAll().add(style, opt);
return this; return this;
@ -621,7 +600,7 @@ export default class EditorModel extends Model {
* @private * @private
*/ */
getStyle() { getStyle() {
return this.get("CssComposer").getAll(); return this.get('CssComposer').getAll();
} }
/** /**
@ -630,7 +609,7 @@ export default class EditorModel extends Model {
* @returns {this} * @returns {this}
*/ */
setState(value: string) { setState(value: string) {
this.set("state", value); this.set('state', value);
return this; return this;
} }
@ -639,7 +618,7 @@ export default class EditorModel extends Model {
* @returns {String} * @returns {String}
*/ */
getState() { getState() {
return this.get("state") || ""; return this.get('state') || '';
} }
/** /**
@ -651,15 +630,15 @@ export default class EditorModel extends Model {
getHtml(opts: any = {}) { getHtml(opts: any = {}) {
const { config } = this; const { config } = this;
const { optsHtml } = config; const { optsHtml } = config;
const js = config.jsInHtml ? this.getJs(opts) : ""; const js = config.jsInHtml ? this.getJs(opts) : '';
const cmp = opts.component || this.get("DomComponents").getComponent(); const cmp = opts.component || this.get('DomComponents').getComponent();
let html = cmp let html = cmp
? this.get("CodeManager").getCode(cmp, "html", { ? this.get('CodeManager').getCode(cmp, 'html', {
...optsHtml, ...optsHtml,
...opts, ...opts,
}) })
: ""; : '';
html += js ? `<script>${js}</script>` : ""; html += js ? `<script>${js}</script>` : '';
return html; return html;
} }
@ -673,21 +652,19 @@ export default class EditorModel extends Model {
const config = this.config; const config = this.config;
const { optsCss } = config; const { optsCss } = config;
const avoidProt = opts.avoidProtected; const avoidProt = opts.avoidProtected;
const keepUnusedStyles = !isUndefined(opts.keepUnusedStyles) const keepUnusedStyles = !isUndefined(opts.keepUnusedStyles) ? opts.keepUnusedStyles : config.keepUnusedStyles;
? opts.keepUnusedStyles const cssc = this.get('CssComposer');
: config.keepUnusedStyles; const wrp = opts.component || this.get('DomComponents').getComponent();
const cssc = this.get("CssComposer"); const protCss = !avoidProt ? config.protectedCss : '';
const wrp = opts.component || this.get("DomComponents").getComponent();
const protCss = !avoidProt ? config.protectedCss : "";
const css = const css =
wrp && wrp &&
this.get("CodeManager").getCode(wrp, "css", { this.get('CodeManager').getCode(wrp, 'css', {
cssc, cssc,
keepUnusedStyles, keepUnusedStyles,
...optsCss, ...optsCss,
...opts, ...opts,
}); });
return wrp ? (opts.json ? css : protCss + css) : ""; return wrp ? (opts.json ? css : protCss + css) : '';
} }
/** /**
@ -696,8 +673,8 @@ export default class EditorModel extends Model {
* @public * @public
*/ */
getJs(opts: any = {}) { getJs(opts: any = {}) {
var wrp = opts.component || this.get("DomComponents").getWrapper(); var wrp = opts.component || this.get('DomComponents').getWrapper();
return wrp ? this.get("CodeManager").getCode(wrp, "js").trim() : ""; return wrp ? this.get('CodeManager').getCode(wrp, 'js').trim() : '';
} }
/** /**
@ -706,7 +683,7 @@ export default class EditorModel extends Model {
*/ */
async store(options?: any) { async store(options?: any) {
const data = this.storeData(); const data = this.storeData();
await this.get("StorageManager").store(data, options); await this.get('StorageManager').store(data, options);
this.clearDirtyCount(); this.clearDirtyCount();
return data; return data;
} }
@ -716,7 +693,7 @@ export default class EditorModel extends Model {
* @public * @public
*/ */
async load(options?: any) { async load(options?: any) {
const result = await this.get("StorageManager").load(options); const result = await this.get('StorageManager').load(options);
this.loadData(result); this.loadData(result);
return result; return result;
} }
@ -725,9 +702,9 @@ export default class EditorModel extends Model {
let result = {}; let result = {};
// Sync content if there is an active RTE // Sync content if there is an active RTE
const editingCmp = this.getEditing(); const editingCmp = this.getEditing();
editingCmp && editingCmp.trigger("sync:content", { noCount: true }); editingCmp && editingCmp.trigger('sync:content', { noCount: true });
this.storables.forEach((m) => { this.storables.forEach(m => {
result = { ...result, ...m.store(1) }; result = { ...result, ...m.store(1) };
}); });
return JSON.parse(JSON.stringify(result)); return JSON.parse(JSON.stringify(result));
@ -735,8 +712,8 @@ export default class EditorModel extends Model {
loadData(data = {}) { loadData(data = {}) {
if (!isEmptyObj(data)) { if (!isEmptyObj(data)) {
this.storables.forEach((module) => module.clear()); this.storables.forEach(module => module.clear());
this.storables.forEach((module) => module.load(data)); this.storables.forEach(module => module.load(data));
} }
return data; return data;
} }
@ -747,8 +724,8 @@ export default class EditorModel extends Model {
* @private * @private
*/ */
getDeviceModel() { getDeviceModel() {
var name = this.get("device"); var name = this.get('device');
return this.get("DeviceManager").get(name); return this.get('DeviceManager').get(name);
} }
/** /**
@ -757,7 +734,7 @@ export default class EditorModel extends Model {
* @private * @private
*/ */
runDefault(opts = {}) { runDefault(opts = {}) {
var command = this.get("Commands").get(this.config.defaultCommand); var command = this.get('Commands').get(this.config.defaultCommand);
if (!command || this.defaultRunning) return; if (!command || this.defaultRunning) return;
command.stop(this, this, opts); command.stop(this, this, opts);
command.run(this, this, opts); command.run(this, this, opts);
@ -770,7 +747,7 @@ export default class EditorModel extends Model {
* @private * @private
*/ */
stopDefault(opts = {}) { stopDefault(opts = {}) {
const commands = this.get("Commands"); const commands = this.get('Commands');
const command = commands.get(this.config.defaultCommand); const command = commands.get(this.config.defaultCommand);
if (!command || !this.defaultRunning) return; if (!command || !this.defaultRunning) return;
command.stop(this, this, opts); command.stop(this, this, opts);
@ -782,9 +759,9 @@ export default class EditorModel extends Model {
* @public * @public
*/ */
refreshCanvas(opts: any = {}) { refreshCanvas(opts: any = {}) {
this.set("canvasOffset", null); this.set('canvasOffset', null);
this.set("canvasOffset", this.get("Canvas").getOffset()); this.set('canvasOffset', this.get('Canvas').getOffset());
opts.tools && this.trigger("canvas:updateTools"); opts.tools && this.trigger('canvas:updateTools');
} }
/** /**
@ -807,8 +784,8 @@ export default class EditorModel extends Model {
const device = this.getDeviceModel(); const device = this.getDeviceModel();
const condition = config.mediaCondition; const condition = config.mediaCondition;
const preview = config.devicePreviewMode; const preview = config.devicePreviewMode;
const width = device && device.get("widthMedia"); const width = device && device.get('widthMedia');
return device && width && !preview ? `(${condition}: ${width})` : ""; return device && width && !preview ? `(${condition}: ${width})` : '';
} }
/** /**
@ -816,15 +793,15 @@ export default class EditorModel extends Model {
* @return {Component} * @return {Component}
*/ */
getWrapper() { getWrapper() {
return this.get("DomComponents").getWrapper(); return this.get('DomComponents').getWrapper();
} }
setCurrentFrame(frameView: FrameView) { setCurrentFrame(frameView: FrameView) {
return this.set("currentFrame", frameView); return this.set('currentFrame', frameView);
} }
getCurrentFrame(): FrameView { getCurrentFrame(): FrameView {
return this.get("currentFrame"); return this.get('currentFrame');
} }
getCurrentFrameModel() { getCurrentFrameModel() {
@ -833,7 +810,7 @@ export default class EditorModel extends Model {
getIcon(icon: string) { getIcon(icon: string) {
const icons = this.config.icons || {}; const icons = this.config.icons || {};
return icons[icon] || ""; return icons[icon] || '';
} }
/** /**
@ -842,27 +819,27 @@ export default class EditorModel extends Model {
* @return {number} * @return {number}
*/ */
getDirtyCount(): number { getDirtyCount(): number {
return this.get("changesCount"); return this.get('changesCount');
} }
clearDirtyCount() { clearDirtyCount() {
return this.set("changesCount", 0); return this.set('changesCount', 0);
} }
getZoomDecimal() { getZoomDecimal() {
return this.get("Canvas").getZoomDecimal(); return this.get('Canvas').getZoomDecimal();
} }
getZoomMultiplier() { getZoomMultiplier() {
return this.get("Canvas").getZoomMultiplier(); return this.get('Canvas').getZoomMultiplier();
} }
setDragMode(value: string) { setDragMode(value: string) {
return this.set("dmode", value); return this.set('dmode', value);
} }
t(...args: any[]) { t(...args: any[]) {
const i18n = this.get("I18n"); const i18n = this.get('I18n');
return i18n?.t(...args); return i18n?.t(...args);
} }
@ -871,7 +848,7 @@ export default class EditorModel extends Model {
* @returns {Boolean} * @returns {Boolean}
*/ */
inAbsoluteMode() { inAbsoluteMode() {
return this.get("dmode") === "absolute"; return this.get('dmode') === 'absolute';
} }
/** /**
@ -881,20 +858,20 @@ export default class EditorModel extends Model {
const { config, view } = this; const { config, view } = this;
const editor = this.getEditor(); const editor = this.getEditor();
const { editors = [] } = config.grapesjs || {}; const { editors = [] } = config.grapesjs || {};
const shallow = this.get("shallow"); const shallow = this.get('shallow');
shallow?.destroyAll(); shallow?.destroyAll();
this.stopListening(); this.stopListening();
this.stopDefault(); this.stopDefault();
this.modules this.modules
.slice() .slice()
.reverse() .reverse()
.forEach((mod) => mod.destroy()); .forEach(mod => mod.destroy());
view && view.remove(); view && view.remove();
this.clear({ silent: true }); this.clear({ silent: true });
this.destroyed = true; this.destroyed = true;
["_config", "view", "_previousAttributes", "_events", "_listeners"].forEach( ['_config', 'view', '_previousAttributes', '_events', '_listeners'].forEach(
//@ts-ignore //@ts-ignore
(i) => (this[i] = {}) i => (this[i] = {})
); );
editors.splice(editors.indexOf(editor), 1); editors.splice(editors.indexOf(editor), 1);
//@ts-ignore //@ts-ignore
@ -902,22 +879,22 @@ export default class EditorModel extends Model {
} }
getEditing() { getEditing() {
const res = this.get("editing"); const res = this.get('editing');
return (res && res.model) || null; return (res && res.model) || null;
} }
setEditing(value: boolean) { setEditing(value: boolean) {
this.set("editing", value); this.set('editing', value);
return this; return this;
} }
isEditing() { isEditing() {
return !!this.get("editing"); return !!this.get('editing');
} }
log(msg: string, opts: any = {}) { log(msg: string, opts: any = {}) {
const { ns, level = "debug" } = opts; const { ns, level = 'debug' } = opts;
this.trigger("log", msg, opts); this.trigger('log', msg, opts);
level && this.trigger(`log:${level}`, msg, opts); level && this.trigger(`log:${level}`, msg, opts);
if (ns) { if (ns) {
@ -928,15 +905,15 @@ export default class EditorModel extends Model {
} }
logInfo(msg: string, opts?: any) { logInfo(msg: string, opts?: any) {
this.log(msg, { ...opts, level: "info" }); this.log(msg, { ...opts, level: 'info' });
} }
logWarning(msg: string, opts?: any) { logWarning(msg: string, opts?: any) {
this.log(msg, { ...opts, level: "warning" }); this.log(msg, { ...opts, level: 'warning' });
} }
logError(msg: string, opts?: any) { logError(msg: string, opts?: any) {
this.log(msg, { ...opts, level: "error" }); this.log(msg, { ...opts, level: 'error' });
} }
initBaseColorPicker(el: any, opts = {}) { initBaseColorPicker(el: any, opts = {}) {
@ -948,13 +925,13 @@ export default class EditorModel extends Model {
//@ts-ignore //@ts-ignore
return $(el).spectrum({ return $(el).spectrum({
containerClassName: `${ppfx}one-bg ${ppfx}two-color`, containerClassName: `${ppfx}one-bg ${ppfx}two-color`,
appendTo: elToAppend || "body", appendTo: elToAppend || 'body',
maxSelectionSize: 8, maxSelectionSize: 8,
showPalette: true, showPalette: true,
palette: [], palette: [],
showAlpha: true, showAlpha: true,
chooseText: "Ok", chooseText: 'Ok',
cancelText: "⨯", cancelText: '⨯',
...opts, ...opts,
...colorPicker, ...colorPicker,
}); });
@ -967,7 +944,7 @@ export default class EditorModel extends Model {
*/ */
skip(clb: Function) { skip(clb: Function) {
this.__skip = true; this.__skip = true;
const um = this.get("UndoManager"); const um = this.get('UndoManager');
um ? um.skip(clb) : clb(); um ? um.skip(clb) : clb();
this.__skip = false; this.__skip = false;
} }
@ -981,7 +958,7 @@ export default class EditorModel extends Model {
* @private * @private
*/ */
data(el: any, name: string, value: any) { data(el: any, name: string, value: any) {
const varName = "_gjs-data"; const varName = '_gjs-data';
if (!el[varName]) { if (!el[varName]) {
el[varName] = {}; el[varName] = {};

6
src/editor/model/Selected.ts

@ -1,6 +1,6 @@
import { isArray } from 'underscore'; import { isArray } from 'underscore';
import { Collection, Model } from '../../common'; import { Collection, Model } from '../../common';
import { Component } from '../../dom_components/model/Component'; import Component from '../../dom_components/model/Component';
export class Selectable extends Model {} export class Selectable extends Model {}
@ -16,7 +16,7 @@ export default class Selected extends Collection<Selectable> {
return this.push(toAdd, opts); return this.push(toAdd, opts);
} }
getComponent(model: Selectable) { getComponent(model: Selectable): Component {
return model.get('component'); return model.get('component');
} }
@ -34,7 +34,7 @@ export default class Selected extends Collection<Selectable> {
return this.map(s => this.getComponent(s)).filter(i => i); return this.map(s => this.getComponent(s)).filter(i => i);
} }
removeComponent(component: Component, opts: any) { removeComponent(component: Component | Component[], opts: any) {
const toRemove = (isArray(component) ? component : [component]).map(c => this.getByComponent(c)); const toRemove = (isArray(component) ? component : [component]).map(c => this.getByComponent(c));
return this.remove(toRemove, opts); return this.remove(toRemove, opts);
} }

7
src/selector_manager/config/config.js → src/selector_manager/config/config.ts

@ -23,8 +23,7 @@ export default {
selectedName: 0, selectedName: 0,
// Icon used to add new selector // Icon used to add new selector
iconAdd: iconAdd: '<svg viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"></path></svg>',
'<svg viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"></path></svg>',
// Icon used to sync styles // Icon used to sync styles
iconSync: iconSync:
@ -98,8 +97,8 @@ export default {
// With this option enabled, also in the second case, the Component will be passed. // With this option enabled, also in the second case, the Component will be passed.
// This method allows to avoid styling classes directly and make, for example, some // This method allows to avoid styling classes directly and make, for example, some
// unintended changes below the visible canvas area (when components share same classes) // unintended changes below the visible canvas area (when components share same classes)
componentFirst: 0, componentFirst: false,
// Avoid rendering the default Selector Manager UI. // Avoid rendering the default Selector Manager UI.
custom: false custom: false,
}; };

104
src/selector_manager/index.ts

@ -72,21 +72,22 @@
* @module SelectorManager * @module SelectorManager
*/ */
import { isString, debounce, isObject, isArray } from "underscore"; import { isString, debounce, isObject, isArray } from 'underscore';
import { isComponent, isRule } from "../utils/mixins"; import { isComponent, isRule } from '../utils/mixins';
import Module from "../abstract/moduleLegacy"; import Module from '../abstract/moduleLegacy';
import { Model, Collection } from "../common"; import { Model, Collection } from '../common';
import defaults from "./config/config"; import defaults from './config/config';
import Selector from "./model/Selector"; import Selector from './model/Selector';
import Selectors from "./model/Selectors"; import Selectors from './model/Selectors';
import State from "./model/State"; import State from './model/State';
import ClassTagsView from "./view/ClassTagsView"; import ClassTagsView from './view/ClassTagsView';
import EditorModel from "../editor/model/Editor"; import EditorModel from '../editor/model/Editor';
import Component from '../dom_components/model/Component';
const isId = (str: string) => isString(str) && str[0] == "#";
const isClass = (str: string) => isString(str) && str[0] == "."; const isId = (str: string) => isString(str) && str[0] == '#';
const isClass = (str: string) => isString(str) && str[0] == '.';
export const evAll = "selector";
export const evAll = 'selector';
export const evPfx = `${evAll}:`; export const evPfx = `${evAll}:`;
export const evAdd = `${evPfx}add`; export const evAdd = `${evPfx}add`;
export const evUpdate = `${evPfx}update`; export const evUpdate = `${evPfx}update`;
@ -96,14 +97,14 @@ export const evCustom = `${evPfx}custom`;
export const evState = `${evPfx}state`; export const evState = `${evPfx}state`;
export default class SelectorManager extends Module { export default class SelectorManager extends Module {
name = "SelectorManager"; name = 'SelectorManager';
Selector = Selector; Selector = Selector;
Selectors = Selectors; Selectors = Selectors;
model!: Model; model!: Model;
states!: Collection; states!: Collection<State>;
selectorTags?: ClassTagsView; selectorTags?: ClassTagsView;
selected!: Selectors; selected!: Selectors;
em!: EditorModel; em!: EditorModel;
@ -139,8 +140,8 @@ export default class SelectorManager extends Module {
// Global selectors container // Global selectors container
this.all = new Selectors(config.selectors); this.all = new Selectors(config.selectors);
this.selected = new Selectors([], { em, config }); this.selected = new Selectors([], { em, config });
this.states = new Collection( this.states = new Collection<State>(
config.states.map((state) => new State(state)), config.states.map(state => new State(state)),
{ model: State } { model: State }
); );
this.model = new Model({ cFirst: config.componentFirst, _undo: true }); this.model = new Model({ cFirst: config.componentFirst, _undo: true });
@ -148,12 +149,10 @@ export default class SelectorManager extends Module {
collections: [this.states, this.selected], collections: [this.states, this.selected],
propagate: [{ entity: this.states, event: this.events.state }], propagate: [{ entity: this.states, event: this.events.state }],
}); });
em.on("change:state", (m, value) => em.trigger(evState, value)); em.on('change:state', (m, value) => em.trigger(evState, value));
this.model.on("change:cFirst", (m, value) => this.model.on('change:cFirst', (m, value) => em.trigger('selector:type', value));
em.trigger("selector:type", value)
);
const listenTo = const listenTo =
"component:toggled component:update:classes change:device styleManager:update selector:state selector:type"; 'component:toggled component:update:classes change:device styleManager:update selector:state selector:type';
this.model.listenTo(em, listenTo, () => this.__update()); this.model.listenTo(em, listenTo, () => this.__update());
return this; return this;
@ -191,26 +190,16 @@ export default class SelectorManager extends Module {
select(value: any, opts = {}) { select(value: any, opts = {}) {
const targets = Array.isArray(value) ? value : [value]; const targets = Array.isArray(value) ? value : [value];
const toSelect: any[] = this.em.get("StyleManager").select(targets, opts); const toSelect: any[] = this.em.get('StyleManager').select(targets, opts);
const selTags = this.selectorTags; const selTags = this.selectorTags;
const res = toSelect const res = toSelect
.filter((i) => i) .filter(i => i)
.map((sel) => .map(sel => (isComponent(sel) ? sel : isRule(sel) && !sel.get('selectorsAdd') ? sel : sel.getSelectorsString()));
isComponent(sel)
? sel
: isRule(sel) && !sel.get("selectorsAdd")
? sel
: sel.getSelectorsString()
);
selTags && selTags.componentChanged({ targets: res }); selTags && selTags.componentChanged({ targets: res });
return this; return this;
} }
addSelector( addSelector(name: string | { name?: string; label?: string }, opts = {}, cOpts = {}): Selector {
name: string | { name: string; label?: string },
opts = {},
cOpts = {}
): Selector {
let props: any = { ...opts }; let props: any = { ...opts };
if (isObject(name)) { if (isObject(name)) {
@ -267,11 +256,11 @@ export default class SelectorManager extends Module {
* const selector = selectorManager.add('.my-class'); * const selector = selectorManager.add('.my-class');
* console.log(selector.toString()) // `.my-class` * console.log(selector.toString()) // `.my-class`
* */ * */
add(props: string | { name: string; label?: string }, opts = {}) { add(props: string | { name?: string; label?: string }, opts = {}) {
const cOpts = isString(props) ? {} : opts; const cOpts = isString(props) ? {} : opts;
// Keep support for arrays but avoid it in docs // Keep support for arrays but avoid it in docs
if (isArray(props)) { if (isArray(props)) {
return props.map((item) => this.addSelector(item, opts, cOpts)); return props.map(item => this.addSelector(item, opts, cOpts));
} else { } else {
return this.addSelector(props, opts, cOpts); return this.addSelector(props, opts, cOpts);
} }
@ -292,10 +281,10 @@ export default class SelectorManager extends Module {
const added: any = []; const added: any = [];
if (isString(classes)) { if (isString(classes)) {
classes = classes.trim().split(" "); classes = classes.trim().split(' ');
} }
classes.forEach((name) => added.push(this.addSelector(name))); classes.forEach(name => added.push(this.addSelector(name)));
return added; return added;
} }
@ -312,12 +301,8 @@ export default class SelectorManager extends Module {
// Keep support for arrays but avoid it in docs // Keep support for arrays but avoid it in docs
if (isArray(name)) { if (isArray(name)) {
const result: Selector[] = []; const result: Selector[] = [];
const selectors = name const selectors = name.map(item => this.getSelector(item)).filter(item => item);
.map((item) => this.getSelector(item)) selectors.forEach(item => result.indexOf(item) < 0 && result.push(item));
.filter((item) => item);
selectors.forEach(
(item) => result.indexOf(item) < 0 && result.push(item)
);
return result; return result;
} else { } else {
return this.getSelector(name, type) || null; return this.getSelector(name, type) || null;
@ -377,7 +362,7 @@ export default class SelectorManager extends Module {
*/ */
setStates(states: State[], opts?: any) { setStates(states: State[], opts?: any) {
return this.states.reset( return this.states.reset(
states.map((state) => new State(state)), states.map(state => new State(state)),
opts opts
); );
} }
@ -399,10 +384,10 @@ export default class SelectorManager extends Module {
* @example * @example
* selectorManager.addSelected('.new-class'); * selectorManager.addSelected('.new-class');
*/ */
addSelected(props: string) { addSelected(props: string | { name?: string; label?: string }) {
const added = this.add(props); const added = this.add(props);
// TODO: target should be the one from StyleManager // TODO: target should be the one from StyleManager
this.em.getSelectedAll().forEach((target) => { this.em.getSelectedAll().forEach(target => {
target.getSelectors().add(added); target.getSelectors().add(added);
}); });
// TODO: update selected collection // TODO: update selected collection
@ -415,8 +400,8 @@ export default class SelectorManager extends Module {
* selectorManager.removeSelected('.myclass'); * selectorManager.removeSelected('.myclass');
*/ */
removeSelected(selector: any) { removeSelected(selector: any) {
this.em.getSelectedAll().forEach((trg) => { this.em.getSelectedAll().forEach(trg => {
!selector.get("protected") && trg && trg.getSelectors().remove(selector); !selector.get('protected') && trg && trg.getSelectors().remove(selector);
}); });
} }
@ -428,7 +413,7 @@ export default class SelectorManager extends Module {
* console.log(targetsToStyle.map(target => target.getSelectorsString())) * console.log(targetsToStyle.map(target => target.getSelectorsString()))
*/ */
getSelectedTargets() { getSelectedTargets() {
return this.em.get("StyleManager").getSelectedAll(); return this.em.get('StyleManager').getSelectedAll();
} }
/** /**
@ -507,18 +492,15 @@ export default class SelectorManager extends Module {
return this.__getCommonSelectors(this.em.getSelectedAll()); return this.__getCommonSelectors(this.em.getSelectedAll());
} }
__getCommonSelectors(components: any[], opts = {}) { __getCommonSelectors(components: Component[], opts = {}) {
const selectors = components const selectors = components.map(cmp => cmp.getSelectors && cmp.getSelectors().getValid(opts)).filter(Boolean);
.map((cmp) => cmp.getSelectors && cmp.getSelectors().getValid(opts))
.filter(Boolean);
return this.__common(...selectors); return this.__common(...selectors);
} }
__common(...args: any) { __common(...args: any): Selector[] {
if (!args.length) return []; if (!args.length) return [];
if (args.length === 1) return args[0]; if (args.length === 1) return args[0];
if (args.length === 2) if (args.length === 2) return args[0].filter((item: any) => args[1].indexOf(item) >= 0);
return args[0].filter((item: any) => args[1].indexOf(item) >= 0);
return ( return (
args args

93
src/selector_manager/view/ClassTagsView.js → src/selector_manager/view/ClassTagsView.ts

@ -2,9 +2,15 @@ import { isEmpty, isArray, isString, debounce } from 'underscore';
import { View } from '../../common'; import { View } from '../../common';
import ClassTagView from './ClassTagView'; import ClassTagView from './ClassTagView';
import html from 'utils/html'; import html from 'utils/html';
import EditorModel from '../../editor/model/Editor';
export default class ClassTagsView extends View { import SelectorManager from '..';
template({ labelInfo, labelHead, iconSync, iconAdd, pfx, ppfx }) { import State from '../model/State';
import Component from '../../dom_components/model/Component';
import Selector from '../model/Selector';
import Selectors from '../model/Selectors';
export default class ClassTagsView extends View<Selector> {
template({ labelInfo, labelHead, iconSync, iconAdd, pfx, ppfx }: any) {
return ` return `
<div id="${pfx}up" class="${pfx}header"> <div id="${pfx}up" class="${pfx}header">
<div id="${pfx}label" class="${pfx}header-label">${labelHead}</div> <div id="${pfx}label" class="${pfx}header-label">${labelHead}</div>
@ -47,7 +53,25 @@ export default class ClassTagsView extends View {
}; };
} }
initialize(o = {}) { $input?: JQuery<HTMLElement>;
$addBtn?: JQuery<HTMLElement>;
$classes?: JQuery<HTMLElement>;
$btnSyncEl?: JQuery<HTMLElement>;
$states?: JQuery<HTMLElement>;
$statesC?: JQuery<HTMLElement>;
em: EditorModel;
target: EditorModel;
module: SelectorManager;
pfx: string;
ppfx: string;
stateInputId: string;
stateInputC: string;
config: any;
states: State[];
constructor(o: any = {}) {
super(o);
this.config = o.config || {}; this.config = o.config || {};
this.pfx = this.config.stylePrefix || ''; this.pfx = this.config.stylePrefix || '';
this.ppfx = this.config.pStylePrefix || ''; this.ppfx = this.config.pStylePrefix || '';
@ -57,12 +81,12 @@ export default class ClassTagsView extends View {
this.states = this.config.states || []; this.states = this.config.states || [];
const { em } = this.config; const { em } = this.config;
const coll = this.collection; const coll = this.collection;
this.target = this.config.em; this.target = em;
const md = o.module; const md = em.get('SelectorManager');
this.module = md; this.module = md;
this.em = em; this.em = em;
this.componentChanged = debounce(this.componentChanged.bind(this)); this.componentChanged = debounce(this.componentChanged.bind(this), 0);
this.checkSync = debounce(this.checkSync.bind(this)); this.checkSync = debounce(this.checkSync.bind(this), 0);
const toList = 'component:toggled component:update:classes'; const toList = 'component:toggled component:update:classes';
const toListCls = 'component:update:classes change:state'; const toListCls = 'component:update:classes change:state';
this.listenTo(em, toList, this.componentChanged); this.listenTo(em, toList, this.componentChanged);
@ -75,7 +99,7 @@ export default class ClassTagsView extends View {
this.listenTo( this.listenTo(
md.getAll(), md.getAll(),
md.events.state, md.events.state,
debounce(() => this.renderStates()) debounce(() => this.renderStates(), 0)
); );
this.delegateEvents(); this.delegateEvents();
} }
@ -88,7 +112,7 @@ export default class ClassTagsView extends View {
const selectors = this.getCommonSelectors({ opts }); const selectors = this.getCommonSelectors({ opts });
const state = em.get('state'); const state = em.get('state');
const mediaText = em.getCurrentMedia(); const mediaText = em.getCurrentMedia();
const ruleComponents = []; const ruleComponents: CSSRule[] = [];
const rule = cssC.get(selectors, state, mediaText) || cssC.add(selectors, state, mediaText); const rule = cssC.get(selectors, state, mediaText) || cssC.add(selectors, state, mediaText);
let style; let style;
@ -119,7 +143,7 @@ export default class ClassTagsView extends View {
* @param {Object} model Removed model * @param {Object} model Removed model
* @private * @private
*/ */
tagRemoved(model) { tagRemoved(model?: State) {
this.updateStateVis(); this.updateStateVis();
} }
@ -128,7 +152,7 @@ export default class ClassTagsView extends View {
* @param {Object} model * @param {Object} model
* @private * @private
*/ */
addNew(model) { addNew(model: State) {
this.addToClasses(model); this.addToClasses(model);
} }
@ -138,8 +162,8 @@ export default class ClassTagsView extends View {
* @private * @private
*/ */
startNewTag() { startNewTag() {
this.$addBtn.css({ display: 'none' }); this.$addBtn?.css({ display: 'none' });
this.$input.show().focus(); this.$input?.show().focus();
} }
/** /**
@ -148,8 +172,8 @@ export default class ClassTagsView extends View {
* @private * @private
*/ */
endNewTag() { endNewTag() {
this.$addBtn.css({ display: '' }); this.$addBtn?.css({ display: '' });
this.$input.hide().val(''); this.$input?.hide().val('');
} }
/** /**
@ -157,10 +181,10 @@ export default class ClassTagsView extends View {
* @param {Object} e * @param {Object} e
* @private * @private
*/ */
onInputKeyUp(e) { onInputKeyUp(e: KeyboardEvent) {
if (e.keyCode === 13) { if (e.keyCode === 13) {
e.preventDefault(); e.preventDefault();
this.addNewTag(this.$input.val()); this.addNewTag(this.$input?.val());
} else if (e.keyCode === 27) { } else if (e.keyCode === 27) {
this.endNewTag(); this.endNewTag();
} }
@ -177,17 +201,18 @@ export default class ClassTagsView extends View {
* @param {Object} e * @param {Object} e
* @public * @public
*/ */
componentChanged({ targets } = {}) { componentChanged({ targets }: any = {}) {
this.updateSelection(targets); this.updateSelection(targets);
} }
updateSelection(targets) { updateSelection(targets: Component | Component[]) {
let trgs = targets || this.getTargets(); let trgs = targets || this.getTargets();
trgs = isArray(trgs) ? trgs : [trgs]; trgs = isArray(trgs) ? trgs : [trgs];
let selectors = []; let selectors: Selector[] = [];
if (trgs && trgs.length) { if (trgs && trgs.length) {
selectors = this.getCommonSelectors({ targets: trgs }); selectors = this.getCommonSelectors({ targets: trgs });
//@ts-ignore TODO This parameters are not in use why do we have them?
this.checkSync({ validSelectors: selectors }); this.checkSync({ validSelectors: selectors });
} }
@ -197,12 +222,12 @@ export default class ClassTagsView extends View {
return selectors; return selectors;
} }
getCommonSelectors({ targets, opts = {} } = {}) { getCommonSelectors({ targets, opts = {} }: any = {}) {
const trgs = targets || this.getTargets(); const trgs = targets || this.getTargets();
return this.module.__getCommonSelectors(trgs, opts); return this.module.__getCommonSelectors(trgs, opts);
} }
_commonSelectors(...args) { _commonSelectors(...args: any) {
return this.module.__common(...args); return this.module.__common(...args);
} }
@ -232,12 +257,12 @@ export default class ClassTagsView extends View {
* inside collection * inside collection
* @private * @private
*/ */
updateStateVis(target) { updateStateVis(targets?: Component[] | Component) {
const em = this.em; const em = this.em;
const avoidInline = em && em.getConfig().avoidInlineStyle; const avoidInline = em && em.getConfig().avoidInlineStyle;
const display = this.collection.length || avoidInline ? '' : 'none'; const display = this.collection.length || avoidInline ? '' : 'none';
this.getStatesC().css('display', display); this.getStatesC().css('display', display);
this.updateSelector(target); this.updateSelector(targets);
} }
__handleStateChange() { __handleStateChange() {
@ -249,9 +274,9 @@ export default class ClassTagsView extends View {
* @return {this} * @return {this}
* @private * @private
*/ */
updateSelector(targets) { updateSelector(targets?: Component[] | Component) {
const elSel = this.el.querySelector('[data-selected]'); const elSel = this.el.querySelector('[data-selected]');
const result = []; const result: string[] = [];
let trgs = targets || this.getTargets(); let trgs = targets || this.getTargets();
trgs = isArray(trgs) ? trgs : [trgs]; trgs = isArray(trgs) ? trgs : [trgs];
@ -260,7 +285,7 @@ export default class ClassTagsView extends View {
this.checkStates(); this.checkStates();
} }
__getName(target) { __getName(target: Component): string {
const { pfx, config, em } = this; const { pfx, config, em } = this;
const { selectedName, componentFirst } = config; const { selectedName, componentFirst } = config;
let result; let result;
@ -268,15 +293,15 @@ export default class ClassTagsView extends View {
if (isString(target)) { if (isString(target)) {
result = html`<span class="${pfx}sel-gen">${target}</span>`; result = html`<span class="${pfx}sel-gen">${target}</span>`;
} else { } else {
const sel = target && target.get && target.getSelectors(); const sel = target?.getSelectors();
if (!sel) return; if (!sel) return '';
const selectors = sel.getStyleable(); const selectors = sel.getStyleable();
const state = em.get('state'); const state = em.get('state');
const idRes = target.getId const idRes = target.getId
? html`<span class="${pfx}sel-cmp">${target.getName()}</span> ? html`<span class="${pfx}sel-cmp">${target.getName()}</span>
<span class="${pfx}sel-id">#${target.getId()}</span>` <span class="${pfx}sel-id">#${target.getId()}</span>`
: ''; : '';
result = this.collection.getFullString(selectors); result = (this.collection as Selectors).getFullString(selectors);
result = result ? html`<span class="${pfx}sel-rule">${result}</span>` : target.get('selectorsAdd') || idRes; result = result ? html`<span class="${pfx}sel-rule">${result}</span>` : target.get('selectorsAdd') || idRes;
result = componentFirst && idRes ? idRes : result; result = componentFirst && idRes ? idRes : result;
result += state ? html`<span class="${pfx}sel-state">:${state}</span>` : ''; result += state ? html`<span class="${pfx}sel-state">:${state}</span>` : '';
@ -291,7 +316,7 @@ export default class ClassTagsView extends View {
* @param {Object} e * @param {Object} e
* @private * @private
*/ */
stateChanged(ev) { stateChanged(ev: any) {
const { em } = this; const { em } = this;
const { value } = ev.target; const { value } = ev.target;
em.set('state', value); em.set('state', value);
@ -302,7 +327,7 @@ export default class ClassTagsView extends View {
* @param {Object} e * @param {Object} e
* @private * @private
*/ */
addNewTag(value) { addNewTag(value: any) {
const label = value.trim(); const label = value.trim();
if (!label) return; if (!label) return;
this.module.addSelected({ label }); this.module.addSelected({ label });
@ -317,7 +342,7 @@ export default class ClassTagsView extends View {
* @return {Object} Object created * @return {Object} Object created
* @private * @private
* */ * */
addToClasses(model, fragmentEl = null) { addToClasses(model: State, fragmentEl?: DocumentFragment) {
const fragment = fragmentEl; const fragment = fragmentEl;
const classes = this.getClasses(); const classes = this.getClasses();
const rendered = new ClassTagView({ const rendered = new ClassTagView({
Loading…
Cancel
Save