mirror of https://github.com/artf/grapesjs.git
4 changed files with 497 additions and 405 deletions
@ -1,280 +1,301 @@ |
|||||
define(['backbone', './ComponentsView'], |
define(['backbone', './ComponentsView'], |
||||
function (Backbone, ComponentsView) { |
function (Backbone, ComponentsView) { |
||||
|
|
||||
return Backbone.View.extend({ |
return Backbone.View.extend({ |
||||
|
|
||||
events: { |
events: { |
||||
'click': 'initResize', |
'click': 'initResize', |
||||
}, |
}, |
||||
|
|
||||
className : function(){ |
className : function(){ |
||||
return this.getClasses(); |
return this.getClasses(); |
||||
}, |
}, |
||||
|
|
||||
tagName: function(){ |
tagName: function(){ |
||||
return this.model.get('tagName'); |
return this.model.get('tagName'); |
||||
}, |
}, |
||||
|
|
||||
initialize: function(opt){ |
initialize: function(opt) { |
||||
this.opts = opt || {}; |
this.opts = opt || {}; |
||||
this.config = opt.config || {}; |
this.config = this.opts.config || {}; |
||||
this.pfx = this.config.stylePrefix || ''; |
this.em = this.config.em || ''; |
||||
this.ppfx = this.config.pStylePrefix || ''; |
this.pfx = this.config.stylePrefix || ''; |
||||
this.components = this.model.get('components'); |
this.ppfx = this.config.pStylePrefix || ''; |
||||
this.attr = this.model.get("attributes"); |
this.components = this.model.get('components'); |
||||
this.classe = this.attr.class || []; |
this.attr = this.model.get("attributes"); |
||||
this.listenTo(this.model, 'destroy remove', this.remove); |
this.classe = this.attr.class || []; |
||||
this.listenTo(this.model, 'change:style', this.updateStyle); |
this.listenTo(this.model, 'destroy remove', this.remove); |
||||
this.listenTo(this.model, 'change:attributes', this.updateAttributes); |
this.listenTo(this.model, 'change:style', this.updateStyle); |
||||
this.listenTo(this.model, 'change:status', this.updateStatus); |
this.listenTo(this.model, 'change:attributes', this.updateAttributes); |
||||
this.listenTo(this.model, 'change:state', this.updateState); |
this.listenTo(this.model, 'change:status', this.updateStatus); |
||||
this.listenTo(this.model.get('classes'), 'add remove change', this.updateClasses); |
this.listenTo(this.model, 'change:state', this.updateState); |
||||
this.$el.data('model', this.model); |
this.listenTo(this.model, 'change:script', this.render); |
||||
this.model.view = this; |
this.listenTo(this.model.get('classes'), 'add remove change', this.updateClasses); |
||||
this.$el.data("collection", this.components); |
this.$el.data('model', this.model); |
||||
|
this.model.view = this; |
||||
if(this.model.get('classes').length) |
this.$el.data("collection", this.components); |
||||
this.importClasses(); |
|
||||
|
if(this.model.get('classes').length) |
||||
this.init(); |
this.importClasses(); |
||||
}, |
|
||||
|
this.init(); |
||||
/** |
}, |
||||
|
|
||||
|
/** |
||||
* Initialize callback |
* Initialize callback |
||||
*/ |
*/ |
||||
init: function () {}, |
init: function () {}, |
||||
|
|
||||
/** |
/** |
||||
* Import, if possible, classes inside main container |
* Import, if possible, classes inside main container |
||||
* @private |
* @private |
||||
* */ |
* */ |
||||
importClasses: function(){ |
importClasses: function(){ |
||||
var clm = this.config.em.get('SelectorManager'); |
var clm = this.config.em.get('SelectorManager'); |
||||
|
|
||||
if(clm){ |
if(clm){ |
||||
this.model.get('classes').each(function(m){ |
this.model.get('classes').each(function(m){ |
||||
clm.add(m.get('name')); |
clm.add(m.get('name')); |
||||
}); |
}); |
||||
} |
} |
||||
}, |
}, |
||||
|
|
||||
/** |
/** |
||||
* Fires on state update. If the state is not empty will add a helper class |
* Fires on state update. If the state is not empty will add a helper class |
||||
* @param {Event} e |
* @param {Event} e |
||||
* @private |
* @private |
||||
* */ |
* */ |
||||
updateState: function(e){ |
updateState: function(e){ |
||||
var cl = 'hc-state'; |
var cl = 'hc-state'; |
||||
var state = this.model.get('state'); |
var state = this.model.get('state'); |
||||
|
|
||||
if(state){ |
if(state){ |
||||
this.$el.addClass(cl); |
this.$el.addClass(cl); |
||||
}else{ |
}else{ |
||||
this.$el.removeClass(cl); |
this.$el.removeClass(cl); |
||||
} |
} |
||||
}, |
}, |
||||
|
|
||||
/** |
/** |
||||
* Update item on status change |
* Update item on status change |
||||
* @param {Event} e |
* @param {Event} e |
||||
* @private |
* @private |
||||
* */ |
* */ |
||||
updateStatus: function(e){ |
updateStatus: function(e){ |
||||
var s = this.model.get('status'), |
var s = this.model.get('status'), |
||||
pfx = this.pfx; |
pfx = this.pfx; |
||||
switch(s) { |
switch(s) { |
||||
case 'selected': |
case 'selected': |
||||
this.$el.addClass(pfx + 'selected'); |
this.$el.addClass(pfx + 'selected'); |
||||
break; |
break; |
||||
case 'moving': |
case 'moving': |
||||
break; |
break; |
||||
default: |
default: |
||||
this.$el.removeClass(pfx + 'selected'); |
this.$el.removeClass(pfx + 'selected'); |
||||
} |
} |
||||
}, |
}, |
||||
|
|
||||
/** |
/** |
||||
* Get classes from attributes. |
* Get classes from attributes. |
||||
* This method is called before initialize |
* This method is called before initialize |
||||
* |
* |
||||
* @return {Array}|null |
* @return {Array}|null |
||||
* @private |
* @private |
||||
* */ |
* */ |
||||
getClasses: function(){ |
getClasses: function(){ |
||||
var attr = this.model.get("attributes"), |
var attr = this.model.get("attributes"), |
||||
classes = attr['class'] || []; |
classes = attr['class'] || []; |
||||
if(classes.length){ |
if(classes.length){ |
||||
return classes.join(" "); |
return classes.join(" "); |
||||
}else |
}else |
||||
return null; |
return null; |
||||
}, |
}, |
||||
|
|
||||
/** |
/** |
||||
* Update attributes |
* Update attributes |
||||
* @private |
* @private |
||||
* */ |
* */ |
||||
updateAttributes: function(){ |
updateAttributes: function(){ |
||||
var attributes = {}, |
var attributes = {}, |
||||
attr = this.model.get("attributes"); |
attr = this.model.get("attributes"); |
||||
for(var key in attr) { |
for(var key in attr) { |
||||
if(attr.hasOwnProperty(key)) |
if(attr.hasOwnProperty(key)) |
||||
attributes[key] = attr[key]; |
attributes[key] = attr[key]; |
||||
} |
} |
||||
// Update src
|
// Update src
|
||||
if(this.model.get("src")) |
if(this.model.get("src")) |
||||
attributes.src = this.model.get("src"); |
attributes.src = this.model.get("src"); |
||||
|
|
||||
var styleStr = this.getStyleString(); |
var styleStr = this.getStyleString(); |
||||
|
|
||||
if(styleStr) |
if(styleStr) |
||||
attributes.style = styleStr; |
attributes.style = styleStr; |
||||
|
|
||||
this.$el.attr(attributes); |
this.$el.attr(attributes); |
||||
}, |
}, |
||||
|
|
||||
/** |
/** |
||||
* Update style attribute |
* Update style attribute |
||||
* @private |
* @private |
||||
* */ |
* */ |
||||
updateStyle: function(){ |
updateStyle: function(){ |
||||
this.$el.attr('style', this.getStyleString()); |
this.$el.attr('style', this.getStyleString()); |
||||
}, |
}, |
||||
|
|
||||
/** |
/** |
||||
* Return style string |
* Return style string |
||||
* @return {string} |
* @return {string} |
||||
* @private |
* @private |
||||
* */ |
* */ |
||||
getStyleString: function(){ |
getStyleString: function(){ |
||||
var style = ''; |
var style = ''; |
||||
this.style = this.model.get('style'); |
this.style = this.model.get('style'); |
||||
for(var key in this.style) { |
for(var key in this.style) { |
||||
if(this.style.hasOwnProperty(key)) |
if(this.style.hasOwnProperty(key)) |
||||
style += key + ':' + this.style[key] + ';'; |
style += key + ':' + this.style[key] + ';'; |
||||
} |
} |
||||
|
|
||||
return style; |
return style; |
||||
}, |
}, |
||||
|
|
||||
/** |
/** |
||||
* Update classe attribute |
* Update classe attribute |
||||
* @private |
* @private |
||||
* */ |
* */ |
||||
updateClasses: function(){ |
updateClasses: function(){ |
||||
var str = ''; |
var str = ''; |
||||
|
|
||||
this.model.get('classes').each(function(model){ |
this.model.get('classes').each(function(model){ |
||||
str += model.get('name') + ' '; |
str += model.get('name') + ' '; |
||||
}); |
}); |
||||
str = str.trim(); |
str = str.trim(); |
||||
|
|
||||
if(str) |
if(str) |
||||
this.$el.attr('class', str); |
this.$el.attr('class', str); |
||||
else |
else |
||||
this.$el.removeAttr('class'); |
this.$el.removeAttr('class'); |
||||
|
|
||||
// Regenerate status class
|
// Regenerate status class
|
||||
this.updateStatus(); |
this.updateStatus(); |
||||
}, |
}, |
||||
|
|
||||
/** |
/** |
||||
* Reply to event call |
* Reply to event call |
||||
* @param object Event that generated the request |
* @param object Event that generated the request |
||||
* @private |
* @private |
||||
* */ |
* */ |
||||
eventCall: function(event){ |
eventCall: function(event){ |
||||
event.viewResponse = this; |
event.viewResponse = this; |
||||
}, |
}, |
||||
|
|
||||
/** |
/** |
||||
* Init component for resizing |
* Init component for resizing |
||||
*/ |
*/ |
||||
initResize: function () { |
initResize: function () { |
||||
var em = this.opts.config.em; |
var em = this.opts.config.em; |
||||
var editor = em ? em.get('Editor') : ''; |
var editor = em ? em.get('Editor') : ''; |
||||
var config = em ? em.get('Config') : ''; |
var config = em ? em.get('Config') : ''; |
||||
var pfx = config.stylePrefix || ''; |
var pfx = config.stylePrefix || ''; |
||||
var attrName = 'data-' + pfx + 'handler'; |
var attrName = 'data-' + pfx + 'handler'; |
||||
var resizeClass = pfx + 'resizing'; |
var resizeClass = pfx + 'resizing'; |
||||
var model = this.model; |
var model = this.model; |
||||
var modelToStyle; |
var modelToStyle; |
||||
|
|
||||
var toggleBodyClass = function(method, e, opts) { |
var toggleBodyClass = function(method, e, opts) { |
||||
var handlerAttr = e.target.getAttribute(attrName); |
var handlerAttr = e.target.getAttribute(attrName); |
||||
var resizeHndClass = pfx + 'resizing-' + handlerAttr; |
var resizeHndClass = pfx + 'resizing-' + handlerAttr; |
||||
var classToAdd = resizeClass;// + ' ' +resizeHndClass;
|
var classToAdd = resizeClass;// + ' ' +resizeHndClass;
|
||||
if (opts.docs) { |
if (opts.docs) { |
||||
opts.docs.find('body')[method](classToAdd); |
opts.docs.find('body')[method](classToAdd); |
||||
} |
} |
||||
}; |
}; |
||||
|
|
||||
if(editor && this.model.get('resizable')) { |
if(editor && this.model.get('resizable')) { |
||||
editor.runCommand('resize', { |
editor.runCommand('resize', { |
||||
el: this.el, |
el: this.el, |
||||
options: { |
options: { |
||||
onStart: function (e, opts) { |
onStart: function (e, opts) { |
||||
toggleBodyClass('addClass', e, opts); |
toggleBodyClass('addClass', e, opts); |
||||
modelToStyle = em.get('StyleManager').getModelToStyle(model); |
modelToStyle = em.get('StyleManager').getModelToStyle(model); |
||||
}, |
}, |
||||
// Update all positioned elements (eg. component toolbar)
|
// Update all positioned elements (eg. component toolbar)
|
||||
onMove: function () { |
onMove: function () { |
||||
editor.trigger('change:canvasOffset'); |
editor.trigger('change:canvasOffset'); |
||||
}, |
}, |
||||
onEnd: function (e, opts) { |
onEnd: function (e, opts) { |
||||
toggleBodyClass('removeClass', e, opts); |
toggleBodyClass('removeClass', e, opts); |
||||
editor.trigger('change:canvasOffset'); |
editor.trigger('change:canvasOffset'); |
||||
}, |
}, |
||||
updateTarget: function(el, rect, store) { |
updateTarget: function(el, rect, store) { |
||||
if (!modelToStyle) { |
if (!modelToStyle) { |
||||
return; |
return; |
||||
} |
} |
||||
var unit = 'px'; |
var unit = 'px'; |
||||
var style = _.clone(modelToStyle.get('style')); |
var style = _.clone(modelToStyle.get('style')); |
||||
var width = rect.w + (store ? 1 : 0); |
var width = rect.w + (store ? 1 : 0); |
||||
style.width = width + unit; |
style.width = width + unit; |
||||
style.height = rect.h + unit; |
style.height = rect.h + unit; |
||||
modelToStyle.set('style', style, {avoidStore: 1}); |
modelToStyle.set('style', style, {avoidStore: 1}); |
||||
em.trigger('targetStyleUpdated'); |
em.trigger('targetStyleUpdated'); |
||||
|
|
||||
// This trick will trigger the Undo Manager. To trigger "change:style"
|
// This trick will trigger the Undo Manager. To trigger "change:style"
|
||||
// on the Model you need to provide a new object and after that
|
// on the Model you need to provide a new object and after that
|
||||
// Undo Manager will trigger only if values are different (this is why
|
// Undo Manager will trigger only if values are different (this is why
|
||||
// above I've added + 1 to width if store required)
|
// above I've added + 1 to width if store required)
|
||||
if(store) { |
if(store) { |
||||
var style3 = _.clone(style); |
var style3 = _.clone(style); |
||||
style3.width = (width - 1) + unit; |
style3.width = (width - 1) + unit; |
||||
modelToStyle.set('style', style3); |
modelToStyle.set('style', style3); |
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
}); |
}); |
||||
} |
} |
||||
}, |
}, |
||||
|
|
||||
/** |
/** |
||||
* Prevent default helper |
* Prevent default helper |
||||
* @param {Event} e |
* @param {Event} e |
||||
* @private |
* @private |
||||
*/ |
*/ |
||||
prevDef: function (e) { |
prevDef: function (e) { |
||||
e.preventDefault(); |
e.preventDefault(); |
||||
}, |
}, |
||||
|
|
||||
render: function() { |
/** |
||||
this.updateAttributes(); |
* Render component's script |
||||
this.updateClasses(); |
* @private |
||||
this.$el.html(this.model.get('content')); |
*/ |
||||
var view = new ComponentsView({ |
updateScript: function () { |
||||
collection: this.model.get('components'), |
var em = this.em; |
||||
config: this.config, |
if(em) { |
||||
defaultTypes: this.opts.defaultTypes, |
var canvas = em.get('Canvas'); |
||||
componentTypes: this.opts.componentTypes, |
canvas.getCanvasView().updateScript(this); |
||||
}); |
} |
||||
|
}, |
||||
// With childNodes lets avoid wrapping 'div'
|
|
||||
this.$el.append(view.render(this.$el).el.childNodes); |
render: function() { |
||||
return this; |
var model = this.model; |
||||
}, |
this.updateAttributes(); |
||||
|
this.updateClasses(); |
||||
}); |
this.$el.html(this.model.get('content')); |
||||
|
var view = new ComponentsView({ |
||||
|
collection: this.model.get('components'), |
||||
|
config: this.config, |
||||
|
defaultTypes: this.opts.defaultTypes, |
||||
|
componentTypes: this.opts.componentTypes, |
||||
|
}); |
||||
|
|
||||
|
// With childNodes lets avoid wrapping 'div'
|
||||
|
this.$el.append(view.render(this.$el).el.childNodes); |
||||
|
|
||||
|
// Render script
|
||||
|
if(model.get('script')) { |
||||
|
this.updateScript(); |
||||
|
} |
||||
|
|
||||
|
return this; |
||||
|
}, |
||||
|
|
||||
|
}); |
||||
}); |
}); |
||||
|
|||||
Loading…
Reference in new issue