Browse Source

Convert SelectorManager to ts

pull/4306/head
Alex 4 years ago
parent
commit
cb16cd6fa1
  1. 394
      src/editor/model/Editor.ts
  2. 155
      src/selector_manager/index.ts
  3. 2
      src/selector_manager/view/ClassTagsView.js

394
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 ? `<script>${js}</script>` : '';
: "";
html += js ? `<script>${js}</script>` : "";
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] = {};

155
src/selector_manager/index.js → 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])
);
}
}

2
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);

Loading…
Cancel
Save