From cb16cd6fa1423674857b0f305228f4349cb2e42a Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 3 May 2022 21:30:48 +0200 Subject: [PATCH] Convert SelectorManager to ts --- src/editor/model/Editor.ts | 394 +++++++++++--------- src/selector_manager/{index.js => index.ts} | 155 +++++--- src/selector_manager/view/ClassTagsView.js | 2 +- 3 files changed, 305 insertions(+), 246 deletions(-) rename src/selector_manager/{index.js => index.ts} (77%) diff --git a/src/editor/model/Editor.ts b/src/editor/model/Editor.ts index f0806b0fd..728412349 100644 --- a/src/editor/model/Editor.ts +++ b/src/editor/model/Editor.ts @@ -1,45 +1,51 @@ -import { isUndefined, isArray, contains, toArray, keys, bindAll } from 'underscore'; -import Backbone from 'backbone'; -import $ from '../../utils/cash-dom'; -import Extender from '../../utils/extender'; -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'; +import { + isUndefined, + isArray, + contains, + toArray, + keys, + bindAll, +} from "underscore"; +import Backbone from "backbone"; +import $ from "../../utils/cash-dom"; +import Extender from "../../utils/extender"; +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 Backbone.$ = $; const deps = [ - require('utils'), - require('i18n'), - require('keymaps'), - require('undo_manager'), - require('storage_manager'), - require('device_manager'), - require('parser'), - require('style_manager'), - require('selector_manager'), - require('modal_dialog'), - require('code_manager'), - require('panels'), - require('rich_text_editor'), - require('asset_manager'), - require('css_composer'), - require('pages'), - require('trait_manager'), - require('dom_components'), - require('navigator'), - require('canvas'), - require('commands'), - require('block_manager'), + require("utils"), + require("i18n"), + require("keymaps"), + require("undo_manager"), + require("storage_manager"), + require("device_manager"), + require("parser"), + require("style_manager"), + require("selector_manager"), + require("modal_dialog"), + require("code_manager"), + require("panels"), + require("rich_text_editor"), + require("asset_manager"), + require("css_composer"), + require("pages"), + require("trait_manager"), + require("dom_components"), + require("navigator"), + require("canvas"), + require("commands"), + require("block_manager"), ]; -const ts_deps: any[] = [ -]; +const ts_deps: any[] = []; Extender({ //@ts-ignore @@ -68,7 +74,7 @@ export default class EditorModel extends Model { modules: [], toLoad: [], opened: {}, - device: '', + device: "", }; } @@ -77,36 +83,35 @@ export default class EditorModel extends Model { destroyed = false; _config: any; attrsOrig: any; -timedInterval?: number; + timedInterval?: number; updateItr?: number; - view?: EditorView - + view?: EditorView; - get storables(): any[]{ - return this.get('storables') + get storables(): any[] { + return this.get("storables"); } - get modules(): IModule[]{ - return this.get('modules') + get modules(): IModule[] { + return this.get("modules"); } - get toLoad(): any[]{ - return this.get('toLoad') + get toLoad(): any[] { + return this.get("toLoad"); } constructor(conf = {}) { - super() + super(); this._config = conf; const { config } = this; - this.set('Config', conf); - this.set('modules', []); - this.set('toLoad', []); - this.set('storables', []); - this.set('selected', new Selected()); - this.set('dmode', config.dragMode); + this.set("Config", conf); + this.set("modules", []); + this.set("toLoad", []); + this.set("storables", []); + this.set("selected", new Selected()); + this.set("dmode", config.dragMode); const { el, log } = config; const toLog = log === true ? keys(logs) : isArray(log) ? log : []; - bindAll(this, 'initBaseColorPicker'); + bindAll(this, "initBaseColorPicker"); if (el && config.fromElement) { config.components = el.innerHTML; @@ -117,7 +122,7 @@ timedInterval?: number; res[next.nodeName] = next.nodeValue; return res; }, {}) - : ''; + : ""; // Move components to pages if (config.components && !config.pageManager) { @@ -125,27 +130,35 @@ timedInterval?: number; } // Load modules - deps.forEach(name => this.loadModule(name)); - ts_deps.forEach(name => this.tsLoadModule(name)); - this.on('change:componentHovered', this.componentHovered, this); - this.on('change:changesCount', this.updateChanges, this); - this.on('change:readyLoad change:readyCanvas', this._checkReady, this); - toLog.forEach(e => this.listenLog(e)); + deps.forEach((name) => this.loadModule(name)); + ts_deps.forEach((name) => this.tsLoadModule(name)); + this.on("change:componentHovered", this.componentHovered, this); + this.on("change:changesCount", this.updateChanges, this); + this.on("change:readyLoad change:readyCanvas", this._checkReady, this); + toLog.forEach((e) => this.listenLog(e)); // Deprecations - [{ from: 'change:selectedComponent', to: 'component:toggled' }].forEach(event => { - const eventFrom = event.from; - const eventTo = event.to; - this.listenTo(this, eventFrom, (...args) => { - this.trigger(eventTo, ...args); - this.logWarning(`The event '${eventFrom}' is deprecated, replace it with '${eventTo}'`); - }); - }); + [{ from: "change:selectedComponent", to: "component:toggled" }].forEach( + (event) => { + const eventFrom = event.from; + const eventTo = event.to; + this.listenTo(this, eventFrom, (...args) => { + this.trigger(eventTo, ...args); + this.logWarning( + `The event '${eventFrom}' is deprecated, replace it with '${eventTo}'` + ); + }); + } + ); } _checkReady() { - if (this.get('readyLoad') && this.get('readyCanvas') && !this.get('ready')) { - this.set('ready', true); + if ( + this.get("readyLoad") && + this.get("readyCanvas") && + !this.get("ready") + ) { + this.set("ready", true); } } @@ -179,15 +192,15 @@ timedInterval?: number; */ loadOnStart() { 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. - this.toLoad.forEach(mdl => mdl.onLoad()); + this.toLoad.forEach((mdl) => mdl.onLoad()); // Stuff to do post load const postLoad = () => { - this.modules.forEach(mdl => mdl.postLoad && mdl.postLoad(this)); - this.set('readyLoad', 1); + this.modules.forEach((mdl) => mdl.postLoad && mdl.postLoad(this)); + this.set("readyLoad", 1); }; if (headless) { @@ -217,8 +230,8 @@ timedInterval?: number; undoManager: false, }); // We only need to load a few modules - ['PageManager', 'Canvas'].forEach(key => shallow.get(key).onLoad()); - this.set('shallow', shallow); + ["PageManager", "Canvas"].forEach((key) => shallow.get(key).onLoad()); + this.set("shallow", shallow); } /** @@ -227,18 +240,18 @@ timedInterval?: number; * @private */ updateChanges() { - const stm = this.get('StorageManager'); + const stm = this.get("StorageManager"); const changes = this.getDirtyCount(); this.updateItr && clearTimeout(this.updateItr); //@ts-ignore - this.updateItr = setTimeout(() => this.trigger('update')); + this.updateItr = setTimeout(() => this.trigger("update")); if (this.config.noticeOnUnload) { - window.onbeforeunload = changes ? e => 1 : null; + window.onbeforeunload = changes ? () => true : null; } if (stm.isAutosave() && changes >= stm.getStepsBeforeSave()) { - this.store().catch(err => this.logError(err)); + this.store().catch((err) => this.logError(err)); } } @@ -253,9 +266,11 @@ timedInterval?: number; const Module = moduleName.default || moduleName; const Mod = new Module(); const name = Mod.name.charAt(0).toLowerCase() + Mod.name.slice(1); - const cfgParent = !isUndefined(config[name]) ? config[name] : config[Mod.name]; + const cfgParent = !isUndefined(config[name]) + ? config[name] + : config[Mod.name]; const cfg = cfgParent === true ? {} : cfgParent || {}; - cfg.pStylePrefix = config.pStylePrefix || ''; + cfg.pStylePrefix = config.pStylePrefix || ""; if (!isUndefined(cfgParent) && !cfgParent) { cfg._disable = 1; @@ -281,7 +296,7 @@ timedInterval?: number; * @return {this} * @private */ - tsLoadModule(moduleName: any) { + tsLoadModule(moduleName: any) { const Module = moduleName.default || moduleName; const Mod = new Module(this); @@ -306,11 +321,11 @@ timedInterval?: number; this.initialize(opts); this.destroyed = false; } - this.set('Editor', editor); + this.set("Editor", editor); } getEditor() { - return this.get('Editor'); + return this.get("Editor"); } /** @@ -323,7 +338,13 @@ timedInterval?: number; * */ handleUpdates(model: any, val: any, opt: any = {}) { // Component has been added temporarily - do not update storage or record changes - if (this.__skip || opt.temporary || opt.noCount || opt.avoidStore || !this.get('ready')) { + if ( + this.__skip || + opt.temporary || + opt.noCount || + opt.avoidStore || + !this.get("ready") + ) { return; } @@ -332,7 +353,7 @@ timedInterval?: number; this.timedInterval = setTimeout(() => { const curr = this.getDirtyCount() || 0; const { unset, ...opts } = opt; - this.set('changesCount', curr + 1, opts); + this.set("changesCount", curr + 1, opts); }, 0); } @@ -348,9 +369,9 @@ timedInterval?: number; * @private * */ componentHovered(editor: any, component: any, options: any) { - const prev = this.previous('componentHovered'); - prev && this.trigger('component:unhovered', prev, options); - component && this.trigger('component:hovered', component, options); + const prev = this.previous("componentHovered"); + prev && this.trigger("component:unhovered", prev, options); + component && this.trigger("component:hovered", component, options); } /** @@ -359,7 +380,7 @@ timedInterval?: number; * @public */ getSelected() { - return this.get('selected').lastComponent(); + return this.get("selected").lastComponent(); } /** @@ -368,7 +389,7 @@ timedInterval?: number; * @public */ getSelectedAll(): any[] { - return this.get('selected').allComponents(); + return this.get("selected").allComponents(); } /** @@ -377,31 +398,32 @@ timedInterval?: number; * @param {Object} [opts={}] Options, optional * @public */ - setSelected(el: any, opts: any = {}) { + setSelected(el: any | any[], opts: any = {}) { const { event } = opts; const ctrlKey = event && (event.ctrlKey || event.metaKey); const { shiftKey } = event || {}; - const multiple = isArray(el); - const els = (multiple ? el : [el]).map(el => getModel(el, $)); + const els = (isArray(el) ? el : [el]).map((el) => getModel(el, $)); const selected = this.getSelectedAll(); const mltSel = this.getConfig().multipleSelection; let added; // If an array is passed remove all selected // expect those yet to be selected - multiple && this.removeSelected(selected.filter(s => !contains(els, s))); + const multiple = isArray(el); + multiple && this.removeSelected(selected.filter((s) => !contains(els, s))); - els.forEach(el => { + els.forEach((el) => { let model = getModel(el, undefined); if (model) { - this.trigger('component:select:before', model, opts); + this.trigger("component:select:before", model, opts); // Check for valid selectable - if (!model.get('selectable') || opts.abort) { + if (!model.get("selectable") || opts.abort) { if (opts.useValid) { let parent = model.parent(); - while (parent && !parent.get('selectable')) parent = parent.parent(); + while (parent && !parent.get("selectable")) + parent = parent.parent(); model = parent; } else { return; @@ -413,13 +435,13 @@ timedInterval?: number; if (ctrlKey && mltSel) { return this.toggleSelected(model); } else if (shiftKey && mltSel) { - this.clearSelection(this.get('Canvas').getWindow()); + this.clearSelection(this.get("Canvas").getWindow()); const coll = model.collection; const index = model.index(); - let min: number|undefined, max: number|undefined; + let min: number | undefined, max: number | undefined; // Fin min and max siblings - this.getSelectedAll().forEach(sel => { + this.getSelectedAll().forEach((sel) => { const selColl = sel.collection; const selIndex = sel.index(); if (selColl === coll) { @@ -450,7 +472,7 @@ timedInterval?: number; return this.addSelected(model); } - !multiple && this.removeSelected(selected.filter(s => s !== model)); + !multiple && this.removeSelected(selected.filter((s) => s !== model)); this.addSelected(model, opts); added = model; }); @@ -466,12 +488,12 @@ timedInterval?: number; const model = getModel(el, $); const models = isArray(model) ? model : [model]; - models.forEach(model => { - if (model && !model.get('selectable')) return; - const selected = this.get('selected'); + models.forEach((model) => { + if (model && !model.get("selectable")) return; + const selected = this.get("selected"); opts.forceChange && this.removeSelected(model, opts); selected.addComponent(model, opts); - model && this.trigger('component:select', model, opts); + model && this.trigger("component:select", model, opts); }); } @@ -482,7 +504,7 @@ timedInterval?: number; * @public */ removeSelected(el: any, opts = {}) { - this.get('selected').removeComponent(getModel(el, $), opts); + this.get("selected").removeComponent(getModel(el, $), opts); } /** @@ -495,8 +517,8 @@ timedInterval?: number; const model = getModel(el, $); const models = isArray(model) ? model : [model]; - models.forEach(model => { - if (this.get('selected').hasComponent(model)) { + models.forEach((model) => { + if (this.get("selected").hasComponent(model)) { this.removeSelected(model, opts); } else { this.addSelected(model, opts); @@ -511,21 +533,21 @@ timedInterval?: number; * @private */ 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); if (!model) return; - opts.forceChange && this.set('componentHovered', ''); + opts.forceChange && this.set("componentHovered", ""); this.trigger(`${ev}:before`, model, opts); // Check for valid hoverable - if (!model.get('hoverable')) { + if (!model.get("hoverable")) { if (opts.useValid && !opts.abort) { let parent = model && model.parent(); - while (parent && !parent.get('hoverable')) parent = parent.parent(); + while (parent && !parent.get("hoverable")) parent = parent.parent(); model = parent; } else { return; @@ -533,13 +555,13 @@ timedInterval?: number; } if (!opts.abort) { - this.set('componentHovered', model, opts); + this.set("componentHovered", model, opts); this.trigger(ev, model, opts); } } getHovered() { - return this.get('componentHovered'); + return this.get("componentHovered"); } /** @@ -550,7 +572,7 @@ timedInterval?: number; * @public */ setComponents(components: any, opt = {}) { - return this.get('DomComponents').setComponents(components, opt); + return this.get("DomComponents").setComponents(components, opt); } /** @@ -559,13 +581,13 @@ timedInterval?: number; * @private */ getComponents() { - var cmp = this.get('DomComponents'); - var cm = this.get('CodeManager'); + var cmp = this.get("DomComponents"); + var cm = this.get("CodeManager"); if (!cmp || !cm) return; var wrp = cmp.getComponents(); - return cm.getCode(wrp, 'json'); + return cm.getCode(wrp, "json"); } /** @@ -576,7 +598,7 @@ timedInterval?: number; * @public */ setStyle(style: any, opt = {}) { - const cssc = this.get('CssComposer'); + const cssc = this.get("CssComposer"); cssc.clear(opt); cssc.getAll().add(style, opt); return this; @@ -599,7 +621,7 @@ timedInterval?: number; * @private */ getStyle() { - return this.get('CssComposer').getAll(); + return this.get("CssComposer").getAll(); } /** @@ -608,7 +630,7 @@ timedInterval?: number; * @returns {this} */ setState(value: string) { - this.set('state', value); + this.set("state", value); return this; } @@ -617,7 +639,7 @@ timedInterval?: number; * @returns {String} */ getState() { - return this.get('state') || ''; + return this.get("state") || ""; } /** @@ -629,15 +651,15 @@ timedInterval?: number; getHtml(opts: any = {}) { const { config } = this; const { optsHtml } = config; - const js = config.jsInHtml ? this.getJs(opts) : ''; - const cmp = opts.component || this.get('DomComponents').getComponent(); + const js = config.jsInHtml ? this.getJs(opts) : ""; + const cmp = opts.component || this.get("DomComponents").getComponent(); let html = cmp - ? this.get('CodeManager').getCode(cmp, 'html', { + ? this.get("CodeManager").getCode(cmp, "html", { ...optsHtml, ...opts, }) - : ''; - html += js ? `` : ''; + : ""; + html += js ? `` : ""; return html; } @@ -651,19 +673,21 @@ timedInterval?: number; const config = this.config; const { optsCss } = config; const avoidProt = opts.avoidProtected; - const keepUnusedStyles = !isUndefined(opts.keepUnusedStyles) ? opts.keepUnusedStyles : config.keepUnusedStyles; - const cssc = this.get('CssComposer'); - const wrp = opts.component || this.get('DomComponents').getComponent(); - const protCss = !avoidProt ? config.protectedCss : ''; + const keepUnusedStyles = !isUndefined(opts.keepUnusedStyles) + ? opts.keepUnusedStyles + : config.keepUnusedStyles; + const cssc = this.get("CssComposer"); + const wrp = opts.component || this.get("DomComponents").getComponent(); + const protCss = !avoidProt ? config.protectedCss : ""; const css = wrp && - this.get('CodeManager').getCode(wrp, 'css', { + this.get("CodeManager").getCode(wrp, "css", { cssc, keepUnusedStyles, ...optsCss, ...opts, }); - return wrp ? (opts.json ? css : protCss + css) : ''; + return wrp ? (opts.json ? css : protCss + css) : ""; } /** @@ -672,8 +696,8 @@ timedInterval?: number; * @public */ getJs(opts: any = {}) { - var wrp = opts.component || this.get('DomComponents').getWrapper(); - return wrp ? this.get('CodeManager').getCode(wrp, 'js').trim() : ''; + var wrp = opts.component || this.get("DomComponents").getWrapper(); + return wrp ? this.get("CodeManager").getCode(wrp, "js").trim() : ""; } /** @@ -682,7 +706,7 @@ timedInterval?: number; */ async store(options?: any) { const data = this.storeData(); - await this.get('StorageManager').store(data, options); + await this.get("StorageManager").store(data, options); this.clearDirtyCount(); return data; } @@ -692,7 +716,7 @@ timedInterval?: number; * @public */ async load(options?: any) { - const result = await this.get('StorageManager').load(options); + const result = await this.get("StorageManager").load(options); this.loadData(result); return result; } @@ -701,9 +725,9 @@ timedInterval?: number; let result = {}; // Sync content if there is an active RTE 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) }; }); return JSON.parse(JSON.stringify(result)); @@ -711,8 +735,8 @@ timedInterval?: number; loadData(data = {}) { if (!isEmptyObj(data)) { - this.storables.forEach(module => module.clear()); - this.storables.forEach(module => module.load(data)); + this.storables.forEach((module) => module.clear()); + this.storables.forEach((module) => module.load(data)); } return data; } @@ -723,8 +747,8 @@ timedInterval?: number; * @private */ getDeviceModel() { - var name = this.get('device'); - return this.get('DeviceManager').get(name); + var name = this.get("device"); + return this.get("DeviceManager").get(name); } /** @@ -733,7 +757,7 @@ timedInterval?: number; * @private */ 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; command.stop(this, this, opts); command.run(this, this, opts); @@ -746,7 +770,7 @@ timedInterval?: number; * @private */ stopDefault(opts = {}) { - const commands = this.get('Commands'); + const commands = this.get("Commands"); const command = commands.get(this.config.defaultCommand); if (!command || !this.defaultRunning) return; command.stop(this, this, opts); @@ -758,9 +782,9 @@ timedInterval?: number; * @public */ refreshCanvas(opts: any = {}) { - this.set('canvasOffset', null); - this.set('canvasOffset', this.get('Canvas').getOffset()); - opts.tools && this.trigger('canvas:updateTools'); + this.set("canvasOffset", null); + this.set("canvasOffset", this.get("Canvas").getOffset()); + opts.tools && this.trigger("canvas:updateTools"); } /** @@ -783,8 +807,8 @@ timedInterval?: number; const device = this.getDeviceModel(); const condition = config.mediaCondition; const preview = config.devicePreviewMode; - const width = device && device.get('widthMedia'); - return device && width && !preview ? `(${condition}: ${width})` : ''; + const width = device && device.get("widthMedia"); + return device && width && !preview ? `(${condition}: ${width})` : ""; } /** @@ -792,15 +816,15 @@ timedInterval?: number; * @return {Component} */ getWrapper() { - return this.get('DomComponents').getWrapper(); + return this.get("DomComponents").getWrapper(); } setCurrentFrame(frameView: FrameView) { - return this.set('currentFrame', frameView); + return this.set("currentFrame", frameView); } getCurrentFrame(): FrameView { - return this.get('currentFrame'); + return this.get("currentFrame"); } getCurrentFrameModel() { @@ -809,7 +833,7 @@ timedInterval?: number; getIcon(icon: string) { const icons = this.config.icons || {}; - return icons[icon] || ''; + return icons[icon] || ""; } /** @@ -817,28 +841,28 @@ timedInterval?: number; * This count resets at any `store()` * @return {number} */ - getDirtyCount() { - return this.get('changesCount'); + getDirtyCount(): number { + return this.get("changesCount"); } clearDirtyCount() { - return this.set('changesCount', 0); + return this.set("changesCount", 0); } getZoomDecimal() { - return this.get('Canvas').getZoomDecimal(); + return this.get("Canvas").getZoomDecimal(); } getZoomMultiplier() { - return this.get('Canvas').getZoomMultiplier(); + return this.get("Canvas").getZoomMultiplier(); } setDragMode(value: string) { - return this.set('dmode', value); + return this.set("dmode", value); } t(...args: any[]) { - const i18n = this.get('I18n'); + const i18n = this.get("I18n"); return i18n?.t(...args); } @@ -847,7 +871,7 @@ timedInterval?: number; * @returns {Boolean} */ inAbsoluteMode() { - return this.get('dmode') === 'absolute'; + return this.get("dmode") === "absolute"; } /** @@ -857,41 +881,43 @@ timedInterval?: number; const { config, view } = this; const editor = this.getEditor(); const { editors = [] } = config.grapesjs || {}; - const shallow = this.get('shallow'); + const shallow = this.get("shallow"); shallow?.destroyAll(); this.stopListening(); this.stopDefault(); this.modules .slice() .reverse() - .forEach(mod => mod.destroy()); + .forEach((mod) => mod.destroy()); view && view.remove(); this.clear({ silent: true }); this.destroyed = true; - //@ts-ignore - ['_config', 'view', '_previousAttributes', '_events', '_listeners'].forEach(i => (this[i] = {})); + ["_config", "view", "_previousAttributes", "_events", "_listeners"].forEach( + //@ts-ignore + (i) => (this[i] = {}) + ); editors.splice(editors.indexOf(editor), 1); //@ts-ignore hasWin() && $(config.el).empty().attr(this.attrsOrig); } getEditing() { - const res = this.get('editing'); + const res = this.get("editing"); return (res && res.model) || null; } setEditing(value: boolean) { - this.set('editing', value); + this.set("editing", value); return this; } isEditing() { - return !!this.get('editing'); + return !!this.get("editing"); } log(msg: string, opts: any = {}) { - const { ns, level = 'debug' } = opts; - this.trigger('log', msg, opts); + const { ns, level = "debug" } = opts; + this.trigger("log", msg, opts); level && this.trigger(`log:${level}`, msg, opts); if (ns) { @@ -902,15 +928,15 @@ timedInterval?: number; } logInfo(msg: string, opts?: any) { - this.log(msg, { ...opts, level: 'info' }); + this.log(msg, { ...opts, level: "info" }); } - logWarning(msg:string, opts?: any) { - this.log(msg, { ...opts, level: 'warning' }); + logWarning(msg: string, opts?: any) { + this.log(msg, { ...opts, level: "warning" }); } logError(msg: string, opts?: any) { - this.log(msg, { ...opts, level: 'error' }); + this.log(msg, { ...opts, level: "error" }); } initBaseColorPicker(el: any, opts = {}) { @@ -922,13 +948,13 @@ timedInterval?: number; //@ts-ignore return $(el).spectrum({ containerClassName: `${ppfx}one-bg ${ppfx}two-color`, - appendTo: elToAppend || 'body', + appendTo: elToAppend || "body", maxSelectionSize: 8, showPalette: true, palette: [], showAlpha: true, - chooseText: 'Ok', - cancelText: '⨯', + chooseText: "Ok", + cancelText: "⨯", ...opts, ...colorPicker, }); @@ -941,7 +967,7 @@ timedInterval?: number; */ skip(clb: Function) { this.__skip = true; - const um = this.get('UndoManager'); + const um = this.get("UndoManager"); um ? um.skip(clb) : clb(); this.__skip = false; } @@ -955,7 +981,7 @@ timedInterval?: number; * @private */ data(el: any, name: string, value: any) { - const varName = '_gjs-data'; + const varName = "_gjs-data"; if (!el[varName]) { el[varName] = {}; diff --git a/src/selector_manager/index.js b/src/selector_manager/index.ts similarity index 77% rename from src/selector_manager/index.js rename to src/selector_manager/index.ts index 1c2c3377a..f7d0bf894 100644 --- a/src/selector_manager/index.js +++ b/src/selector_manager/index.ts @@ -72,20 +72,21 @@ * @module SelectorManager */ -import { isString, debounce, isObject, isArray } from 'underscore'; -import { isComponent, isRule } from '../utils/mixins'; -import Module from '../abstract/moduleLegacy'; -import { Model, Collection } from '../common'; -import defaults from './config/config'; -import Selector from './model/Selector'; -import Selectors from './model/Selectors'; -import State from './model/State'; -import ClassTagsView from './view/ClassTagsView'; - -const isId = str => isString(str) && str[0] == '#'; -const isClass = str => isString(str) && str[0] == '.'; - -export const evAll = 'selector'; +import { isString, debounce, isObject, isArray } from "underscore"; +import { isComponent, isRule } from "../utils/mixins"; +import Module from "../abstract/moduleLegacy"; +import { Model, Collection } from "../common"; +import defaults from "./config/config"; +import Selector from "./model/Selector"; +import Selectors from "./model/Selectors"; +import State from "./model/State"; +import ClassTagsView from "./view/ClassTagsView"; +import EditorModel from "../editor/model/Editor"; + +const isId = (str: string) => isString(str) && str[0] == "#"; +const isClass = (str: string) => isString(str) && str[0] == "."; + +export const evAll = "selector"; export const evPfx = `${evAll}:`; export const evAdd = `${evPfx}add`; export const evUpdate = `${evPfx}update`; @@ -95,12 +96,18 @@ export const evCustom = `${evPfx}custom`; export const evState = `${evPfx}state`; export default class SelectorManager extends Module { - name = 'SelectorManager'; + name = "SelectorManager"; Selector = Selector; Selectors = Selectors; + model!: Model; + states!: Collection; + selectorTags?: ClassTagsView; + selected!: Selectors; + em!: EditorModel; + events = { all: evAll, update: evUpdate, @@ -119,9 +126,10 @@ export default class SelectorManager extends Module { */ init(conf = {}) { + //super(); this.__initConfig(defaults, conf); const config = this.getConfig(); - const em = config.em; + const em = this.em; const ppfx = config.pStylePrefix; if (ppfx) { @@ -132,7 +140,7 @@ export default class SelectorManager extends Module { this.all = new Selectors(config.selectors); this.selected = new Selectors([], { em, config }); this.states = new Collection( - config.states.map(state => new State(state)), + config.states.map((state) => new State(state)), { model: State } ); this.model = new Model({ cFirst: config.componentFirst, _undo: true }); @@ -140,10 +148,12 @@ export default class SelectorManager extends Module { collections: [this.states, this.selected], propagate: [{ entity: this.states, event: this.events.state }], }); - em.on('change:state', (m, value) => em.trigger(evState, value)); - this.model.on('change:cFirst', (m, value) => em.trigger('selector:type', value)); + em.on("change:state", (m, value) => em.trigger(evState, value)); + this.model.on("change:cFirst", (m, value) => + em.trigger("selector:type", value) + ); 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()); return this; @@ -151,13 +161,13 @@ export default class SelectorManager extends Module { __update = debounce(() => { this.__trgCustom(); - }); + }, 0); - __trgCustom(opts) { + __trgCustom(opts?: any) { this.em.trigger(this.events.custom, this.__customData(opts)); } - __customData(opts = {}) { + __customData(opts: any = {}) { const { container } = opts; return { states: this.getStates(), @@ -179,19 +189,29 @@ export default class SelectorManager extends Module { this.__trgCustom(); } - select(value, opts = {}) { + select(value: any, opts = {}) { const targets = Array.isArray(value) ? value : [value]; - const toSelect = this.em.get('StyleManager').select(targets, opts); + const toSelect: any[] = this.em.get("StyleManager").select(targets, opts); const selTags = this.selectorTags; const res = toSelect - .filter(i => i) - .map(sel => (isComponent(sel) ? sel : isRule(sel) && !sel.get('selectorsAdd') ? sel : sel.getSelectorsString())); + .filter((i) => i) + .map((sel) => + isComponent(sel) + ? sel + : isRule(sel) && !sel.get("selectorsAdd") + ? sel + : sel.getSelectorsString() + ); selTags && selTags.componentChanged({ targets: res }); return this; } - addSelector(name, opts = {}, cOpts = {}) { - let props = { ...opts }; + addSelector( + name: string | { name: string; label?: string }, + opts = {}, + cOpts = {} + ) { + let props: any = { ...opts }; if (isObject(name)) { props = name; @@ -222,7 +242,7 @@ export default class SelectorManager extends Module { return selector; } - getSelector(name, type = Selector.TYPE_CLASS) { + getSelector(name: string, type = Selector.TYPE_CLASS) { if (isId(name)) { name = name.substr(1); type = Selector.TYPE_ID; @@ -246,11 +266,11 @@ export default class SelectorManager extends Module { * const selector = selectorManager.add('.my-class'); * console.log(selector.toString()) // `.my-class` * */ - add(props, opts = {}) { + add(props: string | { name: string; label?: string }, opts = {}) { const cOpts = isString(props) ? {} : opts; // Keep support for arrays but avoid it in docs if (isArray(props)) { - return props.map(item => this.addSelector(item, opts, cOpts)); + return props.map((item) => this.addSelector(item, opts, cOpts)); } else { return this.addSelector(props, opts, cOpts); } @@ -267,14 +287,14 @@ export default class SelectorManager extends Module { * sm.addClass(['class1', 'class2']); * // -> [SelectorObject, ...] */ - addClass(classes) { - const added = []; + addClass(classes: string | string[]) { + const added: any = []; 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; } @@ -287,12 +307,16 @@ export default class SelectorManager extends Module { * // Get Id * const selectorId = selectorManager.get('#my-id'); * */ - get(name, type) { + get(name: string | string[], type?: number) { // Keep support for arrays but avoid it in docs if (isArray(name)) { - const result = []; - const selectors = name.map(item => this.getSelector(item)).filter(item => item); - selectors.forEach(item => result.indexOf(item) < 0 && result.push(item)); + const result: Selector[] = []; + const selectors = name + .map((item) => this.getSelector(item)) + .filter((item) => item); + selectors.forEach( + (item) => result.indexOf(item) < 0 && result.push(item) + ); return result; } else { return this.getSelector(name, type) || null; @@ -308,7 +332,7 @@ export default class SelectorManager extends Module { * // or by passing the Selector * selectorManager.remove(selectorManager.get('.myclass')); */ - remove(selector, opts) { + remove(selector: string | Selector, opts?: any) { return this.__remove(selector, opts); } @@ -319,7 +343,7 @@ export default class SelectorManager extends Module { * @example * selectorManager.setState('hover'); */ - setState(value) { + setState(value: string) { this.em.setState(value); return this; } @@ -350,9 +374,9 @@ export default class SelectorManager extends Module { * { name: 'nth-of-type(2n)', label: 'Even/Odd' } * ]); */ - setStates(states, opts) { + setStates(states: State[], opts?: any) { return this.states.reset( - states.map(state => new State(state)), + states.map((state) => new State(state)), opts ); } @@ -374,10 +398,10 @@ export default class SelectorManager extends Module { * @example * selectorManager.addSelected('.new-class'); */ - addSelected(props) { + addSelected(props: string) { const added = this.add(props); // TODO: target should be the one from StyleManager - this.em.getSelectedAll().forEach(target => { + this.em.getSelectedAll().forEach((target) => { target.getSelectors().add(added); }); // TODO: update selected collection @@ -389,9 +413,9 @@ export default class SelectorManager extends Module { * @example * selectorManager.removeSelected('.myclass'); */ - removeSelected(selector) { - this.em.getSelectedAll().forEach(trg => { - !selector.get('protected') && trg && trg.getSelectors().remove(selector); + removeSelected(selector: any) { + this.em.getSelectedAll().forEach((trg) => { + !selector.get("protected") && trg && trg.getSelectors().remove(selector); }); } @@ -403,7 +427,7 @@ export default class SelectorManager extends Module { * console.log(targetsToStyle.map(target => target.getSelectorsString())) */ getSelectedTargets() { - return this.em.get('StyleManager').getSelectedAll(); + return this.em.get("StyleManager").getSelectedAll(); } /** @@ -412,7 +436,7 @@ export default class SelectorManager extends Module { * of selectors (which would change styles on all components with those classes). * @param {Boolean} value */ - setComponentFirst(value) { + setComponentFirst(value: boolean) { this.getConfig().componentFirst = value; this.model.set({ cFirst: value }); } @@ -438,7 +462,7 @@ export default class SelectorManager extends Module { * @returns {String} Escaped name * @private */ - escapeName(name) { + escapeName(name: string) { const { escapeName } = this.getConfig(); return escapeName ? escapeName(name) : Selector.escapeName(name); } @@ -449,7 +473,7 @@ export default class SelectorManager extends Module { * @return {HTMLElement} * @private */ - render(selectors) { + render(selectors: any[]) { const { em, selectorTags } = this; const config = this.getConfig(); const el = selectorTags && selectorTags.el; @@ -457,6 +481,7 @@ export default class SelectorManager extends Module { this.selectorTags = new ClassTagsView({ el, collection: this.selected, + //@ts-ignore module: this, config, }); @@ -468,8 +493,8 @@ export default class SelectorManager extends Module { const { selectorTags, model } = this; model.stopListening(); this.__destroy(); - selectorTags && selectorTags.remove(); - this.selectorTags = {}; + selectorTags?.remove(); + this.selectorTags = undefined; } /** @@ -481,16 +506,24 @@ export default class SelectorManager extends Module { return this.__getCommonSelectors(this.em.getSelectedAll()); } - __getCommonSelectors(components, opts = {}) { - const selectors = components.map(cmp => cmp.getSelectors && cmp.getSelectors().getValid(opts)).filter(Boolean); + __getCommonSelectors(components: any[], opts = {}) { + const selectors = components + .map((cmp) => cmp.getSelectors && cmp.getSelectors().getValid(opts)) + .filter(Boolean); return this.__common(...selectors); } - __common(...args) { + __common(...args: any) { if (!args.length) return []; if (args.length === 1) return args[0]; - if (args.length === 2) return args[0].filter(item => args[1].indexOf(item) >= 0); - - return args.slice(1).reduce((acc, item) => this.__common(acc, item), args[0]); + if (args.length === 2) + return args[0].filter((item: any) => args[1].indexOf(item) >= 0); + + return ( + args + .slice(1) + //@ts-ignore + .reduce((acc, item) => this.__common(acc, item), args[0]) + ); } } diff --git a/src/selector_manager/view/ClassTagsView.js b/src/selector_manager/view/ClassTagsView.js index e1cc65450..a83f29875 100644 --- a/src/selector_manager/view/ClassTagsView.js +++ b/src/selector_manager/view/ClassTagsView.js @@ -175,7 +175,7 @@ export default class ClassTagsView extends View { /** * Triggered when component is changed * @param {Object} e - * @private + * @public */ componentChanged({ targets } = {}) { this.updateSelection(targets);