Browse Source

Add new event trigger and the drag helper for the sorter

Now it's possible to listen new components added to the canvas (check
editor API Refs). Added the possibility to create faster drag helper
while dragging stuff
pull/72/head
Artur Arseniev 9 years ago
parent
commit
a5a128e544
  1. 2
      bower.json
  2. 2
      dist/css/grapes.min.css
  3. 26
      dist/grapes.min.js
  4. 2
      package.json
  5. 4
      src/block_manager/view/BlockView.js
  6. 27
      src/block_manager/view/BlocksView.js
  7. 8
      src/dom_components/view/ComponentsView.js
  8. 3
      src/editor/main.js
  9. 11
      src/editor/model/Editor.js
  10. 7
      src/navigator/view/ItemView.js
  11. 88
      src/utils/Sorter.js
  12. 50
      styles/css/main.css
  13. 44
      styles/scss/main.scss

2
bower.json

@ -1,7 +1,7 @@
{
"name": "grapesjs",
"description": "Open source Web Template Editor",
"version": "0.3.71",
"version": "0.3.72",
"author": "Artur Arseniev",
"homepage": "http://grapesjs.com",
"main": [

2
dist/css/grapes.min.css

File diff suppressed because one or more lines are too long

26
dist/grapes.min.js

File diff suppressed because one or more lines are too long

2
package.json

@ -1,7 +1,7 @@
{
"name": "grapesjs",
"description": "Open source Web Template Editor",
"version": "0.3.71",
"version": "0.3.72",
"author": "Artur Arseniev",
"license": "BSD-3-Clause",
"homepage": "http://grapesjs.com",

4
src/block_manager/view/BlockView.js

@ -19,12 +19,12 @@ function(Backbone) {
* Start block dragging
* @private
*/
onDrag: function() {
onDrag: function(e) {
if(!this.config.getSorter)
return;
this.config.em.refreshCanvas();
var sorter = this.config.getSorter();
//this.config.dragHelper(this.el.cloneNode(1));
sorter.setDragHelper(this.el, e);
sorter.startSort(this.el);
sorter.setDropContent(this.model.get('content'));
this.doc.on('mouseup', this.onDrop);

27
src/block_manager/view/BlocksView.js

@ -4,7 +4,7 @@ function(Backbone, BlockView) {
return Backbone.View.extend({
initialize: function(opts, config) {
_.bindAll(this, 'getSorter', 'onDrag', 'onDrop', 'dragHelper', 'moveHelper');
_.bindAll(this, 'getSorter', 'onDrag', 'onDrop');
this.config = config || {};
this.ppfx = this.config.pStylePrefix || '';
this.listenTo(this.collection, 'add', this.addTo);
@ -14,7 +14,6 @@ function(Backbone, BlockView) {
if(this.em){
this.config.getSorter = this.getSorter;
this.config.dragHelper = this.dragHelper;
this.canvas = this.em.get('Canvas');
}
},
@ -46,16 +45,7 @@ function(Backbone, BlockView) {
}
return this.sorter;
},
/*
updateOffset: function(){
if(!this.sorter)
return;
var sorter = this.sorter;
var offDim = this.canvas.getOffset();
sorter.offTop = offDim.top;
sorter.offLeft = offDim.left;
},
*/
/**
* Callback when block is on drag
* @private
@ -68,19 +58,6 @@ function(Backbone, BlockView) {
document.body.className += ' ' + this.grabbingCls;
},
dragHelper: function(el){
el.className += ' ' + this.ppfx + 'bdrag';
this.helper = el;
document.body.appendChild(el);
$(this.em.get('Canvas').getBody().ownerDocument).on('mousemove', this.moveHelper);
$(document).on('mousemove', this.moveHelper);
},
moveHelper: function(e){
this.helper.style.left = e.pageX + 'px';
this.helper.style.top = e.pageY + 'px';
},
/**
* Callback when block is dropped
* @private

8
src/dom_components/view/ComponentsView.js

@ -5,7 +5,7 @@ function(Backbone, require) {
initialize: function(o) {
this.opts = o || {};
this.config = o.config;
this.config = o.config || {};
this.listenTo( this.collection, 'add', this.addTo );
this.listenTo( this.collection, 'reset', this.render );
},
@ -17,9 +17,13 @@ function(Backbone, require) {
* @return void
* @private
* */
addTo: function(model){
addTo: function(model) {
var i = this.collection.indexOf(model);
this.addToCollection(model, null, i);
if(this.config.em) {
this.config.em.trigger('add:component', model);
}
},
/**

3
src/editor/main.js

@ -27,7 +27,8 @@
* var editor = grapesjs.init({...});
* ```
* Available events
* #canvasScroll: - Triggered when the canvas is scrolled
* #add:component - Triggered when a new component is added to the editor, the model is passed as an argument to the callback
* #canvasScroll - Triggered when the canvas is scrolled
* #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

11
src/editor/model/Editor.js

@ -480,5 +480,16 @@ define(['backbone', 'backboneUndo', 'keymaster', 'Utils', 'StorageManager', 'Dev
this.set('canvasOffset', this.get('Canvas').getOffset());
},
/**
* Clear all selected stuf inside the window, sometimes is useful to call before
* doing some dragging opearation
* @param {Window} win If not passed the current one will be used
* @private
*/
clearSelection: function (win) {
var w = win || window;
w.getSelection().removeAllRanges();
},
});
});

7
src/navigator/view/ItemView.js

@ -8,7 +8,7 @@ define(['backbone', 'text!./../template/item.html','require'],
template: _.template(ItemTemplate),
initialize: function(o){
initialize: function(o) {
this.opt = o;
this.config = o.config;
this.em = o.config.em;
@ -26,6 +26,7 @@ define(['backbone', 'text!./../template/item.html','require'],
this.inputNameCls = this.ppfx + 'nav-comp-name';
this.caretCls = this.ppfx + 'nav-item-caret';
this.titleCls = this.pfx + 'title';
this.customNameProp = 'custom-name';
this.events = {};
this.events['click > #'+this.pfx+'btn-eye'] = 'toggleVisibility';
this.events['click .' + this.caretCls] = 'toggleOpening';
@ -59,7 +60,7 @@ define(['backbone', 'text!./../template/item.html','require'],
e.stopPropagation();
var inputName = this.getInputName();
inputName.readOnly = true;
this.model.set('customName', inputName.value);
this.model.set(this.customNameProp, inputName.value);
},
/**
@ -254,7 +255,7 @@ define(['backbone', 'text!./../template/item.html','require'],
var count = this.countChildren(this.model);
this.$el.html( this.template({
title: this.model.get('customName') || this.model.getName(),
title: this.model.get(this.customNameProp) || this.model.getName(),
addClass: (count ? '' : pfx+'no-chld'),
editBtnCls: this.editBtnCls,
inputNameCls: this.inputNameCls,

88
src/utils/Sorter.js

@ -6,7 +6,7 @@ define(function(require) {
initialize: function(opt) {
this.opt = opt || {};
_.bindAll(this,'startSort','onMove','endMove','rollback', 'udpateOffset');
_.bindAll(this,'startSort','onMove','endMove','rollback', 'udpateOffset', 'moveDragHelper');
var o = opt || {};
this.elT = 0;
this.elL = 0;
@ -35,8 +35,8 @@ define(function(require) {
this.document = o.document || document;
this.$document = $(this.document);
this.dropContent = null;
this.helper = '';
this.em = o.em || '';
this.dragHelper = null;
if(this.em && this.em.on){
this.em.on('change:canvasOffset', this.udpateOffset);
@ -70,6 +70,63 @@ define(function(require) {
this.dropContent = content;
},
/**
* Set drag helper
* @param {HTMLElement} el
* @param {Event} event
*/
setDragHelper: function(el, event) {
var ev = event || '';
var clonedEl = el.cloneNode(1);
// Attach style
var style = '';
var o = getComputedStyle(el);
for(var i = 0; i < o.length; i++) {
style += o[i] + ':' + o.getPropertyValue(o[i])+';';
}
clonedEl.style = style;
clonedEl.className += ' ' + this.pfx + 'bdrag';
document.body.appendChild(clonedEl);
this.dragHelper = clonedEl;
if(ev) {
this.moveDragHelper(ev);
}
// Listen mouse move events
if(this.em) {
$(this.em.get('Canvas').getBody().ownerDocument)
.off('mousemove', this.moveDragHelper).on('mousemove', this.moveDragHelper);
}
$(document)
.off('mousemove', this.moveDragHelper).on('mousemove', this.moveDragHelper);
},
/**
* Update the position of the helper
* @param {Event} e
*/
moveDragHelper: function(e){
if(!this.dragHelper) {
return;
}
var doc = e.target.ownerDocument;
var win = doc.defaultView || doc.parentWindow;
var addTop = 0;
var addLeft = 0;
var frame = win.frameElement;
if(frame) {
var frameRect = frame.getBoundingClientRect(); // maybe to cache ?!?
addTop = frameRect.top || 0;
addLeft = frameRect.left || 0;
}
var hStyle = this.dragHelper.style;
hStyle.left = (e.pageX - win.pageXOffset + addLeft) + 'px';
hStyle.top = (e.pageY - win.pageYOffset + addTop) + 'px';
},
/**
* Returns true if the element matches with selector
* @param {Element} el
@ -153,18 +210,17 @@ define(function(require) {
this.$document.on('mouseup', this.endMove);
}
if(this.helper){
this.helperEl = this.helper;
this.helperEl.className += ' ' + this.ppfx + 'bdrag';
document.body.appendChild(this.helperEl);
}
this.$el.on('mousemove', this.onMove);
$(document).on('keydown', this.rollback);
this.$document.on('keydown', this.rollback);
if(typeof this.onStart === 'function')
this.onStart();
// Avoid strange effects on dragging
if(this.em) {
this.em.clearSelection();
}
},
/**
@ -202,12 +258,6 @@ define(function(require) {
this.lastPos = pos;
}
if(this.helperEl){
var helperS = this.helperEl.style;
helperS.left = this.rX + 'px';
helperS.top = this.rY + 'px';
}
if(typeof this.onMoveClb === 'function')
this.onMoveClb(e);
},
@ -515,11 +565,15 @@ define(function(require) {
created = this.move(this.target, this.eV, this.lastPos);
if(this.plh)
this.plh.style.display = 'none';
this.helperEl = '';
if(this.helper)
this.helper.parentNode.removeChild(this.helper);
if(typeof this.onEndMove === 'function')
this.onEndMove(created);
var dragHelper = this.dragHelper;
if(dragHelper) {
dragHelper.remove();
this.dragHelper = null;
}
},
/**

50
styles/css/main.css

@ -2638,10 +2638,18 @@ $fontColorActive: #4f8ef7;
.gjs-checker-bg, .checker-bg, .gjs-sm-sector .gjs-sm-property .gjs-sm-layer > #gjs-sm-preview-box, .gjs-clm-tags .gjs-sm-property .gjs-sm-layer > #gjs-sm-preview-box {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg=="); }
.gjs-no-user-select {
-moz-user-select: "none";
-khtml-user-select: "none";
-webkit-user-select: "none";
-ms-user-select: "none";
-o-user-select: "none";
user-select: "none"; }
.gjs-bg-main, .gjs-off-prv, .gjs-select option,
.gjs-clm-select option,
.gjs-sm-select option,
.gjs-sm-unit option, .gjs-pn-panel, .gjs-nv-item .gjs-nv-title-c, .gjs-sm-sector .gjs-sm-colorp-c, .gjs-clm-tags .gjs-sm-colorp-c, .gjs-mdl-dialog, #gjs-rte-toolbar, .sp-container {
.gjs-sm-unit option, .gjs-pn-panel, .gjs-nv-item .gjs-nv-title-c, .gjs-sm-sector .gjs-sm-colorp-c, .gjs-clm-tags .gjs-sm-colorp-c, .gjs-block, .gjs-mdl-dialog, #gjs-rte-toolbar, .sp-container {
background-color: #444; }
.gjs-color-main, .gjs-off-prv, .gjs-btn-prim, .gjs-pn-panel, .gjs-pn-btn, .gjs-btnt, .gjs-sm-sector .gjs-sm-field.gjs-sm-composite, .gjs-clm-tags .gjs-sm-field.gjs-sm-composite, .gjs-sm-sector .gjs-sm-composite.gjs-clm-field, .gjs-clm-tags .gjs-sm-composite.gjs-clm-field, .gjs-sm-sector .gjs-sm-stack #gjs-sm-add, .gjs-clm-tags .gjs-sm-stack #gjs-sm-add, .gjs-mdl-dialog, #gjs-rte-toolbar .gjs-rte-btn {
@ -2651,13 +2659,15 @@ $fontColorActive: #4f8ef7;
color: #f8f8f8; }
.gjs-bdrag {
position: absolute;
z-index: 10;
pointer-events: none !important;
position: absolute !important;
z-index: 10 !important;
width: auto; }
.gjs-grabbing {
cursor: grabbing;
cursor: -webkit-grabbing; }
.gjs-grabbing,
.gjs-grabbing * {
cursor: grabbing !important;
cursor: -webkit-grabbing !important; }
.gjs-off-prv {
position: relative;
@ -3071,10 +3081,17 @@ ol.example li.placeholder:before {
position: absolute;
cursor: pointer;
z-index: 1; }
.gjs-nv-navigator .gjs-nv-item #gjs-nv-caret {
font-size: 7px;
width: 8px;
margin-right: 5px; }
.gjs-nv-item #gjs-nv-caret {
font-size: 7px;
width: 8px;
padding: 5px;
cursor: pointer;
opacity: 0.7;
filter: alpha(opacity=70); }
.gjs-nv-item #gjs-nv-caret:hover {
opacity: 1;
filter: alpha(opacity=100); }
.gjs-nv-title {
background-color: rgba(0, 0, 0, 0.1);
@ -3083,7 +3100,6 @@ ol.example li.placeholder:before {
padding: 3px 10px 5px 30px;
border-bottom: 1px solid rgba(0, 0, 0, 0.3);
border-top: 1px solid rgba(255, 255, 255, 0.1);
cursor: pointer;
display: flex;
align-items: center; }
@ -3122,10 +3138,18 @@ ol.example li.placeholder:before {
background-color: rgba(255, 255, 255, 0.1); }
.gjs-nv-nav-item-edit {
visibility: hidden; }
visibility: hidden;
padding: 5px;
font-size: 10px;
opacity: 0.7;
filter: alpha(opacity=70); }
.gjs-nv-nav-item-edit:hover {
opacity: 1;
filter: alpha(opacity=100); }
.gjs-nv-title-c:hover .gjs-nv-nav-item-edit {
visibility: visible; }
visibility: visible;
cursor: pointer; }
.gjs-nav-comp-name {
padding: 5px;

44
styles/scss/main.scss

@ -135,6 +135,10 @@ $fontV: 20;//random(1000)
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==");
}
.#{$app-prefix}no-user-select{
@include user-select('none');
}
.#{$app-prefix}bg-main{
background-color: $mainColor;
}
@ -148,14 +152,16 @@ $fontV: 20;//random(1000)
}
.#{$app-prefix}bdrag {
position: absolute;
z-index: 10;
pointer-events: none !important;
position: absolute !important;
z-index: 10 !important;
width: auto;
}
.#{$app-prefix}grabbing {
cursor: grabbing;
cursor: -webkit-grabbing;
.#{$app-prefix}grabbing,
.#{$app-prefix}grabbing * {
cursor: grabbing !important;
cursor: -webkit-grabbing !important;
}
.#{$app-prefix}off-prv{
@ -624,11 +630,18 @@ ol.example li.placeholder:before {position: absolute;}
cursor:pointer;
z-index: 1;
}
.#{$nv-prefix}item ##{$nv-prefix}caret {
font-size: 7px;
width: 8px;
margin-right: 5px;
}
}
.#{$nv-prefix}item ##{$nv-prefix}caret {
font-size: 7px;
width: 8px;
padding: 5px;
cursor: pointer;
@include opacity(0.7);
&:hover {
@include opacity(1);
}
}
.#{$nv-prefix}item .#{$nv-prefix}title-c {
@ -642,7 +655,6 @@ ol.example li.placeholder:before {position: absolute;}
padding: 3px 10px 5px 30px;
border-bottom: 1px solid $mainDkColor;
border-top: 1px solid $mainLhColor;
cursor:pointer;
display: flex;
align-items: center;
}
@ -677,12 +689,20 @@ ol.example li.placeholder:before {position: absolute;}
.#{$nv-prefix}nav-item-edit {
visibility: hidden;
padding: 5px;
font-size: 10px;
@include opacity(0.7);
&:hover {
@include opacity(1);
}
}
.#{$nv-prefix}title-c:hover {
.#{$nv-prefix}nav-item-edit {
visibility: visible;
cursor: pointer;
}
}
@ -1106,6 +1126,8 @@ $lightBorder: rgba(255, 255, 255, 0.05);
}
.#{$app-prefix}block {
@include user-select(none);
@extend .#{$app-prefix}bg-main;
width: 45%;
padding: 1em;
box-sizing: border-box;

Loading…
Cancel
Save