Browse Source

Merge branch 'refactor-panels'

pull/856/head
Artur Arseniev 9 years ago
parent
commit
80c896aef4
  1. 2
      dist/css/grapes.min.css
  2. 2022
      dist/grapes.js
  3. 4
      src/asset_manager/view/AssetsView.js
  4. 4
      src/block_manager/config/config.js
  5. 13
      src/block_manager/index.js
  6. 4
      src/block_manager/view/BlocksView.js
  7. 24
      src/canvas/view/CanvasView.js
  8. 2
      src/commands/index.js
  9. 41
      src/commands/view/OpenLayers.js
  10. 2
      src/commands/view/SelectPosition.js
  11. 3
      src/dom_components/index.js
  12. 8
      src/dom_components/view/ComponentView.js
  13. 5
      src/editor/config/config.js
  14. 6
      src/editor/index.js
  15. 17
      src/editor/model/Editor.js
  16. 6
      src/index.js
  17. 6
      src/modal_dialog/index.js
  18. 2
      src/modal_dialog/view/ModalView.js
  19. 6
      src/navigator/config/config.js
  20. 77
      src/navigator/index.js
  21. 108
      src/navigator/view/ItemView.js
  22. 47
      src/navigator/view/ItemsView.js
  23. 41
      src/panels/view/PanelView.js
  24. 32
      src/panels/view/PanelsView.js
  25. 4
      src/selector_manager/config/config.js
  26. 15
      src/selector_manager/index.js
  27. 16
      src/selector_manager/view/ClassTagsView.js
  28. 5
      src/storage_manager/index.js
  29. 4
      src/style_manager/config/config.js
  30. 11
      src/style_manager/index.js
  31. 25
      src/style_manager/view/SectorsView.js
  32. 3
      src/styles/scss/_gjs_blocks.scss
  33. 4
      src/styles/scss/_gjs_canvas.scss
  34. 211
      src/styles/scss/_gjs_layers.scss
  35. 71
      src/styles/scss/_gjs_panels.scss
  36. 91
      src/styles/scss/_gjs_selectors.scss
  37. 4
      src/styles/scss/_gjs_style_manager.scss
  38. 29
      src/styles/scss/_gjs_traits.scss
  39. 11
      src/styles/scss/_gjs_variables.scss
  40. 237
      src/styles/scss/main.scss
  41. 4
      src/trait_manager/config/config.js
  42. 20
      src/trait_manager/index.js
  43. 11
      src/trait_manager/view/TraitsView.js
  44. 73
      src/utils/Resizer.js
  45. 12
      src/utils/Sorter.js

2
dist/css/grapes.min.css

File diff suppressed because one or more lines are too long

2022
dist/grapes.js

File diff suppressed because it is too large

4
src/asset_manager/view/AssetsView.js

