mirror of https://github.com/artf/grapesjs.git
5 changed files with 295 additions and 302 deletions
File diff suppressed because one or more lines are too long
@ -1,40 +1,38 @@ |
|||
define(['Navigator'], function(Layers) { |
|||
/** |
|||
* @class OpenStyleManager |
|||
* @private |
|||
* */ |
|||
return { |
|||
/** |
|||
* @class OpenStyleManager |
|||
* @private |
|||
* */ |
|||
return { |
|||
|
|||
run: function(em, sender) |
|||
{ |
|||
if(!this.$layers){ |
|||
var collection = em.DomComponents.getComponent().get('components'), |
|||
config = em.getConfig(), |
|||
panels = em.Panels, |
|||
lyStylePfx = config.layers.stylePrefix || 'nv-'; |
|||
run: function(em, sender) { |
|||
if(!this.$layers) { |
|||
var collection = em.DomComponents.getComponent().get('components'), |
|||
config = em.getConfig(), |
|||
panels = em.Panels, |
|||
lyStylePfx = config.layers.stylePrefix || 'nv-'; |
|||
|
|||
config.layers.stylePrefix = config.stylePrefix + lyStylePfx; |
|||
config.layers.pStylePrefix = config.stylePrefix; |
|||
config.layers.em = em.editor; |
|||
config.layers.opened = em.editor.get('opened'); |
|||
var layers = new Layers(collection, config.layers); |
|||
this.$layers = layers.render(); |
|||
config.layers.stylePrefix = config.stylePrefix + lyStylePfx; |
|||
config.layers.pStylePrefix = config.stylePrefix; |
|||
config.layers.em = em.editor; |
|||
config.layers.opened = em.editor.get('opened'); |
|||
var layers = new Layers(collection, config.layers); |
|||
this.$layers = layers.render(); |
|||
|
|||
// 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'); |
|||
// 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'); |
|||
|
|||
this.panel.set('appendContent', this.$layers).trigger('change:appendContent'); |
|||
} |
|||
this.$layers.show(); |
|||
}, |
|||
this.panel.set('appendContent', this.$layers).trigger('change:appendContent'); |
|||
} |
|||
this.$layers.show(); |
|||
}, |
|||
|
|||
stop: function() |
|||
{ |
|||
if(this.$layers) |
|||
this.$layers.hide(); |
|||
} |
|||
}; |
|||
}); |
|||
stop: function() { |
|||
if(this.$layers) |
|||
this.$layers.hide(); |
|||
} |
|||
}; |
|||
}); |
|||
|
|||
@ -1,292 +1,287 @@ |
|||
define(['backbone', 'text!./../template/item.html','require'], |
|||
function (Backbone, ItemTemplate, require) { |
|||
/** |
|||
* @class ItemView |
|||
* */ |
|||
define(['backbone', 'text!./../template/item.html','require'], function (Backbone, ItemTemplate, require) { |
|||
return Backbone.View.extend({ |
|||
|
|||
return Backbone.View.extend({ |
|||
template: _.template(ItemTemplate), |
|||
|
|||
template: _.template(ItemTemplate), |
|||
initialize: function(o) { |
|||
this.opt = o; |
|||
this.config = o.config; |
|||
this.em = o.config.em; |
|||
this.ppfx = this.em.get('Config').stylePrefix; |
|||
this.sorter = o.sorter || {}; |
|||
this.pfx = this.config.stylePrefix; |
|||
if(typeof this.model.get('open') == 'undefined') |
|||
this.model.set('open',false); |
|||
this.listenTo(this.model.components, 'remove add change reset', this.checkChildren); |
|||
this.listenTo(this.model, 'destroy remove', this.remove); |
|||
this.listenTo(this.model, 'change:status', this.updateStatus); |
|||
this.listenTo(this.model, 'change:open', this.updateOpening); |
|||
this.className = this.pfx + 'item no-select'; |
|||
this.editBtnCls = this.pfx + 'nav-item-edit'; |
|||
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'; |
|||
this.events['click .' + this.titleCls] = 'handleSelect'; |
|||
this.events['click .' + this.editBtnCls] = 'handleEdit'; |
|||
this.events['blur .' + this.inputNameCls] = 'handleEditEnd'; |
|||
|
|||
initialize: function(o) { |
|||
this.opt = o; |
|||
this.config = o.config; |
|||
this.em = o.config.em; |
|||
this.ppfx = this.em.get('Config').stylePrefix; |
|||
this.sorter = o.sorter || {}; |
|||
this.pfx = this.config.stylePrefix; |
|||
if(typeof this.model.get('open') == 'undefined') |
|||
this.model.set('open',false); |
|||
this.listenTo(this.model.components, 'remove add change reset', this.checkChildren); |
|||
this.listenTo(this.model, 'destroy remove', this.remove); |
|||
this.listenTo(this.model, 'change:status', this.updateStatus); |
|||
this.listenTo(this.model, 'change:open', this.updateOpening); |
|||
this.className = this.pfx + 'item no-select'; |
|||
this.editBtnCls = this.pfx + 'nav-item-edit'; |
|||
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'; |
|||
this.events['click .' + this.titleCls] = 'handleSelect'; |
|||
this.events['click .' + this.editBtnCls] = 'handleEdit'; |
|||
this.events['blur .' + this.inputNameCls] = 'handleEditEnd'; |
|||
this.$el.data('model', this.model); |
|||
this.$el.data('collection', this.model.get('components')); |
|||
|
|||
this.$el.data('model', this.model); |
|||
this.$el.data('collection', this.model.get('components')); |
|||
if(o.config.sortable) |
|||
this.events['mousedown > #'+this.pfx+'move'] = 'startSort'; |
|||
|
|||
if(o.config.sortable) |
|||
this.events['mousedown > #'+this.pfx+'move'] = 'startSort'; |
|||
this.delegateEvents(); |
|||
}, |
|||
|
|||
this.delegateEvents(); |
|||
}, |
|||
/** |
|||
* Handle the edit of the component name |
|||
*/ |
|||
handleEdit: function(e) { |
|||
e.stopPropagation(); |
|||
var inputName = this.getInputName(); |
|||
inputName.readOnly = false; |
|||
inputName.focus(); |
|||
}, |
|||
|
|||
/** |
|||
* Handle the edit of the component name |
|||
*/ |
|||
handleEdit: function(e) { |
|||
e.stopPropagation(); |
|||
var inputName = this.getInputName(); |
|||
inputName.readOnly = false; |
|||
inputName.focus(); |
|||
}, |
|||
/** |
|||
* Handle with the end of editing of the component name |
|||
*/ |
|||
handleEditEnd: function (e) { |
|||
e.stopPropagation(); |
|||
var inputName = this.getInputName(); |
|||
inputName.readOnly = true; |
|||
this.model.set(this.customNameProp, inputName.value); |
|||
}, |
|||
|
|||
/** |
|||
* Handle with the end of editing of the component name |
|||
*/ |
|||
handleEditEnd: function (e) { |
|||
e.stopPropagation(); |
|||
var inputName = this.getInputName(); |
|||
inputName.readOnly = true; |
|||
this.model.set(this.customNameProp, inputName.value); |
|||
}, |
|||
/** |
|||
* Get the input containing the name of the component |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getInputName: function () { |
|||
if(!this.inputName) { |
|||
this.inputName = this.el.querySelector('.' + this.inputNameCls); |
|||
} |
|||
return this.inputName; |
|||
}, |
|||
|
|||
/** |
|||
* Get the input containing the name of the component |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getInputName: function () { |
|||
if(!this.inputName) { |
|||
this.inputName = this.el.querySelector('.' + this.inputNameCls); |
|||
} |
|||
return this.inputName; |
|||
}, |
|||
/** |
|||
* Update item opening |
|||
* |
|||
* @return void |
|||
* */ |
|||
updateOpening: function (){ |
|||
var opened = this.opt.opened || {}; |
|||
var model = this.model; |
|||
if(model.get('open')){ |
|||
this.$el.addClass("open"); |
|||
this.$caret.addClass('fa-chevron-down'); |
|||
opened[model.cid] = model; |
|||
}else{ |
|||
this.$el.removeClass("open"); |
|||
this.$caret.removeClass('fa-chevron-down'); |
|||
delete opened[model.cid]; |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Update item opening |
|||
* |
|||
* @return void |
|||
* */ |
|||
updateOpening: function (){ |
|||
var opened = this.opt.opened || {}; |
|||
var model = this.model; |
|||
if(model.get('open')){ |
|||
this.$el.addClass("open"); |
|||
this.$caret.addClass('fa-chevron-down'); |
|||
opened[model.cid] = model; |
|||
}else{ |
|||
this.$el.removeClass("open"); |
|||
this.$caret.removeClass('fa-chevron-down'); |
|||
delete opened[model.cid]; |
|||
} |
|||
}, |
|||
/** |
|||
* Toggle item opening |
|||
* @param {Object} e |
|||
* |
|||
* @return void |
|||
* */ |
|||
toggleOpening: function(e){ |
|||
e.stopPropagation(); |
|||
|
|||
/** |
|||
* Toggle item opening |
|||
* @param {Object} e |
|||
* |
|||
* @return void |
|||
* */ |
|||
toggleOpening: function(e){ |
|||
e.stopPropagation(); |
|||
if(!this.model.components.length) |
|||
return; |
|||
|
|||
if(!this.model.components.length) |
|||
return; |
|||
this.model.set('open', !this.model.get('open') ); |
|||
}, |
|||
|
|||
this.model.set('open', !this.model.get('open') ); |
|||
}, |
|||
/** |
|||
* Handle component selection |
|||
* @return {[type]} [description] |
|||
*/ |
|||
handleSelect: function (e) { |
|||
e.stopPropagation(); |
|||
var em = this.em; |
|||
|
|||
/** |
|||
* Handle component selection |
|||
* @return {[type]} [description] |
|||
*/ |
|||
handleSelect: function (e) { |
|||
e.stopPropagation(); |
|||
if(em){ |
|||
var model = em.get('selectedComponent'); |
|||
if(model){ |
|||
model.set('status', ''); |
|||
} |
|||
this.model.set('status', 'selected'); |
|||
em.set('selectedComponent', this.model); |
|||
} |
|||
}, |
|||
|
|||
// Selection
|
|||
if(this.em){ |
|||
var md = this.em.get('selectedComponent'); |
|||
if(md){ |
|||
md.set('status',''); |
|||
this.model.set('status','selected'); |
|||
this.em.set('selectedComponent', this.model); |
|||
} |
|||
} |
|||
}, |
|||
/** |
|||
* Delegate to sorter |
|||
* @param Event |
|||
* */ |
|||
startSort: function(e){ |
|||
if (this.sorter) { |
|||
this.sorter.startSort(e.target); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Delegate to sorter |
|||
* @param Event |
|||
* */ |
|||
startSort: function(e){ |
|||
if (this.sorter) { |
|||
//this.sorter.startMove(this, e);
|
|||
this.sorter.startSort(e.target); |
|||
} |
|||
}, |
|||
/** |
|||
* Freeze item |
|||
* @return void |
|||
* */ |
|||
freeze: function(){ |
|||
this.$el.addClass(this.pfx + 'opac50'); |
|||
this.model.set('open',0); |
|||
}, |
|||
|
|||
/** |
|||
* Freeze item |
|||
* @return void |
|||
* */ |
|||
freeze: function(){ |
|||
this.$el.addClass(this.pfx + 'opac50'); |
|||
this.model.set('open',0); |
|||
}, |
|||
/** |
|||
* Unfreeze item |
|||
* @return void |
|||
* */ |
|||
unfreeze: function(){ |
|||
this.$el.removeClass(this.pfx + 'opac50'); |
|||
}, |
|||
|
|||
/** |
|||
* Unfreeze item |
|||
* @return void |
|||
* */ |
|||
unfreeze: function(){ |
|||
this.$el.removeClass(this.pfx + 'opac50'); |
|||
}, |
|||
/** |
|||
* Update item on status change |
|||
* @param Event |
|||
* */ |
|||
updateStatus: function(e) { |
|||
var status = this.model.get('status'); |
|||
var cls = this.pfx + 'selected'; |
|||
var el = this.$el; |
|||
switch(status) { |
|||
case 'selected': |
|||
el.addClass(cls); |
|||
break; |
|||
case 'moving': |
|||
break; |
|||
default: |
|||
el.removeClass(cls); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Update item on status change |
|||
* @param Event |
|||
* */ |
|||
updateStatus: function(e) |
|||
{ |
|||
var s = this.model.get('status'), |
|||
pfx = this.pfx; |
|||
switch(s) { |
|||
case 'selected': |
|||
this.$el.addClass(pfx + 'selected'); |
|||
break; |
|||
case 'moving': |
|||
break; |
|||
default: |
|||
this.$el.removeClass(pfx + 'selected'); |
|||
} |
|||
}, |
|||
/** |
|||
* Toggle visibility |
|||
* @param Event |
|||
* |
|||
* @return void |
|||
* */ |
|||
toggleVisibility: function(e){ |
|||
if(!this.$eye) |
|||
this.$eye = this.$el.find('> #'+this.pfx+'btn-eye'); |
|||
|
|||
/** |
|||
* Toggle visibility |
|||
* @param Event |
|||
* |
|||
* @return void |
|||
* */ |
|||
toggleVisibility: function(e){ |
|||
if(!this.$eye) |
|||
this.$eye = this.$el.find('> #'+this.pfx+'btn-eye'); |
|||
var cCss = _.clone(this.model.get('style')), |
|||
hClass = this.pfx + 'hide'; |
|||
if(this.isVisible()){ |
|||
this.$el.addClass(hClass); |
|||
this.$eye.addClass('fa-eye-slash'); |
|||
cCss.display = 'none'; |
|||
}else{ |
|||
this.$el.removeClass(hClass); |
|||
this.$eye.removeClass('fa-eye-slash'); |
|||
delete cCss.display; |
|||
} |
|||
this.model.set('style', cCss); |
|||
}, |
|||
|
|||
var cCss = _.clone(this.model.get('style')), |
|||
hClass = this.pfx + 'hide'; |
|||
if(this.isVisible()){ |
|||
this.$el.addClass(hClass); |
|||
this.$eye.addClass('fa-eye-slash'); |
|||
cCss.display = 'none'; |
|||
}else{ |
|||
this.$el.removeClass(hClass); |
|||
this.$eye.removeClass('fa-eye-slash'); |
|||
delete cCss.display; |
|||
} |
|||
this.model.set('style', cCss); |
|||
}, |
|||
/** |
|||
* Check if component is visible |
|||
* |
|||
* @return bool |
|||
* */ |
|||
isVisible: function(){ |
|||
var css = this.model.get('style'), |
|||
pr = css.display; |
|||
if(pr && pr == 'none' ) |
|||
return; |
|||
return 1; |
|||
}, |
|||
|
|||
/** |
|||
* Check if component is visible |
|||
* |
|||
* @return bool |
|||
* */ |
|||
isVisible: function(){ |
|||
var css = this.model.get('style'), |
|||
pr = css.display; |
|||
if(pr && pr == 'none' ) |
|||
return; |
|||
return 1; |
|||
}, |
|||
/** |
|||
* Update item aspect after children changes |
|||
* |
|||
* @return void |
|||
* */ |
|||
checkChildren: function(){ |
|||
var c = this.countChildren(this.model), |
|||
pfx = this.pfx, |
|||
tC = '> .' + pfx + 'title-c > .' + pfx + 'title'; |
|||
if(!this.$counter) |
|||
this.$counter = this.$el.find('> #' + pfx + 'counter'); |
|||
if(c){ |
|||
this.$el.find(tC).removeClass(pfx + 'no-chld'); |
|||
this.$counter.html(c); |
|||
}else{ |
|||
this.$el.find(tC).addClass(pfx + 'no-chld'); |
|||
this.$counter.empty(); |
|||
this.model.set('open',0); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Update item aspect after children changes |
|||
* |
|||
* @return void |
|||
* */ |
|||
checkChildren: function(){ |
|||
var c = this.countChildren(this.model), |
|||
pfx = this.pfx, |
|||
tC = '> .' + pfx + 'title-c > .' + pfx + 'title'; |
|||
if(!this.$counter) |
|||
this.$counter = this.$el.find('> #' + pfx + 'counter'); |
|||
if(c){ |
|||
this.$el.find(tC).removeClass(pfx + 'no-chld'); |
|||
this.$counter.html(c); |
|||
}else{ |
|||
this.$el.find(tC).addClass(pfx + 'no-chld'); |
|||
this.$counter.empty(); |
|||
this.model.set('open',0); |
|||
} |
|||
}, |
|||
/** |
|||
* Count children inside model |
|||
* @param {Object} model |
|||
* @return {number} |
|||
* @private |
|||
*/ |
|||
countChildren: function(model){ |
|||
var count = 0; |
|||
model.components.each(function(m){ |
|||
var isCountable = this.opt.isCountable; |
|||
var hide = this.config.hideTextnode; |
|||
if(isCountable && !isCountable(m, hide)) |
|||
return; |
|||
count++; |
|||
}, this); |
|||
return count; |
|||
}, |
|||
|
|||
/** |
|||
* Count children inside model |
|||
* @param {Object} model |
|||
* @return {number} |
|||
* @private |
|||
*/ |
|||
countChildren: function(model){ |
|||
var count = 0; |
|||
model.components.each(function(m){ |
|||
var isCountable = this.opt.isCountable; |
|||
var hide = this.config.hideTextnode; |
|||
if(isCountable && !isCountable(m, hide)) |
|||
return; |
|||
count++; |
|||
}, this); |
|||
return count; |
|||
}, |
|||
render: function(){ |
|||
var pfx = this.pfx; |
|||
var vis = this.isVisible(); |
|||
var count = this.countChildren(this.model); |
|||
|
|||
render: function(){ |
|||
var pfx = this.pfx; |
|||
var vis = this.isVisible(); |
|||
var count = this.countChildren(this.model); |
|||
this.$el.html( this.template({ |
|||
title: this.model.get(this.customNameProp) || this.model.getName(), |
|||
addClass: (count ? '' : pfx+'no-chld'), |
|||
editBtnCls: this.editBtnCls, |
|||
inputNameCls: this.inputNameCls, |
|||
caretCls: this.caretCls, |
|||
count: count, |
|||
visible: vis, |
|||
hidable: this.config.hidable, |
|||
prefix: pfx, |
|||
ppfx: this.ppfx |
|||
})); |
|||
|
|||
this.$el.html( this.template({ |
|||
title: this.model.get(this.customNameProp) || this.model.getName(), |
|||
addClass: (count ? '' : pfx+'no-chld'), |
|||
editBtnCls: this.editBtnCls, |
|||
inputNameCls: this.inputNameCls, |
|||
caretCls: this.caretCls, |
|||
count: count, |
|||
visible: vis, |
|||
hidable: this.config.hidable, |
|||
prefix: pfx, |
|||
ppfx: this.ppfx |
|||
})); |
|||
if(typeof ItemsView == 'undefined') |
|||
ItemsView = require('./ItemsView'); |
|||
this.$components = new ItemsView({ |
|||
collection : this.model.components, |
|||
config: this.config, |
|||
sorter: this.sorter, |
|||
opened: this.opt.opened, |
|||
parent: this.model |
|||
}).render().$el; |
|||
this.$el.find('.'+ pfx +'children').html(this.$components); |
|||
this.$caret = this.$el.find('> .' + pfx + 'title-c > .' + pfx + 'title > #' + pfx + 'caret'); |
|||
if(!this.model.get('draggable') || !this.config.sortable){ |
|||
this.$el.find('> #' + pfx + 'move').detach(); |
|||
} |
|||
if(!vis) |
|||
this.className += ' ' + pfx + 'hide'; |
|||
this.$el.attr('class', _.result(this, 'className')); |
|||
this.updateOpening(); |
|||
this.updateStatus(); |
|||
return this; |
|||
}, |
|||
|
|||
if(typeof ItemsView == 'undefined') |
|||
ItemsView = require('./ItemsView'); |
|||
this.$components = new ItemsView({ |
|||
collection : this.model.components, |
|||
config: this.config, |
|||
sorter: this.sorter, |
|||
opened: this.opt.opened, |
|||
parent: this.model |
|||
}).render().$el; |
|||
this.$el.find('.'+ pfx +'children').html(this.$components); |
|||
this.$caret = this.$el.find('> .' + pfx + 'title-c > .' + pfx + 'title > #' + pfx + 'caret'); |
|||
if(!this.model.get('draggable') || !this.config.sortable){ |
|||
this.$el.find('> #' + pfx + 'move').detach(); |
|||
} |
|||
if(!vis) |
|||
this.className += ' ' + pfx + 'hide'; |
|||
this.$el.attr('class', _.result(this, 'className')); |
|||
this.updateOpening(); |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
Loading…
Reference in new issue