Browse Source

General bugfixes, Add toolbars

pull/72/head
Artur Arseniev 9 years ago
parent
commit
cd6cdae523
  1. 12
      index.html
  2. 33
      src/canvas/main.js
  3. 9
      src/canvas/view/CanvasView.js
  4. 51
      src/commands/main.js
  5. 4
      src/commands/view/SelectComponent.js
  6. 4
      src/dom_components/model/Component.js
  7. 10
      src/editor/config/config.js
  8. 5
      src/editor/main.js
  9. 12
      src/editor/view/EditorView.js
  10. 27
      src/rich_text_editor/main.js
  11. 12
      styles/css/main.css
  12. 15
      styles/scss/main.scss

12
index.html

@ -9,18 +9,6 @@
</head> </head>
<style> <style>
body, html{ height: 100%; margin: 0;} body, html{ height: 100%; margin: 0;}
#gjs ::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.1);
}
#gjs ::-webkit-scrollbar-thumb {
background-color: rgba(255, 255, 255, 0.2);
}
#gjs ::-webkit-scrollbar {
width: 7px;
}
</style> </style>
<body> <body>

33
src/canvas/main.js

@ -179,6 +179,39 @@ define(function(require) {
}; };
}, },
/**
* This method comes handy when you need to attach something like toolbars
* to elements inside the canvas, dealing with all relative position,
* offsets, etc. and returning as result the object with positions which are
* viewable by the user (when the canvas is scrolled the top edge of the element
* is not viewable by the user anymore so the new top edge is the one of the canvas)
*
* The target should be visible before being passed here as invisible elements
* return empty string as width
* @param {HTMLElement} target The target in this case could be the toolbar
* @param {HTMLElement} element The element on which I'd attach the toolbar
* @param {Boolean} toRight Set to true if you want the toolbar attached to the right
* @return {Object}
*/
getTargetToElementDim: function (target, element, toRight) {
var canvasPos = CanvasView.getPosition();
var pos = CanvasView.getElementPos(element);
var elTop = pos.top - target.offsetHeight;
var elLeft = pos.left;
elLeft += toRight ? pos.width : 0;
elLeft = toRight ? (elLeft - target.offsetWidth) : elLeft;
var leftPos = elLeft < canvasPos.left ? canvasPos.left : elLeft;
var topPos = elTop < canvasPos.top ? canvasPos.top : elTop;
topPos = topPos > (pos.top + pos.height) ? (pos.top + pos.height) : topPos;
return {
top: topPos,
left: leftPos
};
},
/** /**
* Returns wrapper element * Returns wrapper element
* @return {HTMLElement} * @return {HTMLElement}

9
src/canvas/view/CanvasView.js

@ -27,6 +27,7 @@ function(Backbone, FrameView) {
var body = this.frame.el.contentDocument.body; var body = this.frame.el.contentDocument.body;
this.toolsEl.style.top = '-' + body.scrollTop + u; this.toolsEl.style.top = '-' + body.scrollTop + u;
this.toolsEl.style.left = '-' + body.scrollLeft + u; this.toolsEl.style.left = '-' + body.scrollLeft + u;
this.em.trigger('canvasScroll');
}, },
/** /**
@ -42,12 +43,16 @@ function(Backbone, FrameView) {
var conf = this.config.em.get('Config'); var conf = this.config.em.get('Config');
body.append(wrap.render()).append(cssc.render()); body.append(wrap.render()).append(cssc.render());
var protCss = conf.protectedCss; var protCss = conf.protectedCss;
var frameCss = '.' + ppfx + 'dashed *{outline: 1px dashed rgba(170,170,170,0.7); outline-offset: -2px}' + var frameCss = '.' + ppfx + 'dashed :not([contenteditable]) > *{outline: 1px dashed rgba(170,170,170,0.7); outline-offset: -2px}' +
'.' + ppfx + 'comp-selected{outline: 3px solid #3b97e3 !important}' + '.' + ppfx + 'comp-selected{outline: 3px solid #3b97e3 !important}' +
'.' + ppfx + 'no-select{user-select: none; -webkit-user-select:none; -moz-user-select: none}'+ '.' + ppfx + 'no-select{user-select: none; -webkit-user-select:none; -moz-user-select: none}'+
'.' + ppfx + 'freezed{opacity: 0.5; pointer-events: none}' + '.' + ppfx + 'freezed{opacity: 0.5; pointer-events: none}' +
'.' + ppfx + 'no-pointer{pointer-events: none}' + '.' + ppfx + 'no-pointer{pointer-events: none}' +
'.' + ppfx + 'plh-image{background:#f5f5f5; border:none; height:50px; width:50px; display:block; outline:3px solid #ffca6f; cursor:pointer}'; '.' + ppfx + 'plh-image{background:#f5f5f5; border:none; height:50px; width:50px; display:block; outline:3px solid #ffca6f; cursor:pointer}' +
'* ::-webkit-scrollbar-track {background: rgba(0, 0, 0, 0.1)}' +
'* ::-webkit-scrollbar-thumb {background: rgba(255, 255, 255, 0.2)}' +
'* ::-webkit-scrollbar {width: 10px}' +
(conf.canvasCss || '');
if(protCss) if(protCss)
body.append('<style>' + frameCss + protCss + '</style>'); body.append('<style>' + frameCss + protCss + '</style>');
this.config.em.trigger('loaded'); this.config.em.trigger('loaded');

51
src/commands/main.js

@ -101,7 +101,56 @@ define(function(require) {
defaultCommands['open-assets'] = require('./view/OpenAssets'); defaultCommands['open-assets'] = require('./view/OpenAssets');
defaultCommands.fullscreen = require('./view/Fullscreen'); defaultCommands.fullscreen = require('./view/Fullscreen');
defaultCommands.preview = require('./view/Preview'); defaultCommands.preview = require('./view/Preview');
//this.defaultCommands['resize-comp'] = require('./view/ResizeComponent');
defaultCommands['tlb-delete'] = {
run: function(ed){
var sel = ed.getSelected();
if(!sel || !sel.get('removable')) {
console.warn('The element is not removable');
return;
}
sel.destroy();
ed.Canvas.getToolbarEl().style.display = 'none';
},
};
defaultCommands['tlb-clone'] = {
run: function(ed){
var sel = ed.getSelected();
if(!sel || !sel.get('copyable')) {
console.warn('The element is not clonable');
return;
}
var collection = sel.collection;
var index = collection.indexOf(sel);
collection.add(sel.clone(), {at: index + 1});
},
};
defaultCommands['tlb-move'] = {
run: function(ed){
var sel = ed.getSelected();
var toolbarEl = ed.Canvas.getToolbarEl();
var toolbarDisplay = toolbarEl.style.display;
var cmdMove = ed.Commands.get('move-comp');
cmdMove.onEndMoveFromModel = function() {
ed.editor.runDefault();
ed.editor.set('selectedComponent', sel);
//toolbarEl.style.display = toolbarDisplay;
//ed.trigger('canvasScroll'); <- Need first this on SelectComponent
};
ed.editor.stopDefault();
cmdMove.initSorterFromModel(sel);
sel.set('status', 'selected');
toolbarEl.style.display = 'none';
},
};
if(c.em) if(c.em)
c.model = c.em.get('Canvas'); c.model = c.em.get('Canvas');

4
src/commands/view/SelectComponent.js

@ -253,6 +253,7 @@ define(function(require) {
* @param {Object} model * @param {Object} model
*/ */
updateToolbar: function(model) { updateToolbar: function(model) {
// if no model get the selectedOne
var toolbar = model.get('toolbar'); var toolbar = model.get('toolbar');
var ppfx = this.ppfx; var ppfx = this.ppfx;
var showToolbar = this.config.em.get('Config').showToolbar; var showToolbar = this.config.em.get('Config').showToolbar;
@ -300,8 +301,9 @@ define(function(require) {
var topPos = elTop < canvasPos.top ? canvasPos.top : elTop; var topPos = elTop < canvasPos.top ? canvasPos.top : elTop;
// This will stop the toolbar when the end of the element is reached // This will stop the toolbar when the end of the element is reached
topPos = topPos > (pos.top + pos.height) ? (pos.top + pos.height) : topPos; topPos = topPos > (pos.top + pos.height) ? (pos.top + pos.height) : topPos;
toolbarStyle.left = elLeft + unit;
toolbarStyle.top = topPos + unit; toolbarStyle.top = topPos + unit;
toolbarStyle.left = leftPos + unit;
}, },
/** /**

4
src/dom_components/model/Component.js

@ -58,6 +58,7 @@ define(['backbone','./Components', 'SelectorManager/model/Selectors', 'TraitMana
if(opt && opt.config && opt.config.voidElements.indexOf(this.get('tagName')) >= 0) if(opt && opt.config && opt.config.voidElements.indexOf(this.get('tagName')) >= 0)
this.set('void', true); this.set('void', true);
this.opt = opt;
this.sm = opt ? opt.sm || {} : {}; this.sm = opt ? opt.sm || {} : {};
this.config = o || {}; this.config = o || {};
this.defaultC = this.config.components || []; this.defaultC = this.config.components || [];
@ -143,7 +144,8 @@ define(['backbone','./Components', 'SelectorManager/model/Selectors', 'TraitMana
} }
attr.status = ''; attr.status = '';
attr.view = ''; attr.view = '';
return new this.constructor(attr, {sm: this.sm});
return new this.constructor(attr, this.opt);
}, },
/** /**

10
src/editor/config/config.js

@ -20,14 +20,18 @@ define(function () {
// Width for the editor container // Width for the editor container
width: '100%', width: '100%',
// The css that could only be seen (for instance, inside the code viewer) // CSS that could only be seen (for instance, inside the code viewer)
protectedCss: '*{box-sizing: border-box;}body{margin:0;height:100%}#wrapper{min-height:100%; overflow:auto}', protectedCss: '*{box-sizing: border-box;}body{margin:0;height:100%;background:#fff}#wrapper{min-height:100%; overflow:auto}',
// CSS for the iframe which containing the canvas, useful if you need to custom something inside
// (eg. the style of the selected component)
canvasCss: '',
// Default command // Default command
defaultCommand: 'select-comp', defaultCommand: 'select-comp',
// Show a toolbar when the component is selected // Show a toolbar when the component is selected
showToolbar: 0, showToolbar: 1,
// Allow script tag importing // Allow script tag importing
allowScripts: 0, allowScripts: 0,

5
src/editor/main.js

@ -27,8 +27,9 @@
* var editor = grapesjs.init({...}); * var editor = grapesjs.init({...});
* ``` * ```
* Available events * Available events
* #run:{commandName} * #canvasScroll: - Triggered when the canvas is scrolled
* #stop:{commandName} * #run:{commandName} - Triggered when some command is called to run (eg. editor.runCommand('preview'))
* #stop:{commandName} - Triggered when some command is called to stop (eg. editor.stopCommand('preview'))
* #load - When the editor is loaded * #load - When the editor is loaded
* *
* @module Editor * @module Editor

12
src/editor/view/EditorView.js

@ -14,26 +14,26 @@ function(Backbone){
}, this); }, this);
}, },
render: function(){ render: function() {
var conf = this.conf; var conf = this.conf;
var contEl = $(conf.el || ('body ' + conf.container));
this.$el.empty(); this.$el.empty();
this.$cont = $(conf.el || ('body ' + conf.container));
if(conf.width) if(conf.width)
this.$cont.css('width', conf.width); contEl.css('width', conf.width);
if(conf.height) if(conf.height)
this.$cont.css('height', conf.height); contEl.css('height', conf.height);
// Canvas // Canvas
this.$el.append(this.model.get('Canvas').render()); this.$el.append(this.model.get('Canvas').render());
// Panels // Panels
this.$el.append(this.pn.render()); this.$el.append(this.pn.render());
this.$el.attr('class', this.className); this.$el.attr('class', this.className);
this.$cont.html(this.$el); contEl.addClass(conf.stylePrefix + 'editor-cont');
contEl.html(this.$el);
return this; return this;
} }

27
src/rich_text_editor/main.js

@ -115,16 +115,12 @@ define(function(require) {
* @private * @private
*/ */
udpatePosition: function(){ udpatePosition: function(){
if(!this.lastEl || !c.em) var u = 'px';
return; var canvas = c.em.get('Canvas');
var u = 'px'; var pos = canvas.getTargetToElementDim(toolbar.el, this.lastEl, 1);
var eOffset = c.em.get('canvasOffset'); var toolbarStyle = toolbar.el.style;
var cvsView = c.em.get('Canvas').getCanvasView(); toolbarStyle.top = pos.top + u;
var dims = cvsView.getElementPos(this.lastEl); toolbarStyle.left = pos.left + u;
var toolS = toolbar.el.style;
var toolH = toolbar.$el.outerHeight();
toolS.top = (dims.top - toolH) + u;
toolS.left = (dims.left + eOffset.left) + u;
}, },
/** /**
@ -136,12 +132,19 @@ define(function(require) {
view.$el.wysiwyg({}).focus(); view.$el.wysiwyg({}).focus();
this.lastEl = view.el; this.lastEl = view.el;
this.show();
if(c.em){ if(c.em){
this.udpatePosition(); this.udpatePosition();
c.em.off('change:canvasOffset', this.udpatePosition, this); c.em.off('change:canvasOffset', this.udpatePosition, this);
c.em.on('change:canvasOffset', this.udpatePosition, this); c.em.on('change:canvasOffset', this.udpatePosition, this);
// Update position on scrolling
c.em.off('canvasScroll', this.udpatePosition, this);
c.em.on('canvasScroll', this.udpatePosition, this);
} }
this.show();
//Avoid closing edit mode clicking on toolbar //Avoid closing edit mode clicking on toolbar
toolbar.$el.on('mousedown', this.disableProp); toolbar.$el.on('mousedown', this.disableProp);
}, },
@ -202,4 +205,4 @@ define(function(require) {
}; };
}; };
}); });

12
styles/css/main.css

@ -2661,6 +2661,15 @@ $fontColorActive: #4f8ef7;
padding: 5px; padding: 5px;
cursor: pointer; } cursor: pointer; }
.gjs-editor-cont ::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.1); }
.gjs-editor-cont ::-webkit-scrollbar-thumb {
background-color: rgba(255, 255, 255, 0.2); }
.gjs-editor-cont ::-webkit-scrollbar {
width: 8px; }
/********************* MAIN ************************/ /********************* MAIN ************************/
.clear { .clear {
clear: both; } clear: both; }
@ -2758,7 +2767,6 @@ div.gjs-select {
z-index: 1; z-index: 1;
/* This simulate body behaviour */ } /* This simulate body behaviour */ }
.gjs-cv-canvas > iframe { .gjs-cv-canvas > iframe {
background-color: #fff;
height: 100%; height: 100%;
outline: medium none; outline: medium none;
width: 100%; width: 100%;
@ -3970,7 +3978,7 @@ ol.example li.placeholder:before {
position: absolute; position: absolute;
border-radius: 3px; border-radius: 3px;
overflow: hidden; overflow: hidden;
z-index: 5; } z-index: 10; }
#gjs-rte-toolbar .gjs-rte-btn { #gjs-rte-toolbar .gjs-rte-btn {
display: inline-block; display: inline-block;
padding: 5px; padding: 5px;

15
styles/scss/main.scss

@ -162,6 +162,18 @@ $fontV: 20;//random(1000)
cursor: pointer; cursor: pointer;
} }
.#{$app-prefix}editor-cont ::-webkit-scrollbar-track {
background: $mainDklColor;
}
.#{$app-prefix}editor-cont ::-webkit-scrollbar-thumb {
background-color: rgba(255, 255, 255, 0.2);
}
.#{$app-prefix}editor-cont ::-webkit-scrollbar {
width: 8px;
}
/********************* MAIN ************************/ /********************* MAIN ************************/
.clear{ clear:both } .clear{ clear:both }
@ -274,7 +286,6 @@ div.#{$app-prefix}select {
z-index:1; z-index:1;
> iframe { > iframe {
background-color: #fff;
height: 100%; height: 100%;
outline: medium none; outline: medium none;
width: 100%; width: 100%;
@ -1430,7 +1441,7 @@ $uploadPadding: 150px 10px;
position: absolute; position: absolute;
border-radius: 3px; border-radius: 3px;
overflow: hidden; overflow: hidden;
z-index: 5; z-index: 10;
.#{$rte-prefix}btn { .#{$rte-prefix}btn {
@extend .#{$app-prefix}color-main; @extend .#{$app-prefix}color-main;

Loading…
Cancel
Save