@ -20,10 +20,6 @@ module.exports = Backbone.View.extend({
<button class="${ppfx}btn-prim">${view.config.addBtnText}</button>
<div style="clear:both"></div>
</form>
<div class="${pfx}dips" style="display:none">
<button class="fa fa-th <%${ppfx}btnt"></button>
<button class="fa fa-th-list <%${ppfx}btnt"></button>
</div>
</div>
<div class="${pfx}assets" data-el="assets"></div>
<div style="clear:both"></div>

4
src/block_manager/config/config.js

@ -1,4 +1,8 @@
module.exports = {
// Specify the element to use as a container, string (query) or HTMLElement
// With the empty value, nothing will be rendered
appendTo: '',
blocks: [],
appendTo: ''

13
src/block_manager/index.js

@ -28,6 +28,8 @@
* }
* ...
*/
import { isElement } from 'underscore';
module.exports = () => {
var c = {},
defaults = require('./config/config'),
@ -108,6 +110,15 @@ module.exports = () => {
!blocks.length && blocks.reset(c.blocks);
},
postRender() {
const elTo = this.getConfig().appendTo;
if (elTo) {
const el = isElement(elTo) ? elTo : document.querySelector(elTo);
el.appendChild(this.render());
}
},
/**
* Add new block to the collection.
* @param {string} id Block id
@ -199,6 +210,7 @@ module.exports = () => {
* Render blocks
* @param {Array} blocks Blocks to render, without the argument will render
* all global blocks
* @return {HTMLElement} Rendered element
* @example
* // Render all blocks (inside the global collection)
* blockManager.render();
@ -225,6 +237,7 @@ module.exports = () => {
}
blocksView.collection.reset(toRender);
return this.getContainer();
}
};
};

4
src/block_manager/view/BlocksView.js

@ -174,6 +174,7 @@ module.exports = require('backbone').View.extend({
},
render() {
const ppfx = this.ppfx;
const frag = document.createDocumentFragment();
this.catsEl = null;
this.blocksEl = null;
@ -187,7 +188,8 @@ module.exports = require('backbone').View.extend({
this.collection.each(model => this.add(model, frag));
this.append(frag);
this.$el.addClass(this.blockContClass + 's');
const cls = `${this.blockContClass}s ${ppfx}one-bg ${ppfx}two-color`;
this.$el.addClass(cls);
return this;
}
});

24
src/canvas/view/CanvasView.js

@ -128,11 +128,12 @@ module.exports = Backbone.View.extend({
.${ppfx}dashed *[data-highlightable] {
outline: 1px dashed rgba(170,170,170,0.7);
outline-offset: -3px
outline-offset: -2px;
}
.${ppfx}comp-selected {
outline: 3px solid #3b97e3 !important;
outline-offset: -3px;
}
.${ppfx}comp-selected-parent {
@ -206,8 +207,8 @@ module.exports = Backbone.View.extend({
// the keyCode/which will be always `0`. Even if it's an old/deprecated
// property keymaster (and many others) still use it... using `defineProperty`
// hack seems the only way
const createCustomEvent = e => {
var oEvent = new KeyboardEvent(e.type, e);
const createCustomEvent = (e, cls) => {
var oEvent = new window[cls](e.type, e);
oEvent.keyCodeVal = e.keyCode;
['keyCode', 'which'].forEach(prop => {
Object.defineProperty(oEvent, prop, {
@ -218,12 +219,17 @@ module.exports = Backbone.View.extend({
});
return oEvent;
};
fdoc.addEventListener('keydown', e => {
doc.dispatchEvent(createCustomEvent(e));
});
fdoc.addEventListener('keyup', e => {
doc.dispatchEvent(createCustomEvent(e));
});
[
{ event: 'keydown keyup', class: 'KeyboardEvent' }
//{ event: 'mousedown mousemove mouseup', class: 'MouseEvent' },
].forEach(obj =>
obj.event.split(' ').forEach(event => {
fdoc.addEventListener(event, e =>
doc.dispatchEvent(createCustomEvent(e, obj.class))
);
})
);
}
},

2
src/commands/index.js

@ -204,7 +204,7 @@ module.exports = () => {
cmdMove.initSorterFromModel(sel);
}
sel.set('status', 'selected');
sel.set('status', 'freezed-selected');
}
};

41
src/commands/view/OpenLayers.js

@ -2,37 +2,24 @@ const Layers = require('navigator');
const $ = Backbone.$;
module.exports = {
run(em, sender) {
if (!this.toAppend) {
var collection = em.DomComponents.getComponent().get('components');
var config = em.getConfig();
var pfx = config.stylePrefix;
var panels = em.Panels;
const cLayers = { ...config.layers };
var lyStylePfx = cLayers.stylePrefix || 'nv-';
run(editor) {
const lm = editor.LayerManager;
const pn = editor.Panels;
cLayers.stylePrefix = config.stylePrefix + lyStylePfx;
cLayers.pStylePrefix = config.stylePrefix;
cLayers.em = em.editor;
cLayers.opened = em.editor.get('opened');
// Check if panel exists otherwise crate it
if (!panels.getPanel('views-container'))
this.panel = panels.addPanel({ id: 'views-container' });
else this.panel = panels.getPanel('views-container');
const toAppend = $(`<div class="${pfx}layers"></div>`);
this.panel.set('appendContent', toAppend).trigger('change:appendContent');
cLayers.sortContainer = toAppend.get(0);
const layers = new Layers().init(collection, cLayers);
this.$layers = layers.render();
toAppend.append(this.$layers);
this.toAppend = toAppend;
if (!this.layers) {
const id = 'views-container';
const layers = document.createElement('div');
const panels = pn.getPanel(id) || pn.addPanel({ id });
layers.appendChild(lm.render());
panels.set('appendContent', layers).trigger('change:appendContent');
this.layers = layers;
}
this.toAppend.show();
this.layers.style.display = 'block';
},
stop() {
this.toAppend && this.toAppend.hide();
const layers = this.layers;
layers && (layers.style.display = 'none');
}
};

2
src/commands/view/SelectPosition.js

@ -23,7 +23,7 @@ module.exports = {
em: this.editorModel,
canvasRelative: 1
});
this.sorter.startSort(trg);
trg && this.sorter.startSort(trg);
},
/**

3
src/dom_components/index.js

@ -513,12 +513,11 @@ module.exports = () => {
const previousModel = em.previous('selectedComponent');
// Deselect the previous component
if (previousModel) {
previousModel &&
previousModel.set({
status: '',
state: ''
});
}
model && model.set('status', 'selected');
}

8
src/dom_components/view/ComponentView.js

@ -106,6 +106,7 @@ module.exports = Backbone.View.extend({
var selectedCls = pfx + 'selected';
var selectedParentCls = selectedCls + '-parent';
var freezedCls = `${ppfx}freezed`;
this.$el.removeClass(`${selectedCls} ${selectedParentCls} ${freezedCls}`);
var actualCls = el.getAttribute('class') || '';
var cls = '';
@ -119,10 +120,9 @@ module.exports = Backbone.View.extend({
case 'freezed':
cls = `${actualCls} ${freezedCls}`;
break;
default:
this.$el.removeClass(
`${selectedCls} ${selectedParentCls} ${freezedCls}`
);
case 'freezed-selected':
cls = `${actualCls} ${freezedCls} ${selectedCls}`;
break;
}
cls = cls.trim();

5
src/editor/config/config.js

@ -230,9 +230,12 @@ module.exports = {
]
},
//Configurations for Block Manager
// Configurations for Block Manager
blockManager: {},
// Configurations for Trait Manager
traitManager: {},
// Texts
textViewCode: 'Code'

6
src/editor/index.js

@ -124,6 +124,12 @@ module.exports = config => {
*/
DomComponents: em.get('DomComponents'),
/**
* @property {LayerManager}
* @private
*/
LayerManager: em.get('LayerManager'),
/**
* @property {CssComposer}
* @private

17
src/editor/model/Editor.js

@ -1,4 +1,4 @@
import { isUndefined, defaults } from 'underscore';
import { isUndefined, isElement, defaults } from 'underscore';
const deps = [
require('utils'),
@ -17,6 +17,7 @@ const deps = [
require('css_composer'),
require('trait_manager'),
require('dom_components'),
require('navigator'),
require('canvas'),
require('commands'),
require('block_manager')
@ -216,20 +217,14 @@ module.exports = Backbone.Model.extend({
/**
* Select a component
* @param {Component|HTMLElement} el Component to select
* @param {Object} opts Options, optional
* @param {Object} [opts={}] Options, optional
* @private
*/
setSelected(el, opts = {}) {
let model = el;
if (el instanceof window.HTMLElement) {
model = $(el).data('model');
}
if (model && !model.get('selectable')) {
return;
}
isElement(el) && (model = $(el).data('model'));
if (model && !model.get('selectable')) return;
opts.forceChange && this.set('selectedComponent', '');
this.set('selectedComponent', model, opts);
},

6
src/index.js

@ -1,7 +1,8 @@
import $ from 'cash-dom';
import Editor from './editor';
import PluginManager from './plugin_manager';
import { isElement } from 'underscore';
import polyfills from 'utils/polyfills';
import PluginManager from './plugin_manager';
polyfills();
@ -48,8 +49,7 @@ module.exports = (() => {
const els = config.container;
if (!els) throw new Error("'container' is required");
config = { ...defaultConfig, ...config };
const ilEl = els instanceof window.HTMLElement;
config.el = ilEl ? els : document.querySelector(els);
config.el = isElement(els) ? els : document.querySelector(els);
const editor = new Editor(config).init();
// Load plugins

6
src/modal_dialog/index.js

@ -52,9 +52,9 @@ module.exports = () => {
return this;
},
postRender(editorView) {
// c.em.config.el || 'body'
this.render().appendTo(editorView.el);
postRender(view) {
const el = view.model.getConfig().el || view.el;
this.render().appendTo(el);
},
/**

2
src/modal_dialog/view/ModalView.js

@ -1,6 +1,6 @@
module.exports = require('backbone').View.extend({
template({ pfx, ppfx, content, title }) {
return `<div class="${pfx}dialog ${ppfx}one-bg">
return `<div class="${pfx}dialog ${ppfx}one-bg ${ppfx}two-color">
<div class="${pfx}header">
<div class="${pfx}title">${title}</div>
<div class="${pfx}btn-close">&Cross;</div>

6
src/navigator/config/config.js

@ -1,5 +1,9 @@
module.exports = {
stylePrefix: 'nv-',
stylePrefix: '',
// Specify the element to use as a container, string (query) or HTMLElement
// With the empty value, nothing will be rendered
appendTo: '',
// Enable/Disable globally the possibility to sort layers
sortable: 1,

77
src/navigator/index.js

@ -1,42 +1,62 @@
import defaults from './config/config';
import ItemView from './view/ItemView';
import ItemsView from './view/ItemsView';
import { isElement } from 'underscore';
module.exports = () => {
let itemsView;
let em;
let layers;
let config = {};
const defaults = require('./config/config');
const ItemView = require('./view/ItemView');
const ItemsView = require('./view/ItemsView');
let View = ItemsView;
return {
init(collection, opts) {
config = opts || config;
const em = config.em;
name: 'LayerManager',
// Set default options
for (var name in defaults) {
if (!(name in config)) config[name] = defaults[name];
}
init(opts = {}) {
config = { ...defaults, ...opts };
config.stylePrefix = opts.pStylePrefix;
em = config.em;
return this;
},
let View = ItemsView;
const level = 0;
const opened = opts.opened || {};
onLoad() {
const collection = em.get('DomComponents').getComponents();
const parent = collection.parent;
const options = {
level,
level: 0,
config,
opened
opened: config.opened || {}
};
// Show wrapper if requested
if (config.showWrapper && collection.parent) {
if (config.showWrapper && parent) {
View = ItemView;
options.model = collection.parent;
options.model = parent;
} else {
options.collection = collection;
}
itemsView = new View(options);
em && em.on('change:selectedComponent', this.componentChanged);
layers = new View(options);
em && em.on('component:selected', this.componentChanged);
this.componentChanged();
},
return this;
postRender() {
const elTo = config.appendTo;
if (elTo) {
const el = isElement(elTo) ? elTo : document.querySelector(elTo);
el.appendChild(this.render());
}
},
/**
* Return the view of layers
* @return {View}
*/
getAll() {
return layers;
},
/**
@ -44,18 +64,11 @@ module.exports = () => {
* @private
*/
componentChanged(e, md, opts = {}) {
if (opts.fromLayers) {
return;
}
const em = config.em;
if (opts.fromLayers) return;
const opened = em.get('opened');
const model = em.get('selectedComponent');
const model = em.getSelected();
let parent = model && model.collection ? model.collection.parent : null;
for (let cid in opened) {
opened[cid].set('open', 0);
}
for (let cid in opened) opened[cid].set('open', 0);
while (parent) {
parent.set('open', 1);
@ -65,7 +78,7 @@ module.exports = () => {
},
render() {
return itemsView.render().$el;
return layers.render().el;
}
};
};

108
src/navigator/view/ItemView.js

@ -1,5 +1,6 @@
import { isUndefined } from 'underscore';
const ComponentView = require('dom_components/view/ComponentView');
const inputProp = 'contentEditable';
let ItemsView;
module.exports = require('backbone').View.extend({
@ -8,8 +9,8 @@ module.exports = require('backbone').View.extend({
'click [data-toggle-visible]': 'toggleVisibility',
'click [data-toggle-select]': 'handleSelect',
'click [data-toggle-open]': 'toggleOpening',
'dblclick input': 'handleEdit',
'focusout input': 'handleEditEnd'
'dblclick [data-name]': 'handleEdit',
'focusout [data-name]': 'handleEditEnd'
},
template(model) {
@ -17,36 +18,37 @@ module.exports = require('backbone').View.extend({
const ppfx = this.ppfx;
const hidable = this.config.hidable;
const count = this.countChildren(model);
const addClass = !count ? `${pfx}no-chld` : '';
const addClass = !count ? this.clsNoChild : '';
const clsTitle = `${this.clsTitle} ${addClass}`;
const clsTitleC = `${this.clsTitleC} ${ppfx}one-bg`;
const clsCaret = `${this.clsCaret} fa fa-chevron-right`;
const clsInput = `${this.inputNameCls} ${ppfx}no-app`;
const level = this.level + 1;
const gut = `${30 + level * 10}px`;
const name = model.getName();
return `
${
hidable
? `<i id="${pfx}btn-eye" class="${pfx}btn fa fa-eye ${
? `<i class="${pfx}layer-vis fa fa-eye ${
this.isVisible() ? '' : 'fa-eye-slash'
}" data-toggle-visible></i>`
: ''
}
<div class="${pfx}title-c ${ppfx}one-bg">
<div class="${pfx}title ${addClass}" style="padding-left: ${30 +
level * 10}px" data-toggle-select>
<div class="${pfx}title-inn">
<i id="${pfx}caret" class="fa fa-chevron-right ${
this.caretCls
}" data-toggle-open></i>
<div class="${clsTitleC}">
<div class="${clsTitle}" style="padding-left: ${gut}" data-toggle-select>
<div class="${pfx}layer-title-inn">
<i class="${clsCaret}" data-toggle-open></i>
${model.getIcon()}
<input class="${ppfx}no-app ${
this.inputNameCls
}" value="${model.getName()}" readonly>
<span class="${clsInput}" data-name>${name}</span>
</div>
</div>
</div>
<div id="${pfx}counter">${count ? count : ''}</div>
<div id="${pfx}move" data-toggle-move>
<div class="${this.clsCount}">${count || ''}</div>
<div class="${this.clsMove}" data-toggle-move>
<i class="fa fa-arrows"></i>
</div>
<div class="${pfx}children"></div>
<div class="${this.clsChildren}"></div>
`;
},
@ -68,18 +70,22 @@ module.exports = require('backbone').View.extend({
this.listenTo(model, 'change:status', this.updateStatus);
this.listenTo(model, 'change:open', this.updateOpening);
this.listenTo(model, 'change:style:display', this.updateVisibility);
this.className = `${pfx}item no-select`;
this.editBtnCls = `${pfx}nav-item-edit`;
this.inputNameCls = `${ppfx}nav-comp-name`;
this.caretCls = `${ppfx}nav-item-caret`;
this.titleCls = `${pfx}title`;
this.className = `${pfx}layer no-select ${ppfx}two-color`;
this.inputNameCls = `${ppfx}layer-name`;
this.clsTitleC = `${pfx}layer-title-c`;
this.clsTitle = `${pfx}layer-title`;
this.clsCaret = `${pfx}layer-caret`;
this.clsCount = `${pfx}layer-count`;
this.clsMove = `${pfx}layer-move`;
this.clsChildren = `${pfx}layer-children`;
this.clsNoChild = `${pfx}layer-no-chld`;
this.$el.data('model', model);
this.$el.data('collection', components);
},
getVisibilityEl() {
if (!this.eyeEl) {
this.eyeEl = this.$el.children(`#${this.pfx}btn-eye`);
this.eyeEl = this.$el.children(`.${this.pfx}layer-vis`);
}
return this.eyeEl;
@ -88,7 +94,7 @@ module.exports = require('backbone').View.extend({
updateVisibility() {
const pfx = this.pfx;
const model = this.model;
const hClass = `${pfx}hide`;
const hClass = `${pfx}layer-hidden`;
const hideIcon = 'fa-eye-slash';
const hidden = model.getStyle().display == 'none';
const method = hidden ? 'addClass' : 'removeClass';
@ -121,20 +127,21 @@ module.exports = require('backbone').View.extend({
* Handle the edit of the component name
*/
handleEdit(e) {
e.stopPropagation();
var inputName = this.getInputName();
inputName.readOnly = false;
inputName.focus();
e && e.stopPropagation();
const inputEl = this.getInputName();
inputEl[inputProp] = true;
inputEl.focus();
},
/**
* Handle with the end of editing of the component name
*/
handleEditEnd(e) {
e.stopPropagation();
var inputName = this.getInputName();
inputName.readOnly = true;
this.model.set('custom-name', inputName.value);
e && e.stopPropagation();
const inputEl = this.getInputName();
const name = inputEl.textContent;
inputEl[inputProp] = false;
this.model.set({ name });
},
/**
@ -143,7 +150,7 @@ module.exports = require('backbone').View.extend({
*/
getInputName() {
if (!this.inputName) {
this.inputName = this.el.querySelector('.' + this.inputNameCls);
this.inputName = this.el.querySelector(`.${this.inputNameCls}`);
}
return this.inputName;
},
@ -197,13 +204,10 @@ module.exports = require('backbone').View.extend({
* */
startSort(e) {
e.stopPropagation();
//Right or middel click
if (e.button !== 0) {
return;
}
this.sorter && this.sorter.startSort(e.target);
const sorter = this.sorter;
// Right or middel click
if (e.button !== 0) return;
sorter && sorter.startSort(e.target);
},
/**
@ -252,19 +256,21 @@ module.exports = require('backbone').View.extend({
const model = this.model;
const c = this.countChildren(model);
const pfx = this.pfx;
const noChildCls = `${pfx}no-chld`;
const title = this.$el.children(`.${pfx}title-c`).children(`.${pfx}title`);
//tC = `> .${pfx}title-c > .${pfx}title`;
if (!this.$counter) {
this.$counter = this.$el.children(`#${pfx}counter`);
const noChildCls = this.clsNoChild;
const title = this.$el
.children(`.${this.clsTitleC}`)
.children(`.${this.clsTitle}`);
if (!this.cnt) {
this.cnt = this.$el.children(`.${this.clsCount}`);
}
if (c) {
title.removeClass(noChildCls);
this.$counter.html(c);
this.cnt.html(c);
} else {
title.addClass(noChildCls);
this.$counter.empty();
this.cnt.empty();
model.set('open', 0);
}
},
@ -289,7 +295,9 @@ module.exports = require('backbone').View.extend({
getCaret() {
if (!this.caret) {
const pfx = this.pfx;
this.caret = this.$el.children(`.${pfx}title-c`).find(`#${pfx}caret`);
this.caret = this.$el
.children(`.${this.clsTitleC}`)
.find(`.${this.clsCaret}`);
}
return this.caret;
@ -315,10 +323,10 @@ module.exports = require('backbone').View.extend({
parent: model,
level
}).render().$el;
el.find(`.${pfx}children`).append(children);
el.find(`.${this.clsChildren}`).append(children);
if (!model.get('draggable') || !this.config.sortable) {
el.children(`#${pfx}move`).remove();
el.children(`.${this.clsMove}`).remove();
}
!vis && (this.className += ` ${pfx}hide`);

47
src/navigator/view/ItemsView.js

@ -1,7 +1,6 @@
var Backbone = require('backbone');
var ItemView = require('./ItemView');
const ItemView = require('./ItemView');
module.exports = Backbone.View.extend({
module.exports = require('backbone').View.extend({
initialize(o = {}) {
this.opt = o;
const config = o.config || {};
@ -11,33 +10,38 @@ module.exports = Backbone.View.extend({
this.ppfx = config.pStylePrefix || '';
this.pfx = config.stylePrefix || '';
this.parent = o.parent;
this.listenTo(this.collection, 'add', this.addTo);
this.listenTo(this.collection, 'reset resetNavigator', this.render);
this.className = this.pfx + 'items';
const pfx = this.pfx;
const ppfx = this.ppfx;
const parent = this.parent;
const coll = this.collection;
this.listenTo(coll, 'add', this.addTo);
this.listenTo(coll, 'reset resetNavigator', this.render);
this.className = `${pfx}layers`;
const em = config.em;
if (config.sortable && !this.opt.sorter) {
var pfx = this.pfx;
var utils = config.em.get('Utils');
const utils = em.get('Utils');
this.opt.sorter = new utils.Sorter({
container: config.sortContainer || this.el,
containerSel: '.' + pfx + 'items',
itemSel: '.' + pfx + 'item',
ppfx: this.ppfx,
containerSel: `.${this.className}`,
itemSel: `.${pfx}layer`,
ignoreViewChildren: 1,
onEndMove(created, sorter) {
const srcModel = sorter.getSourceModel();
em.setSelected(srcModel, { forceChange: 1 });
},
avoidSelectOnEnd: 1,
pfx,
nested: 1
nested: 1,
ppfx,
pfx
});
}
this.sorter = this.opt.sorter || '';
// For the sorter
this.$el.data('collection', this.collection);
if (this.parent) {
this.$el.data('model', this.parent);
}
this.$el.data('collection', coll);
parent && this.$el.data('model', parent);
},
/**
@ -123,10 +127,11 @@ module.exports = Backbone.View.extend({
render() {
const frag = document.createDocumentFragment();
this.el.innerHTML = '';
const el = this.el;
el.innerHTML = '';
this.collection.each(model => this.addToCollection(model, frag));
this.el.appendChild(frag);
this.$el.attr('class', this.className);
el.appendChild(frag);
el.className = this.className;
return this;
}
});

41
src/panels/view/PanelView.js

@ -68,16 +68,35 @@ module.exports = Backbone.View.extend({
bl: 0,
br: 0,
appendTo: this.el,
silentFrames: 1,
avoidContainerUpdate: 1,
prefix: editor.getConfig().stylePrefix,
posFetcher: el => {
var rect = el.getBoundingClientRect();
onEnd() {
em && em.trigger('change:canvasOffset');
},
posFetcher: (el, { target }) => {
const style = el.style;
const config = resizer.getConfig();
const keyWidth = config.keyWidth;
const keyHeight = config.keyHeight;
const rect = el.getBoundingClientRect();
const forContainer = target == 'container';
const styleWidth = style[keyWidth];
const styleHeight = style[keyHeight];
const width =
styleWidth && !forContainer ? parseFloat(styleWidth) : rect.width;
const height =
styleHeight && !forContainer
? parseFloat(styleHeight)
: rect.height;
return {
left: 0,
top: 0,
width: rect.width,
height: rect.height
width,
height
};
}
},
...resizable
});
resizer.blur = () => {};
resizer.focus(this.el);
@ -85,20 +104,20 @@ module.exports = Backbone.View.extend({
},
render() {
const el = this.$el;
const pfx = this.ppfx;
el.attr('class', `${this.className} ${pfx}one-bg`);
this.id && el.attr('id', this.id);
const $el = this.$el;
const ppfx = this.ppfx;
const cls = `${this.className} ${this.id} ${ppfx}one-bg ${ppfx}two-color`;
$el.addClass(cls);
if (this.buttons.length) {
var buttons = new ButtonsView({
collection: this.buttons,
config: this.config
});
el.append(buttons.render().el);
$el.append(buttons.render().el);
}
el.append(this.model.get('content'));
$el.append(this.model.get('content'));
return this;
}
});

32
src/panels/view/PanelsView.js

@ -32,15 +32,20 @@ module.exports = Backbone.View.extend({
* @private
* */
addToCollection(model, fragmentEl) {
var fragment = fragmentEl || null;
var view = new PanelView({
const fragment = fragmentEl || null;
const config = this.config;
const el = model.get('el');
const view = new PanelView({
el,
model,
config: this.config
config
});
var rendered = view.render().el;
var appendTo = model.get('appendTo');
const rendered = view.render().el;
const appendTo = model.get('appendTo');
if (appendTo) {
// Do nothing if the panel was requested to be another element
if (el) {
} else if (appendTo) {
var appendEl = document.querySelector(appendTo);
appendEl.appendChild(rendered);
} else {
@ -56,15 +61,12 @@ module.exports = Backbone.View.extend({
},
render() {
var fragment = document.createDocumentFragment();
this.$el.empty();
this.collection.each(function(model) {
this.addToCollection(model, fragment);
}, this);
this.$el.append(fragment);
this.$el.attr('class', this.className);
const $el = this.$el;
const frag = document.createDocumentFragment();
$el.empty();
this.collection.each(model => this.addToCollection(model, frag));
$el.append(frag);
$el.attr('class', this.className);
return this;
}
});

4
src/selector_manager/config/config.js

@ -2,6 +2,10 @@ module.exports = {
// Style prefix
stylePrefix: 'clm-',
// Specify the element to use as a container, string (query) or HTMLElement
// With the empty value, nothing will be rendered
appendTo: '',
// Default selectors
selectors: [],

15
src/selector_manager/index.js

@ -49,7 +49,7 @@
* }
*/
import { isString } from 'underscore';
import { isString, isElement } from 'underscore';
module.exports = config => {
var c = config || {},
@ -71,6 +71,10 @@ module.exports = config => {
*/
name: 'SelectorManager',
getConfig() {
return c;
},
/**
* Initialize module. Automatically called with a new instance of the editor
* @param {Object} config Configurations
@ -103,6 +107,15 @@ module.exports = config => {
return this;
},
postRender() {
const elTo = this.getConfig().appendTo;
if (elTo) {
const el = isElement(elTo) ? elTo : document.querySelector(elTo);
el.appendChild(this.render([]));
}
},
/**
* Add a new selector to collection if it's not already exists. Class type is a default one
* @param {String} name Selector name

16
src/selector_manager/view/ClassTagsView.js

@ -303,8 +303,10 @@ module.exports = Backbone.View.extend({
},
render() {
const ppfx = this.ppfx;
const config = this.config;
this.$el.html(
const $el = this.$el;
$el.html(
this.template({
selectedLabel: config.selectedLabel,
statesLabel: config.statesLabel,
@ -313,14 +315,14 @@ module.exports = Backbone.View.extend({
ppfx: this.ppfx
})
);
this.$input = this.$el.find('input#' + this.newInputId);
this.$addBtn = this.$el.find('#' + this.addBtnId);
this.$classes = this.$el.find('#' + this.pfx + 'tags-c');
this.$states = this.$el.find('#' + this.stateInputId);
this.$statesC = this.$el.find('#' + this.stateInputC);
this.$input = $el.find('input#' + this.newInputId);
this.$addBtn = $el.find('#' + this.addBtnId);
this.$classes = $el.find('#' + this.pfx + 'tags-c');
this.$states = $el.find('#' + this.stateInputId);
this.$statesC = $el.find('#' + this.stateInputC);
this.$states.append(this.getStateOptions());
this.renderClasses();
this.$el.attr('class', this.className);
$el.attr('class', `${this.className} ${ppfx}one-bg ${ppfx}two-color`);
return this;
}
});

5
src/storage_manager/index.js

@ -193,7 +193,7 @@ module.exports = () => {
for (var i = 0, len = keys.length; i < len; i++)
keysF.push(c.id + keys[i]);
st &&
if (st) {
st.load(keysF, res => {
// Restore keys name
var reg = new RegExp('^' + c.id + '');
@ -204,6 +204,9 @@ module.exports = () => {
clb && clb(result);
});
} else {
clb && clb(result);
}
},
/**

4
src/style_manager/config/config.js

@ -3,6 +3,10 @@ module.exports = {
sectors: [],
// Specify the element to use as a container, string (query) or HTMLElement
// With the empty value, nothing will be rendered
appendTo: '',
// Text to show in case no element selected
textNoElement: 'Select an element before using Style Manager',

11
src/style_manager/index.js

@ -38,6 +38,8 @@
* }
* ...
*/
import { isElement } from 'underscore';
module.exports = () => {
var c = {},
defaults = require('./config/config'),
@ -87,6 +89,15 @@ module.exports = () => {
return this;
},
postRender() {
const elTo = this.getConfig().appendTo;
if (elTo) {
const el = isElement(elTo) ? elTo : document.querySelector(elTo);
el.appendChild(this.render());
}
},
/**
* Add new sector to the collection. If the sector with the same id already exists,
* that one will be returned

25
src/style_manager/view/SectorsView.js

@ -3,10 +3,12 @@ import { extend } from 'underscore';
const SectorView = require('./SectorView');
module.exports = Backbone.View.extend({
initialize(o) {
this.config = o.config || {};
this.pfx = this.config.stylePrefix || '';
initialize(o = {}) {
const config = o.config || {};
this.pfx = config.stylePrefix || '';
this.ppfx = config.pStylePrefix || '';
this.target = o.target || {};
this.config = config;
// The target that will emit events for properties
const target = {};
@ -117,15 +119,14 @@ module.exports = Backbone.View.extend({
},
render() {
var fragment = document.createDocumentFragment();
this.$el.empty();
this.collection.each(function(model) {
this.addToCollection(model, fragment);
}, this);
this.$el.attr('id', this.pfx + 'sectors');
this.$el.append(fragment);
const frag = document.createDocumentFragment();
const $el = this.$el;
const pfx = this.pfx;
const ppfx = this.ppfx;
$el.empty();
this.collection.each(model => this.addToCollection(model, frag));
$el.append(frag);
$el.addClass(`${pfx}sectors ${ppfx}one-bg ${ppfx}two-color`);
return this;
}
});

3
src/styles/scss/_gjs_blocks.scss

@ -35,6 +35,7 @@
cursor: all-scroll;
font-size: 11px;
font-weight: lighter;
text-align: center;
display: flex;
flex-direction: column;
justify-content: flex-end;
@ -51,7 +52,7 @@
}
.#{$app-prefix}block-svg {
width: 61%;
width: 54px;
fill: currentColor;
}

4
src/styles/scss/_gjs_canvas.scss

@ -94,6 +94,10 @@ $canvasTop: 40px;
@extend .#{$app-prefix}no-pointer-events;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 9;
}

211
src/styles/scss/_gjs_layers.scss

@ -1,140 +1,117 @@
.#{$nv-prefix} {
&selected-parent {
border: 1px solid $colorYell;
}
.#{$nv-prefix}selected-parent {
border: 1px solid $colorYell;
}
.#{$nv-prefix}opac50{
@include opacity(0.50);
}
.#{$app-prefix}layers {
position:relative;
height: 100%;
##{$nv-prefix}placeholder{
width: 100%;
position: absolute;
##{$nv-prefix}plh-int{
height: 100%;
padding: 1px;
&.#{$nv-prefix}insert{
background-color: $colorGreen;
}
}
&opac50 {
@include opacity(0.5);
}
.#{$nv-prefix}item {
&layer {
font-weight: lighter;
text-align: left;
position: relative;
background-color: rgba(0, 0, 0, 0.1);
}
.#{$nv-prefix}item.#{$nv-prefix}hide {
@include opacity(0.55);
}
.#{$nv-prefix}item ##{$nv-prefix}counter {
font-size: 10px;
position: absolute;
right: 27px;
top: 9px;
}
.#{$nv-prefix}item ##{$nv-prefix}btn-eye{
@extend .btn;
height: auto !important; width: auto !important;
font-size: 13px;
left: 0; top: 0;
padding: 7px 5px 7px 10px;
position: absolute;
cursor:pointer;
z-index: 1;
}
}
font-size: $fontSizeS;
.#{$nv-prefix}item ##{$nv-prefix}caret {
font-size: 7px;
width: 8px;
padding: 2px;
cursor: pointer;
position: absolute;
left: -9px;
top: 6px;
@include opacity(0.7);
&:hover {
@include opacity(1);
}
}
&-hidden {
@include opacity(0.55);
}
.#{$nv-prefix}title {
@extend .#{$app-prefix}category-title;
&-count {
position: absolute;
right: 27px;
top: 9px;
}
padding: 3px 10px 5px 30px;
display: flex;
align-items: center;
}
&-vis {
height: auto !important;
width: auto !important;
left: 0;
top: 0;
padding: 7px 5px 7px 10px;
position: absolute;
cursor: pointer;
z-index: 1;
}
.#{$nv-prefix}title-inn {
position: relative;
}
&-caret {
font-size: 0.5rem;
width: 8px;
padding: 2px;
cursor: pointer;
position: absolute;
left: -9px;
top: 6px;
@include opacity(0.7);
&:hover {
@include opacity(1);
}
}
.#{$nv-prefix}item .#{$nv-prefix}children .#{$nv-prefix}title{
border-left: 1px solid lighten($mainDkColor,2%);
}
.#{$nv-prefix}item > .#{$nv-prefix}children {
display: none;
}
.#{$nv-prefix}item.open > .#{$nv-prefix}children {
display: block;
}
&-title {
@extend .#{$app-prefix}category-title;
.#{$nv-prefix}item > .#{$nv-prefix}no-chld > ##{$nv-prefix}caret::before{
content:'';
}
padding: 3px 10px 5px 30px;
display: flex;
align-items: center;
.#{$nv-prefix}no-chld > .#{$nv-prefix}title-inn > ##{$nv-prefix}caret {
display:none;
}
&-inn {
position: relative;
}
}
.#{$nv-prefix}item > ##{$nv-prefix}move {
position: absolute;
cursor: move;
font-size: 12px;
right: 0; top: 0;
padding: 7px 10px 7px 5px;
}
/*
.#{$nv-prefix}item{
&.#{$nv-prefix}selected{
border: 2px solid $colorBlue;
}
}
*/
.#{$nv-prefix}selected .#{$nv-prefix}title {
background-color: rgba(255,255,255,0.1);
}
&-name {
padding: 5px;
display: inline-block;
box-sizing: content-box;
@extend .#{$app-prefix}no-user-select;
}
.#{$nv-prefix}nav-item-edit {
visibility: hidden;
padding: 5px;
font-size: 9px;
position: absolute;
left: -27px;
top: 1px;
> .#{$nv-prefix}layer-children {
display: none;
}
@include opacity(0.7);
&.open > .#{$nv-prefix}layer-children {
display: block;
}
&:hover {
@include opacity(1);
}
}
&-no-chld > .#{$nv-prefix}layer-title-inn > .#{$nv-prefix}layer-caret {
display: none;
}
.#{$nv-prefix}title-c:hover {
&-move {
padding: 7px 10px 7px 5px;
position: absolute;
font-size: 12px;
cursor: move;
right: 0;
top: 0;
}
.#{$nv-prefix}nav-item-edit {
visibility: visible;
cursor: pointer;
&.#{$nv-prefix}selected .#{$nv-prefix}layer-title {
background-color: rgba(255, 255, 255, 0.1);
}
}
}
.#{$app-prefix}nav-comp-name {
padding: 5px;
box-sizing: content-box;
@extend .#{$app-prefix}no-user-select;
.#{$app-prefix}layers {
position: relative;
height: 100%;
##{$nv-prefix}placeholder {
width: 100%;
position: absolute;
##{$nv-prefix}plh-int {
height: 100%;
padding: 1px;
&.#{$nv-prefix}insert {
background-color: $colorGreen;
}
}
}
}

71
src/styles/scss/_gjs_panels.scss

@ -0,0 +1,71 @@
.#{$pn-prefix} {
&panel {
display: inline-block;
position: absolute;
box-sizing: border-box;
text-align: center;
padding: 5px;
z-index: 3;
.icon-undo,
.icon-redo {
font-size: 20px;
height: 30px;
width: 25px;
}
}
&commands {
width: (100% - $leftWidth);
left: 0;
top: 0;
box-shadow: 0 0 5px $mainDkColor;
}
&options {
right: $leftWidth;
top: 0;
}
&views {
border-bottom: 2px solid $mainDkColor;
right: 0;
width: $leftWidth;
z-index: 4;
&-container {
height: 100%;
padding: 42px 0 0;
right: 0;
width: $leftWidth;
overflow: auto;
box-shadow: 0 0 5px $mainDkColor;
}
}
&buttons {
align-items: center;
display: flex;
justify-content: space-between;
}
&btn {
box-sizing: border-box;
height: 30px;
width: 30px;
line-height: 21px;
background-color: transparent;
border: none;
font-size: 18px;
margin-right: 5px;
border-radius: 2px;
padding: 5px;
position: relative;
cursor: pointer;
&.#{$pn-prefix}active {
background-color: rgba(0, 0, 0, 0.15);
box-shadow: 0 0 3px rgba(0, 0, 0, 0.25) inset;
}
}
}

91
src/styles/scss/_gjs_selectors.scss

@ -0,0 +1,91 @@
.#{$clm-prefix}field {
@extend .#{$sm-prefix}field
}
.#{$clm-prefix}select {
@extend .#{$sm-prefix}field.#{$sm-prefix}select;
}
.#{$clm-prefix}tags {
@extend .#{$sm-prefix}sector;
font-size: $fontSizeS;
padding: 10px 5px;
##{$clm-prefix}label,
##{$clm-prefix}sel {
padding: 7px 0;
float: left;
}
##{$clm-prefix}sel {
font-style: italic;
margin-left: 5px;
}
##{$clm-prefix}status-c {
float: right;
}
##{$clm-prefix}tags-field {
clear: both;
padding: 5px;
margin-bottom: 5px;
}
##{$clm-prefix}tags-c {
display: inline-block;
vertical-align: top;
}
##{$clm-prefix}add-tag {
background-color: rgba(255, 255, 255, 0.15);
border-radius: 2px;
padding: $paddElClm;
box-shadow: 1px 1px 0 rgba(255, 255, 255, 0.2) inset;
border: 1px solid rgba(0, 0, 0, 0.15);
cursor: pointer;
}
##{$clm-prefix}new {
@extend .#{$app-prefix}invis-invis;
color: $fontColor;
padding: $paddElClm;
display: none;
}
.#{$clm-prefix}tag {
display: inline-block;
border-radius: 3px;
margin: 0 3px 3px 0;
padding: 5px;
cursor: default;
}
##{$clm-prefix}close {
@extend .opac50;
font-size: 20px;
line-height: 0;
cursor: pointer;
color: rgba(255, 255, 255, 0.9);
@extend .no-select;
&:hover {
@include opacity(0.7);
}
}
##{$clm-prefix}checkbox {
color: rgba(255, 255, 255, 0.9);
vertical-align: middle;
cursor: pointer;
font-size: 9px;
}
##{$clm-prefix}tag-label {
padding: 0 3px;
cursor: text;
}
}

