Browse Source

Merge branch 'page-manager' of github.com:artf/grapesjs into page-manager

pull/3411/head
Artur Arseniev 6 years ago
parent
commit
a949859f09
  1. 2
      dist/css/grapes.min.css
  2. 6
      package-lock.json
  3. 3
      src/canvas/config/config.js
  4. 5
      src/canvas/model/Frame.js
  5. 10
      src/canvas/view/CanvasView.js
  6. 3
      src/canvas/view/FrameView.js
  7. 46
      src/canvas/view/FrameWrapView.js
  8. 2
      src/code_manager/model/CssGenerator.js
  9. 10
      src/commands/view/CommandAbstract.js
  10. 30
      src/commands/view/SelectComponent.js
  11. 13
      src/css_composer/model/CssRule.js
  12. 4
      src/css_composer/model/CssRules.js
  13. 9
      src/css_composer/view/CssRuleView.js
  14. 37
      src/dom_components/model/Component.js
  15. 1
      src/dom_components/model/ComponentText.js
  16. 9
      src/dom_components/view/ComponentView.js
  17. 1
      src/editor/view/EditorView.js
  18. 210
      src/i18n/locale/se.js
  19. 10
      src/navigator/view/ItemView.js
  20. 13
      src/pages/index.js
  21. 1
      src/pages/model/Page.js
  22. 3
      src/panels/model/Buttons.js
  23. 50
      src/panels/view/ButtonView.js
  24. 14
      src/storage_manager/index.js
  25. 2
      src/style_manager/index.js
  26. 3
      src/styles/scss/_gjs_canvas.scss
  27. 7
      src/undo_manager/index.js
  28. 4
      src/utils/Sorter.js

2
dist/css/grapes.min.css

File diff suppressed because one or more lines are too long

6
package-lock.json