4
src/styles/scss/_gjs_style_manager.scss

@ -1,19 +1,17 @@
.#{$sm-prefix} {
&clear {
font-size: 1rem;
line-height: 0;
cursor: pointer;
}
&header {
font-size: 11px;
font-weight: lighter;
padding: 10px;
}
&properties {
font-size: 11px;
font-size: $fontSizeS;
padding: 10px 5px;
display: flex;
flex-wrap: wrap;

29
src/styles/scss/_gjs_traits.scss

@ -0,0 +1,29 @@
.#{$app-prefix} {
&traits-label {
border-bottom: 1px solid $mainDkColor;
font-weight: lighter;
margin-bottom: 5px;
padding: 10px;
text-align: left;
}
}
.#{$trt-prefix}trait {
display: flex;
justify-content: start;
padding: 5px 10px;
font-weight: lighter;
&s {
font-size: $fontSizeS;
}
.#{$app-prefix}label {
width: 30%;
text-align: left;
}
.#{$app-prefix}field {
width: 70%;
}
}

11
src/styles/scss/_gjs_variables.scss

@ -1,7 +1,7 @@
/* Class names prefixes */
$app-prefix: 'gjs-' !default;
$nv-prefix: $app-prefix + 'nv-' !default;
$nv-prefix: $app-prefix !default;
$rte-prefix: $app-prefix + 'rte-' !default;
$comp-prefix: $app-prefix + 'comp-' !default;
$mdl-prefix: $app-prefix + 'mdl-' !default;
@ -29,12 +29,6 @@ $mainColor: #444 !default; /* Light: #573454 Dark: #3b2639 -moz-linear-g
$fontColor: #ddd !default; /* l: #d8d7db */
$fontColorActive: #f8f8f8 !default;
/* Light theme
$mainColor: #fff;
$fontColor: #9299a3;
$fontColorActive: #4f8ef7;
*/
$mainDkColor: rgba(0, 0, 0, 0.2) !default;/* darken($mainColor, 4%) - #383838 */
$mainDklColor: rgba(0, 0, 0, 0.1) !default;
$mainLhColor: rgba(255, 255, 255, 0.1) !default; /* #515151 */
@ -80,4 +74,5 @@ $mainFont: Helvetica, sans-serif !default;
$fontPath: '../fonts' !default;
$fontName: 'main-fonts' !default;
$fontSize: 0.7rem;
$fontV: 20 !default;//random(1000)
$fontSizeS: 0.75rem;
$fontV: 20 !default;//random(1000)

237
src/styles/scss/main.scss

@ -215,7 +215,7 @@ $prefix: $app-prefix;
.#{$app-prefix}editor {
font-family: $mainFont;
font-size: $fontSize;
font-size: $fontSizeS;
position: relative;
box-sizing: border-box;
height: 100%;
@ -227,33 +227,7 @@ $prefix: $app-prefix;
pointer-events: none;
}
/************* TRAITS ****************/
.#{$app-prefix}traits-label {
border-bottom: 1px solid $mainDkColor;
font-size: 13px;
font-weight: lighter;
margin-bottom: 5px;
padding: 10px;
text-align: left;
}
.#{$trt-prefix}trait {
display: flex;
justify-content: start;
padding: 5px 10px;
font-weight: lighter;
.#{$app-prefix}label {
width: 30%;
text-align: left;
}
.#{$app-prefix}field {
width: 70%;
}
}
/************* CANVAS ****************/
@import "gjs_traits";
@import "gjs_canvas";
/********* COMMANDS **********/
@ -330,112 +304,7 @@ $prefix: $app-prefix;
outline: none;
}
/********* PANELS **********/
.#{$pn-prefix}panel {
//@extend .#{$app-prefix}bg-main;
//@extend .#{$app-prefix}color-main;
display: inline-block;
padding: 5px;
position: absolute;
box-sizing: border-box;
text-align: center;
z-index:3;
&##{$pn-prefix}commands{
width: (100% - $leftWidth);
left:0; top: 0;
box-shadow: 0 0 5px $mainDkColor;
}
&##{$pn-prefix}options{
right: $leftWidth;
top: 0;
}
&##{$pn-prefix}options2{
@extend ##{$pn-prefix}commands;
bottom: 150px;
height: auto;
}
.icon-undo, .icon-redo{
font-size: 20px;
height: 30px;
width: 25px;
}
&##{$pn-prefix}views{
border-bottom: 2px solid $mainDkColor;
right: 0;
width: $leftWidth;
z-index: 4;
}
&##{$pn-prefix}views-container{
height: 100%;
padding: 42px 0 0;
right: 0;
width: $leftWidth;
overflow: auto;
box-shadow: 0 0 5px $mainDkColor;
}
}
.#{$pn-prefix}buttons {
align-items: center;
display: flex;
justify-content: space-between;
}
.#{$pn-prefix}btn, .#{$app-prefix}btnt {
box-sizing: border-box;
height: 30px; width: 30px;
line-height: 21px;
background-color: transparent;
border:none;
font-size: 18px;
margin-right: 5px;
border-radius: 2px;
cursor: pointer;
padding: 5px;
position: relative;
&.#{$pn-prefix}active {
background-color: rgba(0, 0, 0, 0.15);
box-shadow: 0 0 3px rgba(0, 0, 0, 0.25) inset;
}
> .#{$pn-prefix}arrow-rd {
border-bottom: 5px solid $mainLhlColor;
border-left: 5px solid transparent;
bottom: 2px; right: 2px;
position: absolute;
}
> .#{$pn-prefix}buttons{
background-color: $mainColor;
border-radius: 2px;
position: absolute;
display: none;
left: 50px;
top: 0;
padding: 5px;
&.#{$pn-prefix}visible{ display: block; }
> .#{$pn-prefix}arrow-l {
border-bottom: 5px solid transparent;
border-right: 5px solid $mainColor;
border-top: 5px solid transparent;
left: -5px; top: 15px;
position: absolute;
}
}
}
/* pa-refresh pa-rocket pa-trash pa-columns pa-rotate-left/right */
.btn.expand{ background-image: none;}
@import 'gjs_panels';
/*********** Components *************/
@ -474,7 +343,6 @@ $prefix: $app-prefix;
font-weight: lighter;
background-color: $mainDklColor;
font-size: 13px;
letter-spacing: 1px;
padding: 9px 10px 9px 20px;
border-bottom: 1px solid rgba(0, 0, 0, 0.25);
@ -483,108 +351,11 @@ $prefix: $app-prefix;
cursor: pointer;
}
/********* Style Manager **********/
@import "gjs_style_manager";
/********* Blocks **********/
@import "gjs_blocks";
/************* Navigator *************/
@import "gjs_layers";
/********* Class manager **********/
.#{$clm-prefix}field{
@extend .#{$sm-prefix}field
}
.#{$clm-prefix}select{
@extend .#{$sm-prefix}field.#{$sm-prefix}select;
}
.#{$clm-prefix}tags{
@extend .#{$sm-prefix}sector;
font-size: 11px;
padding: 10px 5px;
##{$clm-prefix}label, ##{$clm-prefix}sel{
padding: 7px 0;
float:left;
}
##{$clm-prefix}sel{
font-style: italic;
margin-left: 5px;
}
##{$clm-prefix}status-c{
float:right;
}
##{$clm-prefix}tags-field{
clear:both;
padding: 5px;
margin-bottom: 5px;
}
##{$clm-prefix}tags-c{
display: inline-block;
vertical-align: top;
}
##{$clm-prefix}add-tag{
background-color: rgba(255, 255, 255, 0.15);
border-radius: 2px;
padding: $paddElClm;
box-shadow: 1px 1px 0 rgba(255, 255, 255, 0.2) inset;
border: 1px solid rgba(0, 0, 0, 0.15);
cursor: pointer;
}
##{$clm-prefix}new {
@extend .#{$app-prefix}invis-invis;
color: $fontColor;
padding: $paddElClm;
display:none;
}
.#{$clm-prefix}tag {
display: inline-block;
border-radius:3px;
margin: 0 3px 3px 0;
padding: 5px;
cursor: default;
}
##{$clm-prefix}close {
@extend .opac50;
font-size: 20px;
line-height: 0;
cursor:pointer;
color: rgba(255, 255, 255, 0.9);
@extend .no-select;
&:hover{
@include opacity(0.7);
}
}
##{$clm-prefix}checkbox {
color: rgba(255, 255, 255, 0.9);
vertical-align: middle;
cursor: pointer;
font-size: 9px;
}
##{$clm-prefix}tag-label {
padding: 0 3px;
cursor: text;
}
}
/********* END Class manager **********/
/********* Modal dialog **********/
@import "gjs_selectors";
@import "gjs_modal";
/********* Assets Manager **********/
@import "gjs_assets";
/********* File uploader **********/