@ -18570,9 +18570,9 @@
"dev": true
},
"y18n": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
"integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
"dev": true
},
"yallist": {

3
src/canvas/config/config.js

@ -35,6 +35,9 @@ export default {
*/
autoscrollLimit: 50,
// Experimental: external highlighter box
extHl: 0,
/**
* When some textable component is selected and focused (eg. input or text component) the editor
* stops some commands (eg. disables the copy/paste of components with CTRL+C/V to allow the copy/paste of the text).

5
src/canvas/model/Frame.js

@ -141,6 +141,11 @@ export default Model.extend({
this.removeHeadByAttr('src', src, 'script');
},
getPage() {
const coll = this.collection;
return coll && coll.page;
},
_emitUpdated(data = {}) {
this.em.trigger('frame:updated', { frame: this, ...data });
},

10
src/canvas/view/CanvasView.js

@ -347,14 +347,15 @@ export default Backbone.View.extend({
const frms = model.get('frames');
frms.listenToLoad();
frames.render();
const mainFrame = frms.at(0).view;
em.setCurrentFrame(mainFrame);
const mainFrame = frms.at(0);
const currFrame = mainFrame && mainFrame.view;
em.setCurrentFrame(currFrame);
framesArea && framesArea.appendChild(frames.el);
this.frame = mainFrame;
this.frame = currFrame;
},
render() {
const { el, $el, ppfx, model, em, frames } = this;
const { el, $el, ppfx, config } = this;
$el.html(this.template());
const $frames = $el.find('[data-frames]');
this.framesArea = $frames.get(0);
@ -368,6 +369,7 @@ export default Backbone.View.extend({
</div>
</div>
<div id="${ppfx}tools" style="pointer-events:none">
${config.extHl ? `<div class="${ppfx}highlighter-sel"></div>` : ''}
<div class="${ppfx}badge"></div>
<div class="${ppfx}ghost"></div>
<div class="${ppfx}toolbar" style="pointer-events:all"></div>

3
src/canvas/view/FrameView.js

@ -143,8 +143,9 @@ export default Backbone.View.extend({
},
remove() {
const wrp = this.wrapper;
this._toggleEffects();
this.wrapper.remove();
wrp && wrp.remove();
Backbone.View.prototype.remove.apply(this, arguments);
},

46
src/canvas/view/FrameWrapView.js

@ -1,7 +1,7 @@
import Backbone from 'backbone';
import FrameView from './FrameView';
import { bindAll, isNumber, isNull, debounce } from 'underscore';
import { createEl, motionsEv } from 'utils/dom';
import { createEl } from 'utils/dom';
import Dragger from 'utils/Dragger';
export default Backbone.View.extend({
@ -73,13 +73,14 @@ export default Backbone.View.extend({
this.frame.remove(opts);
Backbone.View.prototype.remove.apply(this, arguments);
['frame', 'dragger', 'cv', 'em', 'canvas', 'elTools'].forEach(
i => (this[i] = {})
i => (this[i] = 0)
);
return this;
},
updateOffset: debounce(function() {
const { em, $el, frame } = this;
if (!em) return;
em.runDefault({ preserveSelected: 1 });
$el.removeClass(this.classAnim);
frame.model._emitUpdated();
@ -105,32 +106,25 @@ export default Backbone.View.extend({
*/
updateDim() {
const { em, el, $el, model, classAnim } = this;
const { width, height } = model.attributes;
const { style } = el;
const currW = style.width || '';
const currH = style.height || '';
const newW = width || '';
const newH = height || '';
const noChanges = currW == newW && currH == newH;
const un = 'px';
this.frame.rect = 0;
$el.addClass(classAnim);
style.width = isNumber(newW) ? `${newW}${un}` : newW;
style.height = isNumber(newH) ? `${newH}${un}` : newH;
const { noChanges, width, height } = this.__handleSize();
// Set width and height from DOM (should be done only once)
if (isNull(width) || isNull(height)) {
const newDims = {
...(!width ? { width: el.offsetWidth } : {}),
...(!height ? { height: el.offsetHeight } : {})
};
model.set(newDims, { silent: 1 });
model.set(
{
...(!width ? { width: el.offsetWidth } : {}),
...(!height ? { height: el.offsetHeight } : {})
},
{ silent: 1 }
);
}
// Prevent fixed highlighting box which appears when on
// component hover during the animation
em.stopDefault({ preserveSelected: 1 });
noChanges ? this.updateOffset() : $el.one(motionsEv, this.updateOffset);
noChanges ? this.updateOffset() : setTimeout(this.updateOffset, 350);
},
onScroll() {
@ -148,9 +142,25 @@ export default Backbone.View.extend({
this.updateDim();
},
__handleSize() {
const un = 'px';
const { model, el } = this;
const { style } = el;
const { width, height } = model.attributes;
const currW = style.width || '';
const currH = style.height || '';
const newW = width || '';
const newH = height || '';
const noChanges = currW == newW && currH == newH;
style.width = isNumber(newW) ? `${newW}${un}` : newW;
style.height = isNumber(newH) ? `${newH}${un}` : newH;
return { noChanges, width, height, newW, newH };
},
render() {
const { frame, $el, ppfx, cv, model, el } = this;
const { onRender } = model.attributes;
this.__handleSize();
frame.render();
$el
.empty()

2
src/code_manager/model/CssGenerator.js

@ -122,7 +122,7 @@ export default Backbone.Model.extend({
});
if ((selectorStrNoAdd && found) || selectorsAdd || singleAtRule) {
const block = rule.getDeclaration();
const block = rule.getDeclaration({ body: 1 });
block && (result += block);
} else {
dump.push(rule);

10
src/commands/view/CommandAbstract.js

@ -18,16 +18,6 @@ export default Backbone.View.extend({
this.freezClass = this.ppfx + 'freezed';
this.canvas = this.em.get && this.em.get('Canvas');
if (this.em.get) this.setElement(this.getCanvas());
if (this.canvas) {
this.$canvas = this.$el;
// this.frameEl = this.canvas.getFrameEl();
this.canvasTool = this.getCanvasTools();
// this.bodyEl = this.getCanvasBody();
}
this.init(this.config);
},

30
src/commands/view/SelectComponent.js

@ -613,7 +613,8 @@ export default {
}
const unit = 'px';
const { style } = this.toggleToolsEl(1, view);
const toolsEl = this.toggleToolsEl(1, view);
const { style } = toolsEl;
const frameOff = this.canvas.canvasRectOffset(el, pos);
const topOff = frameOff.top;
const leftOff = frameOff.left;
@ -629,12 +630,28 @@ export default {
style.left = leftOff + unit;
style.width = pos.width + unit;
style.height = pos.height + unit;
this._trgToolUp('local', {
component,
el: toolsEl,
top: topOff,
left: leftOff,
width: pos.width,
height: pos.height
});
},
_upToolbar: debounce(function() {
this.updateToolsGlobal({ force: 1 });
}),
_trgToolUp(type, opts = {}) {
this.em.trigger('canvas:tools:update', {
type,
...opts
});
},
updateToolsGlobal(opts = {}) {
const { el, pos, component } = this.getElSelected();
@ -653,7 +670,8 @@ export default {
}
const unit = 'px';
const { style } = this.toggleToolsEl(1);
const toolsEl = this.toggleToolsEl(1);
const { style } = toolsEl;
const targetToElem = canvas.getTargetToElementFixed(
el,
canvas.getToolbarEl(),
@ -667,6 +685,14 @@ export default {
style.height = pos.height + unit;
this.updateToolbarPos({ top: targetToElem.top, left: targetToElem.left });
this._trgToolUp('global', {
component,
el: toolsEl,
top: topOff,
left: leftOff,
width: pos.width,
height: pos.height
});
},
/**

13
src/css_composer/model/CssRule.js

@ -1,7 +1,7 @@
import { map } from 'underscore';
import Backbone from 'backbone';
import Styleable from 'domain_abstract/model/Styleable';
import { isEmpty, forEach } from 'underscore';
import { isEmpty, forEach, isString } from 'underscore';
import Selectors from 'selector_manager/model/Selectors';
import { isEmptyObj } from 'utils/mixins';
@ -63,7 +63,7 @@ export default Backbone.Model.extend(Styleable).extend({
return new this.constructor(attr, opts);
},
ensureSelectors() {
ensureSelectors(m, c, opts) {
const { em } = this;
const sm = em && em.get('SelectorManager');
const toListen = [this, 'change:selectors', this.ensureSelectors];
@ -74,12 +74,14 @@ export default Backbone.Model.extend(Styleable).extend({
sels = [...sels.models];
}
sels = isString(sels) ? [sels] : sels;
if (Array.isArray(sels)) {
const res = sels.filter(i => i).map(i => (sm ? sm.add(i) : i));
sels = new Selectors(res);
}
this.set('selectors', sels);
this.set('selectors', sels, opts);
this.listenTo(...toListen);
},
@ -102,11 +104,10 @@ export default Backbone.Model.extend(Styleable).extend({
*/
selectorsToString(opts = {}) {
const result = [];
const { em } = this;
const state = this.get('state');
const wrapper = this.get('wrapper');
const addSelector = this.get('selectorsAdd');
const isBody = wrapper && em && em.getConfig('wrapperIsBody');
const isBody = wrapper && opts.body;
const selOpts = {
escape: str => (CSS && CSS.escape ? CSS.escape(str) : str)
};
@ -126,7 +127,7 @@ export default Backbone.Model.extend(Styleable).extend({
*/
getDeclaration(opts = {}) {
let result = '';
const selectors = this.selectorsToString();
const selectors = this.selectorsToString(opts);
const style = this.styleToString(opts);
const singleAtRule = this.get('singleAtRule');

4
src/css_composer/model/CssRules.js

@ -22,8 +22,8 @@ export default Collection.extend({
return result.filter(i => i.style);
},
onAdd(model) {
model.ensureSelectors(); // required for undo
onAdd(model, c, o) {
model.ensureSelectors(model, c, o); // required for undo
},
onRemove(removed) {

9
src/css_composer/view/CssRuleView.js

@ -5,17 +5,16 @@ export default Backbone.View.extend({
initialize(o = {}) {
this.config = o.config || {};
const model = this.model;
const toTrack = 'change:style change:state change:mediaText';
this.listenTo(model, toTrack, this.render);
const { model } = this;
this.listenTo(model, 'change', this.render);
this.listenTo(model, 'destroy remove', this.remove);
this.listenTo(model.get('selectors'), 'change', this.render);
},
render() {
const model = this.model;
const { model, el } = this;
const important = model.get('important');
this.el.innerHTML = this.model.toCSS({ important });
el.innerHTML = model.toCSS({ important });
return this;
}
});

37
src/dom_components/model/Component.js

@ -30,6 +30,8 @@ export const eventDrag = 'component:drag';
export const keySymbols = '__symbols';
export const keySymbol = '__symbol';
export const keySymbol2w = '__symbol2w';
export const keyUpdate = 'component:update';
export const keyUpdateInside = `${keyUpdate}-inside`;
/**
* The Component object represents a single node of our template structure, so when you update its properties the changes are
@ -123,6 +125,8 @@ const Component = Backbone.Model.extend(Styleable).extend(
propagate: '',
dmode: '',
toolbar: null,
[keySymbol]: 0,
[keySymbols]: 0,
_undo: true,
_undoexc: ['status', 'open']
},
@ -196,6 +200,7 @@ const Component = Backbone.Model.extend(Styleable).extend(
this.listenTo(this, 'change:attributes:id', this._idUpdated);
this.on('change:toolbar', this.__emitUpdateTlb);
this.on('change', this.__onChange);
this.on(keyUpdateInside, this.__propToParent);
this.set('status', '');
this.views = [];
@ -241,7 +246,10 @@ const Component = Backbone.Model.extend(Styleable).extend(
name => delete changed[name]
);
// Propagate component prop changes
!isEmptyObj(changed) && this.__changesUp(opts);
if (!isEmptyObj(changed)) {
this.__changesUp(opts);
this.__propSelfToParent({ component: this, changed, options: opts });
}
},
__changesUp(opts) {
@ -249,6 +257,16 @@ const Component = Backbone.Model.extend(Styleable).extend(
[frame, em].forEach(md => md && md.changesUp(opts));
},
__propSelfToParent(props) {
this.trigger(keyUpdate, props);
this.__propToParent(props);
},
__propToParent(props) {
const parent = this.parent();
parent && parent.trigger(keyUpdateInside, props);
},
__emitUpdateTlb() {
this.emitUpdate('toolbar');
},
@ -1220,13 +1238,13 @@ const Component = Backbone.Model.extend(Styleable).extend(
cloned.unset(keySymbols);
} else if (symbol) {
// Contains already a reference to a symbol
symbol.get(keySymbols).push(cloned);
symbol.set(keySymbols, [...symbol.__getSymbols(), cloned]);
cloned.__initSymb();
} else if (opt.symbol) {
// Request to create a symbol
if (this.__isSymbol()) {
// Already a symbol, cloned should be an instance
this.get(keySymbols).push(cloned);
this.set(keySymbols, [...symbols, cloned]);
cloned.set(keySymbol, this);
cloned.__initSymb();
} else if (opt.symbolInv) {
@ -1539,17 +1557,24 @@ const Component = Backbone.Model.extend(Styleable).extend(
},
emitUpdate(property, ...args) {
const em = this.em;
const event = 'component:update' + (property ? `:${property}` : '');
const { em } = this;
const event = keyUpdate + (property ? `:${property}` : '');
const item = property && this.get(property);
property &&
this.updated(
property,
property && this.get(property),
item,
property && this.previous(property),
...args
);
this.trigger(event, ...args);
em && em.trigger(event, this, ...args);
['components', 'classes'].indexOf(property) >= 0 &&
this.__propSelfToParent({
component: this,
changed: { [property]: item },
options: args[2] || args[1] || {}
});
},
/**

1
src/dom_components/model/ComponentText.js

@ -9,7 +9,6 @@ export default Component.extend({
},
toHTML() {
this.trigger('sync:content', { silent: 1 });
return Component.prototype.toHTML.apply(this, arguments);
}
});

9
src/dom_components/view/ComponentView.js

@ -190,23 +190,24 @@ export default Backbone.View.extend({
* @private
* */
updateStatus(opts = {}) {
const em = this.em;
const { em } = this;
const { extHl } = em ? em.get('Canvas').getConfig() : {};
const el = this.el;
const status = this.model.get('status');
const pfx = this.pfx;
const ppfx = this.ppfx;
const selectedCls = `${ppfx}selected`;
const selectedParentCls = `${selectedCls}-parent`;
const freezedCls = `${ppfx}freezed`;
const hoveredCls = `${ppfx}hovered`;
const toRemove = [selectedCls, selectedParentCls, freezedCls, hoveredCls];
const selCls = extHl && !opts.noExtHl ? '' : selectedCls;
this.$el.removeClass(toRemove.join(' '));
var actualCls = el.getAttribute('class') || '';
var cls = '';
switch (status) {
case 'selected':
cls = `${actualCls} ${selectedCls}`;
cls = `${actualCls} ${selCls}`;
break;
case 'selected-parent':
cls = `${actualCls} ${selectedParentCls}`;
@ -215,7 +216,7 @@ export default Backbone.View.extend({
cls = `${actualCls} ${freezedCls}`;
break;
case 'freezed-selected':
cls = `${actualCls} ${freezedCls} ${selectedCls}`;
cls = `${actualCls} ${freezedCls} ${selCls}`;
break;
case 'hovered':
cls = !opts.avoidHover ? `${actualCls} ${hoveredCls}` : '';

1
src/editor/view/EditorView.js

@ -13,6 +13,7 @@ export default Backbone.View.extend({
model.once('change:ready', () => {
this.pn.active();
this.pn.disableButtons();
model.set('changesCount', 0);
setTimeout(() => {
model.trigger('load', model.get('Editor'));
});

210
src/i18n/locale/se.js

@ -0,0 +1,210 @@
const traitInputAttr = { placeholder: 't.ex. Text här' };
export default {
assetManager: {
addButton: 'Lägg till bild',
inputPlh: 'http://adress/till/bilden.jpg',
modalTitle: 'Välj bild',
uploadTitle: 'Dra och släpp filer här eller klicka för att ladda upp'
},
// Here just as a reference, GrapesJS core doesn't contain any block,
// so this should be omitted from other local files
blockManager: {
labels: {
// 'block-id': 'Block Label',
},
categories: {
// 'category-id': 'Category Label',
}
},
domComponents: {
names: {
'': 'Box',
wrapper: 'Body',
text: 'Text',
comment: 'Kommentar',
image: 'Bild',
video: 'Video',
label: 'Etikett',
link: 'Länk',
map: 'Karta',
tfoot: 'Tabellfot',
tbody: 'Tabellinnehåll',
thead: 'Tabellhuvud',
table: 'Tabell',
row: 'Tabellrad',
cell: 'Tabellcell'
}
},
deviceManager: {
device: 'Enhet',
devices: {
desktop: 'Dator',
tablet: 'Surfplatta',
mobileLandscape: 'Mobil liggande',
mobilePortrait: 'Mobil stående'
}
},
panels: {
buttons: {
titles: {
preview: 'Förhandsgranska',
fullscreen: 'Helskärm',
'sw-visibility': 'Visa komponenter',
'export-template': 'Visa kod',
'open-sm': 'Öppna stilhanterare',
'open-tm': 'Inställningar',
'open-layers': 'Öppna lagerhanterare',
'open-blocks': 'Öppna block'
}
}
},
selectorManager: {
label: 'Klasser',
selected: 'Markerad',
emptyState: '- Status -',
states: {
hover: 'Mus över',
active: 'Klick',
'nth-of-type(2n)': 'Jämn/udda'
}
},
styleManager: {
empty: 'Markera ett element innan du använder stilhanteraren',
layer: 'Lager',
fileButton: 'Bilder',
sectors: {
general: 'Allmänt',
layout: 'Layout',
typography: 'Typografi',
decorations: 'Dekoration',
extra: 'Extra',
flex: 'Flex',
dimension: 'Dimension'
},
// The core library generates the name by their `property` name
properties: {
float: 'Justering',
display: 'Visning',
position: 'Position',
top: 'Topp',
right: 'Höger',
left: 'Vänster',
bottom: 'Botten',
width: 'Bredd',
height: 'Höjd',
'max-width': 'Maxbredd',
'max-height': 'Maxhöjd',
margin: 'Marginal',
'margin-top': 'Övre marginal',
'margin-right': 'Höger marginal',
'margin-left': 'Vänster marginal',
'margin-bottom': 'Undre marginal',
padding: 'Utfyllnad',
'padding-top': 'Övre utfyllnad',
'padding-left': 'Vänster utfyllnad',
'padding-right': 'Höger utfyllnad',
'padding-bottom': 'Nedre utfyllnad',
'font-family': 'Typsnitt',
'font-size': 'Teckenstorlek',
'font-weight': 'Texttyngd',
'letter-spacing': 'Textmellanrum',
color: 'Färg',
'line-height': 'Radhöjd',
'text-align': 'Textjustering',
'text-shadow': 'Textskugga',
'text-shadow-h': 'Horisontell textskugga',
'text-shadow-v': 'Vertikal textskugga',
'text-shadow-blur': 'Textskuggans luddighet',
'text-shadow-color': 'Textskuggans färg',
'border-top-left': 'Vänster övre kantlinje',
'border-top-right': 'Höger övre kantlinje',
'border-bottom-left': 'Vänster nedre kantlinje',
'border-bottom-right': 'Höger nedre kantlinje',
'border-left': 'Vänster kantlinje',
'border-top': 'Övre kantlinje',
'border-right': 'Höger kantlinje',
'border-bottom': 'Nedre kantlinje',
'border-radius-top-left': 'Vänster övre hörnradie',
'border-radius-top-right': 'Höger övre hörnradie',
'border-radius-bottom-left': 'Vänster nedre hörnradie',
'border-radius-bottom-right': 'Höger nedre hörnradie',
'border-radius': 'Hörnradie',
border: 'Kantlinje',
'border-width': 'Kantbredd',
'border-style': 'Kantstil',
'border-color': 'Kantfärg',
'box-shadow': 'Skugga',
'box-shadow-h': 'Horisontell skugga',
'box-shadow-v': 'Vertikal skugga',
'box-shadow-blur': 'Skuggans luddighet',
'box-shadow-spread': "Skuggans spridning",
'box-shadow-color': "Skuggans färg",
'box-shadow-type': "Typ av skugga",
background: 'Bakgrund',
'background-image': 'Bakgrundsbild',
'background-repeat': 'Upprepa bakgrund',
'background-position': 'Bakgrundsplacering',
'background-attachment': 'Bakgrundslåsning',
'background-size': 'Bakgrundsstorlek',
'background-color': 'Bakgrundsfärg',
transition: 'Övergång',
'transition-property': 'Övergångstyp',
'transition-duration': 'Övergångens varaktighet',
'transition-timing-function': 'Övergångens tidsfunktion',
perspective: 'Perspektiv',
transform: 'Transformera',
'transform-rotate-x': 'Rotera längs X-axeln',
'transform-rotate-y': 'Rotera längs Y-axeln',
'transform-rotate-z': 'Rotera längs Z-axeln',
'transform-scale-x': 'Skala längs X-axeln',
'transform-scale-y': 'Skala längs Y-axeln',
'transform-scale-z': 'Skala längs Z-axeln',
'flex-direction': 'Flexriktning',
'flex-wrap': 'Flexbrytning',
'justify-content': 'Justera innehåll',
'align-items': 'Elementjustering',
'align-content': 'Innehållsjustering',
order: 'Ordning',
'flex-basis': 'Flexbas',
'flex-grow': 'Flex väx',
'flex-shrink': 'Flex krymp',
'align-self': 'Självjustering'
}
},
traitManager: {
empty: 'Markera ett element innan du använder egenskapshanteraren',
label: 'Komponentinställningar',
traits: {
// The core library generates the name by their `name` property
labels: {
// id: 'Id',
// alt: 'Alt',
title: 'Titel',
placeholder: 'Platshållartext',
value: 'Värde',
required: 'Obligatorisk',
selected: 'Markerad',
checked: 'Ikryssad',
type: 'Typ',
style: 'Stil',
class: 'Klass',
// href: 'Href',
},
// In a simple trait, like text input, these are used on input attributes
attributes: {
id: traitInputAttr,
alt: traitInputAttr,
title: traitInputAttr,
href: { placeholder: 't.ex. https://google.com' }
},
// In a trait like select, these are used to translate option names
options: {
target: {
false: 'Detta fönster',
_blank: 'Nytt fönster'
}
}
}
}
};

10
src/navigator/view/ItemView.js

@ -47,7 +47,7 @@ export default Backbone.View.extend({
}
<div class="${clsTitleC}">
<div class="${clsTitle}" style="padding-left: ${gut}" data-toggle-select>
<div class="${pfx}layer-title-inn">
<div class="${pfx}layer-title-inn" title="${name}">
<i class="${clsCaret}" data-toggle-open></i>
${icon ? `<span class="${clsBase}__icon">${icon}</span>` : ''}
<span class="${clsInput}" data-name>${name}</span>
@ -84,6 +84,7 @@ export default Backbone.View.extend({
this.listenTo(model, 'change:open', this.updateOpening);
this.listenTo(model, 'change:layerable', this.updateLayerable);
this.listenTo(model, 'change:style:display', this.updateVisibility);
this.listenTo(model, 'rerender:layer', this.render);
this.className = `${pfx}layer ${pfx}layer__t-${type} no-select ${ppfx}two-color`;
this.inputNameCls = `${ppfx}layer-name`;
this.clsTitleC = `${pfx}layer-title-c`;
@ -312,7 +313,8 @@ export default Backbone.View.extend({
updateStatus(e) {
ComponentView.prototype.updateStatus.apply(this, [
{
avoidHover: !this.config.highlightHover
avoidHover: !this.config.highlightHover,
noExtHl: 1
}
]);
},
@ -441,6 +443,8 @@ export default Backbone.View.extend({
__render() {
const { model, config, el } = this;
const { onRender } = config;
onRender.bind(this)({ component: model, el });
const opt = { component: model, el };
onRender.bind(this)(opt);
this.em.trigger('layer:render', opt);
}
});

13
src/pages/index.js

@ -7,11 +7,13 @@ import Page from './model/Page';
export const evAll = 'page';
export const evPfx = `${evAll}:`;
export const evPageSelect = `${evPfx}select`;
export const evPageSelectBefore = `${evPageSelect}:before`;
export const evPageUpdate = `${evPfx}update`;
export const evPageAdd = `${evPfx}add`;
export const evPageAddBefore = `${evPageAdd}:before`;
export const evPageRemove = `${evPfx}remove`;
export const evPageRemoveBefore = `${evPageRemove}:before`;
const chnSel = 'change:selected';
const typeMain = 'main';
export default () => {
@ -27,6 +29,7 @@ export default () => {
events: {
all: evAll,
select: evPageSelect,
selectBefore: evPageSelectBefore,
update: evPageUpdate,
add: evPageAdd,
addBefore: evPageAddBefore,
@ -56,7 +59,7 @@ export default () => {
});
pages.on('reset', coll => coll.at(0) && this.select(coll.at(0)));
pages.on('all', this.__onChange, this);
model.on('change:selected', this._onPageChange);
model.on(chnSel, this._onPageChange);
return this;
},
@ -76,12 +79,13 @@ export default () => {
this.select(mainPage, opt);
},
_onPageChange(m, page) {
_onPageChange(m, page, opts) {
const { em } = this;
const lm = em.get('LayerManager');
const mainComp = page.getMainComponent();
lm && mainComp && lm.setRoot(mainComp);
em.trigger(evPageSelect, page, m.previous('selected'));
this.__onChange(chnSel, page, opts);
},
postLoad() {
@ -165,7 +169,10 @@ export default () => {
*/
select(pg, opts = {}) {
const page = isString(pg) ? this.get(pg) : pg;
page && this.model.set('selected', page, opts);
if (page) {
this.em.trigger(evPageSelectBefore, page, opts);
this.model.set('selected', page, opts);
}
return this;
},

1
src/pages/model/Page.js

@ -20,6 +20,7 @@ export default Model.extend({
}
const frms = props.frames || [defFrame];
const frames = new Frames(frms, config);
frames.page = this;
this.set('frames', frames);
const um = em && em.get('UndoManager');
um && um.add(frames);

3
src/panels/model/Buttons.js

@ -31,8 +31,7 @@ export default Backbone.Collection.extend({
const context = ctx || '';
this.forEach(model => {
if (model.get('context') == context && model !== sender) {
model.set('active', false, { silent: 1 });
model.trigger('updateActive', { fromCollection: 1 });
model.set('active', false, { fromCollection: 1 });
}
});
},

50
src/panels/view/ButtonView.js

@ -13,27 +13,41 @@ export default Backbone.View.extend({
},
initialize(o) {
var cls = this.model.get('className');
this.config = o.config || {};
this.em = this.config.em || {};
const { model } = this;
const cls = model.get('className');
const { command, listen } = model.attributes;
const config = o.config || {};
const { em } = config;
this.config = config;
this.em = em;
const pfx = this.config.stylePrefix || '';
const ppfx = this.config.pStylePrefix || '';
this.pfx = pfx;
this.ppfx = this.config.pStylePrefix || '';
this.id = pfx + this.model.get('id');
this.id = pfx + model.get('id');
this.activeCls = `${pfx}active ${ppfx}four-color`;
this.disableCls = `${ppfx}disabled`;
this.btnsVisCls = `${pfx}visible`;
this.className = pfx + 'btn' + (cls ? ' ' + cls : '');
this.listenTo(this.model, 'change', this.render);
this.listenTo(this.model, 'change:active updateActive', this.updateActive);
this.listenTo(this.model, 'checkActive', this.checkActive);
this.listenTo(this.model, 'change:bntsVis', this.updateBtnsVis);
this.listenTo(this.model, 'change:attributes', this.updateAttributes);
this.listenTo(this.model, 'change:className', this.updateClassName);
this.listenTo(this.model, 'change:disable', this.updateDisable);
if (this.em && this.em.get) this.commands = this.em.get('Commands');
this.listenTo(model, 'change', this.render);
this.listenTo(model, 'change:active updateActive', this.updateActive);
this.listenTo(model, 'checkActive', this.checkActive);
this.listenTo(model, 'change:bntsVis', this.updateBtnsVis);
this.listenTo(model, 'change:attributes', this.updateAttributes);
this.listenTo(model, 'change:className', this.updateClassName);
this.listenTo(model, 'change:disable', this.updateDisable);
if (em && isString(command) && listen) {
const chnOpt = { fromListen: 1 };
this.listenTo(em, `run:${command}`, () =>
model.set('active', true, chnOpt)
);
this.listenTo(em, `stop:${command}`, () =>
model.set('active', false, chnOpt)
);
}
if (em && em.get) this.commands = em.get('Commands');
},
/**
@ -81,9 +95,9 @@ export default Backbone.View.extend({
*
* @return void
* */
updateActive(opts = {}) {
updateActive(m, v, opts = {}) {
const { model, commands, $el, activeCls } = this;
const { fromCollection } = opts;
const { fromCollection, fromListen } = opts;
const context = model.get('context');
const options = model.get('options');
const commandName = model.get('command');
@ -102,13 +116,15 @@ export default Backbone.View.extend({
if (model.get('active')) {
!fromCollection && model.collection.deactivateAll(context, model);
model.set('active', true, { silent: true }).trigger('checkActive');
commands.runCommand(command, { ...options, sender: model });
!fromListen &&
commands.runCommand(command, { ...options, sender: model });
// Disable button if the command has no stop method
command.noStop && model.set('active', false);
} else {
$el.removeClass(activeCls);
commands.stopCommand(command, { ...options, sender: model, force: 1 });
!fromListen &&
commands.stopCommand(command, { ...options, sender: model, force: 1 });
}
},

14
src/storage_manager/index.js

@ -37,6 +37,7 @@ import LocalStorage from './model/LocalStorage';
import RemoteStorage from './model/RemoteStorage';
const eventStart = 'storage:start';
const eventAfter = 'storage:after';
const eventEnd = 'storage:end';
const eventError = 'storage:error';
@ -214,6 +215,7 @@ export default () => {
? st.store(
toStore,
res => {
this.onAfter('store', res);
clb && clb(res);
this.onEnd('store', res);
},
@ -259,6 +261,7 @@ export default () => {
result[itemKeyR] = res[itemKey];
}
this.onAfter('load', result);
clb && clb(result);
this.onEnd('load', result);
},
@ -301,6 +304,17 @@ export default () => {
}
},
/**
* On after callback (before passing data to the callback)
* @private
*/
onAfter(ctx, data) {
if (em) {
em.trigger(eventAfter);
ctx && em.trigger(`${eventAfter}:${ctx}`, data);
}
},
/**
* On end callback
* @private

2
src/style_manager/index.js

@ -299,7 +299,7 @@ export default () => {
} else if (config.avoidInlineStyle) {
rule = cssC.getIdRule(id, opts);
!rule && !skipAdd && (rule = cssC.setIdRule(id, {}, opts));
if (model.is('wrapper')) rule.set('wrapper', 1);
if (model.is('wrapper')) rule.set('wrapper', 1, addOpts);
}
rule && (model = rule);

3
src/styles/scss/_gjs_canvas.scss

@ -244,7 +244,8 @@ $guide_pad: 5px;
}
.#{$app-prefix}highlighter-sel {
outline: 3px solid $colorBlue;
outline: 2px solid $colorBlue;
outline-offset: -2px;
}
##{$app-prefix}tools, .#{$app-prefix}tools {

7
src/undo_manager/index.js

@ -108,9 +108,10 @@ export default () => {
}
});
um.on('undo redo', () =>
em.trigger('component:toggled change:canvasOffset')
);
um.on('undo redo', () => {
em.trigger('component:toggled change:canvasOffset');
em.getSelectedAll().map(c => c.trigger('rerender:layer'));
});
['undo', 'redo'].forEach(ev => um.on(ev, () => em.trigger(ev)));
return this;

4
src/utils/Sorter.js

@ -1112,7 +1112,7 @@ export default Backbone.View.extend({
modelToDrop = model.collection.remove(model, { temporary: 1 });
}
} else {
modelToDrop = dropContent;
modelToDrop = isFunction(dropContent) ? dropContent() : dropContent;
opts.silent = false;
opts.avoidUpdateStyle = 1;
}
@ -1156,7 +1156,7 @@ export default Backbone.View.extend({
}
if (em) {
em.trigger('component:dragEnd', targetCollection, modelToDrop, warns); // @depricated
em.trigger('component:dragEnd', targetCollection, modelToDrop, warns); // @deprecated
em.trigger('sorter:drag:end', {
targetCollection,
modelToDrop,

Loading…
Cancel
Save