4
src/trait_manager/config/config.js

@ -1,6 +1,10 @@
module.exports = {
stylePrefix: 'trt-',
// Specify the element to use as a container, string (query) or HTMLElement
// With the empty value, nothing will be rendered
appendTo: '',
labelContainer: 'Component settings',
// Placeholder label for text input types

20
src/trait_manager/index.js

@ -1,9 +1,10 @@
import { defaults } from 'underscore';
import { defaults, isElement } from 'underscore';
const defaultOpts = require('./config/config');
const TraitsView = require('./view/TraitsView');
module.exports = () => {
let c = {};
const defaultOpts = require('./config/config');
const TraitsView = require('./view/TraitsView');
let TraitsViewer;
return {
@ -42,6 +43,15 @@ module.exports = () => {
return this;
},
postRender() {
const elTo = this.getConfig().appendTo;
if (elTo) {
const el = isElement(elTo) ? elTo : document.querySelector(elTo);
el.appendChild(this.render());
}
},
/**
*
* Get Traits viewer
@ -68,6 +78,10 @@ module.exports = () => {
*/
getType(name) {
return TraitsViewer.itemsView[name];
},
render() {
return TraitsViewer.render().el;
}
};
};

11
src/trait_manager/view/TraitsView.js

@ -16,10 +16,12 @@ module.exports = DomainViews.extend({
color: TraitColorView
},
initialize(o) {
this.config = o.config || {};
initialize(o = {}) {
const config = o.config || {};
this.config = config;
this.em = o.editor;
this.pfx = this.config.stylePrefix || '';
this.pfx = config.stylePrefix || '';
this.ppfx = config.pStylePrefix || '';
this.className = this.pfx + 'traits';
this.listenTo(this.em, 'change:selectedComponent', this.updatedCollection);
this.updatedCollection();
@ -30,7 +32,8 @@ module.exports = DomainViews.extend({
* @private
*/
updatedCollection() {
this.el.className = this.className;
const ppfx = this.ppfx;
this.el.className = `${this.className} ${ppfx}one-bg ${ppfx}two-color`;
var comp = this.em.get('selectedComponent');
if (comp) {
this.collection = comp.get('traits');

73
src/utils/Resizer.js

@ -1,4 +1,4 @@
import { bindAll, defaults, isFunction } from 'underscore';
import { bindAll, defaults, isFunction, each } from 'underscore';
import { on, off, normalizeFloat } from 'utils/mixins';
var defaultOpts = {
@ -38,6 +38,13 @@ var defaultOpts = {
// from the current focused element (currently used only in SelectComponent)
currentUnit: 1,
// With this option active the mousemove event won't be altered when
// the pointer comes over iframes
silentFrames: 0,
// If true the container of handlers won't be updated
avoidContainerUpdate: 0,
// Handlers
tl: 1, // Top left
tc: 1, // Top center
@ -137,6 +144,17 @@ class Resizer {
this.onEnd = opts.onEnd;
}
/**
* Toggle iframes pointer event
* @param {Boolean} silent If true, iframes will be silented
*/
toggleFrames(silent) {
if (this.opts.silentFrames) {
const frames = document.querySelectorAll('iframe');
each(frames, frame => (frame.style.pointerEvents = silent ? 'none' : ''));
}
}
/**
* Detects if the passed element is a resize handler
* @param {HTMLElement} el
@ -170,11 +188,12 @@ class Resizer {
/**
* Return element position
* @param {HTMLElement} el
* @param {Object} opts Custom options
* @return {Object}
*/
getElementPos(el) {
getElementPos(el, opts = {}) {
var posFetcher = this.posFetcher || '';
return posFetcher ? posFetcher(el) : getBoundingRect(el);
return posFetcher ? posFetcher(el, opts) : getBoundingRect(el);
}
/**
@ -189,15 +208,19 @@ class Resizer {
// Show the handlers
this.el = el;
var unit = 'px';
var rect = this.getElementPos(el);
var container = this.container;
var contStyle = container.style;
contStyle.left = rect.left + unit;
contStyle.top = rect.top + unit;
contStyle.width = rect.width + unit;
contStyle.height = rect.height + unit;
container.style.display = 'block';
const config = this.opts;
const unit = 'px';
const rect = this.getElementPos(el, { target: 'container' });
const container = this.container;
const contStyle = container.style;
if (!config.avoidContainerUpdate) {
contStyle.left = rect.left + unit;
contStyle.top = rect.top + unit;
contStyle.width = rect.width + unit;
contStyle.height = rect.height + unit;
contStyle.display = 'block';
}
on(this.getDocumentEl(), 'mousedown', this.handleMouseDown);
}
@ -220,16 +243,14 @@ class Resizer {
*/
start(e) {
//Right or middel click
if (e.button !== 0) {
return;
}
if (e.button !== 0) return;
e.preventDefault();
e.stopPropagation();
const el = this.el;
const resizer = this;
const config = this.opts || {};
var attrName = 'data-' + config.prefix + 'handler';
var rect = this.getElementPos(el);
var rect = this.getElementPos(el, { target: 'el' });
this.handlerAttr = e.target.getAttribute(attrName);
this.clickedHandler = e.target;
this.startDim = {
@ -256,6 +277,7 @@ class Resizer {
on(doc, 'mouseup', this.stop);
isFunction(this.onStart) &&
this.onStart(e, { docs: doc, config, el, resizer });
this.toggleFrames(1);
this.move(e);
}
@ -307,6 +329,7 @@ class Resizer {
off(doc, 'keydown', this.handleKeyDown);
off(doc, 'mouseup', this.stop);
this.updateRect(1);
this.toggleFrames();
isFunction(this.onEnd) && this.onEnd(e, { docs: doc, config });
}
@ -321,7 +344,7 @@ class Resizer {
const conStyle = this.container.style;
const updateTarget = this.updateTarget;
const selectedHandler = this.getSelectedHandler();
const { unitHeight, unitWidth } = config;
const { unitHeight, unitWidth, keyWidth, keyHeight } = config;
// Use custom updating strategy if requested
if (isFunction(updateTarget)) {
@ -333,16 +356,18 @@ class Resizer {
});
} else {
const elStyle = el.style;
elStyle.width = rect.w + unitWidth;
elStyle.height = rect.h + unitHeight;
elStyle[keyWidth] = rect.w + unitWidth;
elStyle[keyHeight] = rect.h + unitHeight;
}
const unitRect = 'px';
const rectEl = this.getElementPos(el);
conStyle.left = rectEl.left + unitRect;
conStyle.top = rectEl.top + unitRect;
conStyle.width = rectEl.width + unitRect;
conStyle.height = rectEl.height + unitRect;
const rectEl = this.getElementPos(el, { target: 'container' });
if (!config.avoidContainerUpdate) {
conStyle.left = rectEl.left + unitRect;
conStyle.top = rectEl.top + unitRect;
conStyle.width = rectEl.width + unitRect;
conStyle.height = rectEl.height + unitRect;
}
}
/**

12
src/utils/Sorter.js

@ -1,4 +1,4 @@
import { isString } from 'underscore';
import { isString, isFunction } from 'underscore';
import { on, off, matches } from 'utils/mixins';
const $ = Backbone.$;
@ -670,7 +670,6 @@ module.exports = Backbone.View.extend({
const width = rect.width;
const height = rect.height;
//console.log(pos, {top, left});
if (
y < top + off || // near top edge
y > top + height - off || // near bottom edge
@ -719,8 +718,6 @@ module.exports = Backbone.View.extend({
width = el.offsetWidth;
}
//console.log('get dim', top, left, this.canvasRelative);
return [top, left, height, width];
},
@ -918,12 +915,11 @@ module.exports = Backbone.View.extend({
var clsReg = new RegExp('(?:^|\\s)' + this.freezeClass + '(?!\\S)', 'gi');
let src = this.eV;
if (src) {
if (src && this.selectOnEnd) {
var srcModel = this.getSourceModel();
if (srcModel && srcModel.set) {
srcModel.set('status', '');
srcModel.set('status', 'selected');
//this.selectOnEnd && srcModel.set('status', 'selected');
}
}
@ -932,9 +928,7 @@ module.exports = Backbone.View.extend({
}
if (this.plh) this.plh.style.display = 'none';
if (typeof this.onEndMove === 'function') this.onEndMove(created);
if (isFunction(this.onEndMove)) this.onEndMove(created, this);
var dragHelper = this.dragHelper;
if (dragHelper) {

Loading…
Cancel
Save