mirror of https://github.com/artf/grapesjs.git
255 changed files with 17243 additions and 18107 deletions
@ -1,18 +1,16 @@ |
|||
define(function () { |
|||
return { |
|||
// Default assets
|
|||
assets: [], |
|||
module.exports = { |
|||
// Default assets
|
|||
assets: [], |
|||
|
|||
// Style prefix
|
|||
stylePrefix: 'am-', |
|||
// Style prefix
|
|||
stylePrefix: 'am-', |
|||
|
|||
// Url where uploads will be send, set false to disable upload
|
|||
upload: 'http://localhost/assets/upload', |
|||
// Url where uploads will be send, set false to disable upload
|
|||
upload: 'http://localhost/assets/upload', |
|||
|
|||
// Text on upload input
|
|||
uploadText: 'Drop files here or click to upload', |
|||
// Text on upload input
|
|||
uploadText: 'Drop files here or click to upload', |
|||
|
|||
// Label for the add button
|
|||
addBtnText: 'Add image', |
|||
}; |
|||
}); |
|||
// Label for the add button
|
|||
addBtnText: 'Add image', |
|||
}; |
|||
|
|||
@ -1,32 +1,30 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
module.exports = Backbone.Model.extend({ |
|||
var Backbone = require('backbone'); |
|||
|
|||
idAttribute: 'src', |
|||
module.exports = Backbone.Model.extend({ |
|||
|
|||
defaults: { |
|||
type: '', |
|||
src: '', |
|||
}, |
|||
idAttribute: 'src', |
|||
|
|||
/** |
|||
* Get filename of the asset |
|||
* @return {string} |
|||
* @private |
|||
* */ |
|||
getFilename: function(){ |
|||
return this.get('src').split('/').pop(); |
|||
}, |
|||
defaults: { |
|||
type: '', |
|||
src: '', |
|||
}, |
|||
|
|||
/** |
|||
* Get extension of the asset |
|||
* @return {string} |
|||
* @private |
|||
* */ |
|||
getExtension: function(){ |
|||
return this.getFilename().split('.').pop(); |
|||
}, |
|||
/** |
|||
* Get filename of the asset |
|||
* @return {string} |
|||
* @private |
|||
* */ |
|||
getFilename: function(){ |
|||
return this.get('src').split('/').pop(); |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
/** |
|||
* Get extension of the asset |
|||
* @return {string} |
|||
* @private |
|||
* */ |
|||
getExtension: function(){ |
|||
return this.getFilename().split('.').pop(); |
|||
}, |
|||
|
|||
}); |
|||
|
|||
@ -1,15 +1,13 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var Asset = require('./Asset'); |
|||
module.exports = Asset.extend({ |
|||
var Backbone = require('backbone'); |
|||
var Asset = require('./Asset'); |
|||
|
|||
defaults: _.extend({}, Asset.prototype.defaults, { |
|||
type: 'image', |
|||
unitDim: 'px', |
|||
height: 0, |
|||
width: 0, |
|||
}), |
|||
module.exports = Asset.extend({ |
|||
|
|||
}); |
|||
}); |
|||
defaults: _.extend({}, Asset.prototype.defaults, { |
|||
type: 'image', |
|||
unitDim: 'px', |
|||
height: 0, |
|||
width: 0, |
|||
}), |
|||
|
|||
}); |
|||
|
|||
@ -1,70 +1,68 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var Asset = require('./Asset'); |
|||
var AssetImage = require('./AssetImage'); |
|||
module.exports = Backbone.Collection.extend({ |
|||
|
|||
model: AssetImage, |
|||
|
|||
initialize: function(models, opt){ |
|||
|
|||
this.model = function(attrs, options) { |
|||
var model; |
|||
switch(attrs.type){ |
|||
default: |
|||
model = new AssetImage(attrs, options); |
|||
} |
|||
return model; |
|||
}; |
|||
|
|||
}, |
|||
|
|||
/** |
|||
* Add new image asset to the collection |
|||
* @param {string} url URL of the image |
|||
* @param {Object} opts Options |
|||
* @return {this} |
|||
* @private |
|||
*/ |
|||
addImg: function(url, opts){ |
|||
this.add({ |
|||
type: 'image', |
|||
src: url, |
|||
}, opts); |
|||
return this; |
|||
}, |
|||
|
|||
/** |
|||
* Prevent inserting assets with the same 'src' |
|||
* Seems like idAttribute is not working with dynamic model assignament |
|||
* @private |
|||
*/ |
|||
add: function(models, opt) { |
|||
var mods = []; |
|||
models = models instanceof Array ? models : [models]; |
|||
|
|||
for (var i = 0, len = models.length; i < len; i++) { |
|||
var model = models[i]; |
|||
|
|||
if(typeof model === 'string') |
|||
model = {src: model, type: 'image'}; |
|||
|
|||
if(!model || !model.src) |
|||
continue; |
|||
|
|||
var found = this.where({src: model.src}); |
|||
|
|||
if(!found.length) |
|||
mods.push(model); |
|||
} |
|||
|
|||
if(mods.length == 1) |
|||
mods = mods[0]; |
|||
|
|||
return Backbone.Collection.prototype.add.apply(this, [mods, opt]); |
|||
}, |
|||
|
|||
|
|||
}); |
|||
}); |
|||
var Backbone = require('backbone'); |
|||
var Asset = require('./Asset'); |
|||
var AssetImage = require('./AssetImage'); |
|||
|
|||
module.exports = Backbone.Collection.extend({ |
|||
|
|||
model: AssetImage, |
|||
|
|||
initialize: function(models, opt){ |
|||
|
|||
this.model = function(attrs, options) { |
|||
var model; |
|||
switch(attrs.type){ |
|||
default: |
|||
model = new AssetImage(attrs, options); |
|||
} |
|||
return model; |
|||
}; |
|||
|
|||
}, |
|||
|
|||
/** |
|||
* Add new image asset to the collection |
|||
* @param {string} url URL of the image |
|||
* @param {Object} opts Options |
|||
* @return {this} |
|||
* @private |
|||
*/ |
|||
addImg: function(url, opts){ |
|||
this.add({ |
|||
type: 'image', |
|||
src: url, |
|||
}, opts); |
|||
return this; |
|||
}, |
|||
|
|||
/** |
|||
* Prevent inserting assets with the same 'src' |
|||
* Seems like idAttribute is not working with dynamic model assignament |
|||
* @private |
|||
*/ |
|||
add: function(models, opt) { |
|||
var mods = []; |
|||
models = models instanceof Array ? models : [models]; |
|||
|
|||
for (var i = 0, len = models.length; i < len; i++) { |
|||
var model = models[i]; |
|||
|
|||
if(typeof model === 'string') |
|||
model = {src: model, type: 'image'}; |
|||
|
|||
if(!model || !model.src) |
|||
continue; |
|||
|
|||
var found = this.where({src: model.src}); |
|||
|
|||
if(!found.length) |
|||
mods.push(model); |
|||
} |
|||
|
|||
if(mods.length == 1) |
|||
mods = mods[0]; |
|||
|
|||
return Backbone.Collection.prototype.add.apply(this, [mods, opt]); |
|||
}, |
|||
|
|||
|
|||
}); |
|||
|
|||
@ -1,99 +1,97 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var AssetView = require('./AssetView'); |
|||
var assetTemplate = require('text!./../template/assetImage.html'); |
|||
module.exports = AssetView.extend({ |
|||
var AssetView = require('./AssetView'); |
|||
var assetTemplate = require('text!./../template/assetImage.html'); |
|||
|
|||
events:{ |
|||
'click': 'handleClick', |
|||
'dblclick': 'handleDblClick', |
|||
}, |
|||
module.exports = AssetView.extend({ |
|||
|
|||
template: _.template(assetTemplate), |
|||
events:{ |
|||
'click': 'handleClick', |
|||
'dblclick': 'handleDblClick', |
|||
}, |
|||
|
|||
initialize: function(o) { |
|||
AssetView.prototype.initialize.apply(this, arguments); |
|||
this.className += ' ' + this.pfx + 'asset-image'; |
|||
this.events['click #' + this.pfx + 'close'] = 'removeItem'; |
|||
this.delegateEvents(); |
|||
}, |
|||
template: _.template(assetTemplate), |
|||
|
|||
/** |
|||
* Trigger when the asset is clicked |
|||
* @private |
|||
* */ |
|||
handleClick: function() { |
|||
var onClick = this.config.onClick; |
|||
var model = this.model; |
|||
model.collection.trigger('deselectAll'); |
|||
this.$el.addClass(this.pfx + 'highlight'); |
|||
initialize: function(o) { |
|||
AssetView.prototype.initialize.apply(this, arguments); |
|||
this.className += ' ' + this.pfx + 'asset-image'; |
|||
this.events['click #' + this.pfx + 'close'] = 'removeItem'; |
|||
this.delegateEvents(); |
|||
}, |
|||
|
|||
if (typeof onClick === 'function') { |
|||
onClick(model); |
|||
} else { |
|||
this.updateTarget(model.get('src')); |
|||
} |
|||
}, |
|||
/** |
|||
* Trigger when the asset is clicked |
|||
* @private |
|||
* */ |
|||
handleClick: function() { |
|||
var onClick = this.config.onClick; |
|||
var model = this.model; |
|||
model.collection.trigger('deselectAll'); |
|||
this.$el.addClass(this.pfx + 'highlight'); |
|||
|
|||
/** |
|||
* Trigger when the asset is double clicked |
|||
* @private |
|||
* */ |
|||
handleDblClick: function() { |
|||
var onDblClick = this.config.onDblClick; |
|||
var model = this.model; |
|||
if (typeof onClick === 'function') { |
|||
onClick(model); |
|||
} else { |
|||
this.updateTarget(model.get('src')); |
|||
} |
|||
}, |
|||
|
|||
if (typeof onDblClick === 'function') { |
|||
onDblClick(model); |
|||
} else { |
|||
this.updateTarget(model.get('src')); |
|||
} |
|||
/** |
|||
* Trigger when the asset is double clicked |
|||
* @private |
|||
* */ |
|||
handleDblClick: function() { |
|||
var onDblClick = this.config.onDblClick; |
|||
var model = this.model; |
|||
|
|||
var onSelect = model.collection.onSelect; |
|||
if(typeof onSelect == 'function'){ |
|||
onSelect(this.model); |
|||
} |
|||
}, |
|||
if (typeof onDblClick === 'function') { |
|||
onDblClick(model); |
|||
} else { |
|||
this.updateTarget(model.get('src')); |
|||
} |
|||
|
|||
/** |
|||
* Update target if exists |
|||
* @param {String} v Value |
|||
* @private |
|||
* */ |
|||
updateTarget: function(v){ |
|||
var target = this.model.collection.target; |
|||
if(target && target.set) { |
|||
var attr = _.clone( target.get('attributes') ); |
|||
target.set('attributes', attr ); |
|||
target.set('src', v ); |
|||
} |
|||
}, |
|||
var onSelect = model.collection.onSelect; |
|||
if(typeof onSelect == 'function'){ |
|||
onSelect(this.model); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Remove asset from collection |
|||
* @private |
|||
* */ |
|||
removeItem: function(e){ |
|||
e.stopPropagation(); |
|||
this.model.collection.remove(this.model); |
|||
}, |
|||
/** |
|||
* Update target if exists |
|||
* @param {String} v Value |
|||
* @private |
|||
* */ |
|||
updateTarget: function(v){ |
|||
var target = this.model.collection.target; |
|||
if(target && target.set) { |
|||
var attr = _.clone( target.get('attributes') ); |
|||
target.set('attributes', attr ); |
|||
target.set('src', v ); |
|||
} |
|||
}, |
|||
|
|||
render : function(){ |
|||
var name = this.model.get('name'), |
|||
dim = this.model.get('width') && this.model.get('height') ? |
|||
this.model.get('width')+' x '+this.model.get('height') : ''; |
|||
name = name ? name : this.model.get('src').split("/").pop(); |
|||
name = name && name.length > 30 ? name.substring(0, 30)+'...' : name; |
|||
dim = dim ? dim + (this.model.get('unitDim') ? this.model.get('unitDim') : ' px' ) : ''; |
|||
this.$el.html( this.template({ |
|||
name: name, |
|||
src: this.model.get('src'), |
|||
dim: dim, |
|||
pfx: this.pfx, |
|||
ppfx: this.ppfx |
|||
})); |
|||
this.$el.attr('class', this.className); |
|||
return this; |
|||
}, |
|||
}); |
|||
}); |
|||
/** |
|||
* Remove asset from collection |
|||
* @private |
|||
* */ |
|||
removeItem: function(e){ |
|||
e.stopPropagation(); |
|||
this.model.collection.remove(this.model); |
|||
}, |
|||
|
|||
render : function(){ |
|||
var name = this.model.get('name'), |
|||
dim = this.model.get('width') && this.model.get('height') ? |
|||
this.model.get('width')+' x '+this.model.get('height') : ''; |
|||
name = name ? name : this.model.get('src').split("/").pop(); |
|||
name = name && name.length > 30 ? name.substring(0, 30)+'...' : name; |
|||
dim = dim ? dim + (this.model.get('unitDim') ? this.model.get('unitDim') : ' px' ) : ''; |
|||
this.$el.html( this.template({ |
|||
name: name, |
|||
src: this.model.get('src'), |
|||
dim: dim, |
|||
pfx: this.pfx, |
|||
ppfx: this.ppfx |
|||
})); |
|||
this.$el.attr('class', this.className); |
|||
return this; |
|||
}, |
|||
}); |
|||
|
|||
@ -1,16 +1,12 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var Backbone = require('backbone'); |
|||
|
|||
module.exports = Backbone.View.extend({ |
|||
initialize: function(o) { |
|||
this.options = o; |
|||
this.config = o.config || {}; |
|||
this.pfx = this.config.stylePrefix || ''; |
|||
this.ppfx = this.config.pStylePrefix || ''; |
|||
this.className = this.pfx + 'asset'; |
|||
this.listenTo( this.model, 'destroy remove', this.remove); |
|||
}, |
|||
}); |
|||
|
|||
}); |
|||
module.exports = Backbone.View.extend({ |
|||
initialize: function(o) { |
|||
this.options = o; |
|||
this.config = o.config || {}; |
|||
this.pfx = this.config.stylePrefix || ''; |
|||
this.ppfx = this.config.pStylePrefix || ''; |
|||
this.className = this.pfx + 'asset'; |
|||
this.listenTo( this.model, 'destroy remove', this.remove); |
|||
}, |
|||
}); |
|||
|
|||
@ -1,136 +1,134 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var AssetView = require('./AssetView'); |
|||
var AssetImageView = require('./AssetImageView'); |
|||
var FileUploader = require('./FileUploader'); |
|||
var assetsTemplate = require('text!./../template/assets.html'); |
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
template: _.template(assetsTemplate), |
|||
|
|||
initialize: function(o) { |
|||
this.options = o; |
|||
this.config = o.config; |
|||
this.pfx = this.config.stylePrefix || ''; |
|||
this.ppfx = this.config.pStylePrefix || ''; |
|||
this.listenTo( this.collection, 'add', this.addToAsset ); |
|||
this.listenTo( this.collection, 'deselectAll', this.deselectAll ); |
|||
this.className = this.pfx + 'assets'; |
|||
|
|||
this.events = {}; |
|||
this.events.submit = 'addFromStr'; |
|||
this.delegateEvents(); |
|||
}, |
|||
|
|||
/** |
|||
* Add new asset to the collection via string |
|||
* @param {Event} e Event object |
|||
* @return {this} |
|||
* @private |
|||
*/ |
|||
addFromStr: function(e){ |
|||
e.preventDefault(); |
|||
|
|||
var input = this.getInputUrl(); |
|||
|
|||
var url = input.value.trim(); |
|||
|
|||
if(!url) |
|||
return; |
|||
|
|||
this.collection.addImg(url, {at: 0}); |
|||
|
|||
this.getAssetsEl().scrollTop = 0; |
|||
input.value = ''; |
|||
return this; |
|||
}, |
|||
|
|||
/** |
|||
* Returns assets element |
|||
* @return {HTMLElement} |
|||
* @private |
|||
*/ |
|||
getAssetsEl: function(){ |
|||
//if(!this.assets) // Not able to cache as after the rerender it losses the ref
|
|||
this.assets = this.el.querySelector('.' + this.pfx + 'assets'); |
|||
return this.assets; |
|||
}, |
|||
|
|||
/** |
|||
* Returns input url element |
|||
* @return {HTMLElement} |
|||
* @private |
|||
*/ |
|||
getInputUrl: function(){ |
|||
if(!this.inputUrl || !this.inputUrl.value) |
|||
this.inputUrl = this.el.querySelector('.'+this.pfx+'add-asset input'); |
|||
return this.inputUrl; |
|||
}, |
|||
|
|||
/** |
|||
* Add asset to collection |
|||
* @private |
|||
* */ |
|||
addToAsset: function(model){ |
|||
this.addAsset(model); |
|||
}, |
|||
|
|||
/** |
|||
* Add new asset to collection |
|||
* @param Object Model |
|||
* @param Object Fragment collection |
|||
* @return Object Object created |
|||
* @private |
|||
* */ |
|||
addAsset: function(model, fragmentEl){ |
|||
var fragment = fragmentEl || null; |
|||
var viewObject = AssetView; |
|||
|
|||
if(model.get('type').indexOf("image") > -1) |
|||
viewObject = AssetImageView; |
|||
|
|||
var view = new viewObject({ |
|||
model : model, |
|||
config : this.config, |
|||
}); |
|||
var rendered = view.render().el; |
|||
|
|||
if(fragment){ |
|||
fragment.appendChild( rendered ); |
|||
}else{ |
|||
var assetsEl = this.getAssetsEl(); |
|||
if(assetsEl) |
|||
assetsEl.insertBefore(rendered, assetsEl.firstChild); |
|||
} |
|||
|
|||
return rendered; |
|||
}, |
|||
|
|||
/** |
|||
* Deselect all assets |
|||
* @private |
|||
* */ |
|||
deselectAll: function(){ |
|||
this.$el.find('.' + this.pfx + 'highlight').removeClass(this.pfx + 'highlight'); |
|||
}, |
|||
|
|||
render: function() { |
|||
var fragment = document.createDocumentFragment(); |
|||
this.$el.empty(); |
|||
|
|||
this.collection.each(function(model){ |
|||
this.addAsset(model, fragment); |
|||
},this); |
|||
|
|||
this.$el.html(this.template({ |
|||
pfx: this.pfx, |
|||
ppfx: this.ppfx, |
|||
btnText: this.config.addBtnText, |
|||
})); |
|||
|
|||
this.$el.find('.'+this.pfx + 'assets').append(fragment); |
|||
return this; |
|||
} |
|||
}); |
|||
}); |
|||
var Backbone = require('backbone'); |
|||
var AssetView = require('./AssetView'); |
|||
var AssetImageView = require('./AssetImageView'); |
|||
var FileUploader = require('./FileUploader'); |
|||
var assetsTemplate = require('text!./../template/assets.html'); |
|||
|
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
template: _.template(assetsTemplate), |
|||
|
|||
initialize: function(o) { |
|||
this.options = o; |
|||
this.config = o.config; |
|||
this.pfx = this.config.stylePrefix || ''; |
|||
this.ppfx = this.config.pStylePrefix || ''; |
|||
this.listenTo( this.collection, 'add', this.addToAsset ); |
|||
this.listenTo( this.collection, 'deselectAll', this.deselectAll ); |
|||
this.className = this.pfx + 'assets'; |
|||
|
|||
this.events = {}; |
|||
this.events.submit = 'addFromStr'; |
|||
this.delegateEvents(); |
|||
}, |
|||
|
|||
/** |
|||
* Add new asset to the collection via string |
|||
* @param {Event} e Event object |
|||
* @return {this} |
|||
* @private |
|||
*/ |
|||
addFromStr: function(e){ |
|||
e.preventDefault(); |
|||
|
|||
var input = this.getInputUrl(); |
|||
|
|||
var url = input.value.trim(); |
|||
|
|||
if(!url) |
|||
return; |
|||
|
|||
this.collection.addImg(url, {at: 0}); |
|||
|
|||
this.getAssetsEl().scrollTop = 0; |
|||
input.value = ''; |
|||
return this; |
|||
}, |
|||
|
|||
/** |
|||
* Returns assets element |
|||
* @return {HTMLElement} |
|||
* @private |
|||
*/ |
|||
getAssetsEl: function(){ |
|||
//if(!this.assets) // Not able to cache as after the rerender it losses the ref
|
|||
this.assets = this.el.querySelector('.' + this.pfx + 'assets'); |
|||
return this.assets; |
|||
}, |
|||
|
|||
/** |
|||
* Returns input url element |
|||
* @return {HTMLElement} |
|||
* @private |
|||
*/ |
|||
getInputUrl: function(){ |
|||
if(!this.inputUrl || !this.inputUrl.value) |
|||
this.inputUrl = this.el.querySelector('.'+this.pfx+'add-asset input'); |
|||
return this.inputUrl; |
|||
}, |
|||
|
|||
/** |
|||
* Add asset to collection |
|||
* @private |
|||
* */ |
|||
addToAsset: function(model){ |
|||
this.addAsset(model); |
|||
}, |
|||
|
|||
/** |
|||
* Add new asset to collection |
|||
* @param Object Model |
|||
* @param Object Fragment collection |
|||
* @return Object Object created |
|||
* @private |
|||
* */ |
|||
addAsset: function(model, fragmentEl){ |
|||
var fragment = fragmentEl || null; |
|||
var viewObject = AssetView; |
|||
|
|||
if(model.get('type').indexOf("image") > -1) |
|||
viewObject = AssetImageView; |
|||
|
|||
var view = new viewObject({ |
|||
model : model, |
|||
config : this.config, |
|||
}); |
|||
var rendered = view.render().el; |
|||
|
|||
if(fragment){ |
|||
fragment.appendChild( rendered ); |
|||
}else{ |
|||
var assetsEl = this.getAssetsEl(); |
|||
if(assetsEl) |
|||
assetsEl.insertBefore(rendered, assetsEl.firstChild); |
|||
} |
|||
|
|||
return rendered; |
|||
}, |
|||
|
|||
/** |
|||
* Deselect all assets |
|||
* @private |
|||
* */ |
|||
deselectAll: function(){ |
|||
this.$el.find('.' + this.pfx + 'highlight').removeClass(this.pfx + 'highlight'); |
|||
}, |
|||
|
|||
render: function() { |
|||
var fragment = document.createDocumentFragment(); |
|||
this.$el.empty(); |
|||
|
|||
this.collection.each(function(model){ |
|||
this.addAsset(model, fragment); |
|||
},this); |
|||
|
|||
this.$el.html(this.template({ |
|||
pfx: this.pfx, |
|||
ppfx: this.ppfx, |
|||
btnText: this.config.addBtnText, |
|||
})); |
|||
|
|||
this.$el.find('.'+this.pfx + 'assets').append(fragment); |
|||
return this; |
|||
} |
|||
}); |
|||
|
|||
@ -1,99 +1,97 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var fileUploaderTemplate = require('text!./../template/fileUploader.html'); |
|||
module.exports = Backbone.View.extend({ |
|||
var Backbone = require('backbone'); |
|||
var fileUploaderTemplate = require('text!./../template/fileUploader.html'); |
|||
|
|||
template: _.template(fileUploaderTemplate), |
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
events: {}, |
|||
template: _.template(fileUploaderTemplate), |
|||
|
|||
initialize: function(o) { |
|||
this.options = o || {}; |
|||
this.config = o.config || {}; |
|||
this.pfx = this.config.stylePrefix || ''; |
|||
this.target = this.collection || {}; |
|||
this.uploadId = this.pfx + 'uploadFile'; |
|||
this.disabled = !this.config.upload; |
|||
this.events['change #' + this.uploadId] = 'uploadFile'; |
|||
this.delegateEvents(); |
|||
}, |
|||
events: {}, |
|||
|
|||
/** |
|||
* Upload files |
|||
* @param {Object} e Event |
|||
* @private |
|||
* */ |
|||
uploadFile : function(e){ |
|||
var files = e.dataTransfer ? e.dataTransfer.files : e.target.files, |
|||
formData = new FormData(); |
|||
for (var i = 0; i < files.length; i++) { |
|||
formData.append('files[]', files[i]); |
|||
} |
|||
var target = this.target; |
|||
$.ajax({ |
|||
url : this.config.upload, |
|||
type : 'POST', |
|||
data : formData, |
|||
beforeSend : this.config.beforeSend, |
|||
complete : this.config.onComplete, |
|||
xhrFields : { |
|||
onprogress: function (e) { |
|||
if (e.lengthComputable) { |
|||
/*var result = e.loaded / e.total * 100 + '%';*/ |
|||
} |
|||
}, |
|||
onload: function (e) { |
|||
//progress.value = 100;
|
|||
} |
|||
}, |
|||
cache: false, contentType: false, processData: false |
|||
}).done(function(data){ |
|||
target.add(data.data); |
|||
}).always(function(){ |
|||
//turnOff loading
|
|||
}); |
|||
}, |
|||
initialize: function(o) { |
|||
this.options = o || {}; |
|||
this.config = o.config || {}; |
|||
this.pfx = this.config.stylePrefix || ''; |
|||
this.target = this.collection || {}; |
|||
this.uploadId = this.pfx + 'uploadFile'; |
|||
this.disabled = !this.config.upload; |
|||
this.events['change #' + this.uploadId] = 'uploadFile'; |
|||
this.delegateEvents(); |
|||
}, |
|||
|
|||
/** |
|||
* Make input file droppable |
|||
* @private |
|||
* */ |
|||
initDrop: function(){ |
|||
var that = this; |
|||
if(!this.uploadForm){ |
|||
this.uploadForm = this.$el.find('form').get(0); |
|||
if( 'draggable' in this.uploadForm ){ |
|||
var uploadFile = this.uploadFile; |
|||
this.uploadForm.ondragover = function(){ |
|||
this.className = that.pfx + 'hover'; |
|||
return false; |
|||
}; |
|||
this.uploadForm.ondragleave = function(){ |
|||
this.className = ''; |
|||
return false; |
|||
}; |
|||
this.uploadForm.ondrop = function(e){ |
|||
this.className = ''; |
|||
e.preventDefault(); |
|||
that.uploadFile(e); |
|||
return; |
|||
}; |
|||
} |
|||
} |
|||
}, |
|||
/** |
|||
* Upload files |
|||
* @param {Object} e Event |
|||
* @private |
|||
* */ |
|||
uploadFile : function(e){ |
|||
var files = e.dataTransfer ? e.dataTransfer.files : e.target.files, |
|||
formData = new FormData(); |
|||
for (var i = 0; i < files.length; i++) { |
|||
formData.append('files[]', files[i]); |
|||
} |
|||
var target = this.target; |
|||
$.ajax({ |
|||
url : this.config.upload, |
|||
type : 'POST', |
|||
data : formData, |
|||
beforeSend : this.config.beforeSend, |
|||
complete : this.config.onComplete, |
|||
xhrFields : { |
|||
onprogress: function (e) { |
|||
if (e.lengthComputable) { |
|||
/*var result = e.loaded / e.total * 100 + '%';*/ |
|||
} |
|||
}, |
|||
onload: function (e) { |
|||
//progress.value = 100;
|
|||
} |
|||
}, |
|||
cache: false, contentType: false, processData: false |
|||
}).done(function(data){ |
|||
target.add(data.data); |
|||
}).always(function(){ |
|||
//turnOff loading
|
|||
}); |
|||
}, |
|||
|
|||
render : function(){ |
|||
this.$el.html( this.template({ |
|||
title: this.config.uploadText, |
|||
uploadId: this.uploadId, |
|||
disabled: this.disabled, |
|||
pfx: this.pfx |
|||
}) ); |
|||
this.initDrop(); |
|||
this.$el.attr('class', this.pfx + 'file-uploader'); |
|||
return this; |
|||
}, |
|||
/** |
|||
* Make input file droppable |
|||
* @private |
|||
* */ |
|||
initDrop: function(){ |
|||
var that = this; |
|||
if(!this.uploadForm){ |
|||
this.uploadForm = this.$el.find('form').get(0); |
|||
if( 'draggable' in this.uploadForm ){ |
|||
var uploadFile = this.uploadFile; |
|||
this.uploadForm.ondragover = function(){ |
|||
this.className = that.pfx + 'hover'; |
|||
return false; |
|||
}; |
|||
this.uploadForm.ondragleave = function(){ |
|||
this.className = ''; |
|||
return false; |
|||
}; |
|||
this.uploadForm.ondrop = function(e){ |
|||
this.className = ''; |
|||
e.preventDefault(); |
|||
that.uploadFile(e); |
|||
return; |
|||
}; |
|||
} |
|||
} |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
render : function(){ |
|||
this.$el.html( this.template({ |
|||
title: this.config.uploadText, |
|||
uploadId: this.uploadId, |
|||
disabled: this.disabled, |
|||
pfx: this.pfx |
|||
}) ); |
|||
this.initDrop(); |
|||
this.$el.attr('class', this.pfx + 'file-uploader'); |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
|
|||
@ -1,7 +1,5 @@ |
|||
define(function () { |
|||
return { |
|||
module.exports = { |
|||
|
|||
'blocks': [], |
|||
'blocks': [], |
|||
|
|||
}; |
|||
}); |
|||
}; |
|||
|
|||
@ -1,14 +1,11 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var Backbone = require('backbone'); |
|||
|
|||
module.exports = Backbone.Model.extend({ |
|||
module.exports = Backbone.Model.extend({ |
|||
|
|||
defaults :{ |
|||
label: '', |
|||
content: '', |
|||
attributes: {}, |
|||
}, |
|||
defaults :{ |
|||
label: '', |
|||
content: '', |
|||
attributes: {}, |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,11 +1,6 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var Block = require('./Block'); |
|||
var Backbone = require('backbone'); |
|||
var Block = require('./Block'); |
|||
|
|||
module.exports = Backbone.Collection.extend({ |
|||
|
|||
model: Block, |
|||
|
|||
}); |
|||
}); |
|||
module.exports = Backbone.Collection.extend({ |
|||
model: Block, |
|||
}); |
|||
|
|||
@ -1,51 +1,48 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var Backbone = require('backbone'); |
|||
|
|||
module.exports = Backbone.View.extend({ |
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
events: { |
|||
mousedown: 'onDrag' |
|||
}, |
|||
events: { |
|||
mousedown: 'onDrag' |
|||
}, |
|||
|
|||
initialize: function(o, config) { |
|||
_.bindAll(this, 'onDrop'); |
|||
this.config = config || {}; |
|||
this.ppfx = this.config.pStylePrefix || ''; |
|||
this.listenTo(this.model, 'destroy', this.remove); |
|||
this.doc = $(document); |
|||
}, |
|||
initialize: function(o, config) { |
|||
_.bindAll(this, 'onDrop'); |
|||
this.config = config || {}; |
|||
this.ppfx = this.config.pStylePrefix || ''; |
|||
this.listenTo(this.model, 'destroy', this.remove); |
|||
this.doc = $(document); |
|||
}, |
|||
|
|||
/** |
|||
* Start block dragging |
|||
* @private |
|||
*/ |
|||
onDrag: function(e) { |
|||
if(!this.config.getSorter) |
|||
return; |
|||
this.config.em.refreshCanvas(); |
|||
var sorter = this.config.getSorter(); |
|||
sorter.setDragHelper(this.el, e); |
|||
sorter.startSort(this.el); |
|||
sorter.setDropContent(this.model.get('content')); |
|||
this.doc.on('mouseup', this.onDrop); |
|||
}, |
|||
/** |
|||
* Start block dragging |
|||
* @private |
|||
*/ |
|||
onDrag: function(e) { |
|||
if(!this.config.getSorter) |
|||
return; |
|||
this.config.em.refreshCanvas(); |
|||
var sorter = this.config.getSorter(); |
|||
sorter.setDragHelper(this.el, e); |
|||
sorter.startSort(this.el); |
|||
sorter.setDropContent(this.model.get('content')); |
|||
this.doc.on('mouseup', this.onDrop); |
|||
}, |
|||
|
|||
/** |
|||
* Drop block |
|||
* @private |
|||
*/ |
|||
onDrop: function() { |
|||
this.doc.off('mouseup', this.onDrop); |
|||
this.config.getSorter().endMove(); |
|||
}, |
|||
/** |
|||
* Drop block |
|||
* @private |
|||
*/ |
|||
onDrop: function() { |
|||
this.doc.off('mouseup', this.onDrop); |
|||
this.config.getSorter().endMove(); |
|||
}, |
|||
|
|||
render: function() { |
|||
var className = this.ppfx + 'block'; |
|||
this.$el.addClass(className); |
|||
this.el.innerHTML = '<div class="' + className + '-label">' + this.model.get('label') + '</div>'; |
|||
return this; |
|||
}, |
|||
render: function() { |
|||
var className = this.ppfx + 'block'; |
|||
this.$el.addClass(className); |
|||
this.el.innerHTML = '<div class="' + className + '-label">' + this.model.get('label') + '</div>'; |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,123 +1,120 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var BlockView = require('./BlockView'); |
|||
|
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
initialize: function(opts, config) { |
|||
_.bindAll(this, 'getSorter', 'onDrag', 'onDrop'); |
|||
this.config = config || {}; |
|||
this.ppfx = this.config.pStylePrefix || ''; |
|||
this.listenTo(this.collection, 'add', this.addTo); |
|||
this.em = this.config.em; |
|||
this.tac = 'test-tac'; |
|||
this.grabbingCls = this.ppfx + 'grabbing'; |
|||
|
|||
if(this.em){ |
|||
this.config.getSorter = this.getSorter; |
|||
this.canvas = this.em.get('Canvas'); |
|||
var Backbone = require('backbone'); |
|||
var BlockView = require('./BlockView'); |
|||
|
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
initialize: function(opts, config) { |
|||
_.bindAll(this, 'getSorter', 'onDrag', 'onDrop'); |
|||
this.config = config || {}; |
|||
this.ppfx = this.config.pStylePrefix || ''; |
|||
this.listenTo(this.collection, 'add', this.addTo); |
|||
this.em = this.config.em; |
|||
this.tac = 'test-tac'; |
|||
this.grabbingCls = this.ppfx + 'grabbing'; |
|||
|
|||
if(this.em){ |
|||
this.config.getSorter = this.getSorter; |
|||
this.canvas = this.em.get('Canvas'); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Get sorter |
|||
* @private |
|||
*/ |
|||
getSorter: function(){ |
|||
if(!this.em) |
|||
return; |
|||
if(!this.sorter){ |
|||
var utils = this.em.get('Utils'); |
|||
var canvas = this.canvas; |
|||
this.sorter = new utils.Sorter({ |
|||
container: canvas.getBody(), |
|||
placer: canvas.getPlacerEl(), |
|||
containerSel: '*', |
|||
itemSel: '*', |
|||
pfx: this.ppfx, |
|||
onStart: this.onDrag, |
|||
onEndMove: this.onDrop, |
|||
document: canvas.getFrameEl().contentDocument, |
|||
direction: 'a', |
|||
wmargin: 1, |
|||
nested: 1, |
|||
em: this.em, |
|||
canvasRelative: 1, |
|||
}); |
|||
} |
|||
return this.sorter; |
|||
}, |
|||
|
|||
/** |
|||
* Callback when block is on drag |
|||
* @private |
|||
*/ |
|||
onDrag: function(){ |
|||
this.em.stopDefault(); |
|||
}, |
|||
|
|||
/** |
|||
* Callback when block is dropped |
|||
* @private |
|||
*/ |
|||
onDrop: function(model){ |
|||
this.em.runDefault(); |
|||
|
|||
if (model && model.get) { |
|||
if(model.get('activeOnRender')) { |
|||
model.trigger('active'); |
|||
model.set('activeOnRender', 0); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Get sorter |
|||
* @private |
|||
*/ |
|||
getSorter: function(){ |
|||
if(!this.em) |
|||
return; |
|||
if(!this.sorter){ |
|||
var utils = this.em.get('Utils'); |
|||
var canvas = this.canvas; |
|||
this.sorter = new utils.Sorter({ |
|||
container: canvas.getBody(), |
|||
placer: canvas.getPlacerEl(), |
|||
containerSel: '*', |
|||
itemSel: '*', |
|||
pfx: this.ppfx, |
|||
onStart: this.onDrag, |
|||
onEndMove: this.onDrop, |
|||
document: canvas.getFrameEl().contentDocument, |
|||
direction: 'a', |
|||
wmargin: 1, |
|||
nested: 1, |
|||
em: this.em, |
|||
canvasRelative: 1, |
|||
}); |
|||
} |
|||
return this.sorter; |
|||
}, |
|||
|
|||
/** |
|||
* Callback when block is on drag |
|||
* @private |
|||
*/ |
|||
onDrag: function(){ |
|||
this.em.stopDefault(); |
|||
}, |
|||
|
|||
/** |
|||
* Callback when block is dropped |
|||
* @private |
|||
*/ |
|||
onDrop: function(model){ |
|||
this.em.runDefault(); |
|||
|
|||
if (model && model.get) { |
|||
if(model.get('activeOnRender')) { |
|||
model.trigger('active'); |
|||
model.set('activeOnRender', 0); |
|||
} |
|||
|
|||
// Register all its components (eg. for the Undo Manager)
|
|||
this.em.initChildrenComp(model); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Add new model to the collection |
|||
* @param {Model} model |
|||
* @private |
|||
* */ |
|||
addTo: function(model){ |
|||
this.add(model); |
|||
}, |
|||
|
|||
/** |
|||
* Render new model inside the view |
|||
* @param {Model} model |
|||
* @param {Object} fragment Fragment collection |
|||
* @private |
|||
* */ |
|||
add: function(model, fragment){ |
|||
var frag = fragment || null; |
|||
var view = new BlockView({ |
|||
model: model, |
|||
attributes: model.get('attributes'), |
|||
}, this.config); |
|||
var rendered = view.render().el; |
|||
|
|||
if(frag) |
|||
frag.appendChild(rendered); |
|||
else |
|||
this.$el.append(rendered); |
|||
}, |
|||
|
|||
|
|||
|
|||
render: function() { |
|||
var frag = document.createDocumentFragment(); |
|||
this.$el.empty(); |
|||
|
|||
this.collection.each(function(model){ |
|||
this.add(model, frag); |
|||
}, this); |
|||
|
|||
this.$el.append(frag); |
|||
this.$el.addClass(this.ppfx + 'blocks-c'); |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
|
|||
// Register all its components (eg. for the Undo Manager)
|
|||
this.em.initChildrenComp(model); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Add new model to the collection |
|||
* @param {Model} model |
|||
* @private |
|||
* */ |
|||
addTo: function(model){ |
|||
this.add(model); |
|||
}, |
|||
|
|||
/** |
|||
* Render new model inside the view |
|||
* @param {Model} model |
|||
* @param {Object} fragment Fragment collection |
|||
* @private |
|||
* */ |
|||
add: function(model, fragment){ |
|||
var frag = fragment || null; |
|||
var view = new BlockView({ |
|||
model: model, |
|||
attributes: model.get('attributes'), |
|||
}, this.config); |
|||
var rendered = view.render().el; |
|||
|
|||
if(frag) |
|||
frag.appendChild(rendered); |
|||
else |
|||
this.$el.append(rendered); |
|||
}, |
|||
|
|||
|
|||
|
|||
render: function() { |
|||
var frag = document.createDocumentFragment(); |
|||
this.$el.empty(); |
|||
|
|||
this.collection.each(function(model){ |
|||
this.add(model, frag); |
|||
}, this); |
|||
|
|||
this.$el.append(frag); |
|||
this.$el.addClass(this.ppfx + 'blocks-c'); |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
|
|||
@ -1,16 +1,14 @@ |
|||
define(function () { |
|||
return { |
|||
module.exports = { |
|||
|
|||
stylePrefix: 'cv-', |
|||
stylePrefix: 'cv-', |
|||
|
|||
// Coming soon
|
|||
rulers: false, |
|||
// Coming soon
|
|||
rulers: false, |
|||
|
|||
/* |
|||
* append scripts in head of iframe before renderBody content |
|||
* need to manually maintain the same scripts in cms's render template |
|||
*/ |
|||
scripts: [] |
|||
/* |
|||
* append scripts in head of iframe before renderBody content |
|||
* need to manually maintain the same scripts in cms's render template |
|||
*/ |
|||
scripts: [] |
|||
|
|||
}; |
|||
}); |
|||
}; |
|||
|
|||
@ -1,329 +1,325 @@ |
|||
define(function(require) { |
|||
|
|||
return function() { |
|||
var c = {}, |
|||
defaults = require('./config/config'), |
|||
Canvas = require('./model/Canvas'), |
|||
CanvasView = require('./view/CanvasView'); |
|||
var canvas; |
|||
|
|||
return { |
|||
|
|||
/** |
|||
* Used inside RTE |
|||
* @private |
|||
*/ |
|||
getCanvasView: function() { |
|||
return CanvasView; |
|||
}, |
|||
|
|||
/** |
|||
* Name of the module |
|||
* @type {String} |
|||
* @private |
|||
*/ |
|||
name: 'Canvas', |
|||
|
|||
/** |
|||
* Initialize module. Automatically called with a new instance of the editor |
|||
* @param {Object} config Configurations |
|||
*/ |
|||
init: function(config) { |
|||
c = config || {}; |
|||
for (var name in defaults) { |
|||
if (!(name in c)) |
|||
c[name] = defaults[name]; |
|||
} |
|||
|
|||
var ppfx = c.pStylePrefix; |
|||
if(ppfx) |
|||
c.stylePrefix = ppfx + c.stylePrefix; |
|||
|
|||
canvas = new Canvas(config); |
|||
CanvasView = new CanvasView({ |
|||
model: canvas, |
|||
config: c, |
|||
}); |
|||
|
|||
var cm = c.em.get('DomComponents'); |
|||
if(cm) |
|||
this.setWrapper(cm); |
|||
|
|||
return this; |
|||
}, |
|||
|
|||
/** |
|||
* Add wrapper |
|||
* @param {Object} wrp Wrapper |
|||
* |
|||
* */ |
|||
setWrapper: function(wrp) { |
|||
canvas.set('wrapper', wrp); |
|||
}, |
|||
|
|||
/** |
|||
* Returns canvas element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getElement: function(){ |
|||
return CanvasView.el; |
|||
}, |
|||
|
|||
/** |
|||
* Returns frame element of the canvas |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getFrameEl: function(){ |
|||
return CanvasView.frame.el; |
|||
}, |
|||
|
|||
/** |
|||
* Returns body element of the frame |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getBody: function(){ |
|||
return CanvasView.frame.el.contentDocument.body; |
|||
}, |
|||
|
|||
/** |
|||
* Returns body wrapper element of the frame |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getWrapperEl: function(){ |
|||
return this.getBody().querySelector('#wrapper'); |
|||
}, |
|||
|
|||
/** |
|||
* Returns element containing canvas tools |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getToolsEl: function(){ |
|||
return CanvasView.toolsEl; |
|||
}, |
|||
|
|||
/** |
|||
* Returns highlighter element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getHighlighter: function(){ |
|||
return CanvasView.hlEl; |
|||
}, |
|||
|
|||
/** |
|||
* Returns badge element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getBadgeEl: function(){ |
|||
return CanvasView.badgeEl; |
|||
}, |
|||
|
|||
/** |
|||
* Returns placer element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getPlacerEl: function(){ |
|||
return CanvasView.placerEl; |
|||
}, |
|||
|
|||
/** |
|||
* Returns ghost element |
|||
* @return {HTMLElement} |
|||
* @private |
|||
*/ |
|||
getGhostEl: function(){ |
|||
return CanvasView.ghostEl; |
|||
}, |
|||
|
|||
/** |
|||
* Returns toolbar element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getToolbarEl: function() { |
|||
return CanvasView.toolbarEl; |
|||
}, |
|||
|
|||
/** |
|||
* Returns resizer element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getResizerEl: function() { |
|||
return CanvasView.resizerEl; |
|||
}, |
|||
|
|||
/** |
|||
* Returns offset viewer element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getOffsetViewerEl: function() { |
|||
return CanvasView.offsetEl; |
|||
}, |
|||
|
|||
/** |
|||
* Returns fixed offset viewer element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getFixedOffsetViewerEl: function() { |
|||
return CanvasView.fixedOffsetEl; |
|||
}, |
|||
|
|||
/** |
|||
* Render canvas |
|||
* */ |
|||
render: function() { |
|||
return CanvasView.render().el; |
|||
}, |
|||
|
|||
/** |
|||
* Get frame position |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getOffset: function() { |
|||
var frameOff = this.offset(this.getFrameEl()); |
|||
var canvasOff = this.offset(this.getElement()); |
|||
return { |
|||
top: frameOff.top - canvasOff.top, |
|||
left: frameOff.left - canvasOff.left |
|||
}; |
|||
}, |
|||
|
|||
/** |
|||
* Get the offset of the element |
|||
* @param {HTMLElement} el |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
offset: function(el){ |
|||
var rect = el.getBoundingClientRect(); |
|||
return { |
|||
top: rect.top + document.body.scrollTop, |
|||
left: rect.left + document.body.scrollLeft |
|||
}; |
|||
}, |
|||
|
|||
/** |
|||
* Get element position relative to the canvas |
|||
* @param {HTMLElement} el |
|||
* @return {Object} |
|||
*/ |
|||
getElementPos: function(el) { |
|||
return CanvasView.getElementPos(el); |
|||
}, |
|||
|
|||
/** |
|||
* 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 {Object} options Custom options |
|||
* @param {Boolean} options.toRight Set to true if you want the toolbar attached to the right |
|||
* @return {Object} |
|||
*/ |
|||
getTargetToElementDim: function (target, element, options) { |
|||
var opts = options || {}; |
|||
var canvasPos = CanvasView.getPosition(); |
|||
var pos = opts.elPos || CanvasView.getElementPos(element); |
|||
var toRight = options.toRight || 0; |
|||
var targetHeight = opts.targetHeight || target.offsetHeight; |
|||
var targetWidth = opts.targetWidth || target.offsetWidth; |
|||
var eventToTrigger = opts.event || null; |
|||
|
|||
var elTop = pos.top - targetHeight; |
|||
var elLeft = pos.left; |
|||
elLeft += toRight ? pos.width : 0; |
|||
elLeft = toRight ? (elLeft - targetWidth) : 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; |
|||
|
|||
var result = { |
|||
top: topPos, |
|||
left: leftPos, |
|||
elementTop: pos.top, |
|||
elementLeft: pos.left, |
|||
elementWidth: pos.width, |
|||
elementHeight: pos.height, |
|||
targetWidth: target.offsetWidth, |
|||
targetHeight: target.offsetHeight, |
|||
canvasTop: canvasPos.top, |
|||
canvasLeft: canvasPos.left, |
|||
}; |
|||
|
|||
// In this way I can catch data and also change the position strategy
|
|||
if(eventToTrigger && c.em) { |
|||
c.em.trigger(eventToTrigger, result); |
|||
} |
|||
|
|||
return result; |
|||
}, |
|||
|
|||
/** |
|||
* Instead of simply returning e.clientX and e.clientY this function |
|||
* calculates also the offset based on the canvas. This is helpful when you |
|||
* need to get X and Y position while moving between the editor area and |
|||
* canvas area, which is in the iframe |
|||
* @param {Event} e |
|||
* @return {Object} |
|||
*/ |
|||
getMouseRelativePos: function (e, options) { |
|||
var opts = options || {}; |
|||
var addTop = 0; |
|||
var addLeft = 0; |
|||
var subWinOffset = opts.subWinOffset; |
|||
var doc = e.target.ownerDocument; |
|||
var win = doc.defaultView || doc.parentWindow; |
|||
var frame = win.frameElement; |
|||
var yOffset = subWinOffset ? win.pageYOffset : 0; |
|||
var xOffset = subWinOffset ? win.pageXOffset : 0; |
|||
|
|||
if (frame) { |
|||
var frameRect = frame.getBoundingClientRect(); |
|||
addTop = frameRect.top || 0; |
|||
addLeft = frameRect.left || 0; |
|||
} |
|||
|
|||
return { |
|||
y: e.clientY + addTop - yOffset, |
|||
x: e.clientX + addLeft - xOffset, |
|||
}; |
|||
}, |
|||
|
|||
/** |
|||
* X and Y mouse position relative to the canvas |
|||
* @param {Event} e |
|||
* @return {Object} |
|||
*/ |
|||
getMouseRelativeCanvas: function (e, options) { |
|||
var opts = options || {}; |
|||
var frame = this.getFrameEl(); |
|||
var body = this.getBody(); |
|||
var addTop = frame.offsetTop || 0; |
|||
var addLeft = frame.offsetLeft || 0; |
|||
var yOffset = body.scrollTop || 0; |
|||
var xOffset = body.scrollLeft || 0; |
|||
|
|||
return { |
|||
y: e.clientY + addTop + yOffset, |
|||
x: e.clientX + addLeft + xOffset, |
|||
}; |
|||
}, |
|||
|
|||
/** |
|||
* Returns wrapper element |
|||
* @return {HTMLElement} |
|||
* ???? |
|||
*/ |
|||
getFrameWrapperEl: function(){ |
|||
return CanvasView.frame.getWrapper(); |
|||
}, |
|||
}; |
|||
module.exports = function() { |
|||
var c = {}, |
|||
defaults = require('./config/config'), |
|||
Canvas = require('./model/Canvas'), |
|||
CanvasView = require('./view/CanvasView'); |
|||
var canvas; |
|||
|
|||
return { |
|||
|
|||
/** |
|||
* Used inside RTE |
|||
* @private |
|||
*/ |
|||
getCanvasView: function() { |
|||
return CanvasView; |
|||
}, |
|||
|
|||
/** |
|||
* Name of the module |
|||
* @type {String} |
|||
* @private |
|||
*/ |
|||
name: 'Canvas', |
|||
|
|||
/** |
|||
* Initialize module. Automatically called with a new instance of the editor |
|||
* @param {Object} config Configurations |
|||
*/ |
|||
init: function(config) { |
|||
c = config || {}; |
|||
for (var name in defaults) { |
|||
if (!(name in c)) |
|||
c[name] = defaults[name]; |
|||
} |
|||
|
|||
var ppfx = c.pStylePrefix; |
|||
if(ppfx) |
|||
c.stylePrefix = ppfx + c.stylePrefix; |
|||
|
|||
canvas = new Canvas(config); |
|||
CanvasView = new CanvasView({ |
|||
model: canvas, |
|||
config: c, |
|||
}); |
|||
|
|||
var cm = c.em.get('DomComponents'); |
|||
if(cm) |
|||
this.setWrapper(cm); |
|||
|
|||
return this; |
|||
}, |
|||
|
|||
/** |
|||
* Add wrapper |
|||
* @param {Object} wrp Wrapper |
|||
* |
|||
* */ |
|||
setWrapper: function(wrp) { |
|||
canvas.set('wrapper', wrp); |
|||
}, |
|||
|
|||
/** |
|||
* Returns canvas element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getElement: function(){ |
|||
return CanvasView.el; |
|||
}, |
|||
|
|||
/** |
|||
* Returns frame element of the canvas |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getFrameEl: function(){ |
|||
return CanvasView.frame.el; |
|||
}, |
|||
|
|||
/** |
|||
* Returns body element of the frame |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getBody: function(){ |
|||
return CanvasView.frame.el.contentDocument.body; |
|||
}, |
|||
|
|||
/** |
|||
* Returns body wrapper element of the frame |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getWrapperEl: function(){ |
|||
return this.getBody().querySelector('#wrapper'); |
|||
}, |
|||
|
|||
/** |
|||
* Returns element containing canvas tools |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getToolsEl: function(){ |
|||
return CanvasView.toolsEl; |
|||
}, |
|||
|
|||
/** |
|||
* Returns highlighter element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getHighlighter: function(){ |
|||
return CanvasView.hlEl; |
|||
}, |
|||
|
|||
/** |
|||
* Returns badge element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getBadgeEl: function(){ |
|||
return CanvasView.badgeEl; |
|||
}, |
|||
|
|||
/** |
|||
* Returns placer element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getPlacerEl: function(){ |
|||
return CanvasView.placerEl; |
|||
}, |
|||
|
|||
/** |
|||
* Returns ghost element |
|||
* @return {HTMLElement} |
|||
* @private |
|||
*/ |
|||
getGhostEl: function(){ |
|||
return CanvasView.ghostEl; |
|||
}, |
|||
|
|||
/** |
|||
* Returns toolbar element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getToolbarEl: function() { |
|||
return CanvasView.toolbarEl; |
|||
}, |
|||
|
|||
/** |
|||
* Returns resizer element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getResizerEl: function() { |
|||
return CanvasView.resizerEl; |
|||
}, |
|||
|
|||
/** |
|||
* Returns offset viewer element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getOffsetViewerEl: function() { |
|||
return CanvasView.offsetEl; |
|||
}, |
|||
|
|||
/** |
|||
* Returns fixed offset viewer element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getFixedOffsetViewerEl: function() { |
|||
return CanvasView.fixedOffsetEl; |
|||
}, |
|||
|
|||
/** |
|||
* Render canvas |
|||
* */ |
|||
render: function() { |
|||
return CanvasView.render().el; |
|||
}, |
|||
|
|||
/** |
|||
* Get frame position |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getOffset: function() { |
|||
var frameOff = this.offset(this.getFrameEl()); |
|||
var canvasOff = this.offset(this.getElement()); |
|||
return { |
|||
top: frameOff.top - canvasOff.top, |
|||
left: frameOff.left - canvasOff.left |
|||
}; |
|||
}, |
|||
|
|||
/** |
|||
* Get the offset of the element |
|||
* @param {HTMLElement} el |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
offset: function(el){ |
|||
var rect = el.getBoundingClientRect(); |
|||
return { |
|||
top: rect.top + document.body.scrollTop, |
|||
left: rect.left + document.body.scrollLeft |
|||
}; |
|||
}, |
|||
|
|||
/** |
|||
* Get element position relative to the canvas |
|||
* @param {HTMLElement} el |
|||
* @return {Object} |
|||
*/ |
|||
getElementPos: function(el) { |
|||
return CanvasView.getElementPos(el); |
|||
}, |
|||
|
|||
/** |
|||
* 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 {Object} options Custom options |
|||
* @param {Boolean} options.toRight Set to true if you want the toolbar attached to the right |
|||
* @return {Object} |
|||
*/ |
|||
getTargetToElementDim: function (target, element, options) { |
|||
var opts = options || {}; |
|||
var canvasPos = CanvasView.getPosition(); |
|||
var pos = opts.elPos || CanvasView.getElementPos(element); |
|||
var toRight = options.toRight || 0; |
|||
var targetHeight = opts.targetHeight || target.offsetHeight; |
|||
var targetWidth = opts.targetWidth || target.offsetWidth; |
|||
var eventToTrigger = opts.event || null; |
|||
|
|||
var elTop = pos.top - targetHeight; |
|||
var elLeft = pos.left; |
|||
elLeft += toRight ? pos.width : 0; |
|||
elLeft = toRight ? (elLeft - targetWidth) : 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; |
|||
|
|||
var result = { |
|||
top: topPos, |
|||
left: leftPos, |
|||
elementTop: pos.top, |
|||
elementLeft: pos.left, |
|||
elementWidth: pos.width, |
|||
elementHeight: pos.height, |
|||
targetWidth: target.offsetWidth, |
|||
targetHeight: target.offsetHeight, |
|||
canvasTop: canvasPos.top, |
|||
canvasLeft: canvasPos.left, |
|||
}; |
|||
|
|||
// In this way I can catch data and also change the position strategy
|
|||
if(eventToTrigger && c.em) { |
|||
c.em.trigger(eventToTrigger, result); |
|||
} |
|||
|
|||
return result; |
|||
}, |
|||
|
|||
/** |
|||
* Instead of simply returning e.clientX and e.clientY this function |
|||
* calculates also the offset based on the canvas. This is helpful when you |
|||
* need to get X and Y position while moving between the editor area and |
|||
* canvas area, which is in the iframe |
|||
* @param {Event} e |
|||
* @return {Object} |
|||
*/ |
|||
getMouseRelativePos: function (e, options) { |
|||
var opts = options || {}; |
|||
var addTop = 0; |
|||
var addLeft = 0; |
|||
var subWinOffset = opts.subWinOffset; |
|||
var doc = e.target.ownerDocument; |
|||
var win = doc.defaultView || doc.parentWindow; |
|||
var frame = win.frameElement; |
|||
var yOffset = subWinOffset ? win.pageYOffset : 0; |
|||
var xOffset = subWinOffset ? win.pageXOffset : 0; |
|||
|
|||
if (frame) { |
|||
var frameRect = frame.getBoundingClientRect(); |
|||
addTop = frameRect.top || 0; |
|||
addLeft = frameRect.left || 0; |
|||
} |
|||
|
|||
return { |
|||
y: e.clientY + addTop - yOffset, |
|||
x: e.clientX + addLeft - xOffset, |
|||
}; |
|||
}, |
|||
|
|||
/** |
|||
* X and Y mouse position relative to the canvas |
|||
* @param {Event} e |
|||
* @return {Object} |
|||
*/ |
|||
getMouseRelativeCanvas: function (e, options) { |
|||
var opts = options || {}; |
|||
var frame = this.getFrameEl(); |
|||
var body = this.getBody(); |
|||
var addTop = frame.offsetTop || 0; |
|||
var addLeft = frame.offsetLeft || 0; |
|||
var yOffset = body.scrollTop || 0; |
|||
var xOffset = body.scrollLeft || 0; |
|||
|
|||
return { |
|||
y: e.clientY + addTop + yOffset, |
|||
x: e.clientX + addLeft + xOffset, |
|||
}; |
|||
}, |
|||
|
|||
/** |
|||
* Returns wrapper element |
|||
* @return {HTMLElement} |
|||
* ???? |
|||
*/ |
|||
getFrameWrapperEl: function(){ |
|||
return CanvasView.frame.getWrapper(); |
|||
}, |
|||
}; |
|||
|
|||
}); |
|||
}; |
|||
|
|||
@ -1,20 +1,17 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var Frame = require('./Frame'); |
|||
var Backbone = require('backbone'); |
|||
var Frame = require('./Frame'); |
|||
|
|||
module.exports = Backbone.Model.extend({ |
|||
module.exports = Backbone.Model.extend({ |
|||
|
|||
defaults :{ |
|||
frame: '', |
|||
wrapper: '', |
|||
rulers: false, |
|||
}, |
|||
defaults :{ |
|||
frame: '', |
|||
wrapper: '', |
|||
rulers: false, |
|||
}, |
|||
|
|||
initialize: function(config) { |
|||
var conf = this.conf || {}; |
|||
this.set('frame', new Frame(conf.frame)); |
|||
}, |
|||
initialize: function(config) { |
|||
var conf = this.conf || {}; |
|||
this.set('frame', new Frame(conf.frame)); |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,15 +1,12 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var Backbone = require('backbone'); |
|||
|
|||
module.exports = Backbone.Model.extend({ |
|||
module.exports = Backbone.Model.extend({ |
|||
|
|||
defaults :{ |
|||
wrapper: '', |
|||
width: '', |
|||
height: '', |
|||
attributes: {}, |
|||
}, |
|||
defaults :{ |
|||
wrapper: '', |
|||
width: '', |
|||
height: '', |
|||
attributes: {}, |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,271 +1,266 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var FrameView = require('./FrameView'); |
|||
/** |
|||
* @class CanvasView |
|||
* */ |
|||
module.exports = Backbone.View.extend({ |
|||
var Backbone = require('backbone'); |
|||
var FrameView = require('./FrameView'); |
|||
|
|||
initialize: function(o) { |
|||
_.bindAll(this, 'renderBody', 'onFrameScroll', 'clearOff'); |
|||
this.config = o.config || {}; |
|||
this.em = this.config.em || {}; |
|||
this.ppfx = this.config.pStylePrefix || ''; |
|||
this.className = this.config.stylePrefix + 'canvas'; |
|||
this.listenTo(this.em, 'change:canvasOffset', this.clearOff); |
|||
this.frame = new FrameView({ |
|||
model: this.model.get('frame'), |
|||
config: this.config |
|||
}); |
|||
}, |
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
/** |
|||
* Update tools position |
|||
* @private |
|||
*/ |
|||
onFrameScroll: function(){ |
|||
var u = 'px'; |
|||
var body = this.frame.el.contentDocument.body; |
|||
this.toolsEl.style.top = '-' + body.scrollTop + u; |
|||
this.toolsEl.style.left = '-' + body.scrollLeft + u; |
|||
this.em.trigger('canvasScroll'); |
|||
}, |
|||
initialize: function(o) { |
|||
_.bindAll(this, 'renderBody', 'onFrameScroll', 'clearOff'); |
|||
this.config = o.config || {}; |
|||
this.em = this.config.em || {}; |
|||
this.ppfx = this.config.pStylePrefix || ''; |
|||
this.className = this.config.stylePrefix + 'canvas'; |
|||
this.listenTo(this.em, 'change:canvasOffset', this.clearOff); |
|||
this.frame = new FrameView({ |
|||
model: this.model.get('frame'), |
|||
config: this.config |
|||
}); |
|||
}, |
|||
|
|||
/** |
|||
* Insert scripts into head, it will call renderBody after all scripts loaded or failed |
|||
* @private |
|||
*/ |
|||
renderScripts: function () { |
|||
var frame = this.frame; |
|||
var that = this; |
|||
/** |
|||
* Update tools position |
|||
* @private |
|||
*/ |
|||
onFrameScroll: function(){ |
|||
var u = 'px'; |
|||
var body = this.frame.el.contentDocument.body; |
|||
this.toolsEl.style.top = '-' + body.scrollTop + u; |
|||
this.toolsEl.style.left = '-' + body.scrollLeft + u; |
|||
this.em.trigger('canvasScroll'); |
|||
}, |
|||
|
|||
frame.el.onload = function () { |
|||
var scripts = that.config.scripts.slice(0), // clone
|
|||
counter = 0; |
|||
/** |
|||
* Insert scripts into head, it will call renderBody after all scripts loaded or failed |
|||
* @private |
|||
*/ |
|||
renderScripts: function () { |
|||
var frame = this.frame; |
|||
var that = this; |
|||
|
|||
function appendScript(scripts) { |
|||
if (scripts.length > 0) { |
|||
var script = document.createElement('script'); |
|||
script.type = 'text/javascript'; |
|||
script.src = scripts.shift(); |
|||
script.onerror = script.onload = appendScript.bind(null, scripts); |
|||
frame.el.contentDocument.head.appendChild(script); |
|||
} else { |
|||
that.renderBody(); |
|||
} |
|||
frame.el.onload = function () { |
|||
var scripts = that.config.scripts.slice(0), // clone
|
|||
counter = 0; |
|||
|
|||
function appendScript(scripts) { |
|||
if (scripts.length > 0) { |
|||
var script = document.createElement('script'); |
|||
script.type = 'text/javascript'; |
|||
script.src = scripts.shift(); |
|||
script.onerror = script.onload = appendScript.bind(null, scripts); |
|||
frame.el.contentDocument.head.appendChild(script); |
|||
} else { |
|||
that.renderBody(); |
|||
} |
|||
appendScript(scripts); |
|||
}; |
|||
}, |
|||
} |
|||
appendScript(scripts); |
|||
}; |
|||
}, |
|||
|
|||
/** |
|||
* Render inside frame's body |
|||
* @private |
|||
*/ |
|||
renderBody: function() { |
|||
var wrap = this.model.get('frame').get('wrapper'); |
|||
var em = this.config.em; |
|||
if(wrap) { |
|||
var ppfx = this.ppfx; |
|||
var body = this.frame.$el.contents().find('body'); |
|||
var cssc = em.get('CssComposer'); |
|||
var conf = em.get('Config'); |
|||
body.append(wrap.render()).append(cssc.render()); |
|||
var protCss = conf.protectedCss; |
|||
/** |
|||
* Render inside frame's body |
|||
* @private |
|||
*/ |
|||
renderBody: function() { |
|||
var wrap = this.model.get('frame').get('wrapper'); |
|||
var em = this.config.em; |
|||
if(wrap) { |
|||
var ppfx = this.ppfx; |
|||
var body = this.frame.$el.contents().find('body'); |
|||
var cssc = em.get('CssComposer'); |
|||
var conf = em.get('Config'); |
|||
body.append(wrap.render()).append(cssc.render()); |
|||
var protCss = conf.protectedCss; |
|||
|
|||
// I need all this styles to make the editor work properly
|
|||
var frameCss = '* {box-sizing: border-box;} body{margin:0;height:auto;background-color:#fff} #wrapper{min-height:100%; overflow:auto}' + |
|||
'.' + ppfx + 'dashed :not([contenteditable]) > *[data-highlightable]{outline: 1px dashed rgba(170,170,170,0.7); outline-offset: -2px}' + |
|||
'.' + ppfx + 'comp-selected{outline: 3px solid #3b97e3 !important}' + |
|||
'.' + ppfx + 'no-select{user-select: none; -webkit-user-select:none; -moz-user-select: none}'+ |
|||
'.' + ppfx + 'freezed{opacity: 0.5; 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 + 'grabbing{cursor: grabbing; cursor: -webkit-grabbing}' + |
|||
'* ::-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 || ''); |
|||
frameCss += protCss || ''; |
|||
body.append('<style>' + frameCss + '</style>'); |
|||
body.append(this.getJsContainer()); |
|||
em.trigger('loaded'); |
|||
this.frame.el.contentWindow.onscroll = this.onFrameScroll; |
|||
this.frame.udpateOffset(); |
|||
// I need all this styles to make the editor work properly
|
|||
var frameCss = '* {box-sizing: border-box;} body{margin:0;height:auto;background-color:#fff} #wrapper{min-height:100%; overflow:auto}' + |
|||
'.' + ppfx + 'dashed :not([contenteditable]) > *[data-highlightable]{outline: 1px dashed rgba(170,170,170,0.7); outline-offset: -2px}' + |
|||
'.' + ppfx + 'comp-selected{outline: 3px solid #3b97e3 !important}' + |
|||
'.' + ppfx + 'no-select{user-select: none; -webkit-user-select:none; -moz-user-select: none}'+ |
|||
'.' + ppfx + 'freezed{opacity: 0.5; 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 + 'grabbing{cursor: grabbing; cursor: -webkit-grabbing}' + |
|||
'* ::-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 || ''); |
|||
frameCss += protCss || ''; |
|||
body.append('<style>' + frameCss + '</style>'); |
|||
body.append(this.getJsContainer()); |
|||
em.trigger('loaded'); |
|||
this.frame.el.contentWindow.onscroll = this.onFrameScroll; |
|||
this.frame.udpateOffset(); |
|||
|
|||
// When the iframe is focused the event dispatcher is not the same so
|
|||
// I need to delegate all events to the parent document
|
|||
var doc = document; |
|||
var fdoc = this.frame.el.contentDocument; |
|||
fdoc.addEventListener('keydown', function(e){ |
|||
doc.dispatchEvent(new KeyboardEvent(e.type, e)); |
|||
}); |
|||
fdoc.addEventListener('keyup', function(e){ |
|||
doc.dispatchEvent(new KeyboardEvent(e.type, e)); |
|||
}); |
|||
} |
|||
}, |
|||
// When the iframe is focused the event dispatcher is not the same so
|
|||
// I need to delegate all events to the parent document
|
|||
var doc = document; |
|||
var fdoc = this.frame.el.contentDocument; |
|||
fdoc.addEventListener('keydown', function(e){ |
|||
doc.dispatchEvent(new KeyboardEvent(e.type, e)); |
|||
}); |
|||
fdoc.addEventListener('keyup', function(e){ |
|||
doc.dispatchEvent(new KeyboardEvent(e.type, e)); |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Get the offset of the element |
|||
* @param {HTMLElement} el |
|||
* @return {Object} |
|||
*/ |
|||
offset: function(el){ |
|||
var rect = el.getBoundingClientRect(); |
|||
var docBody = el.ownerDocument.body; |
|||
return { |
|||
top: rect.top + docBody.scrollTop, |
|||
left: rect.left + docBody.scrollLeft |
|||
}; |
|||
}, |
|||
/** |
|||
* Get the offset of the element |
|||
* @param {HTMLElement} el |
|||
* @return {Object} |
|||
*/ |
|||
offset: function(el){ |
|||
var rect = el.getBoundingClientRect(); |
|||
var docBody = el.ownerDocument.body; |
|||
return { |
|||
top: rect.top + docBody.scrollTop, |
|||
left: rect.left + docBody.scrollLeft |
|||
}; |
|||
}, |
|||
|
|||
/** |
|||
* Cleare cached offsets |
|||
* @private |
|||
*/ |
|||
clearOff: function(){ |
|||
this.frmOff = null; |
|||
this.cvsOff = null; |
|||
}, |
|||
/** |
|||
* Cleare cached offsets |
|||
* @private |
|||
*/ |
|||
clearOff: function(){ |
|||
this.frmOff = null; |
|||
this.cvsOff = null; |
|||
}, |
|||
|
|||
/** |
|||
* Return frame offset |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getFrameOffset: function () { |
|||
if(!this.frmOff) |
|||
this.frmOff = this.offset(this.frame.el); |
|||
return this.frmOff; |
|||
}, |
|||
/** |
|||
* Return frame offset |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getFrameOffset: function () { |
|||
if(!this.frmOff) |
|||
this.frmOff = this.offset(this.frame.el); |
|||
return this.frmOff; |
|||
}, |
|||
|
|||
/** |
|||
* Return canvas offset |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getCanvasOffset: function () { |
|||
if(!this.cvsOff) |
|||
this.cvsOff = this.offset(this.el); |
|||
return this.cvsOff; |
|||
}, |
|||
/** |
|||
* Return canvas offset |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getCanvasOffset: function () { |
|||
if(!this.cvsOff) |
|||
this.cvsOff = this.offset(this.el); |
|||
return this.cvsOff; |
|||
}, |
|||
|
|||
/** |
|||
* Returns element's data info |
|||
* @param {HTMLElement} el |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getElementPos: function(el) { |
|||
var frmOff = this.getFrameOffset(); |
|||
var cvsOff = this.getCanvasOffset(); |
|||
var eo = this.offset(el); |
|||
var top = eo.top + frmOff.top - cvsOff.top; |
|||
var left = eo.left + frmOff.left - cvsOff.left; |
|||
return { |
|||
top: top, |
|||
left: left, |
|||
height: el.offsetHeight, |
|||
width: el.offsetWidth |
|||
}; |
|||
}, |
|||
/** |
|||
* Returns element's data info |
|||
* @param {HTMLElement} el |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getElementPos: function(el) { |
|||
var frmOff = this.getFrameOffset(); |
|||
var cvsOff = this.getCanvasOffset(); |
|||
var eo = this.offset(el); |
|||
var top = eo.top + frmOff.top - cvsOff.top; |
|||
var left = eo.left + frmOff.left - cvsOff.left; |
|||
return { |
|||
top: top, |
|||
left: left, |
|||
height: el.offsetHeight, |
|||
width: el.offsetWidth |
|||
}; |
|||
}, |
|||
|
|||
/** |
|||
* Returns position data of the canvas element |
|||
* @return {Object} obj Position object |
|||
* @private |
|||
*/ |
|||
getPosition: function() { |
|||
var bEl = this.frame.el.contentDocument.body; |
|||
var fo = this.getFrameOffset(); |
|||
var co = this.getCanvasOffset(); |
|||
return { |
|||
top: fo.top + bEl.scrollTop - co.top, |
|||
left: fo.left + bEl.scrollLeft - co.left |
|||
}; |
|||
}, |
|||
/** |
|||
* Returns position data of the canvas element |
|||
* @return {Object} obj Position object |
|||
* @private |
|||
*/ |
|||
getPosition: function() { |
|||
var bEl = this.frame.el.contentDocument.body; |
|||
var fo = this.getFrameOffset(); |
|||
var co = this.getCanvasOffset(); |
|||
return { |
|||
top: fo.top + bEl.scrollTop - co.top, |
|||
left: fo.left + bEl.scrollLeft - co.left |
|||
}; |
|||
}, |
|||
|
|||
/** |
|||
* Update javascript of a specific component passed by its View |
|||
* @param {View} view Component's View |
|||
* @private |
|||
*/ |
|||
updateScript: function(view) { |
|||
if(!view.scriptContainer) { |
|||
view.scriptContainer = $('<div>'); |
|||
this.getJsContainer().append(view.scriptContainer.get(0)); |
|||
} |
|||
/** |
|||
* Update javascript of a specific component passed by its View |
|||
* @param {View} view Component's View |
|||
* @private |
|||
*/ |
|||
updateScript: function(view) { |
|||
if(!view.scriptContainer) { |
|||
view.scriptContainer = $('<div>'); |
|||
this.getJsContainer().append(view.scriptContainer.get(0)); |
|||
} |
|||
|
|||
var id = view.model.cid; |
|||
var script = view.model.get('script'); |
|||
var scrStr = 'function(){' + script + '}'; |
|||
scrStr = typeof script == 'function' ? script.toString() : scrStr; |
|||
var id = view.model.cid; |
|||
var script = view.model.get('script'); |
|||
var scrStr = 'function(){' + script + '}'; |
|||
scrStr = typeof script == 'function' ? script.toString() : scrStr; |
|||
|
|||
view.el.id = id; |
|||
view.scriptContainer.html(''); |
|||
view.el.id = id; |
|||
view.scriptContainer.html(''); |
|||
|
|||
view.scriptContainer.append('<script>' + |
|||
'var item = document.getElementById("'+id+'");' + |
|||
'(' + scrStr + '.bind(item))()</script>'); |
|||
}, |
|||
view.scriptContainer.append('<script>' + |
|||
'var item = document.getElementById("'+id+'");' + |
|||
'(' + scrStr + '.bind(item))()</script>'); |
|||
}, |
|||
|
|||
/** |
|||
* Get javascript container |
|||
* @private |
|||
*/ |
|||
getJsContainer: function () { |
|||
if (!this.jsContainer) { |
|||
this.jsContainer = $('<div>', {class: this.ppfx + 'js-cont'}).get(0); |
|||
} |
|||
return this.jsContainer; |
|||
}, |
|||
/** |
|||
* Get javascript container |
|||
* @private |
|||
*/ |
|||
getJsContainer: function () { |
|||
if (!this.jsContainer) { |
|||
this.jsContainer = $('<div>', {class: this.ppfx + 'js-cont'}).get(0); |
|||
} |
|||
return this.jsContainer; |
|||
}, |
|||
|
|||
|
|||
render: function() { |
|||
this.wrapper = this.model.get('wrapper'); |
|||
render: function() { |
|||
this.wrapper = this.model.get('wrapper'); |
|||
|
|||
if(this.wrapper && typeof this.wrapper.render == 'function'){ |
|||
this.model.get('frame').set('wrapper', this.wrapper); |
|||
this.$el.append(this.frame.render().el); |
|||
var frame = this.frame; |
|||
if (this.config.scripts.length === 0) { |
|||
frame.el.onload = this.renderBody; |
|||
} else { |
|||
this.renderScripts(); // will call renderBody later
|
|||
} |
|||
if(this.wrapper && typeof this.wrapper.render == 'function'){ |
|||
this.model.get('frame').set('wrapper', this.wrapper); |
|||
this.$el.append(this.frame.render().el); |
|||
var frame = this.frame; |
|||
if (this.config.scripts.length === 0) { |
|||
frame.el.onload = this.renderBody; |
|||
} else { |
|||
this.renderScripts(); // will call renderBody later
|
|||
} |
|||
var ppfx = this.ppfx; |
|||
var toolsEl = $('<div>', { id: ppfx + 'tools' }).get(0); |
|||
this.hlEl = $('<div>', { class: ppfx + 'highlighter' }).get(0); |
|||
this.badgeEl = $('<div>', {class: ppfx + 'badge'}).get(0); |
|||
this.placerEl = $('<div>', {class: ppfx + 'placeholder'}).get(0); |
|||
this.placerIntEl = $('<div>', {class: ppfx + 'placeholder-int'}).get(0); |
|||
this.ghostEl = $('<div>', {class: ppfx + 'ghost'}).get(0); |
|||
this.toolbarEl = $('<div>', {class: ppfx + 'toolbar'}).get(0); |
|||
this.resizerEl = $('<div>', {class: ppfx + 'resizer'}).get(0); |
|||
this.offsetEl = $('<div>', {class: ppfx + 'offset-v'}).get(0); |
|||
this.fixedOffsetEl = $('<div>', {class: ppfx + 'offset-fixed-v'}).get(0); |
|||
this.placerEl.appendChild(this.placerIntEl); |
|||
toolsEl.appendChild(this.hlEl); |
|||
toolsEl.appendChild(this.badgeEl); |
|||
toolsEl.appendChild(this.placerEl); |
|||
toolsEl.appendChild(this.ghostEl); |
|||
toolsEl.appendChild(this.toolbarEl); |
|||
toolsEl.appendChild(this.resizerEl); |
|||
toolsEl.appendChild(this.offsetEl); |
|||
toolsEl.appendChild(this.fixedOffsetEl); |
|||
this.$el.append(toolsEl); |
|||
var rte = this.em.get('rte'); |
|||
} |
|||
var ppfx = this.ppfx; |
|||
var toolsEl = $('<div>', { id: ppfx + 'tools' }).get(0); |
|||
this.hlEl = $('<div>', { class: ppfx + 'highlighter' }).get(0); |
|||
this.badgeEl = $('<div>', {class: ppfx + 'badge'}).get(0); |
|||
this.placerEl = $('<div>', {class: ppfx + 'placeholder'}).get(0); |
|||
this.placerIntEl = $('<div>', {class: ppfx + 'placeholder-int'}).get(0); |
|||
this.ghostEl = $('<div>', {class: ppfx + 'ghost'}).get(0); |
|||
this.toolbarEl = $('<div>', {class: ppfx + 'toolbar'}).get(0); |
|||
this.resizerEl = $('<div>', {class: ppfx + 'resizer'}).get(0); |
|||
this.offsetEl = $('<div>', {class: ppfx + 'offset-v'}).get(0); |
|||
this.fixedOffsetEl = $('<div>', {class: ppfx + 'offset-fixed-v'}).get(0); |
|||
this.placerEl.appendChild(this.placerIntEl); |
|||
toolsEl.appendChild(this.hlEl); |
|||
toolsEl.appendChild(this.badgeEl); |
|||
toolsEl.appendChild(this.placerEl); |
|||
toolsEl.appendChild(this.ghostEl); |
|||
toolsEl.appendChild(this.toolbarEl); |
|||
toolsEl.appendChild(this.resizerEl); |
|||
toolsEl.appendChild(this.offsetEl); |
|||
toolsEl.appendChild(this.fixedOffsetEl); |
|||
this.$el.append(toolsEl); |
|||
var rte = this.em.get('rte'); |
|||
|
|||
if(rte) |
|||
toolsEl.appendChild(rte.render()); |
|||
if(rte) |
|||
toolsEl.appendChild(rte.render()); |
|||
|
|||
this.toolsEl = toolsEl; |
|||
this.$el.attr({class: this.className}); |
|||
return this; |
|||
}, |
|||
this.toolsEl = toolsEl; |
|||
this.$el.attr({class: this.className}); |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
|
|||
@ -1,56 +1,51 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var Backbone = require('backbone'); |
|||
|
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
tagName: 'iframe', |
|||
|
|||
attributes: { |
|||
src: 'about:blank', |
|||
allowfullscreen: 'allowfullscreen' |
|||
}, |
|||
|
|||
initialize: function(o) { |
|||
_.bindAll(this, 'udpateOffset'); |
|||
this.config = o.config || {}; |
|||
this.ppfx = this.config.pStylePrefix || ''; |
|||
this.em = this.config.em; |
|||
this.motionsEv = 'transitionend oTransitionEnd transitionend webkitTransitionEnd'; |
|||
this.listenTo(this.em, 'change:device', this.updateWidth); |
|||
}, |
|||
|
|||
/** |
|||
* @class CanvasView |
|||
* */ |
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
tagName: 'iframe', |
|||
|
|||
attributes: { |
|||
src: 'about:blank', |
|||
allowfullscreen: 'allowfullscreen' |
|||
}, |
|||
|
|||
initialize: function(o) { |
|||
_.bindAll(this, 'udpateOffset'); |
|||
this.config = o.config || {}; |
|||
this.ppfx = this.config.pStylePrefix || ''; |
|||
this.em = this.config.em; |
|||
this.motionsEv = 'transitionend oTransitionEnd transitionend webkitTransitionEnd'; |
|||
this.listenTo(this.em, 'change:device', this.updateWidth); |
|||
}, |
|||
|
|||
/** |
|||
* Update width of the frame |
|||
* @private |
|||
*/ |
|||
updateWidth: function(model){ |
|||
var device = this.em.getDeviceModel(); |
|||
this.el.style.width = device ? device.get('width') : ''; |
|||
this.udpateOffset(); |
|||
this.$el.on(this.motionsEv, this.udpateOffset); |
|||
}, |
|||
|
|||
udpateOffset: function(){ |
|||
var offset = this.em.get('Canvas').getOffset(); |
|||
this.em.set('canvasOffset', offset); |
|||
this.$el.off(this.motionsEv, this.udpateOffset); |
|||
}, |
|||
|
|||
getBody: function(){ |
|||
this.$el.contents().find('body'); |
|||
}, |
|||
|
|||
getWrapper: function(){ |
|||
return this.$el.contents().find('body > div'); |
|||
}, |
|||
|
|||
render: function() { |
|||
this.$el.attr({class: this.ppfx + 'frame'}); |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
* Update width of the frame |
|||
* @private |
|||
*/ |
|||
updateWidth: function(model){ |
|||
var device = this.em.getDeviceModel(); |
|||
this.el.style.width = device ? device.get('width') : ''; |
|||
this.udpateOffset(); |
|||
this.$el.on(this.motionsEv, this.udpateOffset); |
|||
}, |
|||
|
|||
udpateOffset: function(){ |
|||
var offset = this.em.get('Canvas').getOffset(); |
|||
this.em.set('canvasOffset', offset); |
|||
this.$el.off(this.motionsEv, this.udpateOffset); |
|||
}, |
|||
|
|||
getBody: function(){ |
|||
this.$el.contents().find('body'); |
|||
}, |
|||
|
|||
getWrapper: function(){ |
|||
return this.$el.contents().find('body > div'); |
|||
}, |
|||
|
|||
render: function() { |
|||
this.$el.attr({class: this.ppfx + 'frame'}); |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
|
|||
@ -1,8 +1,6 @@ |
|||
define(function () { |
|||
return { |
|||
// Style prefix
|
|||
stylePrefix: 'cm-', |
|||
module.exports = { |
|||
// Style prefix
|
|||
stylePrefix: 'cm-', |
|||
|
|||
inlineCss: false, |
|||
}; |
|||
}); |
|||
inlineCss: false, |
|||
}; |
|||
|
|||
@ -1,51 +1,46 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var CodeMirror = require('codemirror/lib/codemirror'); |
|||
var htmlMode = require('codemirror/mode/htmlmixed/htmlmixed'); |
|||
var cssMode = require('codemirror/mode/css/css'); |
|||
var formatting = require('formatting'); |
|||
/** |
|||
* @class CodeViewer |
|||
* */ |
|||
module.exports = Backbone.Model.extend({ |
|||
var Backbone = require('backbone'); |
|||
var CodeMirror = require('codemirror/lib/codemirror'); |
|||
var htmlMode = require('codemirror/mode/htmlmixed/htmlmixed'); |
|||
var cssMode = require('codemirror/mode/css/css'); |
|||
var formatting = require('formatting'); |
|||
|
|||
defaults: { |
|||
input : '', |
|||
label : '', |
|||
codeName : '', |
|||
theme : '', |
|||
readOnly : true, |
|||
lineNumbers : true, |
|||
}, |
|||
module.exports = Backbone.Model.extend({ |
|||
|
|||
/** @inheritdoc */ |
|||
init: function(el) |
|||
{ |
|||
this.editor = CodeMirror.fromTextArea(el, { |
|||
dragDrop: false, |
|||
lineWrapping: true, |
|||
lineNumbers: this.get('lineNumbers'), |
|||
readOnly: this.get('readOnly'), |
|||
mode: this.get('codeName'), |
|||
theme: this.get('theme'), |
|||
}); |
|||
defaults: { |
|||
input : '', |
|||
label : '', |
|||
codeName : '', |
|||
theme : '', |
|||
readOnly : true, |
|||
lineNumbers : true, |
|||
}, |
|||
|
|||
return this; |
|||
}, |
|||
/** @inheritdoc */ |
|||
init: function(el) |
|||
{ |
|||
this.editor = CodeMirror.fromTextArea(el, { |
|||
dragDrop: false, |
|||
lineWrapping: true, |
|||
lineNumbers: this.get('lineNumbers'), |
|||
readOnly: this.get('readOnly'), |
|||
mode: this.get('codeName'), |
|||
theme: this.get('theme'), |
|||
}); |
|||
|
|||
/** @inheritdoc */ |
|||
setContent : function(v) |
|||
{ |
|||
if(!this.editor) |
|||
return; |
|||
this.editor.setValue(v); |
|||
if(this.editor.autoFormatRange){ |
|||
CodeMirror.commands.selectAll(this.editor); |
|||
this.editor.autoFormatRange(this.editor.getCursor(true), this.editor.getCursor(false) ); |
|||
CodeMirror.commands.goDocStart(this.editor); |
|||
} |
|||
}, |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
/** @inheritdoc */ |
|||
setContent : function(v) |
|||
{ |
|||
if(!this.editor) |
|||
return; |
|||
this.editor.setValue(v); |
|||
if(this.editor.autoFormatRange){ |
|||
CodeMirror.commands.selectAll(this.editor); |
|||
this.editor.autoFormatRange(this.editor.getCursor(true), this.editor.getCursor(false) ); |
|||
CodeMirror.commands.goDocStart(this.editor); |
|||
} |
|||
}, |
|||
|
|||
}); |
|||
|
|||
@ -1,152 +1,147 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
/** |
|||
* @class CssGenerator |
|||
* */ |
|||
module.exports = Backbone.Model.extend({ |
|||
|
|||
initialize: function() { |
|||
this.compCls = []; |
|||
}, |
|||
|
|||
/** |
|||
* Get CSS from component |
|||
* @param {Model} model |
|||
* @return {String} |
|||
*/ |
|||
buildFromModel: function (model) { |
|||
var code = ''; |
|||
var style = model.get('style'); |
|||
var classes = model.get('classes'); |
|||
|
|||
// Let's know what classes I've found
|
|||
if(classes) { |
|||
classes.each(function(model){ |
|||
this.compCls.push(model.get('name')); |
|||
}, this); |
|||
var Backbone = require('backbone'); |
|||
|
|||
module.exports = Backbone.Model.extend({ |
|||
|
|||
initialize: function() { |
|||
this.compCls = []; |
|||
}, |
|||
|
|||
/** |
|||
* Get CSS from component |
|||
* @param {Model} model |
|||
* @return {String} |
|||
*/ |
|||
buildFromModel: function (model) { |
|||
var code = ''; |
|||
var style = model.get('style'); |
|||
var classes = model.get('classes'); |
|||
|
|||
// Let's know what classes I've found
|
|||
if(classes) { |
|||
classes.each(function(model){ |
|||
this.compCls.push(model.get('name')); |
|||
}, this); |
|||
} |
|||
|
|||
if(style && Object.keys(style).length !== 0) { |
|||
code += '#' + model.cid + '{'; |
|||
for(var prop in style){ |
|||
if(style.hasOwnProperty(prop)) |
|||
code += prop + ':' + style[prop] + ';'; |
|||
} |
|||
code += '}'; |
|||
} |
|||
|
|||
return code; |
|||
}, |
|||
|
|||
/** |
|||
* Get CSS from components |
|||
* @param {Model} model |
|||
* @return {String} |
|||
*/ |
|||
buildFromComp: function(model) { |
|||
var coll = model.get('components') || model, |
|||
code = ''; |
|||
|
|||
coll.each(function(m) { |
|||
var cln = m.get('components'); |
|||
code += this.buildFromModel(m); |
|||
|
|||
if(cln.length){ |
|||
code += this.buildFromComp(cln); |
|||
} |
|||
|
|||
}, this); |
|||
|
|||
return code; |
|||
}, |
|||
|
|||
/** @inheritdoc */ |
|||
build: function(model, cssc) { |
|||
this.compCls = []; |
|||
var code = this.buildFromModel(model); |
|||
code += this.buildFromComp(model); |
|||
var compCls = this.compCls; |
|||
|
|||
if(cssc){ |
|||
var rules = cssc.getAll(); |
|||
var mediaRules = {}; |
|||
rules.each(function(rule) { |
|||
var width = rule.get('mediaText'); |
|||
|
|||
// If width setted will render it later
|
|||
if(width){ |
|||
var mRule = mediaRules[width]; |
|||
if(mRule) |
|||
mRule.push(rule); |
|||
else |
|||
mediaRules[width] = [rule]; |
|||
return; |
|||
} |
|||
|
|||
if(style && Object.keys(style).length !== 0) { |
|||
code += '#' + model.cid + '{'; |
|||
for(var prop in style){ |
|||
if(style.hasOwnProperty(prop)) |
|||
code += prop + ':' + style[prop] + ';'; |
|||
} |
|||
code += '}'; |
|||
} |
|||
code += this.buildFromRule(rule); |
|||
}, this); |
|||
|
|||
return code; |
|||
}, |
|||
|
|||
/** |
|||
* Get CSS from components |
|||
* @param {Model} model |
|||
* @return {String} |
|||
*/ |
|||
buildFromComp: function(model) { |
|||
var coll = model.get('components') || model, |
|||
code = ''; |
|||
|
|||
coll.each(function(m) { |
|||
var cln = m.get('components'); |
|||
code += this.buildFromModel(m); |
|||
|
|||
if(cln.length){ |
|||
code += this.buildFromComp(cln); |
|||
} |
|||
|
|||
}, this); |
|||
|
|||
return code; |
|||
}, |
|||
|
|||
/** @inheritdoc */ |
|||
build: function(model, cssc) { |
|||
this.compCls = []; |
|||
var code = this.buildFromModel(model); |
|||
code += this.buildFromComp(model); |
|||
var compCls = this.compCls; |
|||
|
|||
if(cssc){ |
|||
var rules = cssc.getAll(); |
|||
var mediaRules = {}; |
|||
rules.each(function(rule) { |
|||
var width = rule.get('mediaText'); |
|||
|
|||
// If width setted will render it later
|
|||
if(width){ |
|||
var mRule = mediaRules[width]; |
|||
if(mRule) |
|||
mRule.push(rule); |
|||
else |
|||
mediaRules[width] = [rule]; |
|||
return; |
|||
} |
|||
|
|||
code += this.buildFromRule(rule); |
|||
}, this); |
|||
|
|||
// Get media rules
|
|||
for (var ruleW in mediaRules) { |
|||
var meRules = mediaRules[ruleW]; |
|||
var ruleC = ''; |
|||
for(var i = 0, len = meRules.length; i < len; i++){ |
|||
ruleC += this.buildFromRule(meRules[i]); |
|||
} |
|||
|
|||
if (ruleC) { |
|||
code += '@media ' + ruleW + '{' + ruleC + '}'; |
|||
} |
|||
} |
|||
// Get media rules
|
|||
for (var ruleW in mediaRules) { |
|||
var meRules = mediaRules[ruleW]; |
|||
var ruleC = ''; |
|||
for(var i = 0, len = meRules.length; i < len; i++){ |
|||
ruleC += this.buildFromRule(meRules[i]); |
|||
} |
|||
|
|||
if (ruleC) { |
|||
code += '@media ' + ruleW + '{' + ruleC + '}'; |
|||
} |
|||
return code; |
|||
}, |
|||
|
|||
/** |
|||
* Get CSS from the rule model |
|||
* @param {Model} rule |
|||
* @return {string} CSS string |
|||
*/ |
|||
buildFromRule: function(rule) { |
|||
var result = ''; |
|||
var selectorsAdd = rule.get('selectorsAdd'); |
|||
var selectors = rule.get('selectors'); |
|||
var ruleStyle = rule.get('style'); |
|||
var state = rule.get('state'); |
|||
var strSel = ''; |
|||
var found = 0; |
|||
var compCls = this.compCls; |
|||
|
|||
// Get string of selectors
|
|||
selectors.each(function(selector){ |
|||
strSel += '.' + selector.get('name'); |
|||
if(compCls.indexOf(selector.get('name')) > -1) |
|||
found = 1; |
|||
}); |
|||
|
|||
// With 'found' will skip rules which selectors are not found in
|
|||
// canvas components.
|
|||
if ((strSel && found) || selectorsAdd) { |
|||
strSel += state ? ':' + state : ''; |
|||
strSel += selectorsAdd ? (strSel ? ', ' : '') + selectorsAdd : ''; |
|||
var strStyle = ''; |
|||
|
|||
// Get string of style properties
|
|||
if(ruleStyle && Object.keys(ruleStyle).length !== 0){ |
|||
for(var prop2 in ruleStyle){ |
|||
if(ruleStyle.hasOwnProperty(prop2)) |
|||
strStyle += prop2 + ':' + ruleStyle[prop2] + ';'; |
|||
} |
|||
} |
|||
|
|||
if(strStyle) |
|||
result += strSel + '{' + strStyle + '}'; |
|||
} |
|||
|
|||
} |
|||
return code; |
|||
}, |
|||
|
|||
/** |
|||
* Get CSS from the rule model |
|||
* @param {Model} rule |
|||
* @return {string} CSS string |
|||
*/ |
|||
buildFromRule: function(rule) { |
|||
var result = ''; |
|||
var selectorsAdd = rule.get('selectorsAdd'); |
|||
var selectors = rule.get('selectors'); |
|||
var ruleStyle = rule.get('style'); |
|||
var state = rule.get('state'); |
|||
var strSel = ''; |
|||
var found = 0; |
|||
var compCls = this.compCls; |
|||
|
|||
// Get string of selectors
|
|||
selectors.each(function(selector){ |
|||
strSel += '.' + selector.get('name'); |
|||
if(compCls.indexOf(selector.get('name')) > -1) |
|||
found = 1; |
|||
}); |
|||
|
|||
// With 'found' will skip rules which selectors are not found in
|
|||
// canvas components.
|
|||
if ((strSel && found) || selectorsAdd) { |
|||
strSel += state ? ':' + state : ''; |
|||
strSel += selectorsAdd ? (strSel ? ', ' : '') + selectorsAdd : ''; |
|||
var strStyle = ''; |
|||
|
|||
// Get string of style properties
|
|||
if(ruleStyle && Object.keys(ruleStyle).length !== 0){ |
|||
for(var prop2 in ruleStyle){ |
|||
if(ruleStyle.hasOwnProperty(prop2)) |
|||
strStyle += prop2 + ':' + ruleStyle[prop2] + ';'; |
|||
} |
|||
} |
|||
|
|||
return result; |
|||
}, |
|||
if(strStyle) |
|||
result += strSel + '{' + strStyle + '}'; |
|||
} |
|||
|
|||
}); |
|||
}); |
|||
return result; |
|||
}, |
|||
|
|||
}); |
|||
|
|||
@ -1,24 +1,19 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
/** |
|||
* @class HtmlGenerator |
|||
* */ |
|||
module.exports = Backbone.Model.extend({ |
|||
var Backbone = require('backbone'); |
|||
|
|||
/** @inheritdoc */ |
|||
build: function(model, cssc){ |
|||
var coll = model.get('components') || model, |
|||
code = ''; |
|||
module.exports = Backbone.Model.extend({ |
|||
|
|||
coll.each(function(m){ |
|||
code += m.toHTML({ |
|||
cssc: cssc |
|||
}); |
|||
}, this); |
|||
/** @inheritdoc */ |
|||
build: function(model, cssc){ |
|||
var coll = model.get('components') || model, |
|||
code = ''; |
|||
|
|||
return code; |
|||
}, |
|||
coll.each(function(m){ |
|||
code += m.toHTML({ |
|||
cssc: cssc |
|||
}); |
|||
}, this); |
|||
|
|||
}); |
|||
}); |
|||
return code; |
|||
}, |
|||
|
|||
}); |
|||
|
|||
@ -1,64 +1,61 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
|
|||
module.exports = Backbone.Model.extend({ |
|||
|
|||
mapModel: function (model) { |
|||
var code = ''; |
|||
var script = model.get('script'); |
|||
var type = model.get('type'); |
|||
var comps = model.get('components'); |
|||
var id = model.cid; |
|||
|
|||
if (script) { |
|||
// If the component has scripts we need to expose his ID
|
|||
var attr = model.get('attributes'); |
|||
attr = _.extend({}, attr, {id: id}); |
|||
model.set('attributes', attr); |
|||
|
|||
var scrStr = 'function(){' + script + '}'; |
|||
scrStr = typeof script == 'function' ? script.toString() : scrStr; |
|||
|
|||
// If the script was updated, I'll put its code in a separate container
|
|||
if (model.get('scriptUpdated')) { |
|||
this.mapJs[type+'-'+id] = {ids: [id], code: scrStr}; |
|||
} else { |
|||
var mapType = this.mapJs[type]; |
|||
|
|||
if(mapType) { |
|||
mapType.ids.push(id); |
|||
} else { |
|||
this.mapJs[type] = {ids: [id], code: scrStr}; |
|||
} |
|||
} |
|||
var Backbone = require('backbone'); |
|||
|
|||
module.exports = Backbone.Model.extend({ |
|||
|
|||
mapModel: function (model) { |
|||
var code = ''; |
|||
var script = model.get('script'); |
|||
var type = model.get('type'); |
|||
var comps = model.get('components'); |
|||
var id = model.cid; |
|||
|
|||
if (script) { |
|||
// If the component has scripts we need to expose his ID
|
|||
var attr = model.get('attributes'); |
|||
attr = _.extend({}, attr, {id: id}); |
|||
model.set('attributes', attr); |
|||
|
|||
var scrStr = 'function(){' + script + '}'; |
|||
scrStr = typeof script == 'function' ? script.toString() : scrStr; |
|||
|
|||
// If the script was updated, I'll put its code in a separate container
|
|||
if (model.get('scriptUpdated')) { |
|||
this.mapJs[type+'-'+id] = {ids: [id], code: scrStr}; |
|||
} else { |
|||
var mapType = this.mapJs[type]; |
|||
|
|||
if(mapType) { |
|||
mapType.ids.push(id); |
|||
} else { |
|||
this.mapJs[type] = {ids: [id], code: scrStr}; |
|||
} |
|||
} |
|||
} |
|||
|
|||
comps.each(function(model) { |
|||
code += this.mapModel(model); |
|||
}, this); |
|||
comps.each(function(model) { |
|||
code += this.mapModel(model); |
|||
}, this); |
|||
|
|||
return code; |
|||
}, |
|||
return code; |
|||
}, |
|||
|
|||
build: function(model) { |
|||
this.mapJs = {}; |
|||
this.mapModel(model); |
|||
build: function(model) { |
|||
this.mapJs = {}; |
|||
this.mapModel(model); |
|||
|
|||
var code = ''; |
|||
var code = ''; |
|||
|
|||
for(var type in this.mapJs) { |
|||
var mapType = this.mapJs[type]; |
|||
var ids = '#' + mapType.ids.join(', #'); |
|||
code += 'var items = document.querySelectorAll("'+ids+'");' + |
|||
'for (var i = 0, len = items.length; i < len; i++) {'+ |
|||
'(' + mapType.code + '.bind(items[i]))();' + |
|||
'}'; |
|||
} |
|||
for(var type in this.mapJs) { |
|||
var mapType = this.mapJs[type]; |
|||
var ids = '#' + mapType.ids.join(', #'); |
|||
code += 'var items = document.querySelectorAll("'+ids+'");' + |
|||
'for (var i = 0, len = items.length; i < len; i++) {'+ |
|||
'(' + mapType.code + '.bind(items[i]))();' + |
|||
'}'; |
|||
} |
|||
|
|||
|
|||
return code; |
|||
}, |
|||
return code; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,41 +1,36 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
/** |
|||
* @class JsonGenerator |
|||
* */ |
|||
module.exports = Backbone.Model.extend({ |
|||
var Backbone = require('backbone'); |
|||
|
|||
/** @inheritdoc */ |
|||
build: function(model) { |
|||
var json = model.toJSON(); |
|||
this.beforeEach(json); |
|||
module.exports = Backbone.Model.extend({ |
|||
|
|||
_.each(json,function(v, attr){ |
|||
var obj = json[attr]; |
|||
if(obj instanceof Backbone.Model){ |
|||
json[attr] = this.build(obj); |
|||
}else if(obj instanceof Backbone.Collection){ |
|||
var coll = obj; |
|||
json[attr] = []; |
|||
if(coll.length){ |
|||
coll.each(function (el, index) { |
|||
json[attr][index] = this.build(el); |
|||
}, this); |
|||
} |
|||
} |
|||
}, this); |
|||
/** @inheritdoc */ |
|||
build: function(model) { |
|||
var json = model.toJSON(); |
|||
this.beforeEach(json); |
|||
|
|||
return json; |
|||
}, |
|||
_.each(json,function(v, attr){ |
|||
var obj = json[attr]; |
|||
if(obj instanceof Backbone.Model){ |
|||
json[attr] = this.build(obj); |
|||
}else if(obj instanceof Backbone.Collection){ |
|||
var coll = obj; |
|||
json[attr] = []; |
|||
if(coll.length){ |
|||
coll.each(function (el, index) { |
|||
json[attr][index] = this.build(el); |
|||
}, this); |
|||
} |
|||
} |
|||
}, this); |
|||
|
|||
/** |
|||
* Execute on each object |
|||
* @param {Object} obj |
|||
*/ |
|||
beforeEach: function(obj) { |
|||
delete obj.status; |
|||
} |
|||
return json; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
/** |
|||
* Execute on each object |
|||
* @param {Object} obj |
|||
*/ |
|||
beforeEach: function(obj) { |
|||
delete obj.status; |
|||
} |
|||
|
|||
}); |
|||
|
|||
@ -1,27 +1,22 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var vTemplate = require('text!./../template/editor.html'); |
|||
/** |
|||
* @class EditorView |
|||
* */ |
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
template: _.template(vTemplate), |
|||
|
|||
initialize: function(o){ |
|||
this.config = o.config || {}; |
|||
this.pfx = this.config.stylePrefix; |
|||
}, |
|||
|
|||
render : function(){ |
|||
var obj = this.model.toJSON(); |
|||
obj.pfx = this.pfx; |
|||
this.$el.html( this.template(obj) ); |
|||
this.$el.attr('class', this.pfx + 'editor-c'); |
|||
this.$el.find('#'+this.pfx+'code').html(this.model.get('input')); |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
var Backbone = require('backbone'); |
|||
var vTemplate = require('text!./../template/editor.html'); |
|||
|
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
template: _.template(vTemplate), |
|||
|
|||
initialize: function(o){ |
|||
this.config = o.config || {}; |
|||
this.pfx = this.config.stylePrefix; |
|||
}, |
|||
|
|||
render: function(){ |
|||
var obj = this.model.toJSON(); |
|||
obj.pfx = this.pfx; |
|||
this.$el.html( this.template(obj) ); |
|||
this.$el.attr('class', this.pfx + 'editor-c'); |
|||
this.$el.find('#'+this.pfx+'code').html(this.model.get('input')); |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
|
|||
@ -1,25 +1,23 @@ |
|||
define(function () { |
|||
return { |
|||
module.exports = { |
|||
|
|||
ESCAPE_KEY : 27, |
|||
ESCAPE_KEY: 27, |
|||
|
|||
stylePrefix : 'com-', |
|||
stylePrefix: 'com-', |
|||
|
|||
defaults : [], |
|||
defaults: [], |
|||
|
|||
// Editor model
|
|||
em : null, |
|||
// Editor model
|
|||
em: null, |
|||
|
|||
// If true center new first-level components
|
|||
firstCentered : true, |
|||
// If true center new first-level components
|
|||
firstCentered: true, |
|||
|
|||
// If true the new component will created with 'height', else 'min-height'
|
|||
newFixedH : false, |
|||
// If true the new component will created with 'height', else 'min-height'
|
|||
newFixedH: false, |
|||
|
|||
// Minimum height (in px) of new component
|
|||
minComponentH : 50, |
|||
// Minimum height (in px) of new component
|
|||
minComponentH: 50, |
|||
|
|||
// Minimum width (in px) of component on creation
|
|||
minComponentW : 50, |
|||
}; |
|||
}); |
|||
// Minimum width (in px) of component on creation
|
|||
minComponentW: 50, |
|||
}; |
|||
|
|||
@ -1,14 +1,9 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
/** |
|||
* @class Command |
|||
* */ |
|||
module.exports = Backbone.Model.extend({ |
|||
|
|||
defaults :{ |
|||
id : '', |
|||
} |
|||
|
|||
}); |
|||
}); |
|||
var Backbone = require('backbone'); |
|||
|
|||
module.exports = Backbone.Model.extend({ |
|||
|
|||
defaults :{ |
|||
id: '', |
|||
} |
|||
|
|||
}); |
|||
|
|||
@ -1,13 +1,8 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var Command = require('./Command'); |
|||
/** |
|||
* @class Commands |
|||
* */ |
|||
module.exports = Backbone.Collection.extend({ |
|||
|
|||
model: Command, |
|||
|
|||
}); |
|||
}); |
|||
var Backbone = require('backbone'); |
|||
var Command = require('./Command'); |
|||
|
|||
module.exports = Backbone.Collection.extend({ |
|||
|
|||
model: Command, |
|||
|
|||
}); |
|||
|
|||
@ -1,117 +1,111 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
/** |
|||
* @class CommandAbstract |
|||
* @private |
|||
* */ |
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
/** |
|||
* Initialize method that can't be removed |
|||
* @param {Object} o Options |
|||
* @private |
|||
* */ |
|||
initialize: function(o) { |
|||
this.config = o || {}; |
|||
this.editorModel = this.em = this.config.em || {}; |
|||
this.pfx = this.config.stylePrefix; |
|||
this.ppfx = this.config.pStylePrefix; |
|||
this.hoverClass = this.pfx + 'hover'; |
|||
this.badgeClass = this.pfx + 'badge'; |
|||
this.plhClass = this.pfx + 'placeholder'; |
|||
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.$wrapper = $(this.getCanvasWrapper()); |
|||
this.frameEl = this.canvas.getFrameEl(); |
|||
this.canvasTool = this.getCanvasTools(); |
|||
this.bodyEl = this.getCanvasBody(); |
|||
} |
|||
|
|||
this.init(this.config); |
|||
}, |
|||
|
|||
/** |
|||
* On frame scroll callback |
|||
* @param {[type]} e [description] |
|||
* @return {[type]} [description] |
|||
*/ |
|||
onFrameScroll: function(e){}, |
|||
|
|||
/** |
|||
* Returns canval element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getCanvas: function(){ |
|||
return this.canvas.getElement(); |
|||
}, |
|||
|
|||
/** |
|||
* Get canvas body element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getCanvasBody: function(){ |
|||
return this.canvas.getBody(); |
|||
}, |
|||
|
|||
/** |
|||
* Get canvas wrapper element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getCanvasWrapper: function(){ |
|||
return this.canvas.getWrapperEl(); |
|||
}, |
|||
|
|||
/** |
|||
* Get canvas wrapper element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getCanvasTools: function(){ |
|||
return this.canvas.getToolsEl(); |
|||
}, |
|||
|
|||
/** |
|||
* Get the offset of the element |
|||
* @param {HTMLElement} el |
|||
* @return {Object} |
|||
*/ |
|||
offset: function(el){ |
|||
var rect = el.getBoundingClientRect(); |
|||
return { |
|||
top: rect.top + el.ownerDocument.body.scrollTop, |
|||
left: rect.left + el.ownerDocument.body.scrollLeft |
|||
}; |
|||
}, |
|||
|
|||
/** |
|||
* Callback triggered after initialize |
|||
* @param {Object} o Options |
|||
* @private |
|||
* */ |
|||
init: function(o){}, |
|||
|
|||
/** |
|||
* Method that run command |
|||
* @param {Object} em Editor model |
|||
* @param {Object} sender Button sender |
|||
* @private |
|||
* */ |
|||
run: function(em, sender) {}, |
|||
|
|||
/** |
|||
* Method that stop command |
|||
* @param {Object} em Editor model |
|||
* @param {Object} sender Button sender |
|||
* @private |
|||
* */ |
|||
stop: function(em, sender) {}, |
|||
|
|||
}); |
|||
}); |
|||
var Backbone = require('backbone'); |
|||
|
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
/** |
|||
* Initialize method that can't be removed |
|||
* @param {Object} o Options |
|||
* @private |
|||
* */ |
|||
initialize: function(o) { |
|||
this.config = o || {}; |
|||
this.editorModel = this.em = this.config.em || {}; |
|||
this.pfx = this.config.stylePrefix; |
|||
this.ppfx = this.config.pStylePrefix; |
|||
this.hoverClass = this.pfx + 'hover'; |
|||
this.badgeClass = this.pfx + 'badge'; |
|||
this.plhClass = this.pfx + 'placeholder'; |
|||
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.$wrapper = $(this.getCanvasWrapper()); |
|||
this.frameEl = this.canvas.getFrameEl(); |
|||
this.canvasTool = this.getCanvasTools(); |
|||
this.bodyEl = this.getCanvasBody(); |
|||
} |
|||
|
|||
this.init(this.config); |
|||
}, |
|||
|
|||
/** |
|||
* On frame scroll callback |
|||
* @param {[type]} e [description] |
|||
* @return {[type]} [description] |
|||
*/ |
|||
onFrameScroll: function(e){}, |
|||
|
|||
/** |
|||
* Returns canval element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getCanvas: function(){ |
|||
return this.canvas.getElement(); |
|||
}, |
|||
|
|||
/** |
|||
* Get canvas body element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getCanvasBody: function(){ |
|||
return this.canvas.getBody(); |
|||
}, |
|||
|
|||
/** |
|||
* Get canvas wrapper element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getCanvasWrapper: function(){ |
|||
return this.canvas.getWrapperEl(); |
|||
}, |
|||
|
|||
/** |
|||
* Get canvas wrapper element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getCanvasTools: function(){ |
|||
return this.canvas.getToolsEl(); |
|||
}, |
|||
|
|||
/** |
|||
* Get the offset of the element |
|||
* @param {HTMLElement} el |
|||
* @return {Object} |
|||
*/ |
|||
offset: function(el){ |
|||
var rect = el.getBoundingClientRect(); |
|||
return { |
|||
top: rect.top + el.ownerDocument.body.scrollTop, |
|||
left: rect.left + el.ownerDocument.body.scrollLeft |
|||
}; |
|||
}, |
|||
|
|||
/** |
|||
* Callback triggered after initialize |
|||
* @param {Object} o Options |
|||
* @private |
|||
* */ |
|||
init: function(o){}, |
|||
|
|||
/** |
|||
* Method that run command |
|||
* @param {Object} em Editor model |
|||
* @param {Object} sender Button sender |
|||
* @private |
|||
* */ |
|||
run: function(em, sender) {}, |
|||
|
|||
/** |
|||
* Method that stop command |
|||
* @param {Object} em Editor model |
|||
* @param {Object} sender Button sender |
|||
* @private |
|||
* */ |
|||
stop: function(em, sender) {}, |
|||
|
|||
}); |
|||
|
|||
@ -1,233 +1,230 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var SelectPosition = require('./SelectPosition'); |
|||
|
|||
module.exports = _.extend({}, SelectPosition, { |
|||
|
|||
init: function(opt) { |
|||
_.bindAll(this,'startDraw','draw','endDraw','rollback'); |
|||
this.config = opt || {}; |
|||
this.hType = this.config.newFixedH ? 'height' : 'min-height'; |
|||
this.allowDraw = 1; |
|||
}, |
|||
|
|||
/** |
|||
* Start with enabling to select position and listening to start drawning |
|||
* @private |
|||
* */ |
|||
enable: function() { |
|||
SelectPosition.enable.apply(this, arguments); |
|||
this.$wr.css('cursor','crosshair'); |
|||
if(this.allowDraw) |
|||
this.$wr.on('mousedown', this.startDraw); |
|||
this.ghost = this.canvas.getGhostEl(); |
|||
}, |
|||
|
|||
/** |
|||
* Start drawing component |
|||
* @param {Object} e Event |
|||
* @private |
|||
* */ |
|||
startDraw : function(e) { |
|||
e.preventDefault(); |
|||
this.stopSelectPosition(); |
|||
this.ghost.style.display = 'block'; |
|||
this.frameOff = this.getOffsetDim(); |
|||
this.startPos = { |
|||
top : e.pageY + this.frameOff.top, |
|||
left: e.pageX + this.frameOff.left |
|||
}; |
|||
this.isDragged = false; |
|||
this.tempComponent = {style: {}}; |
|||
this.beforeDraw(this.tempComponent); |
|||
this.updateSize(this.startPos.top, this.startPos.left, 0, 0); |
|||
this.toggleEvents(1); |
|||
}, |
|||
|
|||
/** |
|||
* Enable/Disable events |
|||
* @param {Boolean} enable |
|||
*/ |
|||
toggleEvents: function(enable) { |
|||
var method = enable ? 'on' : 'off'; |
|||
this.$wr[method]('mousemove', this.draw); |
|||
this.$wr[method]('mouseup', this.endDraw); |
|||
this.$canvas[method]('mousemove', this.draw); |
|||
$(document)[method]('mouseup', this.endDraw); |
|||
$(document)[method]('keypress', this.rollback); |
|||
}, |
|||
|
|||
/** |
|||
* While drawing the component |
|||
* @param {Object} e Event |
|||
* @private |
|||
* */ |
|||
draw: function(e) { |
|||
this.isDragged = true; |
|||
this.updateComponentSize(e); |
|||
}, |
|||
|
|||
/** |
|||
* End drawing component |
|||
* @param {Object} e Event |
|||
* @private |
|||
* */ |
|||
endDraw : function(e) { |
|||
this.toggleEvents(); |
|||
var model = {}; |
|||
// Only if the mouse was moved
|
|||
if(this.isDragged){ |
|||
this.updateComponentSize(e); |
|||
this.setRequirements(this.tempComponent); |
|||
var lp = this.sorter.lastPos; |
|||
model = this.create(this.sorter.target, this.tempComponent, lp.index, lp.method); |
|||
this.sorter.prevTarget = null; |
|||
} |
|||
this.ghost.style.display = 'none'; |
|||
this.startSelectPosition(); |
|||
this.afterDraw(model); |
|||
}, |
|||
|
|||
/** |
|||
* Create new component inside the target |
|||
* @param {Object} target Tha target collection |
|||
* @param {Object} component New component to create |
|||
* @param {number} index Index inside the collection, 0 if no children inside |
|||
* @param {string} method Before or after of the children |
|||
* @param {Object} opts Options |
|||
*/ |
|||
create: function(target, component, index, method, opts) { |
|||
index = method === 'after' ? index + 1 : index; |
|||
var opt = opts || {}; |
|||
var $trg = $(target); |
|||
var trgModel = $trg.data('model'); |
|||
var trgCollection = $trg.data('collection'); |
|||
var droppable = trgModel ? trgModel.get('droppable') : 1; |
|||
opt.at = index; |
|||
if(trgCollection && droppable) |
|||
return trgCollection.add(component, opt); |
|||
else |
|||
console.warn("Invalid target position"); |
|||
}, |
|||
|
|||
/** |
|||
* Check and set basic requirements for the component |
|||
* @param {Object} component New component to be created |
|||
* @return {Object} Component updated |
|||
* @private |
|||
* */ |
|||
setRequirements: function(component) { |
|||
var c = this.config; |
|||
var compStl = component.style; |
|||
// Check min width
|
|||
if(compStl.width.replace(/\D/g,'') < c.minComponentW) |
|||
compStl.width = c.minComponentW +'px'; |
|||
// Check min height
|
|||
if(compStl[this.hType].replace(/\D/g,'') < c.minComponentH) |
|||
compStl[this.hType] = c.minComponentH +'px'; |
|||
// Set overflow in case of fixed height
|
|||
if(c.newFixedH) |
|||
compStl.overflow = 'auto'; |
|||
if(!this.absoluteMode){ |
|||
delete compStl.left; |
|||
delete compStl.top; |
|||
}else |
|||
compStl.position = 'absolute'; |
|||
var lp = this.sorter.lastPos; |
|||
|
|||
if(this.nearFloat(lp.index, lp.method, this.sorter.lastDims)) |
|||
compStl.float = 'left'; |
|||
|
|||
if(this.config.firstCentered && |
|||
this.getCanvasWrapper() == this.sorter.target){ |
|||
compStl.margin = '0 auto'; |
|||
} |
|||
|
|||
return component; |
|||
}, |
|||
|
|||
/** |
|||
* Update new component size while drawing |
|||
* @param {Object} e Event |
|||
* @private |
|||
* */ |
|||
updateComponentSize : function (e) { |
|||
var y = e.pageY + this.frameOff.top; |
|||
var x = e.pageX + this.frameOff.left; |
|||
var start = this.startPos; |
|||
var top = start.top; |
|||
var left = start.left; |
|||
var height = y - top; |
|||
var width = x - left; |
|||
if (x < left) { |
|||
left = x; |
|||
width = start.left - x; |
|||
} |
|||
if (y < top) { |
|||
top = y; |
|||
height = start.top - y; |
|||
} |
|||
this.updateSize(top, left, width, height); |
|||
}, |
|||
|
|||
/** |
|||
* Update size |
|||
* @private |
|||
*/ |
|||
updateSize: function(top, left, width, height){ |
|||
var u = 'px'; |
|||
var ghStl = this.ghost.style; |
|||
var compStl = this.tempComponent.style; |
|||
ghStl.top = compStl.top = top + u; |
|||
ghStl.left = compStl.left = left + u; |
|||
ghStl.width = compStl.width = width + u; |
|||
ghStl[this.hType] = compStl[this.hType] = height + u; |
|||
}, |
|||
|
|||
/** |
|||
* Used to bring the previous situation before event started |
|||
* @param {Object} e Event |
|||
* @param {Boolean} forse Indicates if rollback in anycase |
|||
* @private |
|||
* */ |
|||
rollback: function(e, force) { |
|||
var key = e.which || e.keyCode; |
|||
if(key == this.config.ESCAPE_KEY || force){ |
|||
this.isDragged = false; |
|||
this.endDraw(); |
|||
} |
|||
return; |
|||
}, |
|||
|
|||
/** |
|||
* This event is triggered at the beginning of a draw operation |
|||
* @param {Object} component Object component before creation |
|||
* @private |
|||
* */ |
|||
beforeDraw: function(component){ |
|||
component.editable = false;//set this component editable
|
|||
}, |
|||
|
|||
/** |
|||
* This event is triggered at the end of a draw operation |
|||
* @param {Object} model Component model created |
|||
* @private |
|||
* */ |
|||
afterDraw: function(model){}, |
|||
|
|||
|
|||
run: function(editor, sender, opts){ |
|||
this.editor = editor; |
|||
this.sender = sender; |
|||
this.$wr = this.$wrapper; |
|||
this.enable(); |
|||
}, |
|||
|
|||
stop: function(){ |
|||
this.stopSelectPosition(); |
|||
this.$wrapper.css('cursor',''); |
|||
this.$wrapper.unbind(); |
|||
} |
|||
}); |
|||
}); |
|||
var Backbone = require('backbone'); |
|||
var SelectPosition = require('./SelectPosition'); |
|||
|
|||
module.exports = _.extend({}, SelectPosition, { |
|||
|
|||
init: function(opt) { |
|||
_.bindAll(this,'startDraw','draw','endDraw','rollback'); |
|||
this.config = opt || {}; |
|||
this.hType = this.config.newFixedH ? 'height' : 'min-height'; |
|||
this.allowDraw = 1; |
|||
}, |
|||
|
|||
/** |
|||
* Start with enabling to select position and listening to start drawning |
|||
* @private |
|||
* */ |
|||
enable: function() { |
|||
SelectPosition.enable.apply(this, arguments); |
|||
this.$wr.css('cursor','crosshair'); |
|||
if(this.allowDraw) |
|||
this.$wr.on('mousedown', this.startDraw); |
|||
this.ghost = this.canvas.getGhostEl(); |
|||
}, |
|||
|
|||
/** |
|||
* Start drawing component |
|||
* @param {Object} e Event |
|||
* @private |
|||
* */ |
|||
startDraw : function(e) { |
|||
e.preventDefault(); |
|||
this.stopSelectPosition(); |
|||
this.ghost.style.display = 'block'; |
|||
this.frameOff = this.getOffsetDim(); |
|||
this.startPos = { |
|||
top : e.pageY + this.frameOff.top, |
|||
left: e.pageX + this.frameOff.left |
|||
}; |
|||
this.isDragged = false; |
|||
this.tempComponent = {style: {}}; |
|||
this.beforeDraw(this.tempComponent); |
|||
this.updateSize(this.startPos.top, this.startPos.left, 0, 0); |
|||
this.toggleEvents(1); |
|||
}, |
|||
|
|||
/** |
|||
* Enable/Disable events |
|||
* @param {Boolean} enable |
|||
*/ |
|||
toggleEvents: function(enable) { |
|||
var method = enable ? 'on' : 'off'; |
|||
this.$wr[method]('mousemove', this.draw); |
|||
this.$wr[method]('mouseup', this.endDraw); |
|||
this.$canvas[method]('mousemove', this.draw); |
|||
$(document)[method]('mouseup', this.endDraw); |
|||
$(document)[method]('keypress', this.rollback); |
|||
}, |
|||
|
|||
/** |
|||
* While drawing the component |
|||
* @param {Object} e Event |
|||
* @private |
|||
* */ |
|||
draw: function(e) { |
|||
this.isDragged = true; |
|||
this.updateComponentSize(e); |
|||
}, |
|||
|
|||
/** |
|||
* End drawing component |
|||
* @param {Object} e Event |
|||
* @private |
|||
* */ |
|||
endDraw : function(e) { |
|||
this.toggleEvents(); |
|||
var model = {}; |
|||
// Only if the mouse was moved
|
|||
if(this.isDragged){ |
|||
this.updateComponentSize(e); |
|||
this.setRequirements(this.tempComponent); |
|||
var lp = this.sorter.lastPos; |
|||
model = this.create(this.sorter.target, this.tempComponent, lp.index, lp.method); |
|||
this.sorter.prevTarget = null; |
|||
} |
|||
this.ghost.style.display = 'none'; |
|||
this.startSelectPosition(); |
|||
this.afterDraw(model); |
|||
}, |
|||
|
|||
/** |
|||
* Create new component inside the target |
|||
* @param {Object} target Tha target collection |
|||
* @param {Object} component New component to create |
|||
* @param {number} index Index inside the collection, 0 if no children inside |
|||
* @param {string} method Before or after of the children |
|||
* @param {Object} opts Options |
|||
*/ |
|||
create: function(target, component, index, method, opts) { |
|||
index = method === 'after' ? index + 1 : index; |
|||
var opt = opts || {}; |
|||
var $trg = $(target); |
|||
var trgModel = $trg.data('model'); |
|||
var trgCollection = $trg.data('collection'); |
|||
var droppable = trgModel ? trgModel.get('droppable') : 1; |
|||
opt.at = index; |
|||
if(trgCollection && droppable) |
|||
return trgCollection.add(component, opt); |
|||
else |
|||
console.warn("Invalid target position"); |
|||
}, |
|||
|
|||
/** |
|||
* Check and set basic requirements for the component |
|||
* @param {Object} component New component to be created |
|||
* @return {Object} Component updated |
|||
* @private |
|||
* */ |
|||
setRequirements: function(component) { |
|||
var c = this.config; |
|||
var compStl = component.style; |
|||
// Check min width
|
|||
if(compStl.width.replace(/\D/g,'') < c.minComponentW) |
|||
compStl.width = c.minComponentW +'px'; |
|||
// Check min height
|
|||
if(compStl[this.hType].replace(/\D/g,'') < c.minComponentH) |
|||
compStl[this.hType] = c.minComponentH +'px'; |
|||
// Set overflow in case of fixed height
|
|||
if(c.newFixedH) |
|||
compStl.overflow = 'auto'; |
|||
if(!this.absoluteMode){ |
|||
delete compStl.left; |
|||
delete compStl.top; |
|||
}else |
|||
compStl.position = 'absolute'; |
|||
var lp = this.sorter.lastPos; |
|||
|
|||
if(this.nearFloat(lp.index, lp.method, this.sorter.lastDims)) |
|||
compStl.float = 'left'; |
|||
|
|||
if(this.config.firstCentered && |
|||
this.getCanvasWrapper() == this.sorter.target){ |
|||
compStl.margin = '0 auto'; |
|||
} |
|||
|
|||
return component; |
|||
}, |
|||
|
|||
/** |
|||
* Update new component size while drawing |
|||
* @param {Object} e Event |
|||
* @private |
|||
* */ |
|||
updateComponentSize : function (e) { |
|||
var y = e.pageY + this.frameOff.top; |
|||
var x = e.pageX + this.frameOff.left; |
|||
var start = this.startPos; |
|||
var top = start.top; |
|||
var left = start.left; |
|||
var height = y - top; |
|||
var width = x - left; |
|||
if (x < left) { |
|||
left = x; |
|||
width = start.left - x; |
|||
} |
|||
if (y < top) { |
|||
top = y; |
|||
height = start.top - y; |
|||
} |
|||
this.updateSize(top, left, width, height); |
|||
}, |
|||
|
|||
/** |
|||
* Update size |
|||
* @private |
|||
*/ |
|||
updateSize: function(top, left, width, height){ |
|||
var u = 'px'; |
|||
var ghStl = this.ghost.style; |
|||
var compStl = this.tempComponent.style; |
|||
ghStl.top = compStl.top = top + u; |
|||
ghStl.left = compStl.left = left + u; |
|||
ghStl.width = compStl.width = width + u; |
|||
ghStl[this.hType] = compStl[this.hType] = height + u; |
|||
}, |
|||
|
|||
/** |
|||
* Used to bring the previous situation before event started |
|||
* @param {Object} e Event |
|||
* @param {Boolean} forse Indicates if rollback in anycase |
|||
* @private |
|||
* */ |
|||
rollback: function(e, force) { |
|||
var key = e.which || e.keyCode; |
|||
if(key == this.config.ESCAPE_KEY || force){ |
|||
this.isDragged = false; |
|||
this.endDraw(); |
|||
} |
|||
return; |
|||
}, |
|||
|
|||
/** |
|||
* This event is triggered at the beginning of a draw operation |
|||
* @param {Object} component Object component before creation |
|||
* @private |
|||
* */ |
|||
beforeDraw: function(component){ |
|||
component.editable = false;//set this component editable
|
|||
}, |
|||
|
|||
/** |
|||
* This event is triggered at the end of a draw operation |
|||
* @param {Object} model Component model created |
|||
* @private |
|||
* */ |
|||
afterDraw: function(model){}, |
|||
|
|||
|
|||
run: function(editor, sender, opts){ |
|||
this.editor = editor; |
|||
this.sender = sender; |
|||
this.$wr = this.$wrapper; |
|||
this.enable(); |
|||
}, |
|||
|
|||
stop: function(){ |
|||
this.stopSelectPosition(); |
|||
this.$wrapper.css('cursor',''); |
|||
this.$wrapper.unbind(); |
|||
} |
|||
}); |
|||
|
|||
@ -1,90 +1,79 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var SelectComponent = require('./SelectComponent'); |
|||
/** |
|||
* @class DeleteComponent |
|||
* @private |
|||
* */ |
|||
module.exports = _.extend({},SelectComponent,{ |
|||
var Backbone = require('backbone'); |
|||
var SelectComponent = require('./SelectComponent'); |
|||
|
|||
init: function(o){ |
|||
_.bindAll(this, 'startDelete', 'stopDelete', 'onDelete'); |
|||
this.hoverClass = this.pfx + 'hover-delete'; |
|||
this.badgeClass = this.pfx + 'badge-red'; |
|||
}, |
|||
module.exports = _.extend({},SelectComponent,{ |
|||
|
|||
enable: function() |
|||
{ |
|||
var that = this; |
|||
this.$el.find('*') |
|||
.mouseover(this.startDelete) |
|||
.mouseout(this.stopDelete) |
|||
.click(this.onDelete); |
|||
}, |
|||
init: function(o){ |
|||
_.bindAll(this, 'startDelete', 'stopDelete', 'onDelete'); |
|||
this.hoverClass = this.pfx + 'hover-delete'; |
|||
this.badgeClass = this.pfx + 'badge-red'; |
|||
}, |
|||
|
|||
/** |
|||
* Start command |
|||
* @param {Object} e |
|||
* @private |
|||
*/ |
|||
startDelete: function(e) |
|||
{ |
|||
e.stopPropagation(); |
|||
var $this = $(e.target); |
|||
enable: function() { |
|||
var that = this; |
|||
this.$el.find('*') |
|||
.mouseover(this.startDelete) |
|||
.mouseout(this.stopDelete) |
|||
.click(this.onDelete); |
|||
}, |
|||
|
|||
// Show badge if possible
|
|||
if($this.data('model').get('removable')){ |
|||
$this.addClass(this.hoverClass); |
|||
this.attachBadge($this.get(0)); |
|||
} |
|||
/** |
|||
* Start command |
|||
* @param {Object} e |
|||
* @private |
|||
*/ |
|||
startDelete: function(e) { |
|||
e.stopPropagation(); |
|||
var $this = $(e.target); |
|||
|
|||
}, |
|||
// Show badge if possible
|
|||
if($this.data('model').get('removable')){ |
|||
$this.addClass(this.hoverClass); |
|||
this.attachBadge($this.get(0)); |
|||
} |
|||
|
|||
/** |
|||
* Stop command |
|||
* @param {Object} e |
|||
* @private |
|||
*/ |
|||
stopDelete: function(e) |
|||
{ |
|||
e.stopPropagation(); |
|||
var $this = $(e.target); |
|||
$this.removeClass(this.hoverClass); |
|||
}, |
|||
|
|||
// Hide badge if possible
|
|||
if(this.badge) |
|||
this.badge.css({ left: -1000, top:-1000 }); |
|||
}, |
|||
/** |
|||
* Stop command |
|||
* @param {Object} e |
|||
* @private |
|||
*/ |
|||
stopDelete: function(e) { |
|||
e.stopPropagation(); |
|||
var $this = $(e.target); |
|||
$this.removeClass(this.hoverClass); |
|||
|
|||
/** |
|||
* Delete command |
|||
* @param {Object} e |
|||
* @private |
|||
*/ |
|||
onDelete: function(e) |
|||
{ |
|||
e.stopPropagation(); |
|||
var $this = $(e.target); |
|||
// Hide badge if possible
|
|||
if(this.badge) |
|||
this.badge.css({ left: -1000, top:-1000 }); |
|||
}, |
|||
|
|||
// Do nothing in case can't remove
|
|||
if(!$this.data('model').get('removable')) |
|||
return; |
|||
/** |
|||
* Delete command |
|||
* @param {Object} e |
|||
* @private |
|||
*/ |
|||
onDelete: function(e) { |
|||
e.stopPropagation(); |
|||
var $this = $(e.target); |
|||
|
|||
$this.data('model').destroy(); |
|||
this.removeBadge(); |
|||
this.clean(); |
|||
}, |
|||
// Do nothing in case can't remove
|
|||
if(!$this.data('model').get('removable')) |
|||
return; |
|||
|
|||
/** |
|||
* Updates badge label |
|||
* @param {Object} model |
|||
* @private |
|||
* */ |
|||
updateBadgeLabel: function (model) |
|||
{ |
|||
this.badge.html( 'Remove ' + model.getName() ); |
|||
}, |
|||
$this.data('model').destroy(); |
|||
this.removeBadge(); |
|||
this.clean(); |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
/** |
|||
* Updates badge label |
|||
* @param {Object} model |
|||
* @private |
|||
* */ |
|||
updateBadgeLabel: function (model) { |
|||
this.badge.html( 'Remove ' + model.getName() ); |
|||
}, |
|||
|
|||
}); |
|||
|
|||
@ -1,78 +1,72 @@ |
|||
define(function() { |
|||
/** |
|||
* @class ExportTemplate |
|||
* @private |
|||
* */ |
|||
return { |
|||
module.exports = { |
|||
|
|||
run: function(editor, sender) { |
|||
this.sender = sender; |
|||
this.wrapper = editor.DomComponents.getWrapper(); |
|||
this.components = editor.DomComponents.getComponents(); |
|||
this.modal = editor.Modal || null; |
|||
this.cm = editor.CodeManager || null; |
|||
this.cssc = editor.CssComposer || null; |
|||
this.protCss = editor.Config.protectedCss; |
|||
this.pfx = editor.Config.stylePrefix || ''; |
|||
this.enable(); |
|||
}, |
|||
run: function(editor, sender) { |
|||
this.sender = sender; |
|||
this.wrapper = editor.DomComponents.getWrapper(); |
|||
this.components = editor.DomComponents.getComponents(); |
|||
this.modal = editor.Modal || null; |
|||
this.cm = editor.CodeManager || null; |
|||
this.cssc = editor.CssComposer || null; |
|||
this.protCss = editor.Config.protectedCss; |
|||
this.pfx = editor.Config.stylePrefix || ''; |
|||
this.enable(); |
|||
}, |
|||
|
|||
/** |
|||
* Build editor |
|||
* @param {String} codeName |
|||
* @param {String} theme |
|||
* @param {String} label |
|||
* |
|||
* @return {Object} Editor |
|||
* @private |
|||
* */ |
|||
buildEditor: function(codeName, theme, label) { |
|||
if(!this.codeMirror) |
|||
this.codeMirror = this.cm.getViewer('CodeMirror'); |
|||
/** |
|||
* Build editor |
|||
* @param {String} codeName |
|||
* @param {String} theme |
|||
* @param {String} label |
|||
* |
|||
* @return {Object} Editor |
|||
* @private |
|||
* */ |
|||
buildEditor: function(codeName, theme, label) { |
|||
if(!this.codeMirror) |
|||
this.codeMirror = this.cm.getViewer('CodeMirror'); |
|||
|
|||
var $input = $('<textarea>'), |
|||
var $input = $('<textarea>'), |
|||
|
|||
editor = this.codeMirror.clone().set({ |
|||
label : label, |
|||
codeName : codeName, |
|||
theme : theme, |
|||
input : $input[0], |
|||
}), |
|||
editor = this.codeMirror.clone().set({ |
|||
label : label, |
|||
codeName : codeName, |
|||
theme : theme, |
|||
input : $input[0], |
|||
}), |
|||
|
|||
$editor = new this.cm.EditorView({ |
|||
model : editor, |
|||
config : this.cm.getConfig() |
|||
}).render().$el; |
|||
$editor = new this.cm.EditorView({ |
|||
model : editor, |
|||
config : this.cm.getConfig() |
|||
}).render().$el; |
|||
|
|||
editor.init( $input[0] ); |
|||
editor.init( $input[0] ); |
|||
|
|||
return { el: editor, $el: $editor }; |
|||
}, |
|||
return { el: editor, $el: $editor }; |
|||
}, |
|||
|
|||
enable: function() { |
|||
if(!this.$editors){ |
|||
var oHtmlEd = this.buildEditor('htmlmixed', 'hopscotch', 'HTML'), |
|||
oCsslEd = this.buildEditor('css', 'hopscotch', 'CSS'); |
|||
this.htmlEditor = oHtmlEd.el; |
|||
this.cssEditor = oCsslEd.el; |
|||
this.$editors = $('<div>', {class: this.pfx + 'export-dl'}); |
|||
this.$editors.append(oHtmlEd.$el).append(oCsslEd.$el); |
|||
} |
|||
enable: function() { |
|||
if(!this.$editors){ |
|||
var oHtmlEd = this.buildEditor('htmlmixed', 'hopscotch', 'HTML'), |
|||
oCsslEd = this.buildEditor('css', 'hopscotch', 'CSS'); |
|||
this.htmlEditor = oHtmlEd.el; |
|||
this.cssEditor = oCsslEd.el; |
|||
this.$editors = $('<div>', {class: this.pfx + 'export-dl'}); |
|||
this.$editors.append(oHtmlEd.$el).append(oCsslEd.$el); |
|||
} |
|||
|
|||
if(this.modal){ |
|||
this.modal.setTitle('Export template'); |
|||
this.modal.setContent(this.$editors); |
|||
this.modal.open(); |
|||
} |
|||
var addCss = this.protCss || ''; |
|||
//this.htmlEditor.setContent(this.cm.getCode(this.components, 'html', this.cssc));
|
|||
this.htmlEditor.setContent(this.em.getHtml()); |
|||
this.cssEditor.setContent(addCss + this.cm.getCode(this.wrapper, 'css', this.cssc)); |
|||
if(this.modal){ |
|||
this.modal.setTitle('Export template'); |
|||
this.modal.setContent(this.$editors); |
|||
this.modal.open(); |
|||
} |
|||
var addCss = this.protCss || ''; |
|||
//this.htmlEditor.setContent(this.cm.getCode(this.components, 'html', this.cssc));
|
|||
this.htmlEditor.setContent(this.em.getHtml()); |
|||
this.cssEditor.setContent(addCss + this.cm.getCode(this.wrapper, 'css', this.cssc)); |
|||
|
|||
if(this.sender) |
|||
this.sender.set('active',false); |
|||
}, |
|||
if(this.sender) |
|||
this.sender.set('active',false); |
|||
}, |
|||
|
|||
stop: function(){} |
|||
}; |
|||
}); |
|||
stop: function(){} |
|||
}; |
|||
|
|||
@ -1,86 +1,83 @@ |
|||
define(function() { |
|||
module.exports = { |
|||
/** |
|||
* Check if fullscreen mode is enabled |
|||
* @return {Boolean} |
|||
*/ |
|||
isEnabled: function(){ |
|||
var d = document; |
|||
if(d.fullscreenElement || d.webkitFullscreenElement || d.mozFullScreenElement) |
|||
return 1; |
|||
else |
|||
return 0; |
|||
}, |
|||
|
|||
return { |
|||
/** |
|||
* Check if fullscreen mode is enabled |
|||
* @return {Boolean} |
|||
*/ |
|||
isEnabled: function(){ |
|||
var d = document; |
|||
if(d.fullscreenElement || d.webkitFullscreenElement || d.mozFullScreenElement) |
|||
return 1; |
|||
else |
|||
return 0; |
|||
}, |
|||
/** |
|||
* Enable fullscreen mode and return browser prefix |
|||
* @param {HTMLElement} el |
|||
* @return {string} |
|||
*/ |
|||
enable: function(el){ |
|||
var pfx = ''; |
|||
if (el.requestFullscreen) |
|||
el.requestFullscreen(); |
|||
else if (el.webkitRequestFullscreen) { |
|||
pfx = 'webkit'; |
|||
el.webkitRequestFullscreen(); |
|||
}else if (el.mozRequestFullScreen) { |
|||
pfx = 'moz'; |
|||
el.mozRequestFullScreen(); |
|||
}else if (el.msRequestFullscreen) |
|||
el.msRequestFullscreen(); |
|||
else |
|||
console.warn('Fullscreen not supported'); |
|||
return pfx; |
|||
}, |
|||
|
|||
/** |
|||
* Enable fullscreen mode and return browser prefix |
|||
* @param {HTMLElement} el |
|||
* @return {string} |
|||
*/ |
|||
enable: function(el){ |
|||
var pfx = ''; |
|||
if (el.requestFullscreen) |
|||
el.requestFullscreen(); |
|||
else if (el.webkitRequestFullscreen) { |
|||
pfx = 'webkit'; |
|||
el.webkitRequestFullscreen(); |
|||
}else if (el.mozRequestFullScreen) { |
|||
pfx = 'moz'; |
|||
el.mozRequestFullScreen(); |
|||
}else if (el.msRequestFullscreen) |
|||
el.msRequestFullscreen(); |
|||
else |
|||
console.warn('Fullscreen not supported'); |
|||
return pfx; |
|||
}, |
|||
/** |
|||
* Disable fullscreen mode |
|||
*/ |
|||
disable: function(){ |
|||
var d = document; |
|||
if (d.exitFullscreen) |
|||
d.exitFullscreen(); |
|||
else if (d.webkitExitFullscreen) |
|||
d.webkitExitFullscreen(); |
|||
else if (d.mozCancelFullScreen) |
|||
d.mozCancelFullScreen(); |
|||
else if (d.msExitFullscreen) |
|||
d.msExitFullscreen(); |
|||
}, |
|||
|
|||
/** |
|||
* Disable fullscreen mode |
|||
*/ |
|||
disable: function(){ |
|||
var d = document; |
|||
if (d.exitFullscreen) |
|||
d.exitFullscreen(); |
|||
else if (d.webkitExitFullscreen) |
|||
d.webkitExitFullscreen(); |
|||
else if (d.mozCancelFullScreen) |
|||
d.mozCancelFullScreen(); |
|||
else if (d.msExitFullscreen) |
|||
d.msExitFullscreen(); |
|||
}, |
|||
/** |
|||
* Triggered when the state of the fullscreen is changed. Inside detects if |
|||
* it's enabled |
|||
* @param {strinf} pfx Browser prefix |
|||
* @param {Event} e |
|||
*/ |
|||
fsChanged: function(pfx, e){ |
|||
var d = document; |
|||
var ev = (pfx || '') + 'fullscreenchange'; |
|||
if(!this.isEnabled()){ |
|||
this.stop(null, this.sender); |
|||
document.removeEventListener(ev, this.fsChanged); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Triggered when the state of the fullscreen is changed. Inside detects if |
|||
* it's enabled |
|||
* @param {strinf} pfx Browser prefix |
|||
* @param {Event} e |
|||
*/ |
|||
fsChanged: function(pfx, e){ |
|||
var d = document; |
|||
var ev = (pfx || '') + 'fullscreenchange'; |
|||
if(!this.isEnabled()){ |
|||
this.stop(null, this.sender); |
|||
document.removeEventListener(ev, this.fsChanged); |
|||
} |
|||
}, |
|||
run: function(editor, sender){ |
|||
this.sender = sender; |
|||
var pfx = this.enable(editor.getContainer()); |
|||
this.fsChanged = this.fsChanged.bind(this, pfx); |
|||
document.addEventListener(pfx + 'fullscreenchange', this.fsChanged); |
|||
if(editor) |
|||
editor.trigger('change:canvasOffset'); |
|||
}, |
|||
|
|||
run: function(editor, sender){ |
|||
this.sender = sender; |
|||
var pfx = this.enable(editor.getContainer()); |
|||
this.fsChanged = this.fsChanged.bind(this, pfx); |
|||
document.addEventListener(pfx + 'fullscreenchange', this.fsChanged); |
|||
if(editor) |
|||
editor.trigger('change:canvasOffset'); |
|||
}, |
|||
stop: function(editor, sender){ |
|||
if(sender && sender.set) |
|||
sender.set('active', false); |
|||
this.disable(); |
|||
if(editor) |
|||
editor.trigger('change:canvasOffset'); |
|||
} |
|||
|
|||
stop: function(editor, sender){ |
|||
if(sender && sender.set) |
|||
sender.set('active', false); |
|||
this.disable(); |
|||
if(editor) |
|||
editor.trigger('change:canvasOffset'); |
|||
} |
|||
|
|||
}; |
|||
}); |
|||
}; |
|||
|
|||
@ -1,41 +1,35 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var InsertCustom = require('./InsertCustom'); |
|||
/** |
|||
* @class ImageComponent |
|||
* @private |
|||
* */ |
|||
module.exports = _.extend({}, InsertCustom, { |
|||
var Backbone = require('backbone'); |
|||
var InsertCustom = require('./InsertCustom'); |
|||
|
|||
/** |
|||
* Trigger before insert |
|||
* @param {Object} object |
|||
* @private |
|||
* |
|||
* */ |
|||
beforeInsert: function(object){ |
|||
object.type = 'image'; |
|||
object.style = {}; |
|||
object.attributes = {}; |
|||
object.attributes.onmousedown = 'return false'; |
|||
if (this.config.firstCentered && |
|||
this.getCanvasWrapper() == this.sorter.target ) { |
|||
object.style.margin = '0 auto'; |
|||
} |
|||
}, |
|||
module.exports = _.extend({}, InsertCustom, { |
|||
|
|||
/** |
|||
* Trigger after insert |
|||
* @param {Object} model Model created after insert |
|||
* @private |
|||
* */ |
|||
afterInsert: function(model){ |
|||
model.trigger('dblclick'); |
|||
if(this.sender) |
|||
this.sender.set('active', false); |
|||
}, |
|||
/** |
|||
* Trigger before insert |
|||
* @param {Object} object |
|||
* @private |
|||
* |
|||
* */ |
|||
beforeInsert: function(object){ |
|||
object.type = 'image'; |
|||
object.style = {}; |
|||
object.attributes = {}; |
|||
object.attributes.onmousedown = 'return false'; |
|||
if (this.config.firstCentered && |
|||
this.getCanvasWrapper() == this.sorter.target ) { |
|||
object.style.margin = '0 auto'; |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Trigger after insert |
|||
* @param {Object} model Model created after insert |
|||
* @private |
|||
* */ |
|||
afterInsert: function(model){ |
|||
model.trigger('dblclick'); |
|||
if(this.sender) |
|||
this.sender.set('active', false); |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
|
|||
}); |
|||
|
|||
@ -1,85 +1,79 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var CreateComponent = require('./CreateComponent'); |
|||
/** |
|||
* @class InsertCustom |
|||
* @private |
|||
* */ |
|||
module.exports = _.extend({}, CreateComponent, { |
|||
var Backbone = require('backbone'); |
|||
var CreateComponent = require('./CreateComponent'); |
|||
|
|||
init: function(){ |
|||
CreateComponent.init.apply(this, arguments); |
|||
_.bindAll(this, 'insertComponent'); |
|||
this.allowDraw = 0; |
|||
}, |
|||
module.exports = _.extend({}, CreateComponent, { |
|||
|
|||
/** |
|||
* Run method |
|||
* @private |
|||
* */ |
|||
run: function(em, sender, options) { |
|||
this.em = em; |
|||
this.sender = sender; |
|||
this.opt = options || {}; |
|||
this.$wr = this.$wrapper; |
|||
this.enable(); |
|||
}, |
|||
init: function(){ |
|||
CreateComponent.init.apply(this, arguments); |
|||
_.bindAll(this, 'insertComponent'); |
|||
this.allowDraw = 0; |
|||
}, |
|||
|
|||
enable: function(){ |
|||
CreateComponent.enable.apply(this, arguments); |
|||
this.$wr.on('click', this.insertComponent); |
|||
}, |
|||
/** |
|||
* Run method |
|||
* @private |
|||
* */ |
|||
run: function(em, sender, options) { |
|||
this.em = em; |
|||
this.sender = sender; |
|||
this.opt = options || {}; |
|||
this.$wr = this.$wrapper; |
|||
this.enable(); |
|||
}, |
|||
|
|||
/** |
|||
* Start insert event |
|||
* @private |
|||
* */ |
|||
insertComponent: function(){ |
|||
this.$wr.off('click', this.insertComponent); |
|||
this.stopSelectPosition(); |
|||
var object = this.buildContent(); |
|||
this.beforeInsert(object); |
|||
var index = this.sorter.lastPos.index; |
|||
// By default, collections do not trigger add event, so silent is used
|
|||
var model = this.create(this.sorter.target, object, index, null, {silent: false}); |
|||
enable: function(){ |
|||
CreateComponent.enable.apply(this, arguments); |
|||
this.$wr.on('click', this.insertComponent); |
|||
}, |
|||
|
|||
if(this.opt.terminateAfterInsert && this.sender) |
|||
this.sender.set('active', false); |
|||
else |
|||
this.enable(); |
|||
/** |
|||
* Start insert event |
|||
* @private |
|||
* */ |
|||
insertComponent: function(){ |
|||
this.$wr.off('click', this.insertComponent); |
|||
this.stopSelectPosition(); |
|||
var object = this.buildContent(); |
|||
this.beforeInsert(object); |
|||
var index = this.sorter.lastPos.index; |
|||
// By default, collections do not trigger add event, so silent is used
|
|||
var model = this.create(this.sorter.target, object, index, null, {silent: false}); |
|||
|
|||
if(!model) |
|||
return; |
|||
if(this.opt.terminateAfterInsert && this.sender) |
|||
this.sender.set('active', false); |
|||
else |
|||
this.enable(); |
|||
|
|||
if(this.em) |
|||
this.em.editor.initChildrenComp(model); |
|||
if(!model) |
|||
return; |
|||
|
|||
this.afterInsert(model, this); |
|||
}, |
|||
if(this.em) |
|||
this.em.editor.initChildrenComp(model); |
|||
|
|||
/** |
|||
* Trigger before insert |
|||
* @param {Object} obj |
|||
* @private |
|||
* */ |
|||
beforeInsert: function(obj){}, |
|||
this.afterInsert(model, this); |
|||
}, |
|||
|
|||
/** |
|||
* Trigger after insert |
|||
* @param {Object} model Model created after insert |
|||
* @private |
|||
* */ |
|||
afterInsert: function(model){}, |
|||
/** |
|||
* Trigger before insert |
|||
* @param {Object} obj |
|||
* @private |
|||
* */ |
|||
beforeInsert: function(obj){}, |
|||
|
|||
/** |
|||
* Create different object, based on content, to insert inside canvas |
|||
* |
|||
* @return {Object} |
|||
* @private |
|||
* */ |
|||
buildContent: function(){ |
|||
return this.opt.content || {}; |
|||
}, |
|||
}); |
|||
}); |
|||
/** |
|||
* Trigger after insert |
|||
* @param {Object} model Model created after insert |
|||
* @private |
|||
* */ |
|||
afterInsert: function(model){}, |
|||
|
|||
/** |
|||
* Create different object, based on content, to insert inside canvas |
|||
* |
|||
* @return {Object} |
|||
* @private |
|||
* */ |
|||
buildContent: function(){ |
|||
return this.opt.content || {}; |
|||
}, |
|||
}); |
|||
|
|||
@ -1,151 +1,148 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var SelectComponent = require('./SelectComponent'); |
|||
var SelectPosition = require('./SelectPosition'); |
|||
|
|||
module.exports = _.extend({}, SelectPosition, SelectComponent, { |
|||
|
|||
init: function(o){ |
|||
SelectComponent.init.apply(this, arguments); |
|||
_.bindAll(this, 'initSorter','rollback', 'onEndMove'); |
|||
this.opt = o; |
|||
this.hoverClass = this.ppfx + 'highlighter-warning'; |
|||
this.badgeClass = this.ppfx + 'badge-warning'; |
|||
this.noSelClass = this.ppfx + 'no-select'; |
|||
}, |
|||
|
|||
enable: function() { |
|||
SelectComponent.enable.apply(this, arguments); |
|||
this.getBadgeEl().addClass(this.badgeClass); |
|||
this.getHighlighterEl().addClass(this.hoverClass); |
|||
var wp = this.$wrapper; |
|||
wp.css('cursor','move'); |
|||
wp.on('mousedown', this.initSorter); |
|||
|
|||
// Avoid strange moving behavior
|
|||
wp.addClass(this.noSelClass); |
|||
}, |
|||
|
|||
/** |
|||
* Overwrite for doing nothing |
|||
* @private |
|||
*/ |
|||
toggleClipboard: function(){}, |
|||
|
|||
/** |
|||
* Delegate sorting |
|||
* @param {Event} e |
|||
* @private |
|||
* */ |
|||
initSorter: function(e){ |
|||
var el = $(e.target).data('model'); |
|||
var drag = el.get('draggable'); |
|||
if(!drag) |
|||
return; |
|||
|
|||
// Avoid badge showing on move
|
|||
this.cacheEl = null; |
|||
this.startSelectPosition(e.target, this.frameEl.contentDocument); |
|||
this.sorter.draggable = drag; |
|||
this.sorter.onEndMove = this.onEndMove.bind(this); |
|||
this.stopSelectComponent(); |
|||
this.$wrapper.off('mousedown', this.initSorter); |
|||
this.getContentWindow().on('keydown', this.rollback); |
|||
}, |
|||
|
|||
/** |
|||
* Init sorter from model |
|||
* @param {Object} model |
|||
* @private |
|||
*/ |
|||
initSorterFromModel: function(model) { |
|||
var drag = model.get('draggable'); |
|||
if(!drag) |
|||
return; |
|||
// Avoid badge showing on move
|
|||
this.cacheEl = null; |
|||
var el = model.view.el; |
|||
this.startSelectPosition(el, this.frameEl.contentDocument); |
|||
this.sorter.draggable = drag; |
|||
this.sorter.onEndMove = this.onEndMoveFromModel.bind(this); |
|||
|
|||
/* |
|||
this.sorter.setDragHelper(el); |
|||
var dragHelper = this.sorter.dragHelper; |
|||
dragHelper.className = this.ppfx + 'drag-helper'; |
|||
dragHelper.innerHTML = ''; |
|||
dragHelper.backgroundColor = 'white'; |
|||
*/ |
|||
|
|||
this.stopSelectComponent(); |
|||
this.getContentWindow().on('keydown', this.rollback); |
|||
}, |
|||
|
|||
onEndMoveFromModel: function() { |
|||
this.getContentWindow().off('keydown', this.rollback); |
|||
}, |
|||
|
|||
/** |
|||
* Callback after sorting |
|||
* @private |
|||
*/ |
|||
onEndMove: function(){ |
|||
this.enable(); |
|||
this.getContentWindow().off('keydown', this.rollback); |
|||
}, |
|||
|
|||
/** |
|||
* Say what to do after the component was selected (selectComponent) |
|||
* @param {Event} e |
|||
* @param {Object} Selected element |
|||
* @private |
|||
* */ |
|||
onSelect: function(e,el){}, |
|||
|
|||
/** |
|||
* Used to bring the previous situation before start moving the component |
|||
* @param {Event} e |
|||
* @param {Boolean} Indicates if rollback in anycase |
|||
* @private |
|||
* */ |
|||
rollback: function(e, force){ |
|||
var key = e.which || e.keyCode; |
|||
if(key == this.opt.ESCAPE_KEY || force){ |
|||
this.sorter.moved = false; |
|||
this.sorter.endMove(); |
|||
} |
|||
return; |
|||
}, |
|||
|
|||
/** |
|||
* Returns badge element |
|||
* @return {HTMLElement} |
|||
* @private |
|||
*/ |
|||
getBadgeEl: function(){ |
|||
if(!this.$badge) |
|||
this.$badge = $(this.getBadge()); |
|||
return this.$badge; |
|||
}, |
|||
|
|||
/** |
|||
* Returns highlighter element |
|||
* @return {HTMLElement} |
|||
* @private |
|||
*/ |
|||
getHighlighterEl: function(){ |
|||
if(!this.$hl) |
|||
this.$hl = $(this.canvas.getHighlighter()); |
|||
return this.$hl; |
|||
}, |
|||
|
|||
stop: function(){ |
|||
SelectComponent.stop.apply(this, arguments); |
|||
this.getBadgeEl().removeClass(this.badgeClass); |
|||
this.getHighlighterEl().removeClass(this.hoverClass); |
|||
var wp = this.$wrapper; |
|||
wp.css('cursor', '').unbind().removeClass(this.noSelClass); |
|||
} |
|||
}); |
|||
}); |
|||
var Backbone = require('backbone'); |
|||
var SelectComponent = require('./SelectComponent'); |
|||
var SelectPosition = require('./SelectPosition'); |
|||
|
|||
module.exports = _.extend({}, SelectPosition, SelectComponent, { |
|||
|
|||
init: function(o){ |
|||
SelectComponent.init.apply(this, arguments); |
|||
_.bindAll(this, 'initSorter','rollback', 'onEndMove'); |
|||
this.opt = o; |
|||
this.hoverClass = this.ppfx + 'highlighter-warning'; |
|||
this.badgeClass = this.ppfx + 'badge-warning'; |
|||
this.noSelClass = this.ppfx + 'no-select'; |
|||
}, |
|||
|
|||
enable: function() { |
|||
SelectComponent.enable.apply(this, arguments); |
|||
this.getBadgeEl().addClass(this.badgeClass); |
|||
this.getHighlighterEl().addClass(this.hoverClass); |
|||
var wp = this.$wrapper; |
|||
wp.css('cursor','move'); |
|||
wp.on('mousedown', this.initSorter); |
|||
|
|||
// Avoid strange moving behavior
|
|||
wp.addClass(this.noSelClass); |
|||
}, |
|||
|
|||
/** |
|||
* Overwrite for doing nothing |
|||
* @private |
|||
*/ |
|||
toggleClipboard: function(){}, |
|||
|
|||
/** |
|||
* Delegate sorting |
|||
* @param {Event} e |
|||
* @private |
|||
* */ |
|||
initSorter: function(e){ |
|||
var el = $(e.target).data('model'); |
|||
var drag = el.get('draggable'); |
|||
if(!drag) |
|||
return; |
|||
|
|||
// Avoid badge showing on move
|
|||
this.cacheEl = null; |
|||
this.startSelectPosition(e.target, this.frameEl.contentDocument); |
|||
this.sorter.draggable = drag; |
|||
this.sorter.onEndMove = this.onEndMove.bind(this); |
|||
this.stopSelectComponent(); |
|||
this.$wrapper.off('mousedown', this.initSorter); |
|||
this.getContentWindow().on('keydown', this.rollback); |
|||
}, |
|||
|
|||
/** |
|||
* Init sorter from model |
|||
* @param {Object} model |
|||
* @private |
|||
*/ |
|||
initSorterFromModel: function(model) { |
|||
var drag = model.get('draggable'); |
|||
if(!drag) |
|||
return; |
|||
// Avoid badge showing on move
|
|||
this.cacheEl = null; |
|||
var el = model.view.el; |
|||
this.startSelectPosition(el, this.frameEl.contentDocument); |
|||
this.sorter.draggable = drag; |
|||
this.sorter.onEndMove = this.onEndMoveFromModel.bind(this); |
|||
|
|||
/* |
|||
this.sorter.setDragHelper(el); |
|||
var dragHelper = this.sorter.dragHelper; |
|||
dragHelper.className = this.ppfx + 'drag-helper'; |
|||
dragHelper.innerHTML = ''; |
|||
dragHelper.backgroundColor = 'white'; |
|||
*/ |
|||
|
|||
this.stopSelectComponent(); |
|||
this.getContentWindow().on('keydown', this.rollback); |
|||
}, |
|||
|
|||
onEndMoveFromModel: function() { |
|||
this.getContentWindow().off('keydown', this.rollback); |
|||
}, |
|||
|
|||
/** |
|||
* Callback after sorting |
|||
* @private |
|||
*/ |
|||
onEndMove: function(){ |
|||
this.enable(); |
|||
this.getContentWindow().off('keydown', this.rollback); |
|||
}, |
|||
|
|||
/** |
|||
* Say what to do after the component was selected (selectComponent) |
|||
* @param {Event} e |
|||
* @param {Object} Selected element |
|||
* @private |
|||
* */ |
|||
onSelect: function(e,el){}, |
|||
|
|||
/** |
|||
* Used to bring the previous situation before start moving the component |
|||
* @param {Event} e |
|||
* @param {Boolean} Indicates if rollback in anycase |
|||
* @private |
|||
* */ |
|||
rollback: function(e, force){ |
|||
var key = e.which || e.keyCode; |
|||
if(key == this.opt.ESCAPE_KEY || force){ |
|||
this.sorter.moved = false; |
|||
this.sorter.endMove(); |
|||
} |
|||
return; |
|||
}, |
|||
|
|||
/** |
|||
* Returns badge element |
|||
* @return {HTMLElement} |
|||
* @private |
|||
*/ |
|||
getBadgeEl: function(){ |
|||
if(!this.$badge) |
|||
this.$badge = $(this.getBadge()); |
|||
return this.$badge; |
|||
}, |
|||
|
|||
/** |
|||
* Returns highlighter element |
|||
* @return {HTMLElement} |
|||
* @private |
|||
*/ |
|||
getHighlighterEl: function(){ |
|||
if(!this.$hl) |
|||
this.$hl = $(this.canvas.getHighlighter()); |
|||
return this.$hl; |
|||
}, |
|||
|
|||
stop: function(){ |
|||
SelectComponent.stop.apply(this, arguments); |
|||
this.getBadgeEl().removeClass(this.badgeClass); |
|||
this.getHighlighterEl().removeClass(this.hoverClass); |
|||
var wp = this.$wrapper; |
|||
wp.css('cursor', '').unbind().removeClass(this.noSelClass); |
|||
} |
|||
}); |
|||
|
|||
@ -1,24 +1,21 @@ |
|||
define(function() { |
|||
module.exports = { |
|||
|
|||
return { |
|||
run: function(editor, sender, opts) { |
|||
var opt = opts || {}; |
|||
var config = editor.getConfig(); |
|||
var modal = editor.Modal; |
|||
var assetManager = editor.AssetManager; |
|||
|
|||
run: function(editor, sender, opts) { |
|||
var opt = opts || {}; |
|||
var config = editor.getConfig(); |
|||
var modal = editor.Modal; |
|||
var assetManager = editor.AssetManager; |
|||
assetManager.onClick(opt.onClick); |
|||
assetManager.onDblClick(opt.onDblClick); |
|||
|
|||
assetManager.onClick(opt.onClick); |
|||
assetManager.onDblClick(opt.onDblClick); |
|||
// old API
|
|||
assetManager.setTarget(opt.target); |
|||
assetManager.onSelect(opt.onSelect); |
|||
|
|||
// old API
|
|||
assetManager.setTarget(opt.target); |
|||
assetManager.onSelect(opt.onSelect); |
|||
modal.setTitle(opt.modalTitle || 'Select image'); |
|||
modal.setContent(assetManager.render()); |
|||
modal.open(); |
|||
}, |
|||
|
|||
modal.setTitle(opt.modalTitle || 'Select image'); |
|||
modal.setContent(assetManager.render()); |
|||
modal.open(); |
|||
}, |
|||
|
|||
}; |
|||
}); |
|||
}; |
|||
|
|||
@ -1,29 +1,26 @@ |
|||
define(function() { |
|||
module.exports = { |
|||
|
|||
return { |
|||
run: function(editor, sender) { |
|||
var config = editor.Config; |
|||
var pfx = config.stylePrefix; |
|||
var bm = editor.BlockManager; |
|||
var panelC; |
|||
if(!this.blocks){ |
|||
this.blocks = $('<div/>').get(0); |
|||
this.blocks.appendChild(bm.render()); |
|||
var panels = editor.Panels; |
|||
if(!panels.getPanel('views-container')) |
|||
panelC = panels.addPanel({id: 'views-container'}); |
|||
else |
|||
panelC = panels.getPanel('views-container'); |
|||
panelC.set('appendContent', this.blocks).trigger('change:appendContent'); |
|||
} |
|||
|
|||
run: function(editor, sender) { |
|||
var config = editor.Config; |
|||
var pfx = config.stylePrefix; |
|||
var bm = editor.BlockManager; |
|||
var panelC; |
|||
if(!this.blocks){ |
|||
this.blocks = $('<div/>').get(0); |
|||
this.blocks.appendChild(bm.render()); |
|||
var panels = editor.Panels; |
|||
if(!panels.getPanel('views-container')) |
|||
panelC = panels.addPanel({id: 'views-container'}); |
|||
else |
|||
panelC = panels.getPanel('views-container'); |
|||
panelC.set('appendContent', this.blocks).trigger('change:appendContent'); |
|||
} |
|||
this.blocks.style.display = 'block'; |
|||
}, |
|||
|
|||
this.blocks.style.display = 'block'; |
|||
}, |
|||
|
|||
stop: function() { |
|||
if(this.blocks) |
|||
this.blocks.style.display = 'none'; |
|||
} |
|||
}; |
|||
}); |
|||
stop: function() { |
|||
if(this.blocks) |
|||
this.blocks.style.display = 'none'; |
|||
} |
|||
}; |
|||
|
|||
@ -1,40 +1,34 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Layers = require('Navigator'); |
|||
/** |
|||
* @class OpenStyleManager |
|||
* @private |
|||
* */ |
|||
module.exports = { |
|||
var Layers = require('Navigator'); |
|||
|
|||
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-'; |
|||
module.exports = { |
|||
|
|||
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(); |
|||
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-'; |
|||
|
|||
// 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'); |
|||
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(); |
|||
|
|||
this.panel.set('appendContent', this.$layers).trigger('change:appendContent'); |
|||
} |
|||
this.$layers.show(); |
|||
}, |
|||
// 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'); |
|||
|
|||
stop: function() { |
|||
if(this.$layers) |
|||
this.$layers.hide(); |
|||
this.panel.set('appendContent', this.$layers).trigger('change:appendContent'); |
|||
} |
|||
}; |
|||
}); |
|||
this.$layers.show(); |
|||
}, |
|||
|
|||
stop: function() { |
|||
if(this.$layers) |
|||
this.$layers.hide(); |
|||
} |
|||
}; |
|||
|
|||
@ -1,84 +1,78 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var StyleManager = require('StyleManager'); |
|||
/** |
|||
* @class OpenStyleManager |
|||
* @private |
|||
* */ |
|||
module.exports = { |
|||
var StyleManager = require('StyleManager'); |
|||
|
|||
run: function(em, sender) { |
|||
this.sender = sender; |
|||
if(!this.$cn){ |
|||
var config = em.getConfig(), |
|||
panels = em.Panels; |
|||
// Main container
|
|||
this.$cn = $('<div/>'); |
|||
// Secondary container
|
|||
this.$cn2 = $('<div/>'); |
|||
this.$cn.append(this.$cn2); |
|||
module.exports = { |
|||
|
|||
// Device Manager
|
|||
var dvm = em.DeviceManager; |
|||
if(dvm && config.showDevices){ |
|||
var devicePanel = panels.addPanel({ id: 'devices-c'}); |
|||
devicePanel.set('appendContent', dvm.render()).trigger('change:appendContent'); |
|||
} |
|||
run: function(em, sender) { |
|||
this.sender = sender; |
|||
if(!this.$cn){ |
|||
var config = em.getConfig(), |
|||
panels = em.Panels; |
|||
// Main container
|
|||
this.$cn = $('<div/>'); |
|||
// Secondary container
|
|||
this.$cn2 = $('<div/>'); |
|||
this.$cn.append(this.$cn2); |
|||
|
|||
// Class Manager container
|
|||
var clm = em.SelectorManager; |
|||
if(clm) |
|||
this.$cn2.append(clm.render([])); |
|||
// Device Manager
|
|||
var dvm = em.DeviceManager; |
|||
if(dvm && config.showDevices){ |
|||
var devicePanel = panels.addPanel({ id: 'devices-c'}); |
|||
devicePanel.set('appendContent', dvm.render()).trigger('change:appendContent'); |
|||
} |
|||
|
|||
this.$cn2.append(em.StyleManager.render()); |
|||
var smConfig = em.StyleManager.getConfig(); |
|||
// Create header
|
|||
this.$header = $('<div>', { |
|||
class: smConfig.stylePrefix + 'header', |
|||
text: smConfig.textNoElement, |
|||
}); |
|||
//this.$cn = this.$cn.add(this.$header);
|
|||
this.$cn.append(this.$header); |
|||
// Class Manager container
|
|||
var clm = em.SelectorManager; |
|||
if(clm) |
|||
this.$cn2.append(clm.render([])); |
|||
|
|||
// Create panel if not exists
|
|||
if(!panels.getPanel('views-container')) |
|||
this.panel = panels.addPanel({ id: 'views-container'}); |
|||
else |
|||
this.panel = panels.getPanel('views-container'); |
|||
this.$cn2.append(em.StyleManager.render()); |
|||
var smConfig = em.StyleManager.getConfig(); |
|||
// Create header
|
|||
this.$header = $('<div>', { |
|||
class: smConfig.stylePrefix + 'header', |
|||
text: smConfig.textNoElement, |
|||
}); |
|||
//this.$cn = this.$cn.add(this.$header);
|
|||
this.$cn.append(this.$header); |
|||
|
|||
// Add all containers to the panel
|
|||
this.panel.set('appendContent', this.$cn).trigger('change:appendContent'); |
|||
// Create panel if not exists
|
|||
if(!panels.getPanel('views-container')) |
|||
this.panel = panels.addPanel({ id: 'views-container'}); |
|||
else |
|||
this.panel = panels.getPanel('views-container'); |
|||
|
|||
this.target = em.editor; |
|||
this.listenTo( this.target ,'change:selectedComponent', this.toggleSm); |
|||
} |
|||
this.toggleSm(); |
|||
}, |
|||
// Add all containers to the panel
|
|||
this.panel.set('appendContent', this.$cn).trigger('change:appendContent'); |
|||
|
|||
/** |
|||
* Toggle Style Manager visibility |
|||
* @private |
|||
*/ |
|||
toggleSm: function() { |
|||
if(!this.sender.get('active')) |
|||
return; |
|||
if(this.target.get('selectedComponent')){ |
|||
this.$cn2.show(); |
|||
this.$header.hide(); |
|||
}else{ |
|||
this.$cn2.hide(); |
|||
this.$header.show(); |
|||
} |
|||
}, |
|||
this.target = em.editor; |
|||
this.listenTo( this.target ,'change:selectedComponent', this.toggleSm); |
|||
} |
|||
this.toggleSm(); |
|||
}, |
|||
|
|||
stop: function() { |
|||
// Hide secondary container if exists
|
|||
if(this.$cn2) |
|||
this.$cn2.hide(); |
|||
/** |
|||
* Toggle Style Manager visibility |
|||
* @private |
|||
*/ |
|||
toggleSm: function() { |
|||
if(!this.sender.get('active')) |
|||
return; |
|||
if(this.target.get('selectedComponent')){ |
|||
this.$cn2.show(); |
|||
this.$header.hide(); |
|||
}else{ |
|||
this.$cn2.hide(); |
|||
this.$header.show(); |
|||
} |
|||
}, |
|||
|
|||
// Hide header container if exists
|
|||
if(this.$header) |
|||
this.$header.hide(); |
|||
} |
|||
}; |
|||
}); |
|||
stop: function() { |
|||
// Hide secondary container if exists
|
|||
if(this.$cn2) |
|||
this.$cn2.hide(); |
|||
|
|||
// Hide header container if exists
|
|||
if(this.$header) |
|||
this.$header.hide(); |
|||
} |
|||
}; |
|||
|
|||
@ -1,33 +1,30 @@ |
|||
define(function() { |
|||
module.exports = { |
|||
|
|||
return { |
|||
run: function(editor, sender) { |
|||
var config = editor.Config; |
|||
var pfx = config.stylePrefix; |
|||
var tm = editor.TraitManager; |
|||
var panelC; |
|||
if(!this.obj){ |
|||
var tmView = tm.getTraitsViewer(); |
|||
var confTm = tm.getConfig(); |
|||
this.obj = $('<div/>') |
|||
.append('<div class="'+pfx+'traits-label">' + confTm.labelContainer + '</div>') |
|||
.get(0); |
|||
this.obj.appendChild(tmView.render().el); |
|||
var panels = editor.Panels; |
|||
if(!panels.getPanel('views-container')) |
|||
panelC = panels.addPanel({id: 'views-container'}); |
|||
else |
|||
panelC = panels.getPanel('views-container'); |
|||
panelC.set('appendContent', this.obj).trigger('change:appendContent'); |
|||
} |
|||
|
|||
run: function(editor, sender) { |
|||
var config = editor.Config; |
|||
var pfx = config.stylePrefix; |
|||
var tm = editor.TraitManager; |
|||
var panelC; |
|||
if(!this.obj){ |
|||
var tmView = tm.getTraitsViewer(); |
|||
var confTm = tm.getConfig(); |
|||
this.obj = $('<div/>') |
|||
.append('<div class="'+pfx+'traits-label">' + confTm.labelContainer + '</div>') |
|||
.get(0); |
|||
this.obj.appendChild(tmView.render().el); |
|||
var panels = editor.Panels; |
|||
if(!panels.getPanel('views-container')) |
|||
panelC = panels.addPanel({id: 'views-container'}); |
|||
else |
|||
panelC = panels.getPanel('views-container'); |
|||
panelC.set('appendContent', this.obj).trigger('change:appendContent'); |
|||
} |
|||
this.obj.style.display = 'block'; |
|||
}, |
|||
|
|||
this.obj.style.display = 'block'; |
|||
}, |
|||
|
|||
stop: function() { |
|||
if(this.obj) |
|||
this.obj.style.display = 'none'; |
|||
} |
|||
}; |
|||
}); |
|||
stop: function() { |
|||
if(this.obj) |
|||
this.obj.style.display = 'none'; |
|||
} |
|||
}; |
|||
|
|||
@ -1,68 +1,65 @@ |
|||
define(function() { |
|||
module.exports = { |
|||
|
|||
return { |
|||
getPanels: function(editor){ |
|||
if(!this.panels) |
|||
this.panels = editor.Panels.getPanelsEl(); |
|||
return this.panels; |
|||
}, |
|||
|
|||
getPanels: function(editor){ |
|||
if(!this.panels) |
|||
this.panels = editor.Panels.getPanelsEl(); |
|||
return this.panels; |
|||
}, |
|||
tglPointers: function(editor, v) { |
|||
var elP = editor.Canvas.getBody().querySelectorAll('.' + this.ppfx + 'no-pointer'); |
|||
_.each(elP, function(item){ |
|||
item.style.pointerEvents = v ? '' : 'all'; |
|||
}); |
|||
}, |
|||
|
|||
tglPointers: function(editor, v) { |
|||
var elP = editor.Canvas.getBody().querySelectorAll('.' + this.ppfx + 'no-pointer'); |
|||
_.each(elP, function(item){ |
|||
item.style.pointerEvents = v ? '' : 'all'; |
|||
}); |
|||
}, |
|||
run: function(editor, sender) { |
|||
if(sender && sender.set) |
|||
sender.set('active', false); |
|||
editor.stopCommand('sw-visibility'); |
|||
var that = this; |
|||
var panels = this.getPanels(editor); |
|||
var canvas = editor.Canvas.getElement(); |
|||
var editorEl = editor.getEl(); |
|||
var pfx = editor.Config.stylePrefix; |
|||
if(!this.helper) { |
|||
this.helper = document.createElement('span'); |
|||
this.helper.className = pfx + 'off-prv fa fa-eye-slash'; |
|||
editorEl.appendChild(this.helper); |
|||
this.helper.onclick = function(){ |
|||
that.stop(editor); |
|||
}; |
|||
} |
|||
this.helper.style.display = 'inline-block'; |
|||
this.tglPointers(editor); |
|||
|
|||
run: function(editor, sender) { |
|||
if(sender && sender.set) |
|||
sender.set('active', false); |
|||
editor.stopCommand('sw-visibility'); |
|||
var that = this; |
|||
var panels = this.getPanels(editor); |
|||
var canvas = editor.Canvas.getElement(); |
|||
var editorEl = editor.getEl(); |
|||
var pfx = editor.Config.stylePrefix; |
|||
if(!this.helper) { |
|||
this.helper = document.createElement('span'); |
|||
this.helper.className = pfx + 'off-prv fa fa-eye-slash'; |
|||
editorEl.appendChild(this.helper); |
|||
this.helper.onclick = function(){ |
|||
that.stop(editor); |
|||
}; |
|||
} |
|||
this.helper.style.display = 'inline-block'; |
|||
this.tglPointers(editor); |
|||
/* |
|||
editor.Canvas.getBody().querySelectorAll('.' + pfx + 'no-pointer').forEach(function(){ |
|||
this.style.pointerEvents = 'all'; |
|||
});*/ |
|||
|
|||
/* |
|||
editor.Canvas.getBody().querySelectorAll('.' + pfx + 'no-pointer').forEach(function(){ |
|||
this.style.pointerEvents = 'all'; |
|||
});*/ |
|||
panels.style.display = 'none'; |
|||
var canvasS = canvas.style; |
|||
canvasS.width = '100%'; |
|||
canvasS.height = '100%'; |
|||
canvasS.top = '0'; |
|||
canvasS.left = '0'; |
|||
canvasS.padding = '0'; |
|||
canvasS.margin = '0'; |
|||
editor.trigger('change:canvasOffset'); |
|||
}, |
|||
|
|||
panels.style.display = 'none'; |
|||
var canvasS = canvas.style; |
|||
canvasS.width = '100%'; |
|||
canvasS.height = '100%'; |
|||
canvasS.top = '0'; |
|||
canvasS.left = '0'; |
|||
canvasS.padding = '0'; |
|||
canvasS.margin = '0'; |
|||
editor.trigger('change:canvasOffset'); |
|||
}, |
|||
|
|||
stop: function(editor, sender) { |
|||
var panels = this.getPanels(editor); |
|||
editor.runCommand('sw-visibility'); |
|||
editor.getModel().runDefault(); |
|||
panels.style.display = 'block'; |
|||
var canvas = editor.Canvas.getElement(); |
|||
canvas.setAttribute('style', ''); |
|||
if(this.helper) { |
|||
this.helper.style.display = 'none'; |
|||
} |
|||
editor.trigger('change:canvasOffset'); |
|||
this.tglPointers(editor, 1); |
|||
} |
|||
}; |
|||
}); |
|||
stop: function(editor, sender) { |
|||
var panels = this.getPanels(editor); |
|||
editor.runCommand('sw-visibility'); |
|||
editor.getModel().runDefault(); |
|||
panels.style.display = 'block'; |
|||
var canvas = editor.Canvas.getElement(); |
|||
canvas.setAttribute('style', ''); |
|||
if(this.helper) { |
|||
this.helper.style.display = 'none'; |
|||
} |
|||
editor.trigger('change:canvasOffset'); |
|||
this.tglPointers(editor, 1); |
|||
} |
|||
}; |
|||
|
|||
@ -1,32 +1,30 @@ |
|||
define(function() { |
|||
return { |
|||
module.exports = { |
|||
|
|||
run: function(editor, sender, opts) { |
|||
var el = (opts && opts.el) || ''; |
|||
var canvas = editor.Canvas; |
|||
var canvasResizer = this.canvasResizer; |
|||
var options = opts.options || {}; |
|||
run: function(editor, sender, opts) { |
|||
var el = (opts && opts.el) || ''; |
|||
var canvas = editor.Canvas; |
|||
var canvasResizer = this.canvasResizer; |
|||
var options = opts.options || {}; |
|||
|
|||
// Create the resizer for the canvas if not yet created
|
|||
if(!canvasResizer) { |
|||
var canvasView = canvas.getCanvasView(); |
|||
options.ratioDefault = 1; |
|||
options.appendTo = canvas.getResizerEl(); |
|||
options.prefix = editor.getConfig().stylePrefix; |
|||
options.posFetcher = canvasView.getElementPos.bind(canvasView); |
|||
options.mousePosFetcher = canvas.getMouseRelativePos; |
|||
this.canvasResizer = editor.Utils.Resizer.init(options); |
|||
canvasResizer = this.canvasResizer; |
|||
} |
|||
// Create the resizer for the canvas if not yet created
|
|||
if(!canvasResizer) { |
|||
var canvasView = canvas.getCanvasView(); |
|||
options.ratioDefault = 1; |
|||
options.appendTo = canvas.getResizerEl(); |
|||
options.prefix = editor.getConfig().stylePrefix; |
|||
options.posFetcher = canvasView.getElementPos.bind(canvasView); |
|||
options.mousePosFetcher = canvas.getMouseRelativePos; |
|||
this.canvasResizer = editor.Utils.Resizer.init(options); |
|||
canvasResizer = this.canvasResizer; |
|||
} |
|||
|
|||
canvasResizer.setOptions(options); |
|||
canvasResizer.focus(el); |
|||
}, |
|||
canvasResizer.setOptions(options); |
|||
canvasResizer.focus(el); |
|||
}, |
|||
|
|||
stop: function() { |
|||
if(this.canvasResizer) |
|||
this.canvasResizer.blur(); |
|||
}, |
|||
stop: function() { |
|||
if(this.canvasResizer) |
|||
this.canvasResizer.blur(); |
|||
}, |
|||
|
|||
}; |
|||
}); |
|||
}; |
|||
|
|||
File diff suppressed because it is too large
@ -1,103 +1,100 @@ |
|||
define(function() { |
|||
module.exports = { |
|||
|
|||
return { |
|||
/** |
|||
* Start select position event |
|||
* @param {HTMLElement} trg |
|||
* @private |
|||
* */ |
|||
startSelectPosition: function(trg, doc) { |
|||
this.isPointed = false; |
|||
var utils = this.editorModel.get('Utils'); |
|||
if(utils && !this.sorter) |
|||
this.sorter = new utils.Sorter({ |
|||
container: this.getCanvasBody(), |
|||
placer: this.canvas.getPlacerEl(), |
|||
containerSel: '*', |
|||
itemSel: '*', |
|||
pfx: this.ppfx, |
|||
direction: 'a', |
|||
document: doc, |
|||
wmargin: 1, |
|||
nested: 1, |
|||
em: this.editorModel, |
|||
canvasRelative: 1, |
|||
}); |
|||
this.sorter.startSort(trg); |
|||
}, |
|||
|
|||
/** |
|||
* Start select position event |
|||
* @param {HTMLElement} trg |
|||
* @private |
|||
* */ |
|||
startSelectPosition: function(trg, doc) { |
|||
this.isPointed = false; |
|||
var utils = this.editorModel.get('Utils'); |
|||
if(utils && !this.sorter) |
|||
this.sorter = new utils.Sorter({ |
|||
container: this.getCanvasBody(), |
|||
placer: this.canvas.getPlacerEl(), |
|||
containerSel: '*', |
|||
itemSel: '*', |
|||
pfx: this.ppfx, |
|||
direction: 'a', |
|||
document: doc, |
|||
wmargin: 1, |
|||
nested: 1, |
|||
em: this.editorModel, |
|||
canvasRelative: 1, |
|||
}); |
|||
this.sorter.startSort(trg); |
|||
}, |
|||
/** |
|||
* Get frame position |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getOffsetDim: function() { |
|||
var frameOff = this.offset(this.canvas.getFrameEl()); |
|||
var canvasOff = this.offset(this.canvas.getElement()); |
|||
var top = frameOff.top - canvasOff.top; |
|||
var left = frameOff.left - canvasOff.left; |
|||
return { top: top, left: left }; |
|||
}, |
|||
|
|||
/** |
|||
* Get frame position |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getOffsetDim: function() { |
|||
var frameOff = this.offset(this.canvas.getFrameEl()); |
|||
var canvasOff = this.offset(this.canvas.getElement()); |
|||
var top = frameOff.top - canvasOff.top; |
|||
var left = frameOff.left - canvasOff.left; |
|||
return { top: top, left: left }; |
|||
}, |
|||
/** |
|||
* Stop select position event |
|||
* @private |
|||
* */ |
|||
stopSelectPosition: function() { |
|||
this.posTargetCollection = null; |
|||
this.posIndex = this.posMethod=='after' && this.cDim.length!==0 ? this.posIndex + 1 : this.posIndex; //Normalize
|
|||
if(this.sorter){ |
|||
this.sorter.moved = 0; |
|||
this.sorter.endMove(); |
|||
} |
|||
if(this.cDim){ |
|||
this.posIsLastEl = this.cDim.length!==0 && this.posMethod=='after' && this.posIndex==this.cDim.length; |
|||
this.posTargetEl = (this.cDim.length===0 ? $(this.outsideElem) : |
|||
(!this.posIsLastEl && this.cDim[this.posIndex] ? $(this.cDim[this.posIndex][5]).parent() : $(this.outsideElem) )); |
|||
this.posTargetModel = this.posTargetEl.data("model"); |
|||
this.posTargetCollection = this.posTargetEl.data("model-comp"); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Stop select position event |
|||
* @private |
|||
* */ |
|||
stopSelectPosition: function() { |
|||
this.posTargetCollection = null; |
|||
this.posIndex = this.posMethod=='after' && this.cDim.length!==0 ? this.posIndex + 1 : this.posIndex; //Normalize
|
|||
if(this.sorter){ |
|||
this.sorter.moved = 0; |
|||
this.sorter.endMove(); |
|||
} |
|||
if(this.cDim){ |
|||
this.posIsLastEl = this.cDim.length!==0 && this.posMethod=='after' && this.posIndex==this.cDim.length; |
|||
this.posTargetEl = (this.cDim.length===0 ? $(this.outsideElem) : |
|||
(!this.posIsLastEl && this.cDim[this.posIndex] ? $(this.cDim[this.posIndex][5]).parent() : $(this.outsideElem) )); |
|||
this.posTargetModel = this.posTargetEl.data("model"); |
|||
this.posTargetCollection = this.posTargetEl.data("model-comp"); |
|||
} |
|||
}, |
|||
/** |
|||
* Enabel select position |
|||
* @private |
|||
*/ |
|||
enable: function() { |
|||
this.startSelectPosition(); |
|||
}, |
|||
|
|||
/** |
|||
* Enabel select position |
|||
* @private |
|||
*/ |
|||
enable: function() { |
|||
this.startSelectPosition(); |
|||
}, |
|||
/** |
|||
* Check if the pointer is near to the float component |
|||
* @param {number} index |
|||
* @param {string} method |
|||
* @param {Array<Array>} dims |
|||
* @return {Boolean} |
|||
* @private |
|||
* */ |
|||
nearFloat: function(index, method, dims) { |
|||
var i = index || 0; |
|||
var m = method || 'before'; |
|||
var len = dims.length; |
|||
var isLast = len !== 0 && m == 'after' && i == len; |
|||
if(len !== 0 && ( |
|||
(!isLast && !dims[i][4]) || |
|||
(dims[i-1] && !dims[i-1][4]) || |
|||
(isLast && !dims[i-1][4]) ) ) |
|||
return 1; |
|||
return 0; |
|||
}, |
|||
|
|||
/** |
|||
* Check if the pointer is near to the float component |
|||
* @param {number} index |
|||
* @param {string} method |
|||
* @param {Array<Array>} dims |
|||
* @return {Boolean} |
|||
* @private |
|||
* */ |
|||
nearFloat: function(index, method, dims) { |
|||
var i = index || 0; |
|||
var m = method || 'before'; |
|||
var len = dims.length; |
|||
var isLast = len !== 0 && m == 'after' && i == len; |
|||
if(len !== 0 && ( |
|||
(!isLast && !dims[i][4]) || |
|||
(dims[i-1] && !dims[i-1][4]) || |
|||
(isLast && !dims[i-1][4]) ) ) |
|||
return 1; |
|||
return 0; |
|||
}, |
|||
|
|||
run: function() { |
|||
this.enable(); |
|||
}, |
|||
|
|||
run: function() { |
|||
this.enable(); |
|||
}, |
|||
|
|||
stop: function() { |
|||
this.stopSelectPosition(); |
|||
this.$wrapper.css('cursor',''); |
|||
this.$wrapper.unbind(); |
|||
} |
|||
}; |
|||
}); |
|||
stop: function() { |
|||
this.stopSelectPosition(); |
|||
this.$wrapper.css('cursor',''); |
|||
this.$wrapper.unbind(); |
|||
} |
|||
}; |
|||
|
|||
@ -1,149 +1,147 @@ |
|||
define(function() { |
|||
return { |
|||
|
|||
getOffsetMethod: function(state) { |
|||
var method = state || ''; |
|||
return 'get' + method + 'OffsetViewerEl'; |
|||
}, |
|||
|
|||
run: function(editor, sender, opts) { |
|||
var opt = opts || {}; |
|||
var state = opt.state || ''; |
|||
var config = editor.getConfig(); |
|||
|
|||
if (!config.showOffsets || |
|||
(!config.showOffsetsSelected && state == 'Fixed') ) { |
|||
return; |
|||
} |
|||
|
|||
var canvas = editor.Canvas; |
|||
var el = opt.el || ''; |
|||
var pos = opt.elPos || canvas.getElementPos(el); |
|||
var style = window.getComputedStyle(el); |
|||
var ppfx = this.ppfx; |
|||
var stateVar = state + 'State'; |
|||
var method = this.getOffsetMethod(state); |
|||
var offsetViewer = canvas[method](); |
|||
offsetViewer.style.display = 'block'; |
|||
|
|||
var marginT = this['marginT' + state]; |
|||
var marginB = this['marginB' + state]; |
|||
var marginL = this['marginL' + state]; |
|||
var marginR = this['marginR' + state]; |
|||
var padT = this['padT' + state]; |
|||
var padB = this['padB' + state]; |
|||
var padL = this['padL' + state]; |
|||
var padR = this['padR' + state]; |
|||
|
|||
if(!this[stateVar]) { |
|||
var stateLow = state.toLowerCase(); |
|||
var marginName = stateLow + 'margin-v'; |
|||
var paddingName = stateLow + 'padding-v'; |
|||
var marginV = $('<div>', {class: ppfx + marginName}).get(0); |
|||
var paddingV = $('<div>', {class: ppfx + paddingName}).get(0); |
|||
var marginEls = ppfx + marginName + '-el'; |
|||
var paddingEls = ppfx + paddingName + '-el'; |
|||
marginT = $('<div>', {class: ppfx + marginName + '-top ' + marginEls}).get(0); |
|||
marginB = $('<div>', {class: ppfx + marginName + '-bottom ' + marginEls}).get(0); |
|||
marginL = $('<div>', {class: ppfx + marginName + '-left ' + marginEls}).get(0); |
|||
marginR = $('<div>', {class: ppfx + marginName + '-right ' + marginEls}).get(0); |
|||
padT = $('<div>', {class: ppfx + paddingName + '-top ' + paddingEls}).get(0); |
|||
padB = $('<div>', {class: ppfx + paddingName + '-bottom ' + paddingEls}).get(0); |
|||
padL = $('<div>', {class: ppfx + paddingName + '-left ' + paddingEls}).get(0); |
|||
padR = $('<div>', {class: ppfx + paddingName + '-right ' + paddingEls}).get(0); |
|||
this['marginT' + state] = marginT; |
|||
this['marginB' + state] = marginB; |
|||
this['marginL' + state] = marginL; |
|||
this['marginR' + state] = marginR; |
|||
this['padT' + state] = padT; |
|||
this['padB' + state] = padB; |
|||
this['padL' + state] = padL; |
|||
this['padR' + state] = padR; |
|||
marginV.appendChild(marginT); |
|||
marginV.appendChild(marginB); |
|||
marginV.appendChild(marginL); |
|||
marginV.appendChild(marginR); |
|||
paddingV.appendChild(padT); |
|||
paddingV.appendChild(padB); |
|||
paddingV.appendChild(padL); |
|||
paddingV.appendChild(padR); |
|||
offsetViewer.appendChild(marginV); |
|||
offsetViewer.appendChild(paddingV); |
|||
this[stateVar] = '1'; |
|||
} |
|||
|
|||
var unit = 'px'; |
|||
var marginLeftSt = style.marginLeft.replace(unit, ''); |
|||
var marginTopSt = parseInt(style.marginTop.replace(unit, '')); |
|||
var marginBottomSt = parseInt(style.marginBottom.replace(unit, '')); |
|||
var mtStyle = marginT.style; |
|||
var mbStyle = marginB.style; |
|||
var mlStyle = marginL.style; |
|||
var mrStyle = marginR.style; |
|||
var ptStyle = padT.style; |
|||
var pbStyle = padB.style; |
|||
var plStyle = padL.style; |
|||
var prStyle = padR.style; |
|||
var posLeft = parseInt(pos.left); |
|||
|
|||
// Margin style
|
|||
mtStyle.height = style.marginTop; |
|||
mtStyle.width = style.width; |
|||
mtStyle.top = pos.top - style.marginTop.replace(unit, '') + unit; |
|||
mtStyle.left = posLeft + unit; |
|||
|
|||
mbStyle.height = style.marginBottom; |
|||
mbStyle.width = style.width; |
|||
mbStyle.top = pos.top + pos.height + unit; |
|||
mbStyle.left = posLeft + unit; |
|||
|
|||
var marginSideH = pos.height + marginTopSt + marginBottomSt + unit; |
|||
var marginSideT = pos.top - marginTopSt + unit; |
|||
mlStyle.height = marginSideH; |
|||
mlStyle.width = style.marginLeft; |
|||
mlStyle.top = marginSideT; |
|||
mlStyle.left = posLeft - marginLeftSt + unit; |
|||
|
|||
mrStyle.height = marginSideH; |
|||
mrStyle.width = style.marginRight; |
|||
mrStyle.top = marginSideT; |
|||
mrStyle.left = posLeft + pos.width + unit; |
|||
|
|||
// Padding style
|
|||
var padTop = parseInt(style.paddingTop.replace(unit, '')); |
|||
ptStyle.height = style.paddingTop; |
|||
ptStyle.width = style.width; |
|||
ptStyle.top = pos.top + unit; |
|||
ptStyle.left = posLeft + unit; |
|||
|
|||
var padBot = parseInt(style.paddingBottom.replace(unit, '')); |
|||
pbStyle.height = style.paddingBottom; |
|||
pbStyle.width = style.width; |
|||
pbStyle.top = pos.top + pos.height - padBot + unit; |
|||
pbStyle.left = posLeft + unit; |
|||
|
|||
var padSideH = (pos.height - padBot - padTop) + unit; |
|||
var padSideT = pos.top + padTop + unit; |
|||
plStyle.height = padSideH; |
|||
plStyle.width = style.paddingLeft; |
|||
plStyle.top = padSideT; |
|||
plStyle.left = pos.left + unit; |
|||
|
|||
var padRight = parseInt(style.paddingRight.replace(unit, '')); |
|||
prStyle.height = padSideH; |
|||
prStyle.width = style.paddingRight; |
|||
prStyle.top = padSideT; |
|||
prStyle.left = pos.left + pos.width - padRight + unit; |
|||
}, |
|||
|
|||
stop: function(editor, sender, opts) { |
|||
var opt = opts || {}; |
|||
var state = opt.state || ''; |
|||
var method = this.getOffsetMethod(state); |
|||
var canvas = editor.Canvas; |
|||
var offsetViewer = canvas[method](); |
|||
offsetViewer.style.display = 'none'; |
|||
}, |
|||
|
|||
}; |
|||
}); |
|||
module.exports = { |
|||
|
|||
getOffsetMethod: function(state) { |
|||
var method = state || ''; |
|||
return 'get' + method + 'OffsetViewerEl'; |
|||
}, |
|||
|
|||
run: function(editor, sender, opts) { |
|||
var opt = opts || {}; |
|||
var state = opt.state || ''; |
|||
var config = editor.getConfig(); |
|||
|
|||
if (!config.showOffsets || |
|||
(!config.showOffsetsSelected && state == 'Fixed') ) { |
|||
return; |
|||
} |
|||
|
|||
var canvas = editor.Canvas; |
|||
var el = opt.el || ''; |
|||
var pos = opt.elPos || canvas.getElementPos(el); |
|||
var style = window.getComputedStyle(el); |
|||
var ppfx = this.ppfx; |
|||
var stateVar = state + 'State'; |
|||
var method = this.getOffsetMethod(state); |
|||
var offsetViewer = canvas[method](); |
|||
offsetViewer.style.display = 'block'; |
|||
|
|||
var marginT = this['marginT' + state]; |
|||
var marginB = this['marginB' + state]; |
|||
var marginL = this['marginL' + state]; |
|||
var marginR = this['marginR' + state]; |
|||
var padT = this['padT' + state]; |
|||
var padB = this['padB' + state]; |
|||
var padL = this['padL' + state]; |
|||
var padR = this['padR' + state]; |
|||
|
|||
if(!this[stateVar]) { |
|||
var stateLow = state.toLowerCase(); |
|||
var marginName = stateLow + 'margin-v'; |
|||
var paddingName = stateLow + 'padding-v'; |
|||
var marginV = $('<div>', {class: ppfx + marginName}).get(0); |
|||
var paddingV = $('<div>', {class: ppfx + paddingName}).get(0); |
|||
var marginEls = ppfx + marginName + '-el'; |
|||
var paddingEls = ppfx + paddingName + '-el'; |
|||
marginT = $('<div>', {class: ppfx + marginName + '-top ' + marginEls}).get(0); |
|||
marginB = $('<div>', {class: ppfx + marginName + '-bottom ' + marginEls}).get(0); |
|||
marginL = $('<div>', {class: ppfx + marginName + '-left ' + marginEls}).get(0); |
|||
marginR = $('<div>', {class: ppfx + marginName + '-right ' + marginEls}).get(0); |
|||
padT = $('<div>', {class: ppfx + paddingName + '-top ' + paddingEls}).get(0); |
|||
padB = $('<div>', {class: ppfx + paddingName + '-bottom ' + paddingEls}).get(0); |
|||
padL = $('<div>', {class: ppfx + paddingName + '-left ' + paddingEls}).get(0); |
|||
padR = $('<div>', {class: ppfx + paddingName + '-right ' + paddingEls}).get(0); |
|||
this['marginT' + state] = marginT; |
|||
this['marginB' + state] = marginB; |
|||
this['marginL' + state] = marginL; |
|||
this['marginR' + state] = marginR; |
|||
this['padT' + state] = padT; |
|||
this['padB' + state] = padB; |
|||
this['padL' + state] = padL; |
|||
this['padR' + state] = padR; |
|||
marginV.appendChild(marginT); |
|||
marginV.appendChild(marginB); |
|||
marginV.appendChild(marginL); |
|||
marginV.appendChild(marginR); |
|||
paddingV.appendChild(padT); |
|||
paddingV.appendChild(padB); |
|||
paddingV.appendChild(padL); |
|||
paddingV.appendChild(padR); |
|||
offsetViewer.appendChild(marginV); |
|||
offsetViewer.appendChild(paddingV); |
|||
this[stateVar] = '1'; |
|||
} |
|||
|
|||
var unit = 'px'; |
|||
var marginLeftSt = style.marginLeft.replace(unit, ''); |
|||
var marginTopSt = parseInt(style.marginTop.replace(unit, '')); |
|||
var marginBottomSt = parseInt(style.marginBottom.replace(unit, '')); |
|||
var mtStyle = marginT.style; |
|||
var mbStyle = marginB.style; |
|||
var mlStyle = marginL.style; |
|||
var mrStyle = marginR.style; |
|||
var ptStyle = padT.style; |
|||
var pbStyle = padB.style; |
|||
var plStyle = padL.style; |
|||
var prStyle = padR.style; |
|||
var posLeft = parseInt(pos.left); |
|||
|
|||
// Margin style
|
|||
mtStyle.height = style.marginTop; |
|||
mtStyle.width = style.width; |
|||
mtStyle.top = pos.top - style.marginTop.replace(unit, '') + unit; |
|||
mtStyle.left = posLeft + unit; |
|||
|
|||
mbStyle.height = style.marginBottom; |
|||
mbStyle.width = style.width; |
|||
mbStyle.top = pos.top + pos.height + unit; |
|||
mbStyle.left = posLeft + unit; |
|||
|
|||
var marginSideH = pos.height + marginTopSt + marginBottomSt + unit; |
|||
var marginSideT = pos.top - marginTopSt + unit; |
|||
mlStyle.height = marginSideH; |
|||
mlStyle.width = style.marginLeft; |
|||
mlStyle.top = marginSideT; |
|||
mlStyle.left = posLeft - marginLeftSt + unit; |
|||
|
|||
mrStyle.height = marginSideH; |
|||
mrStyle.width = style.marginRight; |
|||
mrStyle.top = marginSideT; |
|||
mrStyle.left = posLeft + pos.width + unit; |
|||
|
|||
// Padding style
|
|||
var padTop = parseInt(style.paddingTop.replace(unit, '')); |
|||
ptStyle.height = style.paddingTop; |
|||
ptStyle.width = style.width; |
|||
ptStyle.top = pos.top + unit; |
|||
ptStyle.left = posLeft + unit; |
|||
|
|||
var padBot = parseInt(style.paddingBottom.replace(unit, '')); |
|||
pbStyle.height = style.paddingBottom; |
|||
pbStyle.width = style.width; |
|||
pbStyle.top = pos.top + pos.height - padBot + unit; |
|||
pbStyle.left = posLeft + unit; |
|||
|
|||
var padSideH = (pos.height - padBot - padTop) + unit; |
|||
var padSideT = pos.top + padTop + unit; |
|||
plStyle.height = padSideH; |
|||
plStyle.width = style.paddingLeft; |
|||
plStyle.top = padSideT; |
|||
plStyle.left = pos.left + unit; |
|||
|
|||
var padRight = parseInt(style.paddingRight.replace(unit, '')); |
|||
prStyle.height = padSideH; |
|||
prStyle.width = style.paddingRight; |
|||
prStyle.top = padSideT; |
|||
prStyle.left = pos.left + pos.width - padRight + unit; |
|||
}, |
|||
|
|||
stop: function(editor, sender, opts) { |
|||
var opt = opts || {}; |
|||
var state = opt.state || ''; |
|||
var method = this.getOffsetMethod(state); |
|||
var canvas = editor.Canvas; |
|||
var offsetViewer = canvas[method](); |
|||
offsetViewer.style.display = 'none'; |
|||
}, |
|||
|
|||
}; |
|||
|
|||
@ -1,13 +1,11 @@ |
|||
define(function() { |
|||
return { |
|||
module.exports = { |
|||
|
|||
run: function(ed) { |
|||
ed.Canvas.getBody().className = this.ppfx + 'dashed'; |
|||
}, |
|||
run: function(ed) { |
|||
ed.Canvas.getBody().className = this.ppfx + 'dashed'; |
|||
}, |
|||
|
|||
stop: function(ed) { |
|||
ed.Canvas.getBody().className = ""; |
|||
} |
|||
stop: function(ed) { |
|||
ed.Canvas.getBody().className = ""; |
|||
} |
|||
|
|||
}; |
|||
}); |
|||
}; |
|||
|
|||
@ -1,37 +1,31 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var CreateComponent = require('./CreateComponent'); |
|||
/** |
|||
* @class TextComponent |
|||
* @private |
|||
* */ |
|||
module.exports = _.extend({}, CreateComponent, { |
|||
var Backbone = require('backbone'); |
|||
var CreateComponent = require('./CreateComponent'); |
|||
|
|||
/** |
|||
* This event is triggered at the beginning of a draw operation |
|||
* @param {Object} component Object component before creation |
|||
* @private |
|||
* */ |
|||
beforeDraw: function(component){ |
|||
component.type = 'text'; |
|||
if(!component.style) |
|||
component.style = {}; |
|||
component.style.padding = '10px'; |
|||
}, |
|||
module.exports = _.extend({}, CreateComponent, { |
|||
|
|||
/** |
|||
* This event is triggered at the end of a draw operation |
|||
* @param {Object} model Component model created |
|||
* @private |
|||
* */ |
|||
afterDraw: function(model){ |
|||
if(!model || !model.set) |
|||
return; |
|||
model.trigger('focus'); |
|||
if(this.sender) |
|||
this.sender.set('active', false); |
|||
}, |
|||
/** |
|||
* This event is triggered at the beginning of a draw operation |
|||
* @param {Object} component Object component before creation |
|||
* @private |
|||
* */ |
|||
beforeDraw: function(component){ |
|||
component.type = 'text'; |
|||
if(!component.style) |
|||
component.style = {}; |
|||
component.style.padding = '10px'; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
/** |
|||
* This event is triggered at the end of a draw operation |
|||
* @param {Object} model Component model created |
|||
* @private |
|||
* */ |
|||
afterDraw: function(model){ |
|||
if(!model || !model.set) |
|||
return; |
|||
model.trigger('focus'); |
|||
if(this.sender) |
|||
this.sender.set('active', false); |
|||
}, |
|||
|
|||
}); |
|||
|
|||
@ -1,14 +1,12 @@ |
|||
define(function () { |
|||
return { |
|||
module.exports = { |
|||
|
|||
// Style prefix
|
|||
stylePrefix: 'css-', |
|||
// Style prefix
|
|||
stylePrefix: 'css-', |
|||
|
|||
// Custom CSS string to render on top
|
|||
'staticRules': '', |
|||
// Custom CSS string to render on top
|
|||
'staticRules': '', |
|||
|
|||
// Default CSS style
|
|||
rules: [], |
|||
// Default CSS style
|
|||
rules: [], |
|||
|
|||
}; |
|||
}); |
|||
}; |
|||
|
|||
@ -1,95 +1,93 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var Selectors = require('./Selectors'); |
|||
module.exports = Backbone.Model.extend({ |
|||
|
|||
defaults: { |
|||
// Css selectors
|
|||
selectors: {}, |
|||
|
|||
// Additional string css selectors
|
|||
selectorsAdd: '', |
|||
|
|||
// Css properties style
|
|||
style: {}, |
|||
|
|||
// On which device width this rule should be rendered, eg. @media (max-width: 1000px)
|
|||
mediaText: '', |
|||
|
|||
// State of the rule, eg: hover | pressed | focused
|
|||
state: '', |
|||
|
|||
// Indicates if the rule is stylable
|
|||
stylable: true, |
|||
}, |
|||
|
|||
initialize: function(c, opt) { |
|||
this.config = c || {}; |
|||
this.sm = opt ? opt.sm || {} : {}; |
|||
this.slct = this.config.selectors || []; |
|||
|
|||
if(this.sm.get){ |
|||
var slct = []; |
|||
for(var i = 0; i < this.slct.length; i++) |
|||
slct.push(this.sm.get('SelectorManager').add(this.slct[i].name || this.slct[i])); |
|||
this.slct = slct; |
|||
} |
|||
|
|||
this.set('selectors', new Selectors(this.slct)); |
|||
}, |
|||
|
|||
/** |
|||
* Compare the actual model with parameters |
|||
* @param {Object} selectors Collection of selectors |
|||
* @param {String} state Css rule state |
|||
* @param {String} width For which device this style is oriented |
|||
* @param {Object} ruleProps Other rule props |
|||
* @return {Boolean} |
|||
* @private |
|||
*/ |
|||
compare: function(selectors, state, width, ruleProps){ |
|||
var otherRule = ruleProps || {}; |
|||
var st = state || ''; |
|||
var wd = width || ''; |
|||
var selectorsAdd = otherRule.selectorsAdd || ''; |
|||
var cId = 'cid'; |
|||
//var a1 = _.pluck(selectors.models || selectors, cId);
|
|||
//var a2 = _.pluck(this.get('selectors').models, cId);
|
|||
if(!(selectors instanceof Array) && !selectors.models) |
|||
selectors = [selectors]; |
|||
var a1 = _.map((selectors.models || selectors), function(model) { |
|||
return model.get('name'); |
|||
}); |
|||
var a2 = _.map(this.get('selectors').models, function(model) { |
|||
return model.get('name'); |
|||
}); |
|||
var f = false; |
|||
|
|||
if(a1.length !== a2.length) |
|||
return f; |
|||
|
|||
for (var i = 0; i < a1.length; i++) { |
|||
var re = 0; |
|||
for (var j = 0; j < a2.length; j++) { |
|||
if (a1[i] === a2[j]) |
|||
re = 1; |
|||
} |
|||
if(re === 0) |
|||
return f; |
|||
} |
|||
|
|||
if(this.get('state') !== st) |
|||
return f; |
|||
|
|||
if(this.get('mediaText') !== wd) |
|||
return f; |
|||
|
|||
if(this.get('selectorsAdd') !== selectorsAdd) |
|||
return f; |
|||
|
|||
return true; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
var Backbone = require('backbone'); |
|||
var Selectors = require('./Selectors'); |
|||
|
|||
module.exports = Backbone.Model.extend({ |
|||
|
|||
defaults: { |
|||
// Css selectors
|
|||
selectors: {}, |
|||
|
|||
// Additional string css selectors
|
|||
selectorsAdd: '', |
|||
|
|||
// Css properties style
|
|||
style: {}, |
|||
|
|||
// On which device width this rule should be rendered, eg. @media (max-width: 1000px)
|
|||
mediaText: '', |
|||
|
|||
// State of the rule, eg: hover | pressed | focused
|
|||
state: '', |
|||
|
|||
// Indicates if the rule is stylable
|
|||
stylable: true, |
|||
}, |
|||
|
|||
initialize: function(c, opt) { |
|||
this.config = c || {}; |
|||
this.sm = opt ? opt.sm || {} : {}; |
|||
this.slct = this.config.selectors || []; |
|||
|
|||
if(this.sm.get){ |
|||
var slct = []; |
|||
for(var i = 0; i < this.slct.length; i++) |
|||
slct.push(this.sm.get('SelectorManager').add(this.slct[i].name || this.slct[i])); |
|||
this.slct = slct; |
|||
} |
|||
|
|||
this.set('selectors', new Selectors(this.slct)); |
|||
}, |
|||
|
|||
/** |
|||
* Compare the actual model with parameters |
|||
* @param {Object} selectors Collection of selectors |
|||
* @param {String} state Css rule state |
|||
* @param {String} width For which device this style is oriented |
|||
* @param {Object} ruleProps Other rule props |
|||
* @return {Boolean} |
|||
* @private |
|||
*/ |
|||
compare: function(selectors, state, width, ruleProps){ |
|||
var otherRule = ruleProps || {}; |
|||
var st = state || ''; |
|||
var wd = width || ''; |
|||
var selectorsAdd = otherRule.selectorsAdd || ''; |
|||
var cId = 'cid'; |
|||
//var a1 = _.pluck(selectors.models || selectors, cId);
|
|||
//var a2 = _.pluck(this.get('selectors').models, cId);
|
|||
if(!(selectors instanceof Array) && !selectors.models) |
|||
selectors = [selectors]; |
|||
var a1 = _.map((selectors.models || selectors), function(model) { |
|||
return model.get('name'); |
|||
}); |
|||
var a2 = _.map(this.get('selectors').models, function(model) { |
|||
return model.get('name'); |
|||
}); |
|||
var f = false; |
|||
|
|||
if(a1.length !== a2.length) |
|||
return f; |
|||
|
|||
for (var i = 0; i < a1.length; i++) { |
|||
var re = 0; |
|||
for (var j = 0; j < a2.length; j++) { |
|||
if (a1[i] === a2[j]) |
|||
re = 1; |
|||
} |
|||
if(re === 0) |
|||
return f; |
|||
} |
|||
|
|||
if(this.get('state') !== st) |
|||
return f; |
|||
|
|||
if(this.get('mediaText') !== wd) |
|||
return f; |
|||
|
|||
if(this.get('selectorsAdd') !== selectorsAdd) |
|||
return f; |
|||
|
|||
return true; |
|||
}, |
|||
|
|||
}); |
|||
|
|||
@ -1,36 +1,34 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var CssRule = require('./CssRule'); |
|||
module.exports = Backbone.Collection.extend({ |
|||
var Backbone = require('backbone'); |
|||
var CssRule = require('./CssRule'); |
|||
|
|||
initialize: function(models, opt){ |
|||
module.exports = Backbone.Collection.extend({ |
|||
|
|||
// Inject editor
|
|||
if(opt && opt.sm) |
|||
this.editor = opt.sm; |
|||
initialize: function(models, opt){ |
|||
|
|||
this.model = function(attrs, options) { |
|||
var model; |
|||
// Inject editor
|
|||
if(opt && opt.sm) |
|||
this.editor = opt.sm; |
|||
|
|||
if(!options.sm && opt && opt.sm) |
|||
options.sm = opt.sm; |
|||
this.model = function(attrs, options) { |
|||
var model; |
|||
|
|||
switch(1){ |
|||
default: |
|||
model = new CssRule(attrs, options); |
|||
} |
|||
if(!options.sm && opt && opt.sm) |
|||
options.sm = opt.sm; |
|||
|
|||
return model; |
|||
}; |
|||
switch(1){ |
|||
default: |
|||
model = new CssRule(attrs, options); |
|||
} |
|||
|
|||
}, |
|||
return model; |
|||
}; |
|||
|
|||
add: function(models, opt){ |
|||
if(typeof models === 'string') |
|||
models = this.editor.get('Parser').parseCss(models); |
|||
return Backbone.Collection.prototype.add.apply(this, [models, opt]); |
|||
}, |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
add: function(models, opt){ |
|||
if(typeof models === 'string') |
|||
models = this.editor.get('Parser').parseCss(models); |
|||
return Backbone.Collection.prototype.add.apply(this, [models, opt]); |
|||
}, |
|||
|
|||
}); |
|||
|
|||
@ -1,26 +1,24 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
module.exports = Backbone.Collection.extend({ |
|||
var Backbone = require('backbone'); |
|||
|
|||
initialize: function(models, opt){ |
|||
module.exports = Backbone.Collection.extend({ |
|||
|
|||
this.model = function(attrs, opts) { |
|||
var model; |
|||
initialize: function(models, opt){ |
|||
|
|||
switch(1){ |
|||
this.model = function(attrs, opts) { |
|||
var model; |
|||
|
|||
default: |
|||
if(!this.ClassTag) |
|||
this.ClassTag = require("SelectorManager/model/Selector"); |
|||
model = new this.ClassTag(attrs, opts); |
|||
switch(1){ |
|||
|
|||
} |
|||
default: |
|||
if(!this.ClassTag) |
|||
this.ClassTag = require("SelectorManager/model/Selector"); |
|||
model = new this.ClassTag(attrs, opts); |
|||
|
|||
return model; |
|||
}; |
|||
} |
|||
|
|||
}, |
|||
return model; |
|||
}; |
|||
|
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
|
|||
@ -1,79 +1,77 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
module.exports = Backbone.View.extend({ |
|||
var Backbone = require('backbone'); |
|||
|
|||
tagName: 'style', |
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
initialize: function(o) { |
|||
this.config = o.config || {}; |
|||
this.listenTo(this.model, 'change:style', this.render); |
|||
this.listenTo(this.model, 'change:state', this.render); |
|||
this.listenTo(this.model, 'destroy remove', this.remove); |
|||
this.listenTo(this.model, 'change:mediaText', this.render); |
|||
this.listenTo(this.model.get('selectors'), 'change', this.selChanged); |
|||
}, |
|||
tagName: 'style', |
|||
|
|||
/** |
|||
* Triggered when some selector is changed |
|||
* @private |
|||
*/ |
|||
selChanged: function(){ |
|||
this.selStr = this.renderSelectors(); |
|||
this.render(); |
|||
}, |
|||
initialize: function(o) { |
|||
this.config = o.config || {}; |
|||
this.listenTo(this.model, 'change:style', this.render); |
|||
this.listenTo(this.model, 'change:state', this.render); |
|||
this.listenTo(this.model, 'destroy remove', this.remove); |
|||
this.listenTo(this.model, 'change:mediaText', this.render); |
|||
this.listenTo(this.model.get('selectors'), 'change', this.selChanged); |
|||
}, |
|||
|
|||
/** |
|||
* Triggered when some selector is changed |
|||
* @private |
|||
*/ |
|||
selChanged: function(){ |
|||
this.selStr = this.renderSelectors(); |
|||
this.render(); |
|||
}, |
|||
|
|||
/** |
|||
* Returns string of selectors |
|||
* @return {String} |
|||
* @private |
|||
*/ |
|||
renderSelectors: function() { |
|||
var sel = []; |
|||
var model = this.model; |
|||
var add = model.get('selectorsAdd'); |
|||
model.get('selectors').each(function(m){ |
|||
sel.push('.' + m.get('name')); |
|||
}); |
|||
var sels = sel.join(''); |
|||
return sels + (sels && add ? ', ' : '') + add; |
|||
}, |
|||
/** |
|||
* Returns string of selectors |
|||
* @return {String} |
|||
* @private |
|||
*/ |
|||
renderSelectors: function() { |
|||
var sel = []; |
|||
var model = this.model; |
|||
var add = model.get('selectorsAdd'); |
|||
model.get('selectors').each(function(m){ |
|||
sel.push('.' + m.get('name')); |
|||
}); |
|||
var sels = sel.join(''); |
|||
return sels + (sels && add ? ', ' : '') + add; |
|||
}, |
|||
|
|||
/** |
|||
* Returns string of properties |
|||
* @return {String} |
|||
* @private |
|||
*/ |
|||
renderProperties: function(){ |
|||
var sel = [], |
|||
props = this.model.get('style'); |
|||
for (var prop in props){ |
|||
sel.push(prop + ':' + props[prop] + ';'); |
|||
} |
|||
return sel.join(''); |
|||
}, |
|||
/** |
|||
* Returns string of properties |
|||
* @return {String} |
|||
* @private |
|||
*/ |
|||
renderProperties: function(){ |
|||
var sel = [], |
|||
props = this.model.get('style'); |
|||
for (var prop in props){ |
|||
sel.push(prop + ':' + props[prop] + ';'); |
|||
} |
|||
return sel.join(''); |
|||
}, |
|||
|
|||
render : function() { |
|||
var block = '', |
|||
selStr = '', |
|||
o = ''; |
|||
if(!this.selStr) |
|||
this.selStr = this.renderSelectors(); |
|||
var prpStr = this.renderProperties(); |
|||
var stateStr = this.model.get('state'); |
|||
var mediaText = this.model.get('mediaText'); |
|||
if(this.selStr){ |
|||
stateStr = stateStr ? ':' + stateStr : ''; |
|||
block = prpStr !== '' ? '{' + prpStr + '}' : ''; |
|||
} |
|||
o = this.selStr && block ? this.selStr + stateStr + block : ''; |
|||
render : function() { |
|||
var block = '', |
|||
selStr = '', |
|||
o = ''; |
|||
if(!this.selStr) |
|||
this.selStr = this.renderSelectors(); |
|||
var prpStr = this.renderProperties(); |
|||
var stateStr = this.model.get('state'); |
|||
var mediaText = this.model.get('mediaText'); |
|||
if(this.selStr){ |
|||
stateStr = stateStr ? ':' + stateStr : ''; |
|||
block = prpStr !== '' ? '{' + prpStr + '}' : ''; |
|||
} |
|||
o = this.selStr && block ? this.selStr + stateStr + block : ''; |
|||
|
|||
if(mediaText && o) |
|||
o = '@media ' + mediaText + '{' + o + '}'; |
|||
if(mediaText && o) |
|||
o = '@media ' + mediaText + '{' + o + '}'; |
|||
|
|||
this.$el.html(o); |
|||
return this; |
|||
}, |
|||
this.$el.html(o); |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
|
|||
@ -1,63 +1,61 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var CssRuleView = require('./CssRuleView'); |
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
initialize: function(o) { |
|||
this.config = o.config || {}; |
|||
this.pfx = this.config.stylePrefix || ''; |
|||
this.className = this.pfx + 'rules'; |
|||
this.listenTo( this.collection, 'add', this.addTo ); |
|||
this.listenTo( this.collection, 'reset', this.render ); |
|||
}, |
|||
|
|||
/** |
|||
* Add to collection |
|||
* @param {Object} model |
|||
* @private |
|||
* */ |
|||
addTo: function(model){ |
|||
//console.log('Added');
|
|||
this.addToCollection(model); |
|||
}, |
|||
|
|||
/** |
|||
* Add new object to collection |
|||
* @param {Object} model |
|||
* @param {Object} fragmentEl |
|||
* @return {Object} |
|||
* @private |
|||
* */ |
|||
addToCollection: function(model, fragmentEl){ |
|||
var fragment = fragmentEl || null; |
|||
var viewObject = CssRuleView; |
|||
|
|||
var view = new viewObject({ |
|||
model: model, |
|||
config: this.config, |
|||
}); |
|||
var rendered = view.render().el; |
|||
|
|||
if(fragment) |
|||
fragment.appendChild( rendered ); |
|||
else |
|||
this.$el.append(rendered); |
|||
|
|||
return rendered; |
|||
}, |
|||
|
|||
render: function() { |
|||
var fragment = document.createDocumentFragment(); |
|||
this.$el.empty(); |
|||
|
|||
this.collection.each(function(model){ |
|||
this.addToCollection(model, fragment); |
|||
}, this); |
|||
|
|||
this.$el.append(fragment); |
|||
this.$el.attr('class', this.className); |
|||
return this; |
|||
} |
|||
}); |
|||
}); |
|||
var Backbone = require('backbone'); |
|||
var CssRuleView = require('./CssRuleView'); |
|||
|
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
initialize: function(o) { |
|||
this.config = o.config || {}; |
|||
this.pfx = this.config.stylePrefix || ''; |
|||
this.className = this.pfx + 'rules'; |
|||
this.listenTo( this.collection, 'add', this.addTo ); |
|||
this.listenTo( this.collection, 'reset', this.render ); |
|||
}, |
|||
|
|||
/** |
|||
* Add to collection |
|||
* @param {Object} model |
|||
* @private |
|||
* */ |
|||
addTo: function(model){ |
|||
//console.log('Added');
|
|||
this.addToCollection(model); |
|||
}, |
|||
|
|||
/** |
|||
* Add new object to collection |
|||
* @param {Object} model |
|||
* @param {Object} fragmentEl |
|||
* @return {Object} |
|||
* @private |
|||
* */ |
|||
addToCollection: function(model, fragmentEl){ |
|||
var fragment = fragmentEl || null; |
|||
var viewObject = CssRuleView; |
|||
|
|||
var view = new viewObject({ |
|||
model: model, |
|||
config: this.config, |
|||
}); |
|||
var rendered = view.render().el; |
|||
|
|||
if(fragment) |
|||
fragment.appendChild( rendered ); |
|||
else |
|||
this.$el.append(rendered); |
|||
|
|||
return rendered; |
|||
}, |
|||
|
|||
render: function() { |
|||
var fragment = document.createDocumentFragment(); |
|||
this.$el.empty(); |
|||
|
|||
this.collection.each(function(model){ |
|||
this.addToCollection(model, fragment); |
|||
}, this); |
|||
|
|||
this.$el.append(fragment); |
|||
this.$el.attr('class', this.className); |
|||
return this; |
|||
} |
|||
}); |
|||
|
|||
@ -1,9 +1,7 @@ |
|||
define(function () { |
|||
return { |
|||
module.exports = { |
|||
|
|||
devices: [], |
|||
devices: [], |
|||
|
|||
deviceLabel: 'Device', |
|||
deviceLabel: 'Device', |
|||
|
|||
}; |
|||
}); |
|||
}; |
|||
|
|||
@ -1,15 +1,12 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var Backbone = require('backbone'); |
|||
|
|||
module.exports = Backbone.Model.extend({ |
|||
module.exports = Backbone.Model.extend({ |
|||
|
|||
idAttribute: 'name', |
|||
idAttribute: 'name', |
|||
|
|||
defaults :{ |
|||
name: '', |
|||
width: '', |
|||
}, |
|||
defaults :{ |
|||
name: '', |
|||
width: '', |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,84 +1,81 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var devicesTemplate = require('text!./../template/devices.html'); |
|||
var Backbone = require('backbone'); |
|||
var devicesTemplate = require('text!./../template/devices.html'); |
|||
|
|||
module.exports = Backbone.View.extend({ |
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
template: _.template(devicesTemplate), |
|||
template: _.template(devicesTemplate), |
|||
|
|||
events: { |
|||
'change': 'updateDevice' |
|||
}, |
|||
events: { |
|||
'change': 'updateDevice' |
|||
}, |
|||
|
|||
initialize: function(o) { |
|||
this.config = o.config || {}; |
|||
this.em = this.config.em; |
|||
this.ppfx = this.config.pStylePrefix || ''; |
|||
this.events['click .' + this.ppfx + 'add-trasp'] = this.startAdd; |
|||
this.listenTo(this.em, 'change:device', this.updateSelect); |
|||
this.delegateEvents(); |
|||
}, |
|||
initialize: function(o) { |
|||
this.config = o.config || {}; |
|||
this.em = this.config.em; |
|||
this.ppfx = this.config.pStylePrefix || ''; |
|||
this.events['click .' + this.ppfx + 'add-trasp'] = this.startAdd; |
|||
this.listenTo(this.em, 'change:device', this.updateSelect); |
|||
this.delegateEvents(); |
|||
}, |
|||
|
|||
/** |
|||
* Start adding new device |
|||
* @return {[type]} [description] |
|||
* @private |
|||
*/ |
|||
startAdd: function(){}, |
|||
/** |
|||
* Start adding new device |
|||
* @return {[type]} [description] |
|||
* @private |
|||
*/ |
|||
startAdd: function(){}, |
|||
|
|||
/** |
|||
* Update device of the editor |
|||
* @private |
|||
*/ |
|||
updateDevice: function(){ |
|||
var em = this.em; |
|||
if(em){ |
|||
var devEl = this.devicesEl; |
|||
var val = devEl ? devEl.val() : ''; |
|||
em.set('device', val); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Update select value on device update |
|||
* @private |
|||
*/ |
|||
updateSelect: function(){ |
|||
var em = this.em; |
|||
/** |
|||
* Update device of the editor |
|||
* @private |
|||
*/ |
|||
updateDevice: function(){ |
|||
var em = this.em; |
|||
if(em){ |
|||
var devEl = this.devicesEl; |
|||
if(em && em.getDeviceModel && devEl){ |
|||
var device = em.getDeviceModel(); |
|||
var name = device ? device.get('name') : ''; |
|||
devEl.val(name); |
|||
} |
|||
}, |
|||
var val = devEl ? devEl.val() : ''; |
|||
em.set('device', val); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Update select value on device update |
|||
* @private |
|||
*/ |
|||
updateSelect: function(){ |
|||
var em = this.em; |
|||
var devEl = this.devicesEl; |
|||
if(em && em.getDeviceModel && devEl){ |
|||
var device = em.getDeviceModel(); |
|||
var name = device ? device.get('name') : ''; |
|||
devEl.val(name); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Return devices options |
|||
* @return {string} String of options |
|||
* @private |
|||
*/ |
|||
getOptions: function(){ |
|||
var result = ''; |
|||
this.collection.each(function(device){ |
|||
var name = device.get('name'); |
|||
result += '<option value="' + name+ '">' + name + '</option>'; |
|||
}); |
|||
return result; |
|||
}, |
|||
/** |
|||
* Return devices options |
|||
* @return {string} String of options |
|||
* @private |
|||
*/ |
|||
getOptions: function(){ |
|||
var result = ''; |
|||
this.collection.each(function(device){ |
|||
var name = device.get('name'); |
|||
result += '<option value="' + name+ '">' + name + '</option>'; |
|||
}); |
|||
return result; |
|||
}, |
|||
|
|||
render: function() { |
|||
var pfx = this.ppfx; |
|||
this.$el.html(this.template({ |
|||
ppfx: pfx, |
|||
deviceLabel: this.config.deviceLabel |
|||
})); |
|||
this.devicesEl = this.$el.find('.' + pfx + 'devices'); |
|||
this.devicesEl.append(this.getOptions()); |
|||
this.el.className = pfx + 'devices-c'; |
|||
return this; |
|||
}, |
|||
render: function() { |
|||
var pfx = this.ppfx; |
|||
this.$el.html(this.template({ |
|||
ppfx: pfx, |
|||
deviceLabel: this.config.deviceLabel |
|||
})); |
|||
this.devicesEl = this.$el.find('.' + pfx + 'devices'); |
|||
this.devicesEl.append(this.getOptions()); |
|||
this.el.className = pfx + 'devices-c'; |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,32 +1,30 @@ |
|||
define(function () { |
|||
return { |
|||
stylePrefix: 'comp-', |
|||
module.exports = { |
|||
stylePrefix: 'comp-', |
|||
|
|||
wrapperId: 'wrapper', |
|||
wrapperId: 'wrapper', |
|||
|
|||
// Default wrapper configuration
|
|||
wrapper: { |
|||
//classes: ['body'],
|
|||
removable: false, |
|||
copyable: false, |
|||
stylable: ['background','background-color','background-image', 'background-repeat','background-attachment','background-position'], |
|||
draggable: false, |
|||
badgable: false, |
|||
components: [], |
|||
}, |
|||
// Default wrapper configuration
|
|||
wrapper: { |
|||
//classes: ['body'],
|
|||
removable: false, |
|||
copyable: false, |
|||
stylable: ['background','background-color','background-image', 'background-repeat','background-attachment','background-position'], |
|||
draggable: false, |
|||
badgable: false, |
|||
components: [], |
|||
}, |
|||
|
|||
// Could be used for default components
|
|||
components: [], |
|||
// Could be used for default components
|
|||
components: [], |
|||
|
|||
rte: {}, |
|||
rte: {}, |
|||
|
|||
// Class for new image component
|
|||
imageCompClass : 'fa fa-picture-o', |
|||
// Class for new image component
|
|||
imageCompClass : 'fa fa-picture-o', |
|||
|
|||
// Open assets manager on create of image component
|
|||
oAssetsOnCreate : true, |
|||
// Open assets manager on create of image component
|
|||
oAssetsOnCreate : true, |
|||
|
|||
// List of void elements
|
|||
voidElements: ['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr'], |
|||
}; |
|||
}); |
|||
// List of void elements
|
|||
voidElements: ['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr'], |
|||
}; |
|||
|
|||
@ -1,375 +1,372 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var Components = require('./Components'); |
|||
var Selectors = require('SelectorManager/model/Selectors'); |
|||
var Traits = require('TraitManager/model/Traits'); |
|||
var Backbone = require('backbone'); |
|||
var Components = require('./Components'); |
|||
var Selectors = require('SelectorManager/model/Selectors'); |
|||
var Traits = require('TraitManager/model/Traits'); |
|||
|
|||
module.exports = Backbone.Model.extend({ |
|||
|
|||
defaults: { |
|||
// HTML tag of the component
|
|||
tagName: 'div', |
|||
|
|||
// Component type, eg. 'text', 'image', 'video', etc.
|
|||
type: '', |
|||
|
|||
// True if the component is removable from the canvas
|
|||
removable: true, |
|||
|
|||
// Indicates if it's possible to drag the component inside other
|
|||
// Tip: Indicate an array of selectors where it could be dropped inside
|
|||
draggable: true, |
|||
|
|||
// Indicates if it's possible to drop other components inside
|
|||
// Tip: Indicate an array of selectors which could be dropped inside
|
|||
droppable: true, |
|||
|
|||
// Set false if don't want to see the badge (with the name) over the component
|
|||
badgable: true, |
|||
|
|||
// True if it's possible to style it
|
|||
// Tip: Indicate an array of CSS properties which is possible to style
|
|||
stylable: true, |
|||
|
|||
// Highlightable with 'dotted' style if true
|
|||
highlightable: true, |
|||
|
|||
// True if it's possible to clone the component
|
|||
copyable: true, |
|||
|
|||
// Indicates if it's possible to resize the component (at the moment implemented only on Image Components)
|
|||
resizable: false, |
|||
|
|||
// Allow to edit the content of the component (used on Text components)
|
|||
editable: false, |
|||
|
|||
// Hide the component inside Layers
|
|||
hiddenLayer: false, |
|||
|
|||
// This property is used by the HTML exporter as void elements do not
|
|||
// have closing tag, eg. <br/>, <hr/>, etc.
|
|||
void: false, |
|||
|
|||
// Indicates if the component is in some CSS state like ':hover', ':active', etc.
|
|||
state: '', |
|||
|
|||
// State, eg. 'selected'
|
|||
status: '', |
|||
|
|||
// Content of the component (not escaped) which will be appended before children rendering
|
|||
content: '', |
|||
|
|||
// Component related style
|
|||
style: {}, |
|||
|
|||
// Key-value object of the component's attributes
|
|||
attributes: '', |
|||
|
|||
// Array of classes
|
|||
classes: '', |
|||
|
|||
// Component's javascript
|
|||
script: '', |
|||
|
|||
// Traits
|
|||
traits: ['id', 'title'], |
|||
|
|||
/** |
|||
* Set an array of items to show up inside the toolbar (eg. move, clone, delete) |
|||
* when the component is selected |
|||
* toolbar: [{ |
|||
* attributes: {class: 'fa fa-arrows'}, |
|||
* command: 'tlb-move', |
|||
* },{ |
|||
* attributes: {class: 'fa fa-clone'}, |
|||
* command: 'tlb-clone', |
|||
* }] |
|||
*/ |
|||
toolbar: null, |
|||
|
|||
// TODO
|
|||
previousModel: '', |
|||
mirror: '', |
|||
}, |
|||
|
|||
initialize: function(o, opt) { |
|||
// Check void elements
|
|||
if(opt && opt.config && opt.config.voidElements.indexOf(this.get('tagName')) >= 0) |
|||
this.set('void', true); |
|||
|
|||
this.opt = opt; |
|||
this.sm = opt ? opt.sm || {} : {}; |
|||
this.config = o || {}; |
|||
this.defaultC = this.config.components || []; |
|||
this.defaultCl = this.normalizeClasses(this.get('classes') || this.config.classes || []); |
|||
this.components = new Components(this.defaultC, opt); |
|||
this.components.parent = this; |
|||
this.listenTo(this, 'change:script', this.scriptUpdated); |
|||
this.set('attributes', this.get('attributes') || {}); |
|||
this.set('components', this.components); |
|||
this.set('classes', new Selectors(this.defaultCl)); |
|||
var traits = new Traits(); |
|||
traits.setTarget(this); |
|||
traits.add(this.get('traits')); |
|||
this.set('traits', traits); |
|||
this.initToolbar(); |
|||
|
|||
// Normalize few properties from strings to arrays
|
|||
var toNormalize = ['stylable']; |
|||
toNormalize.forEach(function(name) { |
|||
var value = this.get(name); |
|||
|
|||
if (typeof value == 'string') { |
|||
var newValue = value.split(',').map(function(prop) { |
|||
return prop.trim(); |
|||
}); |
|||
this.set(name, newValue); |
|||
} |
|||
}, this); |
|||
|
|||
this.init(); |
|||
}, |
|||
|
|||
/** |
|||
* Initialize callback |
|||
*/ |
|||
init: function () {}, |
|||
|
|||
/** |
|||
* Script updated |
|||
*/ |
|||
scriptUpdated: function() { |
|||
this.set('scriptUpdated', 1); |
|||
}, |
|||
|
|||
/** |
|||
* Init toolbar |
|||
*/ |
|||
initToolbar: function () { |
|||
var model = this; |
|||
if(!model.get('toolbar')) { |
|||
var tb = []; |
|||
if(model.get('draggable')) { |
|||
tb.push({ |
|||
attributes: {class: 'fa fa-arrows'}, |
|||
command: 'tlb-move', |
|||
}); |
|||
} |
|||
if(model.get('copyable')) { |
|||
tb.push({ |
|||
attributes: {class: 'fa fa-clone'}, |
|||
command: 'tlb-clone', |
|||
}); |
|||
} |
|||
if(model.get('removable')) { |
|||
tb.push({ |
|||
attributes: {class: 'fa fa-trash-o'}, |
|||
command: 'tlb-delete', |
|||
}); |
|||
} |
|||
model.set('toolbar', tb); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Load traits |
|||
* @param {Array} traits |
|||
* @private |
|||
*/ |
|||
loadTraits: function(traits) { |
|||
var trt = new Traits(); |
|||
trt.setTarget(this); |
|||
trt.add(traits); |
|||
this.set('traits', trt); |
|||
}, |
|||
|
|||
/** |
|||
* Normalize input classes from array to array of objects |
|||
* @param {Array} arr |
|||
* @return {Array} |
|||
* @private |
|||
*/ |
|||
normalizeClasses: function(arr) { |
|||
var res = []; |
|||
|
|||
if(!this.sm.get) |
|||
return; |
|||
|
|||
var clm = this.sm.get('SelectorManager'); |
|||
if(!clm) |
|||
return; |
|||
|
|||
arr.forEach(function(val){ |
|||
var name = ''; |
|||
|
|||
if(typeof val === 'string') |
|||
name = val; |
|||
else |
|||
name = val.name; |
|||
|
|||
var model = clm.add(name); |
|||
res.push(model); |
|||
}); |
|||
return res; |
|||
}, |
|||
|
|||
/** |
|||
* Override original clone method |
|||
* @private |
|||
*/ |
|||
clone: function(reset) { |
|||
var attr = _.clone(this.attributes), |
|||
comp = this.get('components'), |
|||
traits = this.get('traits'), |
|||
cls = this.get('classes'); |
|||
attr.components = []; |
|||
attr.classes = []; |
|||
attr.traits = []; |
|||
|
|||
comp.each(function(md,i) { |
|||
attr.components[i] = md.clone(1); |
|||
}); |
|||
traits.each(function(md, i) { |
|||
attr.traits[i] = md.clone(); |
|||
module.exports = Backbone.Model.extend({ |
|||
|
|||
defaults: { |
|||
// HTML tag of the component
|
|||
tagName: 'div', |
|||
|
|||
// Component type, eg. 'text', 'image', 'video', etc.
|
|||
type: '', |
|||
|
|||
// True if the component is removable from the canvas
|
|||
removable: true, |
|||
|
|||
// Indicates if it's possible to drag the component inside other
|
|||
// Tip: Indicate an array of selectors where it could be dropped inside
|
|||
draggable: true, |
|||
|
|||
// Indicates if it's possible to drop other components inside
|
|||
// Tip: Indicate an array of selectors which could be dropped inside
|
|||
droppable: true, |
|||
|
|||
// Set false if don't want to see the badge (with the name) over the component
|
|||
badgable: true, |
|||
|
|||
// True if it's possible to style it
|
|||
// Tip: Indicate an array of CSS properties which is possible to style
|
|||
stylable: true, |
|||
|
|||
// Highlightable with 'dotted' style if true
|
|||
highlightable: true, |
|||
|
|||
// True if it's possible to clone the component
|
|||
copyable: true, |
|||
|
|||
// Indicates if it's possible to resize the component (at the moment implemented only on Image Components)
|
|||
resizable: false, |
|||
|
|||
// Allow to edit the content of the component (used on Text components)
|
|||
editable: false, |
|||
|
|||
// Hide the component inside Layers
|
|||
hiddenLayer: false, |
|||
|
|||
// This property is used by the HTML exporter as void elements do not
|
|||
// have closing tag, eg. <br/>, <hr/>, etc.
|
|||
void: false, |
|||
|
|||
// Indicates if the component is in some CSS state like ':hover', ':active', etc.
|
|||
state: '', |
|||
|
|||
// State, eg. 'selected'
|
|||
status: '', |
|||
|
|||
// Content of the component (not escaped) which will be appended before children rendering
|
|||
content: '', |
|||
|
|||
// Component related style
|
|||
style: {}, |
|||
|
|||
// Key-value object of the component's attributes
|
|||
attributes: '', |
|||
|
|||
// Array of classes
|
|||
classes: '', |
|||
|
|||
// Component's javascript
|
|||
script: '', |
|||
|
|||
// Traits
|
|||
traits: ['id', 'title'], |
|||
|
|||
/** |
|||
* Set an array of items to show up inside the toolbar (eg. move, clone, delete) |
|||
* when the component is selected |
|||
* toolbar: [{ |
|||
* attributes: {class: 'fa fa-arrows'}, |
|||
* command: 'tlb-move', |
|||
* },{ |
|||
* attributes: {class: 'fa fa-clone'}, |
|||
* command: 'tlb-clone', |
|||
* }] |
|||
*/ |
|||
toolbar: null, |
|||
|
|||
// TODO
|
|||
previousModel: '', |
|||
mirror: '', |
|||
}, |
|||
|
|||
initialize: function(o, opt) { |
|||
// Check void elements
|
|||
if(opt && opt.config && opt.config.voidElements.indexOf(this.get('tagName')) >= 0) |
|||
this.set('void', true); |
|||
|
|||
this.opt = opt; |
|||
this.sm = opt ? opt.sm || {} : {}; |
|||
this.config = o || {}; |
|||
this.defaultC = this.config.components || []; |
|||
this.defaultCl = this.normalizeClasses(this.get('classes') || this.config.classes || []); |
|||
this.components = new Components(this.defaultC, opt); |
|||
this.components.parent = this; |
|||
this.listenTo(this, 'change:script', this.scriptUpdated); |
|||
this.set('attributes', this.get('attributes') || {}); |
|||
this.set('components', this.components); |
|||
this.set('classes', new Selectors(this.defaultCl)); |
|||
var traits = new Traits(); |
|||
traits.setTarget(this); |
|||
traits.add(this.get('traits')); |
|||
this.set('traits', traits); |
|||
this.initToolbar(); |
|||
|
|||
// Normalize few properties from strings to arrays
|
|||
var toNormalize = ['stylable']; |
|||
toNormalize.forEach(function(name) { |
|||
var value = this.get(name); |
|||
|
|||
if (typeof value == 'string') { |
|||
var newValue = value.split(',').map(function(prop) { |
|||
return prop.trim(); |
|||
}); |
|||
cls.each(function(md,i) { |
|||
attr.classes[i] = md.get('name'); |
|||
this.set(name, newValue); |
|||
} |
|||
}, this); |
|||
|
|||
this.init(); |
|||
}, |
|||
|
|||
/** |
|||
* Initialize callback |
|||
*/ |
|||
init: function () {}, |
|||
|
|||
/** |
|||
* Script updated |
|||
*/ |
|||
scriptUpdated: function() { |
|||
this.set('scriptUpdated', 1); |
|||
}, |
|||
|
|||
/** |
|||
* Init toolbar |
|||
*/ |
|||
initToolbar: function () { |
|||
var model = this; |
|||
if(!model.get('toolbar')) { |
|||
var tb = []; |
|||
if(model.get('draggable')) { |
|||
tb.push({ |
|||
attributes: {class: 'fa fa-arrows'}, |
|||
command: 'tlb-move', |
|||
}); |
|||
|
|||
attr.status = ''; |
|||
attr.view = ''; |
|||
|
|||
if(reset){ |
|||
this.opt.collection = null; |
|||
} |
|||
|
|||
return new this.constructor(attr, this.opt); |
|||
}, |
|||
|
|||
/** |
|||
* Get name of the component |
|||
* @return {string} |
|||
* @private |
|||
* */ |
|||
getName: function() { |
|||
if(!this.name){ |
|||
var id = this.cid.replace(/\D/g,''), |
|||
type = this.get('type'); |
|||
var tag = this.get('tagName'); |
|||
tag = tag == 'div' ? 'box' : tag; |
|||
tag = type ? type : tag; |
|||
this.name = tag.charAt(0).toUpperCase() + tag.slice(1); |
|||
} |
|||
return this.name; |
|||
}, |
|||
|
|||
/** |
|||
* Return HTML string of the component |
|||
* @param {Object} opts Options |
|||
* @return {string} HTML string |
|||
* @private |
|||
*/ |
|||
toHTML: function(opts) { |
|||
var code = ''; |
|||
var m = this; |
|||
var tag = m.get('tagName'), |
|||
sTag = m.get('void'), |
|||
attrId = ''; |
|||
// Build the string of attributes
|
|||
var strAttr = ''; |
|||
var attr = this.getAttrToHTML(); |
|||
for(var prop in attr){ |
|||
var val = attr[prop]; |
|||
strAttr += typeof val !== undefined && val !== '' ? |
|||
' ' + prop + '="' + val + '"' : ''; |
|||
} |
|||
// Build the string of classes
|
|||
var strCls = ''; |
|||
m.get('classes').each(function(m){ |
|||
strCls += ' ' + m.get('name'); |
|||
} |
|||
if(model.get('copyable')) { |
|||
tb.push({ |
|||
attributes: {class: 'fa fa-clone'}, |
|||
command: 'tlb-clone', |
|||
}); |
|||
strCls = strCls !== '' ? ' class="' + strCls.trim() + '"' : ''; |
|||
|
|||
// If style is not empty I need an ID attached to the component
|
|||
// TODO: need to refactor in case of 'ID Trait'
|
|||
if(!_.isEmpty(m.get('style'))) |
|||
attrId = ' id="' + m.cid + '" '; |
|||
|
|||
code += '<' + tag + strCls + attrId + strAttr + (sTag ? '/' : '') + '>' + m.get('content'); |
|||
|
|||
m.get('components').each(function(m) { |
|||
code += m.toHTML(); |
|||
} |
|||
if(model.get('removable')) { |
|||
tb.push({ |
|||
attributes: {class: 'fa fa-trash-o'}, |
|||
command: 'tlb-delete', |
|||
}); |
|||
|
|||
if(!sTag) |
|||
code += '</'+tag+'>'; |
|||
|
|||
return code; |
|||
}, |
|||
|
|||
/** |
|||
* Returns object of attributes for HTML |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getAttrToHTML: function() { |
|||
var attr = this.get('attributes') || {}; |
|||
delete attr.style; |
|||
return attr; |
|||
}, |
|||
|
|||
/** |
|||
* Return a shallow copy of the model's attributes for JSON |
|||
* stringification. |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
toJSON: function() { |
|||
var obj = Backbone.Model.prototype.toJSON.apply(this, arguments); |
|||
var scriptStr = this.getScriptString(); |
|||
|
|||
if (scriptStr) { |
|||
obj.script = scriptStr; |
|||
} |
|||
|
|||
return obj; |
|||
}, |
|||
|
|||
/** |
|||
* Return script in string format, cleans 'function() {..' from scripts |
|||
* if it's a function |
|||
* @param {string|Function} script |
|||
* @return {string} |
|||
* @private |
|||
*/ |
|||
getScriptString: function (script) { |
|||
var scr = script || this.get('script'); |
|||
|
|||
// Need to cast script functions to string
|
|||
if (typeof scr == 'function') { |
|||
var scrStr = scr.toString().trim(); |
|||
scrStr = scrStr.replace(/^function\s?\(\)\s?\{/, ''); |
|||
scrStr = scrStr.replace(/\}$/, ''); |
|||
scr = scrStr; |
|||
} |
|||
|
|||
return scr; |
|||
} |
|||
model.set('toolbar', tb); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Load traits |
|||
* @param {Array} traits |
|||
* @private |
|||
*/ |
|||
loadTraits: function(traits) { |
|||
var trt = new Traits(); |
|||
trt.setTarget(this); |
|||
trt.add(traits); |
|||
this.set('traits', trt); |
|||
}, |
|||
|
|||
/** |
|||
* Normalize input classes from array to array of objects |
|||
* @param {Array} arr |
|||
* @return {Array} |
|||
* @private |
|||
*/ |
|||
normalizeClasses: function(arr) { |
|||
var res = []; |
|||
|
|||
if(!this.sm.get) |
|||
return; |
|||
|
|||
var clm = this.sm.get('SelectorManager'); |
|||
if(!clm) |
|||
return; |
|||
|
|||
arr.forEach(function(val){ |
|||
var name = ''; |
|||
|
|||
if(typeof val === 'string') |
|||
name = val; |
|||
else |
|||
name = val.name; |
|||
|
|||
var model = clm.add(name); |
|||
res.push(model); |
|||
}); |
|||
return res; |
|||
}, |
|||
|
|||
/** |
|||
* Override original clone method |
|||
* @private |
|||
*/ |
|||
clone: function(reset) { |
|||
var attr = _.clone(this.attributes), |
|||
comp = this.get('components'), |
|||
traits = this.get('traits'), |
|||
cls = this.get('classes'); |
|||
attr.components = []; |
|||
attr.classes = []; |
|||
attr.traits = []; |
|||
|
|||
comp.each(function(md,i) { |
|||
attr.components[i] = md.clone(1); |
|||
}); |
|||
traits.each(function(md, i) { |
|||
attr.traits[i] = md.clone(); |
|||
}); |
|||
cls.each(function(md,i) { |
|||
attr.classes[i] = md.get('name'); |
|||
}); |
|||
|
|||
attr.status = ''; |
|||
attr.view = ''; |
|||
|
|||
if(reset){ |
|||
this.opt.collection = null; |
|||
} |
|||
|
|||
return new this.constructor(attr, this.opt); |
|||
}, |
|||
|
|||
/** |
|||
* Get name of the component |
|||
* @return {string} |
|||
* @private |
|||
* */ |
|||
getName: function() { |
|||
if(!this.name){ |
|||
var id = this.cid.replace(/\D/g,''), |
|||
type = this.get('type'); |
|||
var tag = this.get('tagName'); |
|||
tag = tag == 'div' ? 'box' : tag; |
|||
tag = type ? type : tag; |
|||
this.name = tag.charAt(0).toUpperCase() + tag.slice(1); |
|||
} |
|||
return this.name; |
|||
}, |
|||
|
|||
/** |
|||
* Return HTML string of the component |
|||
* @param {Object} opts Options |
|||
* @return {string} HTML string |
|||
* @private |
|||
*/ |
|||
toHTML: function(opts) { |
|||
var code = ''; |
|||
var m = this; |
|||
var tag = m.get('tagName'), |
|||
sTag = m.get('void'), |
|||
attrId = ''; |
|||
// Build the string of attributes
|
|||
var strAttr = ''; |
|||
var attr = this.getAttrToHTML(); |
|||
for(var prop in attr){ |
|||
var val = attr[prop]; |
|||
strAttr += typeof val !== undefined && val !== '' ? |
|||
' ' + prop + '="' + val + '"' : ''; |
|||
} |
|||
// Build the string of classes
|
|||
var strCls = ''; |
|||
m.get('classes').each(function(m){ |
|||
strCls += ' ' + m.get('name'); |
|||
}); |
|||
strCls = strCls !== '' ? ' class="' + strCls.trim() + '"' : ''; |
|||
|
|||
},{ |
|||
// If style is not empty I need an ID attached to the component
|
|||
// TODO: need to refactor in case of 'ID Trait'
|
|||
if(!_.isEmpty(m.get('style'))) |
|||
attrId = ' id="' + m.cid + '" '; |
|||
|
|||
/** |
|||
* Detect if the passed element is a valid component. |
|||
* In case the element is valid an object abstracted |
|||
* from the element will be returned |
|||
* @param {HTMLElement} |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
isComponent: function(el) { |
|||
return {tagName: el.tagName ? el.tagName.toLowerCase() : ''}; |
|||
}, |
|||
code += '<' + tag + strCls + attrId + strAttr + (sTag ? '/' : '') + '>' + m.get('content'); |
|||
|
|||
m.get('components').each(function(m) { |
|||
code += m.toHTML(); |
|||
}); |
|||
}); |
|||
|
|||
if(!sTag) |
|||
code += '</'+tag+'>'; |
|||
|
|||
return code; |
|||
}, |
|||
|
|||
/** |
|||
* Returns object of attributes for HTML |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getAttrToHTML: function() { |
|||
var attr = this.get('attributes') || {}; |
|||
delete attr.style; |
|||
return attr; |
|||
}, |
|||
|
|||
/** |
|||
* Return a shallow copy of the model's attributes for JSON |
|||
* stringification. |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
toJSON: function() { |
|||
var obj = Backbone.Model.prototype.toJSON.apply(this, arguments); |
|||
var scriptStr = this.getScriptString(); |
|||
|
|||
if (scriptStr) { |
|||
obj.script = scriptStr; |
|||
} |
|||
|
|||
return obj; |
|||
}, |
|||
|
|||
/** |
|||
* Return script in string format, cleans 'function() {..' from scripts |
|||
* if it's a function |
|||
* @param {string|Function} script |
|||
* @return {string} |
|||
* @private |
|||
*/ |
|||
getScriptString: function (script) { |
|||
var scr = script || this.get('script'); |
|||
|
|||
// Need to cast script functions to string
|
|||
if (typeof scr == 'function') { |
|||
var scrStr = scr.toString().trim(); |
|||
scrStr = scrStr.replace(/^function\s?\(\)\s?\{/, ''); |
|||
scrStr = scrStr.replace(/\}$/, ''); |
|||
scr = scrStr; |
|||
} |
|||
|
|||
return scr; |
|||
} |
|||
|
|||
},{ |
|||
|
|||
/** |
|||
* Detect if the passed element is a valid component. |
|||
* In case the element is valid an object abstracted |
|||
* from the element will be returned |
|||
* @param {HTMLElement} |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
isComponent: function(el) { |
|||
return {tagName: el.tagName ? el.tagName.toLowerCase() : ''}; |
|||
}, |
|||
|
|||
}); |
|||
|
|||
@ -1,104 +1,101 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Component = require('./Component'); |
|||
var Component = require('./Component'); |
|||
|
|||
module.exports = Component.extend({ |
|||
module.exports = Component.extend({ |
|||
|
|||
defaults: _.extend({}, Component.prototype.defaults, { |
|||
type: 'image', |
|||
tagName: 'img', |
|||
src: '', |
|||
void: 1, |
|||
droppable: false, |
|||
resizable: true, |
|||
traits: ['alt'] |
|||
}), |
|||
defaults: _.extend({}, Component.prototype.defaults, { |
|||
type: 'image', |
|||
tagName: 'img', |
|||
src: '', |
|||
void: 1, |
|||
droppable: false, |
|||
resizable: true, |
|||
traits: ['alt'] |
|||
}), |
|||
|
|||
initialize: function(o, opt) { |
|||
Component.prototype.initialize.apply(this, arguments); |
|||
var attr = this.get('attributes'); |
|||
if(attr.src) |
|||
this.set('src', attr.src); |
|||
}, |
|||
initialize: function(o, opt) { |
|||
Component.prototype.initialize.apply(this, arguments); |
|||
var attr = this.get('attributes'); |
|||
if(attr.src) |
|||
this.set('src', attr.src); |
|||
}, |
|||
|
|||
initToolbar: function() { |
|||
Component.prototype.initToolbar.apply(this, arguments); |
|||
initToolbar: function() { |
|||
Component.prototype.initToolbar.apply(this, arguments); |
|||
|
|||
if (this.sm && this.sm.get) { |
|||
var cmd = this.sm.get('Commands'); |
|||
var cmdName = 'image-editor'; |
|||
if (this.sm && this.sm.get) { |
|||
var cmd = this.sm.get('Commands'); |
|||
var cmdName = 'image-editor'; |
|||
|
|||
// Add Image Editor button only if the default command exists
|
|||
if (cmd.has(cmdName)) { |
|||
var tb = this.get('toolbar'); |
|||
tb.push({ |
|||
attributes: {class: 'fa fa-pencil'}, |
|||
command: cmdName, |
|||
}); |
|||
this.set('toolbar', tb); |
|||
} |
|||
} |
|||
}, |
|||
// Add Image Editor button only if the default command exists
|
|||
if (cmd.has(cmdName)) { |
|||
var tb = this.get('toolbar'); |
|||
tb.push({ |
|||
attributes: {class: 'fa fa-pencil'}, |
|||
command: cmdName, |
|||
}); |
|||
this.set('toolbar', tb); |
|||
} |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Returns object of attributes for HTML |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getAttrToHTML: function() { |
|||
var attr = Component.prototype.getAttrToHTML.apply(this, arguments); |
|||
delete attr.onmousedown; |
|||
var src = this.get('src'); |
|||
if(src) |
|||
attr.src = src; |
|||
return attr; |
|||
}, |
|||
/** |
|||
* Returns object of attributes for HTML |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getAttrToHTML: function() { |
|||
var attr = Component.prototype.getAttrToHTML.apply(this, arguments); |
|||
delete attr.onmousedown; |
|||
var src = this.get('src'); |
|||
if(src) |
|||
attr.src = src; |
|||
return attr; |
|||
}, |
|||
|
|||
/** |
|||
* Parse uri |
|||
* @param {string} uri |
|||
* @return {object} |
|||
* @private |
|||
*/ |
|||
parseUri: function(uri) { |
|||
var el = document.createElement('a'); |
|||
el.href = uri; |
|||
var query = {}; |
|||
var qrs = el.search.substring(1).split('&'); |
|||
for (var i = 0; i < qrs.length; i++) { |
|||
var pair = qrs[i].split('='); |
|||
var name = decodeURIComponent(pair[0]); |
|||
if(name) |
|||
query[name] = decodeURIComponent(pair[1]); |
|||
} |
|||
return { |
|||
hostname: el.hostname, |
|||
pathname: el.pathname, |
|||
protocol: el.protocol, |
|||
search: el.search, |
|||
hash: el.hash, |
|||
port: el.port, |
|||
query: query, |
|||
}; |
|||
}, |
|||
/** |
|||
* Parse uri |
|||
* @param {string} uri |
|||
* @return {object} |
|||
* @private |
|||
*/ |
|||
parseUri: function(uri) { |
|||
var el = document.createElement('a'); |
|||
el.href = uri; |
|||
var query = {}; |
|||
var qrs = el.search.substring(1).split('&'); |
|||
for (var i = 0; i < qrs.length; i++) { |
|||
var pair = qrs[i].split('='); |
|||
var name = decodeURIComponent(pair[0]); |
|||
if(name) |
|||
query[name] = decodeURIComponent(pair[1]); |
|||
} |
|||
return { |
|||
hostname: el.hostname, |
|||
pathname: el.pathname, |
|||
protocol: el.protocol, |
|||
search: el.search, |
|||
hash: el.hash, |
|||
port: el.port, |
|||
query: query, |
|||
}; |
|||
}, |
|||
|
|||
},{ |
|||
},{ |
|||
|
|||
/** |
|||
* Detect if the passed element is a valid component. |
|||
* In case the element is valid an object abstracted |
|||
* from the element will be returned |
|||
* @param {HTMLElement} |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
isComponent: function(el) { |
|||
var result = ''; |
|||
if(el.tagName == 'IMG'){ |
|||
result = {type: 'image'}; |
|||
} |
|||
return result; |
|||
}, |
|||
/** |
|||
* Detect if the passed element is a valid component. |
|||
* In case the element is valid an object abstracted |
|||
* from the element will be returned |
|||
* @param {HTMLElement} |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
isComponent: function(el) { |
|||
var result = ''; |
|||
if(el.tagName == 'IMG'){ |
|||
result = {type: 'image'}; |
|||
} |
|||
return result; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,43 +1,40 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Component = require('./ComponentText'); |
|||
var Component = require('./ComponentText'); |
|||
|
|||
module.exports = Component.extend({ |
|||
module.exports = Component.extend({ |
|||
|
|||
defaults: _.extend({}, Component.prototype.defaults, { |
|||
type: 'link', |
|||
tagName: 'a', |
|||
traits: ['title', 'href', 'target'], |
|||
}), |
|||
defaults: _.extend({}, Component.prototype.defaults, { |
|||
type: 'link', |
|||
tagName: 'a', |
|||
traits: ['title', 'href', 'target'], |
|||
}), |
|||
|
|||
/** |
|||
* Returns object of attributes for HTML |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getAttrToHTML: function() { |
|||
var attr = Component.prototype.getAttrToHTML.apply(this, arguments); |
|||
delete attr.onmousedown; |
|||
return attr; |
|||
}, |
|||
/** |
|||
* Returns object of attributes for HTML |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getAttrToHTML: function() { |
|||
var attr = Component.prototype.getAttrToHTML.apply(this, arguments); |
|||
delete attr.onmousedown; |
|||
return attr; |
|||
}, |
|||
|
|||
},{ |
|||
},{ |
|||
|
|||
/** |
|||
* Detect if the passed element is a valid component. |
|||
* In case the element is valid an object abstracted |
|||
* from the element will be returned |
|||
* @param {HTMLElement} |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
isComponent: function(el) { |
|||
var result = ''; |
|||
if(el.tagName == 'A'){ |
|||
result = {type: 'link'}; |
|||
} |
|||
return result; |
|||
}, |
|||
/** |
|||
* Detect if the passed element is a valid component. |
|||
* In case the element is valid an object abstracted |
|||
* from the element will be returned |
|||
* @param {HTMLElement} |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
isComponent: function(el) { |
|||
var result = ''; |
|||
if(el.tagName == 'A'){ |
|||
result = {type: 'link'}; |
|||
} |
|||
return result; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,110 +1,107 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Component = require('./ComponentImage'); |
|||
var OComponent = require('./Component'); |
|||
var Component = require('./ComponentImage'); |
|||
var OComponent = require('./Component'); |
|||
|
|||
module.exports = Component.extend({ |
|||
module.exports = Component.extend({ |
|||
|
|||
defaults: _.extend({}, Component.prototype.defaults, { |
|||
type: 'map', |
|||
void: 0, |
|||
mapUrl: 'https://maps.google.com/maps', |
|||
tagName: 'iframe', |
|||
mapType: 'q', |
|||
address: '', |
|||
zoom: '1', |
|||
attributes: {frameborder: 0}, |
|||
toolbar: OComponent.prototype.defaults.toolbar, |
|||
traits: [{ |
|||
label: 'Address', |
|||
name: 'address', |
|||
placeholder: 'eg. London, UK', |
|||
changeProp: 1, |
|||
},{ |
|||
type: 'select', |
|||
label: 'Map type', |
|||
name: 'mapType', |
|||
changeProp: 1, |
|||
options: [ |
|||
{value: 'q', name: 'Roadmap'}, |
|||
{value: 'w', name: 'Satellite'} |
|||
] |
|||
},{ |
|||
label: 'Zoom', |
|||
name: 'zoom', |
|||
type: 'range', |
|||
min: '1', |
|||
max: '20', |
|||
changeProp: 1, |
|||
}], |
|||
}), |
|||
defaults: _.extend({}, Component.prototype.defaults, { |
|||
type: 'map', |
|||
void: 0, |
|||
mapUrl: 'https://maps.google.com/maps', |
|||
tagName: 'iframe', |
|||
mapType: 'q', |
|||
address: '', |
|||
zoom: '1', |
|||
attributes: {frameborder: 0}, |
|||
toolbar: OComponent.prototype.defaults.toolbar, |
|||
traits: [{ |
|||
label: 'Address', |
|||
name: 'address', |
|||
placeholder: 'eg. London, UK', |
|||
changeProp: 1, |
|||
},{ |
|||
type: 'select', |
|||
label: 'Map type', |
|||
name: 'mapType', |
|||
changeProp: 1, |
|||
options: [ |
|||
{value: 'q', name: 'Roadmap'}, |
|||
{value: 'w', name: 'Satellite'} |
|||
] |
|||
},{ |
|||
label: 'Zoom', |
|||
name: 'zoom', |
|||
type: 'range', |
|||
min: '1', |
|||
max: '20', |
|||
changeProp: 1, |
|||
}], |
|||
}), |
|||
|
|||
|
|||
initialize: function(o, opt) { |
|||
if(this.get('src')) |
|||
this.parseFromSrc(); |
|||
else |
|||
this.updateSrc(); |
|||
Component.prototype.initialize.apply(this, arguments); |
|||
this.listenTo(this, 'change:address change:zoom change:mapType', this.updateSrc); |
|||
}, |
|||
initialize: function(o, opt) { |
|||
if(this.get('src')) |
|||
this.parseFromSrc(); |
|||
else |
|||
this.updateSrc(); |
|||
Component.prototype.initialize.apply(this, arguments); |
|||
this.listenTo(this, 'change:address change:zoom change:mapType', this.updateSrc); |
|||
}, |
|||
|
|||
updateSrc: function() { |
|||
this.set('src', this.getMapUrl()); |
|||
}, |
|||
updateSrc: function() { |
|||
this.set('src', this.getMapUrl()); |
|||
}, |
|||
|
|||
/** |
|||
* Returns url of the map |
|||
* @return {string} |
|||
* @private |
|||
*/ |
|||
getMapUrl: function() { |
|||
var md = this; |
|||
var addr = md.get('address'); |
|||
var zoom = md.get('zoom'); |
|||
var type = md.get('mapType'); |
|||
var size = ''; |
|||
addr = addr ? '&q=' + addr : ''; |
|||
zoom = zoom ? '&z=' + zoom : ''; |
|||
type = type ? '&t=' + type : ''; |
|||
var result = md.get('mapUrl')+'?' + addr + zoom + type; |
|||
result += '&output=embed'; |
|||
return result; |
|||
}, |
|||
/** |
|||
* Returns url of the map |
|||
* @return {string} |
|||
* @private |
|||
*/ |
|||
getMapUrl: function() { |
|||
var md = this; |
|||
var addr = md.get('address'); |
|||
var zoom = md.get('zoom'); |
|||
var type = md.get('mapType'); |
|||
var size = ''; |
|||
addr = addr ? '&q=' + addr : ''; |
|||
zoom = zoom ? '&z=' + zoom : ''; |
|||
type = type ? '&t=' + type : ''; |
|||
var result = md.get('mapUrl')+'?' + addr + zoom + type; |
|||
result += '&output=embed'; |
|||
return result; |
|||
}, |
|||
|
|||
/** |
|||
* Set attributes by src string |
|||
* @private |
|||
*/ |
|||
parseFromSrc: function() { |
|||
var uri = this.parseUri(this.get('src')); |
|||
var qr = uri.query; |
|||
if(qr.q) |
|||
this.set('address', qr.q); |
|||
if(qr.z) |
|||
this.set('zoom', qr.z); |
|||
if(qr.t) |
|||
this.set('mapType', qr.t); |
|||
}, |
|||
/** |
|||
* Set attributes by src string |
|||
* @private |
|||
*/ |
|||
parseFromSrc: function() { |
|||
var uri = this.parseUri(this.get('src')); |
|||
var qr = uri.query; |
|||
if(qr.q) |
|||
this.set('address', qr.q); |
|||
if(qr.z) |
|||
this.set('zoom', qr.z); |
|||
if(qr.t) |
|||
this.set('mapType', qr.t); |
|||
}, |
|||
|
|||
},{ |
|||
},{ |
|||
|
|||
/** |
|||
* Detect if the passed element is a valid component. |
|||
* In case the element is valid an object abstracted |
|||
* from the element will be returned |
|||
* @param {HTMLElement} |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
isComponent: function(el) { |
|||
var result = ''; |
|||
if(el.tagName == 'IFRAME' && |
|||
/maps\.google\.com/.test(el.src) ){ |
|||
result = {type: 'map', src: el.src}; |
|||
} |
|||
return result; |
|||
}, |
|||
/** |
|||
* Detect if the passed element is a valid component. |
|||
* In case the element is valid an object abstracted |
|||
* from the element will be returned |
|||
* @param {HTMLElement} |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
isComponent: function(el) { |
|||
var result = ''; |
|||
if(el.tagName == 'IFRAME' && |
|||
/maps\.google\.com/.test(el.src) ){ |
|||
result = {type: 'map', src: el.src}; |
|||
} |
|||
return result; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,30 +1,27 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Component = require('./Component'); |
|||
var Component = require('./Component'); |
|||
|
|||
module.exports = Component.extend({ |
|||
module.exports = Component.extend({ |
|||
|
|||
defaults: _.extend({}, Component.prototype.defaults, { |
|||
type: 'script', |
|||
droppable: false, |
|||
draggable: false, |
|||
hiddenLayer: true, |
|||
}), |
|||
defaults: _.extend({}, Component.prototype.defaults, { |
|||
type: 'script', |
|||
droppable: false, |
|||
draggable: false, |
|||
hiddenLayer: true, |
|||
}), |
|||
|
|||
}, { |
|||
}, { |
|||
|
|||
isComponent: function(el) { |
|||
if (el.tagName == 'SCRIPT') { |
|||
var result = {type: 'script'}; |
|||
isComponent: function(el) { |
|||
if (el.tagName == 'SCRIPT') { |
|||
var result = {type: 'script'}; |
|||
|
|||
if (el.src) { |
|||
result.src = el.src; |
|||
result.onload = el.onload; |
|||
} |
|||
if (el.src) { |
|||
result.src = el.src; |
|||
result.onload = el.onload; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
}, |
|||
return result; |
|||
} |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,92 +1,89 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Component = require('./Component'); |
|||
var Component = require('./Component'); |
|||
|
|||
module.exports = Component.extend({ |
|||
module.exports = Component.extend({ |
|||
|
|||
defaults: _.extend({}, Component.prototype.defaults, { |
|||
type: 'table', |
|||
tagName: 'table', |
|||
droppable: ['tr', 'tbody', 'thead', 'tfoot'], |
|||
columns: 3, |
|||
rows: 2, |
|||
/* |
|||
traits: [{ |
|||
label: 'Columns', |
|||
name: 'columns', |
|||
changeProp: 1, |
|||
},{ |
|||
label: 'Rows', |
|||
name: 'rows', |
|||
changeProp: 1, |
|||
}] |
|||
*/ |
|||
}), |
|||
defaults: _.extend({}, Component.prototype.defaults, { |
|||
type: 'table', |
|||
tagName: 'table', |
|||
droppable: ['tr', 'tbody', 'thead', 'tfoot'], |
|||
columns: 3, |
|||
rows: 2, |
|||
/* |
|||
traits: [{ |
|||
label: 'Columns', |
|||
name: 'columns', |
|||
changeProp: 1, |
|||
},{ |
|||
label: 'Rows', |
|||
name: 'rows', |
|||
changeProp: 1, |
|||
}] |
|||
*/ |
|||
}), |
|||
|
|||
initialize: function(o, opt) { |
|||
Component.prototype.initialize.apply(this, arguments); |
|||
var components = this.get('components'); |
|||
var rows = this.get('rows'); |
|||
var columns = this.get('columns'); |
|||
initialize: function(o, opt) { |
|||
Component.prototype.initialize.apply(this, arguments); |
|||
var components = this.get('components'); |
|||
var rows = this.get('rows'); |
|||
var columns = this.get('columns'); |
|||
|
|||
// Init components if empty
|
|||
if(!components.length){ |
|||
var rowsToAdd = []; |
|||
// Init components if empty
|
|||
if(!components.length){ |
|||
var rowsToAdd = []; |
|||
|
|||
while(rows--){ |
|||
var columnsToAdd = []; |
|||
var clm = columns; |
|||
while(rows--){ |
|||
var columnsToAdd = []; |
|||
var clm = columns; |
|||
|
|||
while (clm--) { |
|||
columnsToAdd.push({ |
|||
type: 'cell', |
|||
classes: ['cell'] |
|||
}); |
|||
} |
|||
while (clm--) { |
|||
columnsToAdd.push({ |
|||
type: 'cell', |
|||
classes: ['cell'] |
|||
}); |
|||
} |
|||
|
|||
rowsToAdd.push({ |
|||
type: 'row', |
|||
classes: ['row'], |
|||
components: columnsToAdd |
|||
}); |
|||
} |
|||
components.add(rowsToAdd); |
|||
} |
|||
rowsToAdd.push({ |
|||
type: 'row', |
|||
classes: ['row'], |
|||
components: columnsToAdd |
|||
}); |
|||
} |
|||
components.add(rowsToAdd); |
|||
} |
|||
|
|||
// Clean table from non rows
|
|||
var rowsColl = []; |
|||
components.each(function(model){ |
|||
if(model.get('type') != 'row'){ |
|||
model.get('components').each(function(row) { |
|||
if(row.get('type') == 'row'){ |
|||
row.collection = components; |
|||
rowsColl.push(row); |
|||
} |
|||
}); |
|||
}else{ |
|||
rowsColl.push(model); |
|||
} |
|||
}); |
|||
components.reset(rowsColl); |
|||
}, |
|||
// Clean table from non rows
|
|||
var rowsColl = []; |
|||
components.each(function(model){ |
|||
if(model.get('type') != 'row'){ |
|||
model.get('components').each(function(row) { |
|||
if(row.get('type') == 'row'){ |
|||
row.collection = components; |
|||
rowsColl.push(row); |
|||
} |
|||
}); |
|||
}else{ |
|||
rowsColl.push(model); |
|||
} |
|||
}); |
|||
components.reset(rowsColl); |
|||
}, |
|||
|
|||
},{ |
|||
},{ |
|||
|
|||
/** |
|||
* Detect if the passed element is a valid component. |
|||
* In case the element is valid an object abstracted |
|||
* from the element will be returned |
|||
* @param {HTMLElement} |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
isComponent: function(el) { |
|||
var result = ''; |
|||
if(el.tagName == 'TABLE'){ |
|||
result = {type: 'table'}; |
|||
} |
|||
return result; |
|||
}, |
|||
/** |
|||
* Detect if the passed element is a valid component. |
|||
* In case the element is valid an object abstracted |
|||
* from the element will be returned |
|||
* @param {HTMLElement} |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
isComponent: function(el) { |
|||
var result = ''; |
|||
if(el.tagName == 'TABLE'){ |
|||
result = {type: 'table'}; |
|||
} |
|||
return result; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,36 +1,33 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Component = require('./Component'); |
|||
var Component = require('./Component'); |
|||
|
|||
module.exports = Component.extend({ |
|||
module.exports = Component.extend({ |
|||
|
|||
defaults: _.extend({}, Component.prototype.defaults, { |
|||
type: 'cell', |
|||
tagName: 'td', |
|||
draggable: ['tr'], |
|||
}), |
|||
defaults: _.extend({}, Component.prototype.defaults, { |
|||
type: 'cell', |
|||
tagName: 'td', |
|||
draggable: ['tr'], |
|||
}), |
|||
|
|||
},{ |
|||
},{ |
|||
|
|||
/** |
|||
* Detect if the passed element is a valid component. |
|||
* In case the element is valid an object abstracted |
|||
* from the element will be returned |
|||
* @param {HTMLElement} |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
isComponent: function(el) { |
|||
var result = ''; |
|||
var tag = el.tagName; |
|||
if(tag == 'TD' || tag == 'TH'){ |
|||
result = { |
|||
type: 'cell', |
|||
tagName: tag.toLowerCase() |
|||
}; |
|||
} |
|||
return result; |
|||
}, |
|||
/** |
|||
* Detect if the passed element is a valid component. |
|||
* In case the element is valid an object abstracted |
|||
* from the element will be returned |
|||
* @param {HTMLElement} |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
isComponent: function(el) { |
|||
var result = ''; |
|||
var tag = el.tagName; |
|||
if(tag == 'TD' || tag == 'TH'){ |
|||
result = { |
|||
type: 'cell', |
|||
tagName: tag.toLowerCase() |
|||
}; |
|||
} |
|||
return result; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,47 +1,44 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Component = require('./Component'); |
|||
var Component = require('./Component'); |
|||
|
|||
module.exports = Component.extend({ |
|||
module.exports = Component.extend({ |
|||
|
|||
defaults: _.extend({}, Component.prototype.defaults, { |
|||
type: 'row', |
|||
tagName: 'tr', |
|||
draggable: ['table', 'tbody', 'thead'], |
|||
droppable: ['th', 'td'] |
|||
}), |
|||
defaults: _.extend({}, Component.prototype.defaults, { |
|||
type: 'row', |
|||
tagName: 'tr', |
|||
draggable: ['table', 'tbody', 'thead'], |
|||
droppable: ['th', 'td'] |
|||
}), |
|||
|
|||
initialize: function(o, opt) { |
|||
Component.prototype.initialize.apply(this, arguments); |
|||
initialize: function(o, opt) { |
|||
Component.prototype.initialize.apply(this, arguments); |
|||
|
|||
// Clean the row from non cell components
|
|||
var cells = []; |
|||
var components = this.get('components'); |
|||
components.each(function(model){ |
|||
if(model.get('type') == 'cell'){ |
|||
cells.push(model); |
|||
} |
|||
}); |
|||
components.reset(cells); |
|||
} |
|||
// Clean the row from non cell components
|
|||
var cells = []; |
|||
var components = this.get('components'); |
|||
components.each(function(model){ |
|||
if(model.get('type') == 'cell'){ |
|||
cells.push(model); |
|||
} |
|||
}); |
|||
components.reset(cells); |
|||
} |
|||
|
|||
},{ |
|||
},{ |
|||
|
|||
/** |
|||
* Detect if the passed element is a valid component. |
|||
* In case the element is valid an object abstracted |
|||
* from the element will be returned |
|||
* @param {HTMLElement} |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
isComponent: function(el) { |
|||
var result = ''; |
|||
if(el.tagName == 'TR'){ |
|||
result = {type: 'row'}; |
|||
} |
|||
return result; |
|||
}, |
|||
/** |
|||
* Detect if the passed element is a valid component. |
|||
* In case the element is valid an object abstracted |
|||
* from the element will be returned |
|||
* @param {HTMLElement} |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
isComponent: function(el) { |
|||
var result = ''; |
|||
if(el.tagName == 'TR'){ |
|||
result = {type: 'row'}; |
|||
} |
|||
return result; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,14 +1,11 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Component = require('./Component'); |
|||
var Component = require('./Component'); |
|||
|
|||
module.exports = Component.extend({ |
|||
module.exports = Component.extend({ |
|||
|
|||
defaults: _.extend({}, Component.prototype.defaults, { |
|||
type: 'text', |
|||
droppable: false, |
|||
editable: true, |
|||
}), |
|||
defaults: _.extend({}, Component.prototype.defaults, { |
|||
type: 'text', |
|||
droppable: false, |
|||
editable: true, |
|||
}), |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,30 +1,27 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Component = require('./Component'); |
|||
var Component = require('./Component'); |
|||
|
|||
module.exports = Component.extend({ |
|||
module.exports = Component.extend({ |
|||
|
|||
defaults: _.extend({}, Component.prototype.defaults, { |
|||
droppable: false, |
|||
editable: true, |
|||
}), |
|||
defaults: _.extend({}, Component.prototype.defaults, { |
|||
droppable: false, |
|||
editable: true, |
|||
}), |
|||
|
|||
toHTML: function() { |
|||
return this.get('content'); |
|||
}, |
|||
toHTML: function() { |
|||
return this.get('content'); |
|||
}, |
|||
|
|||
}, { |
|||
}, { |
|||
|
|||
isComponent: function(el) { |
|||
var result = ''; |
|||
if(el.nodeType === 3){ |
|||
result = { |
|||
type: 'textnode', |
|||
content: el.textContent |
|||
}; |
|||
} |
|||
return result; |
|||
}, |
|||
isComponent: function(el) { |
|||
var result = ''; |
|||
if(el.nodeType === 3){ |
|||
result = { |
|||
type: 'textnode', |
|||
content: el.textContent |
|||
}; |
|||
} |
|||
return result; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,319 +1,316 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Component = require('./ComponentImage'); |
|||
var OComponent = require('./Component'); |
|||
var Component = require('./ComponentImage'); |
|||
var OComponent = require('./Component'); |
|||
|
|||
var yt = 'yt'; |
|||
var vi = 'vi'; |
|||
var yt = 'yt'; |
|||
var vi = 'vi'; |
|||
|
|||
module.exports = Component.extend({ |
|||
module.exports = Component.extend({ |
|||
|
|||
defaults: _.extend({}, Component.prototype.defaults, { |
|||
type: 'video', |
|||
tagName: 'video', |
|||
videoId: '', |
|||
void: 0, |
|||
provider: '', // on change of provider, traits are switched
|
|||
ytUrl: 'https://www.youtube.com/embed/', |
|||
viUrl: 'https://player.vimeo.com/video/', |
|||
loop: 0, |
|||
muted: 0, |
|||
autoplay: 0, |
|||
controls: 1, |
|||
color: '', |
|||
sources: [], |
|||
attributes:{allowfullscreen:'allowfullscreen'}, |
|||
toolbar: OComponent.prototype.defaults.toolbar, |
|||
}), |
|||
defaults: _.extend({}, Component.prototype.defaults, { |
|||
type: 'video', |
|||
tagName: 'video', |
|||
videoId: '', |
|||
void: 0, |
|||
provider: '', // on change of provider, traits are switched
|
|||
ytUrl: 'https://www.youtube.com/embed/', |
|||
viUrl: 'https://player.vimeo.com/video/', |
|||
loop: 0, |
|||
muted: 0, |
|||
autoplay: 0, |
|||
controls: 1, |
|||
color: '', |
|||
sources: [], |
|||
attributes:{allowfullscreen:'allowfullscreen'}, |
|||
toolbar: OComponent.prototype.defaults.toolbar, |
|||
}), |
|||
|
|||
initialize: function(o, opt) { |
|||
var traits = []; |
|||
var prov = this.get('provider'); |
|||
switch (prov) { |
|||
case yt: |
|||
traits = this.getYoutubeTraits(); |
|||
break; |
|||
case vi: |
|||
traits = this.getVimeoTraits(); |
|||
break; |
|||
default: |
|||
traits = this.getSourceTraits(); |
|||
} |
|||
if(this.get('src')) |
|||
this.parseFromSrc(); |
|||
this.set('traits', traits); |
|||
Component.prototype.initialize.apply(this, arguments); |
|||
this.listenTo(this, 'change:provider', this.updateTraits); |
|||
this.listenTo(this, 'change:videoId', this.updateSrc); |
|||
}, |
|||
initialize: function(o, opt) { |
|||
var traits = []; |
|||
var prov = this.get('provider'); |
|||
switch (prov) { |
|||
case yt: |
|||
traits = this.getYoutubeTraits(); |
|||
break; |
|||
case vi: |
|||
traits = this.getVimeoTraits(); |
|||
break; |
|||
default: |
|||
traits = this.getSourceTraits(); |
|||
} |
|||
if(this.get('src')) |
|||
this.parseFromSrc(); |
|||
this.set('traits', traits); |
|||
Component.prototype.initialize.apply(this, arguments); |
|||
this.listenTo(this, 'change:provider', this.updateTraits); |
|||
this.listenTo(this, 'change:videoId', this.updateSrc); |
|||
}, |
|||
|
|||
/** |
|||
* Set attributes by src string |
|||
*/ |
|||
parseFromSrc: function() { |
|||
var prov = this.get('provider'); |
|||
var uri = this.parseUri(this.get('src')); |
|||
var qr = uri.query; |
|||
switch (prov) { |
|||
case yt: case vi: |
|||
var videoId = uri.pathname.split('/').pop(); |
|||
this.set('videoId', videoId); |
|||
if(qr.autoplay) |
|||
this.set('autoplay', 1); |
|||
if(qr.loop) |
|||
this.set('loop', 1); |
|||
if(parseInt(qr.controls) === 0) |
|||
this.set('controls', 0); |
|||
if(qr.color) |
|||
this.set('color', qr.color); |
|||
break; |
|||
default: |
|||
} |
|||
}, |
|||
/** |
|||
* Set attributes by src string |
|||
*/ |
|||
parseFromSrc: function() { |
|||
var prov = this.get('provider'); |
|||
var uri = this.parseUri(this.get('src')); |
|||
var qr = uri.query; |
|||
switch (prov) { |
|||
case yt: case vi: |
|||
var videoId = uri.pathname.split('/').pop(); |
|||
this.set('videoId', videoId); |
|||
if(qr.autoplay) |
|||
this.set('autoplay', 1); |
|||
if(qr.loop) |
|||
this.set('loop', 1); |
|||
if(parseInt(qr.controls) === 0) |
|||
this.set('controls', 0); |
|||
if(qr.color) |
|||
this.set('color', qr.color); |
|||
break; |
|||
default: |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Update src on change of video ID |
|||
* @private |
|||
*/ |
|||
updateSrc: function() { |
|||
var prov = this.get('provider'); |
|||
switch (prov) { |
|||
case yt: |
|||
this.set('src',this.getYoutubeSrc()); |
|||
break; |
|||
case vi: |
|||
this.set('src',this.getVimeoSrc()); |
|||
break; |
|||
} |
|||
}, |
|||
/** |
|||
* Update src on change of video ID |
|||
* @private |
|||
*/ |
|||
updateSrc: function() { |
|||
var prov = this.get('provider'); |
|||
switch (prov) { |
|||
case yt: |
|||
this.set('src',this.getYoutubeSrc()); |
|||
break; |
|||
case vi: |
|||
this.set('src',this.getVimeoSrc()); |
|||
break; |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Returns object of attributes for HTML |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getAttrToHTML: function() { |
|||
var attr = Component.prototype.getAttrToHTML.apply(this, arguments); |
|||
var prov = this.get('provider'); |
|||
switch (prov) { |
|||
case yt: case vi: |
|||
break; |
|||
default: |
|||
if(this.get('loop')) |
|||
attr.loop = 'loop'; |
|||
if(this.get('autoplay')) |
|||
attr.autoplay = 'autoplay'; |
|||
if(this.get('controls')) |
|||
attr.controls = 'controls'; |
|||
} |
|||
return attr; |
|||
}, |
|||
/** |
|||
* Returns object of attributes for HTML |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getAttrToHTML: function() { |
|||
var attr = Component.prototype.getAttrToHTML.apply(this, arguments); |
|||
var prov = this.get('provider'); |
|||
switch (prov) { |
|||
case yt: case vi: |
|||
break; |
|||
default: |
|||
if(this.get('loop')) |
|||
attr.loop = 'loop'; |
|||
if(this.get('autoplay')) |
|||
attr.autoplay = 'autoplay'; |
|||
if(this.get('controls')) |
|||
attr.controls = 'controls'; |
|||
} |
|||
return attr; |
|||
}, |
|||
|
|||
/** |
|||
* Update traits by provider |
|||
* @private |
|||
*/ |
|||
updateTraits: function() { |
|||
var prov = this.get('provider'); |
|||
var traits = this.getSourceTraits(); |
|||
switch (prov) { |
|||
case yt: |
|||
this.set('tagName', 'iframe'); |
|||
traits = this.getYoutubeTraits(); |
|||
break; |
|||
case vi: |
|||
this.set('tagName', 'iframe'); |
|||
traits = this.getVimeoTraits(); |
|||
break; |
|||
default: |
|||
this.set('tagName', 'video'); |
|||
} |
|||
this.loadTraits(traits); |
|||
this.sm.trigger('change:selectedComponent'); |
|||
}, |
|||
/** |
|||
* Update traits by provider |
|||
* @private |
|||
*/ |
|||
updateTraits: function() { |
|||
var prov = this.get('provider'); |
|||
var traits = this.getSourceTraits(); |
|||
switch (prov) { |
|||
case yt: |
|||
this.set('tagName', 'iframe'); |
|||
traits = this.getYoutubeTraits(); |
|||
break; |
|||
case vi: |
|||
this.set('tagName', 'iframe'); |
|||
traits = this.getVimeoTraits(); |
|||
break; |
|||
default: |
|||
this.set('tagName', 'video'); |
|||
} |
|||
this.loadTraits(traits); |
|||
this.sm.trigger('change:selectedComponent'); |
|||
}, |
|||
|
|||
// Listen provider change and switch traits, in TraitView listen traits change
|
|||
// Listen provider change and switch traits, in TraitView listen traits change
|
|||
|
|||
/** |
|||
* Return the provider trait |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getProviderTrait: function() { |
|||
return { |
|||
type: 'select', |
|||
label: 'Provider', |
|||
name: 'provider', |
|||
changeProp: 1, |
|||
value: this.get('provider'), |
|||
options: [ |
|||
{value: 'so', name: 'HTML5 Source'}, |
|||
{value: yt, name: 'Youtube'}, |
|||
{value: vi, name: 'Vimeo'} |
|||
] |
|||
}; |
|||
}, |
|||
/** |
|||
* Return the provider trait |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getProviderTrait: function() { |
|||
return { |
|||
type: 'select', |
|||
label: 'Provider', |
|||
name: 'provider', |
|||
changeProp: 1, |
|||
value: this.get('provider'), |
|||
options: [ |
|||
{value: 'so', name: 'HTML5 Source'}, |
|||
{value: yt, name: 'Youtube'}, |
|||
{value: vi, name: 'Vimeo'} |
|||
] |
|||
}; |
|||
}, |
|||
|
|||
/** |
|||
* Return traits for the source provider |
|||
* @return {Array<Object>} |
|||
* @private |
|||
*/ |
|||
getSourceTraits: function() { |
|||
return [ |
|||
this.getProviderTrait(), { |
|||
label: 'Source', |
|||
name: 'src', |
|||
placeholder: 'eg. ./media/video.mp4', |
|||
changeProp: 1, |
|||
}, |
|||
this.getAutoplayTrait(), |
|||
this.getLoopTrait(), |
|||
this.getControlsTrait()]; |
|||
}, |
|||
/** |
|||
* Return traits for the source provider |
|||
* @return {Array<Object>} |
|||
* @private |
|||
*/ |
|||
getYoutubeTraits: function() { |
|||
return [ |
|||
this.getProviderTrait(), { |
|||
label: 'Video ID', |
|||
name: 'videoId', |
|||
placeholder: 'eg. jNQXAC9IVRw', |
|||
changeProp: 1, |
|||
}, |
|||
this.getAutoplayTrait(), |
|||
this.getLoopTrait(), |
|||
this.getControlsTrait() |
|||
]; |
|||
}, |
|||
/** |
|||
* Return traits for the source provider |
|||
* @return {Array<Object>} |
|||
* @private |
|||
*/ |
|||
getSourceTraits: function() { |
|||
return [ |
|||
this.getProviderTrait(), { |
|||
label: 'Source', |
|||
name: 'src', |
|||
placeholder: 'eg. ./media/video.mp4', |
|||
changeProp: 1, |
|||
}, |
|||
this.getAutoplayTrait(), |
|||
this.getLoopTrait(), |
|||
this.getControlsTrait()]; |
|||
}, |
|||
/** |
|||
* Return traits for the source provider |
|||
* @return {Array<Object>} |
|||
* @private |
|||
*/ |
|||
getYoutubeTraits: function() { |
|||
return [ |
|||
this.getProviderTrait(), { |
|||
label: 'Video ID', |
|||
name: 'videoId', |
|||
placeholder: 'eg. jNQXAC9IVRw', |
|||
changeProp: 1, |
|||
}, |
|||
this.getAutoplayTrait(), |
|||
this.getLoopTrait(), |
|||
this.getControlsTrait() |
|||
]; |
|||
}, |
|||
|
|||
/** |
|||
* Return traits for the source provider |
|||
* @return {Array<Object>} |
|||
* @private |
|||
*/ |
|||
getVimeoTraits: function() { |
|||
return [ |
|||
this.getProviderTrait(), { |
|||
label: 'Video ID', |
|||
name: 'videoId', |
|||
placeholder: 'eg. 123456789', |
|||
changeProp: 1, |
|||
},{ |
|||
label: 'Color', |
|||
name: 'color', |
|||
placeholder: 'eg. FF0000', |
|||
changeProp: 1, |
|||
}, |
|||
this.getAutoplayTrait(), |
|||
this.getLoopTrait(), |
|||
this.getControlsTrait()]; |
|||
}, |
|||
/** |
|||
* Return traits for the source provider |
|||
* @return {Array<Object>} |
|||
* @private |
|||
*/ |
|||
getVimeoTraits: function() { |
|||
return [ |
|||
this.getProviderTrait(), { |
|||
label: 'Video ID', |
|||
name: 'videoId', |
|||
placeholder: 'eg. 123456789', |
|||
changeProp: 1, |
|||
},{ |
|||
label: 'Color', |
|||
name: 'color', |
|||
placeholder: 'eg. FF0000', |
|||
changeProp: 1, |
|||
}, |
|||
this.getAutoplayTrait(), |
|||
this.getLoopTrait(), |
|||
this.getControlsTrait()]; |
|||
}, |
|||
|
|||
/** |
|||
* Return object trait |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getAutoplayTrait: function(){ |
|||
return { |
|||
type: 'checkbox', |
|||
label: 'Autoplay', |
|||
name: 'autoplay', |
|||
changeProp: 1, |
|||
}; |
|||
}, |
|||
/** |
|||
* Return object trait |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getAutoplayTrait: function(){ |
|||
return { |
|||
type: 'checkbox', |
|||
label: 'Autoplay', |
|||
name: 'autoplay', |
|||
changeProp: 1, |
|||
}; |
|||
}, |
|||
|
|||
/** |
|||
* Return object trait |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getLoopTrait: function(){ |
|||
return { |
|||
type: 'checkbox', |
|||
label: 'Loop', |
|||
name: 'loop', |
|||
changeProp: 1, |
|||
}; |
|||
}, |
|||
/** |
|||
* Return object trait |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getLoopTrait: function(){ |
|||
return { |
|||
type: 'checkbox', |
|||
label: 'Loop', |
|||
name: 'loop', |
|||
changeProp: 1, |
|||
}; |
|||
}, |
|||
|
|||
/** |
|||
* Return object trait |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getControlsTrait: function(){ |
|||
return { |
|||
type: 'checkbox', |
|||
label: 'Controls', |
|||
name: 'controls', |
|||
changeProp: 1, |
|||
}; |
|||
}, |
|||
/** |
|||
* Return object trait |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
getControlsTrait: function(){ |
|||
return { |
|||
type: 'checkbox', |
|||
label: 'Controls', |
|||
name: 'controls', |
|||
changeProp: 1, |
|||
}; |
|||
}, |
|||
|
|||
|
|||
/** |
|||
* Returns url to youtube video |
|||
* @return {string} |
|||
* @private |
|||
*/ |
|||
getYoutubeSrc: function() { |
|||
var url = this.get('ytUrl'); |
|||
url += this.get('videoId') + '?'; |
|||
url += this.get('autoplay') ? '&autoplay=1' : ''; |
|||
url += !this.get('controls') ? '&controls=0' : ''; |
|||
url += this.get('loop') ? '&loop=1' : ''; |
|||
return url; |
|||
}, |
|||
/** |
|||
* Returns url to youtube video |
|||
* @return {string} |
|||
* @private |
|||
*/ |
|||
getYoutubeSrc: function() { |
|||
var url = this.get('ytUrl'); |
|||
url += this.get('videoId') + '?'; |
|||
url += this.get('autoplay') ? '&autoplay=1' : ''; |
|||
url += !this.get('controls') ? '&controls=0' : ''; |
|||
url += this.get('loop') ? '&loop=1' : ''; |
|||
return url; |
|||
}, |
|||
|
|||
/** |
|||
* Returns url to vimeo video |
|||
* @return {string} |
|||
* @private |
|||
*/ |
|||
getVimeoSrc: function() { |
|||
var url = this.get('viUrl'); |
|||
url += this.get('videoId') + '?'; |
|||
url += this.get('autoplay') ? '&autoplay=1' : ''; |
|||
url += this.get('loop') ? '&loop=1' : ''; |
|||
url += !this.get('controls') ? '&title=0&portrait=0&badge=0' : ''; |
|||
url += this.get('color') ? '&color=' + this.get('color') : ''; |
|||
return url; |
|||
}, |
|||
/** |
|||
* Returns url to vimeo video |
|||
* @return {string} |
|||
* @private |
|||
*/ |
|||
getVimeoSrc: function() { |
|||
var url = this.get('viUrl'); |
|||
url += this.get('videoId') + '?'; |
|||
url += this.get('autoplay') ? '&autoplay=1' : ''; |
|||
url += this.get('loop') ? '&loop=1' : ''; |
|||
url += !this.get('controls') ? '&title=0&portrait=0&badge=0' : ''; |
|||
url += this.get('color') ? '&color=' + this.get('color') : ''; |
|||
return url; |
|||
}, |
|||
|
|||
},{ |
|||
},{ |
|||
|
|||
/** |
|||
* Detect if the passed element is a valid component. |
|||
* In case the element is valid an object abstracted |
|||
* from the element will be returned |
|||
* @param {HTMLElement} |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
isComponent: function(el) { |
|||
var result = ''; |
|||
var isYtProv = /youtube\.com\/embed/.test(el.src); |
|||
var isViProv = /player\.vimeo\.com\/video/.test(el.src); |
|||
var isExtProv = isYtProv || isViProv; |
|||
if(el.tagName == 'VIDEO' || |
|||
(el.tagName == 'IFRAME' && isExtProv) ){ |
|||
result = {type: 'video'}; |
|||
if(el.src) |
|||
result.src = el.src; |
|||
if(isExtProv){ |
|||
if(isYtProv) |
|||
result.provider = yt; |
|||
else if(isViProv) |
|||
result.provider = vi; |
|||
} |
|||
} |
|||
return result; |
|||
}, |
|||
/** |
|||
* Detect if the passed element is a valid component. |
|||
* In case the element is valid an object abstracted |
|||
* from the element will be returned |
|||
* @param {HTMLElement} |
|||
* @return {Object} |
|||
* @private |
|||
*/ |
|||
isComponent: function(el) { |
|||
var result = ''; |
|||
var isYtProv = /youtube\.com\/embed/.test(el.src); |
|||
var isViProv = /player\.vimeo\.com\/video/.test(el.src); |
|||
var isExtProv = isYtProv || isViProv; |
|||
if(el.tagName == 'VIDEO' || |
|||
(el.tagName == 'IFRAME' && isExtProv) ){ |
|||
result = {type: 'video'}; |
|||
if(el.src) |
|||
result.src = el.src; |
|||
if(isExtProv){ |
|||
if(isYtProv) |
|||
result.provider = yt; |
|||
else if(isViProv) |
|||
result.provider = vi; |
|||
} |
|||
} |
|||
return result; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,81 +1,78 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var Backbone = require('backbone'); |
|||
|
|||
module.exports = Backbone.Collection.extend({ |
|||
module.exports = Backbone.Collection.extend({ |
|||
|
|||
initialize: function(models, opt){ |
|||
initialize: function(models, opt){ |
|||
|
|||
this.on('add', this.onAdd); |
|||
this.on('add', this.onAdd); |
|||
|
|||
this.config = opt && opt.config ? opt.config : null; |
|||
this.config = opt && opt.config ? opt.config : null; |
|||
|
|||
// Inject editor
|
|||
if(opt && opt.sm) |
|||
this.editor = opt.sm; |
|||
// Inject editor
|
|||
if(opt && opt.sm) |
|||
this.editor = opt.sm; |
|||
|
|||
this.model = function(attrs, options) { |
|||
var model; |
|||
this.model = function(attrs, options) { |
|||
var model; |
|||
|
|||
if(!options.sm && opt && opt.sm) |
|||
options.sm = opt.sm; |
|||
if(!options.sm && opt && opt.sm) |
|||
options.sm = opt.sm; |
|||
|
|||
if(opt && opt.config) |
|||
options.config = opt.config; |
|||
if(opt && opt.config) |
|||
options.config = opt.config; |
|||
|
|||
if(opt && opt.defaultTypes) |
|||
options.defaultTypes = opt.defaultTypes; |
|||
if(opt && opt.defaultTypes) |
|||
options.defaultTypes = opt.defaultTypes; |
|||
|
|||
if(opt && opt.componentTypes) |
|||
options.componentTypes = opt.componentTypes; |
|||
if(opt && opt.componentTypes) |
|||
options.componentTypes = opt.componentTypes; |
|||
|
|||
var df = opt.defaultTypes; |
|||
var df = opt.defaultTypes; |
|||
|
|||
for (var it = 0; it < df.length; it++) { |
|||
var dfId = df[it].id; |
|||
if(dfId == attrs.type) { |
|||
model = df[it].model; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
if(!model) { |
|||
// get the last one
|
|||
model = df[df.length - 1].model; |
|||
} |
|||
|
|||
return new model(attrs, options); |
|||
}; |
|||
|
|||
}, |
|||
|
|||
add: function(models, opt){ |
|||
if(typeof models === 'string'){ |
|||
var parsed = this.editor.get('Parser').parseHtml(models); |
|||
models = parsed.html; |
|||
|
|||
var cssc = this.editor.get('CssComposer'); |
|||
if(parsed.css && cssc){ |
|||
var added = cssc.addCollection(parsed.css, {extend: 1}); |
|||
} |
|||
} |
|||
|
|||
return Backbone.Collection.prototype.add.apply(this, [models, opt]); |
|||
}, |
|||
|
|||
onAdd: function(model, c, opts){ |
|||
var style = model.get('style'); |
|||
var em = this.editor; |
|||
|
|||
if(!_.isEmpty(style) && em && em.get('Config').forceClass){ |
|||
var cssC = this.editor.get('CssComposer'); |
|||
var newClass = this.editor.get('SelectorManager').add(model.cid); |
|||
model.set({style:{}}); |
|||
model.get('classes').add(newClass); |
|||
var rule = cssC.add(newClass); |
|||
rule.set('style', style); |
|||
for (var it = 0; it < df.length; it++) { |
|||
var dfId = df[it].id; |
|||
if(dfId == attrs.type) { |
|||
model = df[it].model; |
|||
break; |
|||
} |
|||
}, |
|||
} |
|||
|
|||
if(!model) { |
|||
// get the last one
|
|||
model = df[df.length - 1].model; |
|||
} |
|||
|
|||
return new model(attrs, options); |
|||
}; |
|||
|
|||
}, |
|||
|
|||
add: function(models, opt){ |
|||
if(typeof models === 'string'){ |
|||
var parsed = this.editor.get('Parser').parseHtml(models); |
|||
models = parsed.html; |
|||
|
|||
var cssc = this.editor.get('CssComposer'); |
|||
if(parsed.css && cssc){ |
|||
var added = cssc.addCollection(parsed.css, {extend: 1}); |
|||
} |
|||
} |
|||
|
|||
return Backbone.Collection.prototype.add.apply(this, [models, opt]); |
|||
}, |
|||
|
|||
onAdd: function(model, c, opts){ |
|||
var style = model.get('style'); |
|||
var em = this.editor; |
|||
|
|||
if(!_.isEmpty(style) && em && em.get('Config').forceClass){ |
|||
var cssC = this.editor.get('CssComposer'); |
|||
var newClass = this.editor.get('SelectorManager').add(model.cid); |
|||
model.set({style:{}}); |
|||
model.get('classes').add(newClass); |
|||
var rule = cssC.add(newClass); |
|||
rule.set('style', style); |
|||
} |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
|
|||
@ -1,8 +1,4 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var ToolbarButton = require('./ToolbarButton'); |
|||
var Backbone = require('backbone'); |
|||
var ToolbarButton = require('./ToolbarButton'); |
|||
|
|||
module.exports = Backbone.Collection.extend({model: ToolbarButton}); |
|||
|
|||
}); |
|||
module.exports = Backbone.Collection.extend({model: ToolbarButton}); |
|||
|
|||
@ -1,14 +1,10 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var Backbone = require('backbone'); |
|||
|
|||
module.exports = Backbone.Model.extend({ |
|||
module.exports = Backbone.Model.extend({ |
|||
|
|||
defaults: { |
|||
command: '', |
|||
attributes: {}, |
|||
}, |
|||
defaults: { |
|||
command: '', |
|||
attributes: {}, |
|||
}, |
|||
|
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,74 +1,71 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var ComponentView = require('./ComponentView'); |
|||
var Backbone = require('backbone'); |
|||
var ComponentView = require('./ComponentView'); |
|||
|
|||
module.exports = ComponentView.extend({ |
|||
module.exports = ComponentView.extend({ |
|||
|
|||
tagName: 'img', |
|||
tagName: 'img', |
|||
|
|||
events: { |
|||
'dblclick': 'openModal', |
|||
'click': 'initResize', |
|||
}, |
|||
events: { |
|||
'dblclick': 'openModal', |
|||
'click': 'initResize', |
|||
}, |
|||
|
|||
initialize: function(o) { |
|||
ComponentView.prototype.initialize.apply(this, arguments); |
|||
this.listenTo(this.model, 'change:src', this.updateSrc); |
|||
this.listenTo(this.model, 'dblclick active', this.openModal); |
|||
this.classEmpty = this.ppfx + 'plh-image'; |
|||
initialize: function(o) { |
|||
ComponentView.prototype.initialize.apply(this, arguments); |
|||
this.listenTo(this.model, 'change:src', this.updateSrc); |
|||
this.listenTo(this.model, 'dblclick active', this.openModal); |
|||
this.classEmpty = this.ppfx + 'plh-image'; |
|||
|
|||
if(this.config.modal) |
|||
this.modal = this.config.modal; |
|||
if(this.config.modal) |
|||
this.modal = this.config.modal; |
|||
|
|||
if(this.config.am) |
|||
this.am = this.config.am; |
|||
}, |
|||
if(this.config.am) |
|||
this.am = this.config.am; |
|||
}, |
|||
|
|||
/** |
|||
* Update src attribute |
|||
* @private |
|||
* */ |
|||
updateSrc: function() { |
|||
var src = this.model.get("src"); |
|||
this.$el.attr('src', src); |
|||
if(!src) |
|||
this.$el.addClass(this.classEmpty); |
|||
else |
|||
this.$el.removeClass(this.classEmpty); |
|||
}, |
|||
/** |
|||
* Update src attribute |
|||
* @private |
|||
* */ |
|||
updateSrc: function() { |
|||
var src = this.model.get("src"); |
|||
this.$el.attr('src', src); |
|||
if(!src) |
|||
this.$el.addClass(this.classEmpty); |
|||
else |
|||
this.$el.removeClass(this.classEmpty); |
|||
}, |
|||
|
|||
/** |
|||
* Open dialog for image changing |
|||
* @param {Object} e Event |
|||
* @private |
|||
* */ |
|||
openModal: function(e) { |
|||
var em = this.opts.config.em; |
|||
var editor = em ? em.get('Editor') : ''; |
|||
/** |
|||
* Open dialog for image changing |
|||
* @param {Object} e Event |
|||
* @private |
|||
* */ |
|||
openModal: function(e) { |
|||
var em = this.opts.config.em; |
|||
var editor = em ? em.get('Editor') : ''; |
|||
|
|||
if(editor) { |
|||
editor.runCommand('open-assets', { |
|||
target: this.model, |
|||
onSelect: function() { |
|||
editor.Modal.close(); |
|||
editor.AssetManager.setTarget(null); |
|||
} |
|||
}); |
|||
} |
|||
}, |
|||
if(editor) { |
|||
editor.runCommand('open-assets', { |
|||
target: this.model, |
|||
onSelect: function() { |
|||
editor.Modal.close(); |
|||
editor.AssetManager.setTarget(null); |
|||
} |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
render: function() { |
|||
this.updateAttributes(); |
|||
this.updateClasses(); |
|||
render: function() { |
|||
this.updateAttributes(); |
|||
this.updateClasses(); |
|||
|
|||
var actCls = this.$el.attr('class') || ''; |
|||
if(!this.model.get('src')) |
|||
this.$el.attr('class', (actCls + ' ' + this.classEmpty).trim()); |
|||
var actCls = this.$el.attr('class') || ''; |
|||
if(!this.model.get('src')) |
|||
this.$el.attr('class', (actCls + ' ' + this.classEmpty).trim()); |
|||
|
|||
// Avoid strange behaviours while try to drag
|
|||
this.$el.attr('onmousedown', 'return false'); |
|||
return this; |
|||
}, |
|||
}); |
|||
}); |
|||
// Avoid strange behaviours while try to drag
|
|||
this.$el.attr('onmousedown', 'return false'); |
|||
return this; |
|||
}, |
|||
}); |
|||
|
|||
@ -1,23 +1,20 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var ComponentView = require('./ComponentTextView'); |
|||
var Backbone = require('backbone'); |
|||
var ComponentView = require('./ComponentTextView'); |
|||
|
|||
module.exports = ComponentView.extend({ |
|||
module.exports = ComponentView.extend({ |
|||
|
|||
events: { |
|||
'dblclick': 'enableEditing', |
|||
}, |
|||
events: { |
|||
'dblclick': 'enableEditing', |
|||
}, |
|||
|
|||
render: function() { |
|||
ComponentView.prototype.render.apply(this, arguments); |
|||
render: function() { |
|||
ComponentView.prototype.render.apply(this, arguments); |
|||
|
|||
// I need capturing instead of bubbling as bubbled clicks from other
|
|||
// children will execute the link event
|
|||
this.el.addEventListener('click', this.prevDef, true); |
|||
// I need capturing instead of bubbling as bubbled clicks from other
|
|||
// children will execute the link event
|
|||
this.el.addEventListener('click', this.prevDef, true); |
|||
|
|||
return this; |
|||
}, |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,46 +1,43 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var ComponentView = require('./ComponentImageView'); |
|||
|
|||
module.exports = ComponentView.extend({ |
|||
|
|||
tagName: 'div', |
|||
|
|||
events: {}, |
|||
|
|||
initialize: function(o){ |
|||
ComponentView.prototype.initialize.apply(this, arguments); |
|||
this.classEmpty = this.ppfx + 'plh-map'; |
|||
}, |
|||
|
|||
/** |
|||
* Update the map on the canvas |
|||
* @private |
|||
*/ |
|||
updateSrc: function() { |
|||
this.getIframe().src = this.model.get('src'); |
|||
}, |
|||
|
|||
getIframe: function() { |
|||
if(!this.iframe){ |
|||
var ifrm = document.createElement("iframe"); |
|||
ifrm.src = this.model.get('src'); |
|||
ifrm.frameBorder = 0; |
|||
ifrm.style.height = '100%'; |
|||
ifrm.style.width = '100%'; |
|||
ifrm.className = this.ppfx + 'no-pointer'; |
|||
this.iframe = ifrm; |
|||
} |
|||
return this.iframe; |
|||
}, |
|||
|
|||
render: function() { |
|||
ComponentView.prototype.render.apply(this, arguments); |
|||
this.updateClasses(); |
|||
this.el.appendChild(this.getIframe()); |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
var Backbone = require('backbone'); |
|||
var ComponentView = require('./ComponentImageView'); |
|||
|
|||
module.exports = ComponentView.extend({ |
|||
|
|||
tagName: 'div', |
|||
|
|||
events: {}, |
|||
|
|||
initialize: function(o){ |
|||
ComponentView.prototype.initialize.apply(this, arguments); |
|||
this.classEmpty = this.ppfx + 'plh-map'; |
|||
}, |
|||
|
|||
/** |
|||
* Update the map on the canvas |
|||
* @private |
|||
*/ |
|||
updateSrc: function() { |
|||
this.getIframe().src = this.model.get('src'); |
|||
}, |
|||
|
|||
getIframe: function() { |
|||
if(!this.iframe){ |
|||
var ifrm = document.createElement("iframe"); |
|||
ifrm.src = this.model.get('src'); |
|||
ifrm.frameBorder = 0; |
|||
ifrm.style.height = '100%'; |
|||
ifrm.style.width = '100%'; |
|||
ifrm.className = this.ppfx + 'no-pointer'; |
|||
this.iframe = ifrm; |
|||
} |
|||
return this.iframe; |
|||
}, |
|||
|
|||
render: function() { |
|||
ComponentView.prototype.render.apply(this, arguments); |
|||
this.updateClasses(); |
|||
this.el.appendChild(this.getIframe()); |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
|
|||
@ -1,44 +1,41 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var ComponentView = require('./ComponentImageView'); |
|||
var Backbone = require('backbone'); |
|||
var ComponentView = require('./ComponentImageView'); |
|||
|
|||
module.exports = ComponentView.extend({ |
|||
module.exports = ComponentView.extend({ |
|||
|
|||
tagName: 'script', |
|||
tagName: 'script', |
|||
|
|||
events: {}, |
|||
events: {}, |
|||
|
|||
render: function() { |
|||
var model = this.model; |
|||
var src = model.get('src'); |
|||
var em = this.em; |
|||
var scriptCount = em && em.get('scriptCount') ? em.get('scriptCount') : 0; |
|||
var content = ''; |
|||
render: function() { |
|||
var model = this.model; |
|||
var src = model.get('src'); |
|||
var em = this.em; |
|||
var scriptCount = em && em.get('scriptCount') ? em.get('scriptCount') : 0; |
|||
var content = ''; |
|||
|
|||
// If it's an external script
|
|||
if(src) { |
|||
var onload = model.get('onload'); |
|||
var svar = 'script' + scriptCount; |
|||
var svarNext = 'script' + (scriptCount + 1); |
|||
content = "var "+svar+" = document.createElement('script');\n" + |
|||
svar+".onload = function(){\n" + |
|||
(onload ? onload + "();\n" : '') + |
|||
"typeof "+svarNext+"Start == 'function' && "+svarNext+"Start();\n" + |
|||
"};\n" + |
|||
svar+".src = '" + src + "';\n"+ |
|||
"function "+svar+"Start() { document.body.appendChild("+svar+"); };\n" + |
|||
(!scriptCount ? svar+"Start();" : ''); |
|||
if(em){ |
|||
em.set('scriptCount', scriptCount + 1); |
|||
} |
|||
} else { |
|||
content = model.get('content'); |
|||
// If it's an external script
|
|||
if(src) { |
|||
var onload = model.get('onload'); |
|||
var svar = 'script' + scriptCount; |
|||
var svarNext = 'script' + (scriptCount + 1); |
|||
content = "var "+svar+" = document.createElement('script');\n" + |
|||
svar+".onload = function(){\n" + |
|||
(onload ? onload + "();\n" : '') + |
|||
"typeof "+svarNext+"Start == 'function' && "+svarNext+"Start();\n" + |
|||
"};\n" + |
|||
svar+".src = '" + src + "';\n"+ |
|||
"function "+svar+"Start() { document.body.appendChild("+svar+"); };\n" + |
|||
(!scriptCount ? svar+"Start();" : ''); |
|||
if(em){ |
|||
em.set('scriptCount', scriptCount + 1); |
|||
} |
|||
} else { |
|||
content = model.get('content'); |
|||
} |
|||
|
|||
this.el.innerHTML = content; |
|||
return this; |
|||
}, |
|||
this.el.innerHTML = content; |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,8 +1,4 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var ComponentView = require('./ComponentView'); |
|||
var Backbone = require('backbone'); |
|||
var ComponentView = require('./ComponentView'); |
|||
|
|||
module.exports = ComponentView.extend({ |
|||
}); |
|||
}); |
|||
module.exports = ComponentView.extend({}); |
|||
|
|||
@ -1,8 +1,4 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var ComponentView = require('./ComponentView'); |
|||
var Backbone = require('backbone'); |
|||
var ComponentView = require('./ComponentView'); |
|||
|
|||
module.exports = ComponentView.extend({ |
|||
}); |
|||
}); |
|||
module.exports = ComponentView.extend({}); |
|||
|
|||
@ -1,11 +1,6 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var ComponentView = require('./ComponentView'); |
|||
var Backbone = require('backbone'); |
|||
var ComponentView = require('./ComponentView'); |
|||
|
|||
module.exports = ComponentView.extend({ |
|||
|
|||
events: {}, |
|||
|
|||
}); |
|||
}); |
|||
module.exports = ComponentView.extend({ |
|||
events: {}, |
|||
}); |
|||
|
|||
@ -1,6 +1,3 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var Backbone = require('backbone'); |
|||
|
|||
module.exports = Backbone.View.extend({}); |
|||
}); |
|||
module.exports = Backbone.View.extend({}); |
|||
|
|||
@ -1,113 +1,110 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var ComponentView = require('./ComponentView'); |
|||
|
|||
module.exports = ComponentView.extend({ |
|||
|
|||
events: { |
|||
'dblclick': 'enableEditing', |
|||
'change': 'parseRender', |
|||
}, |
|||
|
|||
initialize: function(o) { |
|||
ComponentView.prototype.initialize.apply(this, arguments); |
|||
_.bindAll(this,'disableEditing'); |
|||
this.listenTo(this.model, 'focus active', this.enableEditing); |
|||
this.rte = this.config.rte || ''; |
|||
this.activeRte = null; |
|||
this.em = this.config.em; |
|||
}, |
|||
|
|||
/** |
|||
* Enable the component to be editable |
|||
* @param {Event} e |
|||
* @private |
|||
* */ |
|||
enableEditing: function(e) { |
|||
var editable = this.model.get('editable'); |
|||
if(this.rte && editable) { |
|||
try { |
|||
this.activeRte = this.rte.attach(this, this.activeRte); |
|||
this.rte.focus(this, this.activeRte); |
|||
} catch (err) { |
|||
console.error(err); |
|||
} |
|||
} |
|||
this.toggleEvents(1); |
|||
}, |
|||
|
|||
/** |
|||
* Disable this component to be editable |
|||
* @param {Event} |
|||
* @private |
|||
* */ |
|||
disableEditing: function(e) { |
|||
var model = this.model; |
|||
var editable = model.get('editable'); |
|||
|
|||
if(this.rte && editable) { |
|||
try { |
|||
this.rte.detach(this, this.activeRte); |
|||
} catch (err) { |
|||
var Backbone = require('backbone'); |
|||
var ComponentView = require('./ComponentView'); |
|||
|
|||
module.exports = ComponentView.extend({ |
|||
|
|||
events: { |
|||
'dblclick': 'enableEditing', |
|||
'change': 'parseRender', |
|||
}, |
|||
|
|||
initialize: function(o) { |
|||
ComponentView.prototype.initialize.apply(this, arguments); |
|||
_.bindAll(this,'disableEditing'); |
|||
this.listenTo(this.model, 'focus active', this.enableEditing); |
|||
this.rte = this.config.rte || ''; |
|||
this.activeRte = null; |
|||
this.em = this.config.em; |
|||
}, |
|||
|
|||
/** |
|||
* Enable the component to be editable |
|||
* @param {Event} e |
|||
* @private |
|||
* */ |
|||
enableEditing: function(e) { |
|||
var editable = this.model.get('editable'); |
|||
if(this.rte && editable) { |
|||
try { |
|||
this.activeRte = this.rte.attach(this, this.activeRte); |
|||
this.rte.focus(this, this.activeRte); |
|||
} catch (err) { |
|||
console.error(err); |
|||
} |
|||
var el = this.getChildrenContainer(); |
|||
model.set('content', el.innerHTML); |
|||
} |
|||
|
|||
if(!this.rte.customRte && editable) { |
|||
this.parseRender(); |
|||
} |
|||
this.toggleEvents(1); |
|||
}, |
|||
|
|||
/** |
|||
* Disable this component to be editable |
|||
* @param {Event} |
|||
* @private |
|||
* */ |
|||
disableEditing: function(e) { |
|||
var model = this.model; |
|||
var editable = model.get('editable'); |
|||
|
|||
if(this.rte && editable) { |
|||
try { |
|||
this.rte.detach(this, this.activeRte); |
|||
} catch (err) { |
|||
console.error(err); |
|||
} |
|||
|
|||
this.toggleEvents(); |
|||
}, |
|||
|
|||
/** |
|||
* Isolate disable propagation method |
|||
* @param {Event} |
|||
* @private |
|||
* */ |
|||
disablePropagation: function(e){ |
|||
e.stopPropagation(); |
|||
}, |
|||
|
|||
/** |
|||
* Parse content and re-render it |
|||
* @private |
|||
*/ |
|||
parseRender: function() { |
|||
var el = this.getChildrenContainer(); |
|||
var comps = this.model.get('components'); |
|||
var opts = {silent: true}; |
|||
|
|||
// Avoid re-render on reset with silent option
|
|||
comps.reset(null, opts); |
|||
comps.add(el.innerHTML, opts); |
|||
this.model.set('content', ''); |
|||
this.render(); |
|||
|
|||
// As the reset was in silent mode I need to notify
|
|||
// the navigator about the change
|
|||
comps.trigger('resetNavigator'); |
|||
}, |
|||
|
|||
/** |
|||
* Enable/Disable events |
|||
* @param {Boolean} enable |
|||
*/ |
|||
toggleEvents: function(enable) { |
|||
var method = enable ? 'on' : 'off'; |
|||
|
|||
// The ownerDocument is from the frame
|
|||
var elDocs = [this.el.ownerDocument, document, this.rte]; |
|||
$(elDocs).off('mousedown', this.disableEditing); |
|||
$(elDocs)[method]('mousedown', this.disableEditing); |
|||
|
|||
// Avoid closing edit mode on component click
|
|||
this.$el.off('mousedown', this.disablePropagation); |
|||
this.$el[method]('mousedown', this.disablePropagation); |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
model.set('content', el.innerHTML); |
|||
} |
|||
|
|||
if(!this.rte.customRte && editable) { |
|||
this.parseRender(); |
|||
} |
|||
|
|||
this.toggleEvents(); |
|||
}, |
|||
|
|||
/** |
|||
* Isolate disable propagation method |
|||
* @param {Event} |
|||
* @private |
|||
* */ |
|||
disablePropagation: function(e){ |
|||
e.stopPropagation(); |
|||
}, |
|||
|
|||
/** |
|||
* Parse content and re-render it |
|||
* @private |
|||
*/ |
|||
parseRender: function() { |
|||
var el = this.getChildrenContainer(); |
|||
var comps = this.model.get('components'); |
|||
var opts = {silent: true}; |
|||
|
|||
// Avoid re-render on reset with silent option
|
|||
comps.reset(null, opts); |
|||
comps.add(el.innerHTML, opts); |
|||
this.model.set('content', ''); |
|||
this.render(); |
|||
|
|||
// As the reset was in silent mode I need to notify
|
|||
// the navigator about the change
|
|||
comps.trigger('resetNavigator'); |
|||
}, |
|||
|
|||
/** |
|||
* Enable/Disable events |
|||
* @param {Boolean} enable |
|||
*/ |
|||
toggleEvents: function(enable) { |
|||
var method = enable ? 'on' : 'off'; |
|||
|
|||
// The ownerDocument is from the frame
|
|||
var elDocs = [this.el.ownerDocument, document, this.rte]; |
|||
$(elDocs).off('mousedown', this.disableEditing); |
|||
$(elDocs)[method]('mousedown', this.disableEditing); |
|||
|
|||
// Avoid closing edit mode on component click
|
|||
this.$el.off('mousedown', this.disablePropagation); |
|||
this.$el[method]('mousedown', this.disablePropagation); |
|||
}, |
|||
|
|||
}); |
|||
|
|||
@ -1,121 +1,118 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var ComponentView = require('./ComponentImageView'); |
|||
var Backbone = require('backbone'); |
|||
var ComponentView = require('./ComponentImageView'); |
|||
|
|||
module.exports = ComponentView.extend({ |
|||
module.exports = ComponentView.extend({ |
|||
|
|||
tagName: 'div', |
|||
tagName: 'div', |
|||
|
|||
events: {}, |
|||
events: {}, |
|||
|
|||
initialize: function(o){ |
|||
ComponentView.prototype.initialize.apply(this, arguments); |
|||
this.listenTo(this.model, 'change:loop change:autoplay change:controls change:color', this.updateVideo); |
|||
this.listenTo(this.model, 'change:provider', this.updateProvider); |
|||
}, |
|||
initialize: function(o){ |
|||
ComponentView.prototype.initialize.apply(this, arguments); |
|||
this.listenTo(this.model, 'change:loop change:autoplay change:controls change:color', this.updateVideo); |
|||
this.listenTo(this.model, 'change:provider', this.updateProvider); |
|||
}, |
|||
|
|||
/** |
|||
* Rerender on update of the provider |
|||
* @private |
|||
*/ |
|||
updateProvider: function() { |
|||
var prov = this.model.get('provider'); |
|||
this.el.innerHTML = ''; |
|||
this.el.appendChild(this.renderByProvider(prov)); |
|||
}, |
|||
/** |
|||
* Rerender on update of the provider |
|||
* @private |
|||
*/ |
|||
updateProvider: function() { |
|||
var prov = this.model.get('provider'); |
|||
this.el.innerHTML = ''; |
|||
this.el.appendChild(this.renderByProvider(prov)); |
|||
}, |
|||
|
|||
/** |
|||
* Update the source of the video |
|||
* @private |
|||
*/ |
|||
updateSrc: function() { |
|||
var prov = this.model.get('provider'); |
|||
var src = this.model.get('src'); |
|||
switch (prov) { |
|||
case 'yt': |
|||
src = this.model.getYoutubeSrc(); |
|||
break; |
|||
case 'vi': |
|||
src = this.model.getVimeoSrc(); |
|||
break; |
|||
} |
|||
this.videoEl.src = src; |
|||
}, |
|||
/** |
|||
* Update the source of the video |
|||
* @private |
|||
*/ |
|||
updateSrc: function() { |
|||
var prov = this.model.get('provider'); |
|||
var src = this.model.get('src'); |
|||
switch (prov) { |
|||
case 'yt': |
|||
src = this.model.getYoutubeSrc(); |
|||
break; |
|||
case 'vi': |
|||
src = this.model.getVimeoSrc(); |
|||
break; |
|||
} |
|||
this.videoEl.src = src; |
|||
}, |
|||
|
|||
/** |
|||
* Update video parameters |
|||
* @private |
|||
*/ |
|||
updateVideo: function() { |
|||
var prov = this.model.get('provider'); |
|||
var videoEl = this.videoEl; |
|||
var md = this.model; |
|||
switch (prov) { |
|||
case 'yt': case 'vi': |
|||
this.model.trigger('change:videoId'); |
|||
break; |
|||
default: |
|||
videoEl.loop = md.get('loop'); |
|||
videoEl.autoplay = md.get('autoplay'); |
|||
videoEl.controls = md.get('controls'); |
|||
} |
|||
}, |
|||
/** |
|||
* Update video parameters |
|||
* @private |
|||
*/ |
|||
updateVideo: function() { |
|||
var prov = this.model.get('provider'); |
|||
var videoEl = this.videoEl; |
|||
var md = this.model; |
|||
switch (prov) { |
|||
case 'yt': case 'vi': |
|||
this.model.trigger('change:videoId'); |
|||
break; |
|||
default: |
|||
videoEl.loop = md.get('loop'); |
|||
videoEl.autoplay = md.get('autoplay'); |
|||
videoEl.controls = md.get('controls'); |
|||
} |
|||
}, |
|||
|
|||
renderByProvider: function(prov) { |
|||
var videoEl; |
|||
switch (prov) { |
|||
case 'yt': |
|||
videoEl = this.renderYoutube(); |
|||
break; |
|||
case 'vi': |
|||
videoEl = this.renderVimeo(); |
|||
break; |
|||
default: |
|||
videoEl = this.renderSource(); |
|||
} |
|||
this.videoEl = videoEl; |
|||
return videoEl; |
|||
}, |
|||
renderByProvider: function(prov) { |
|||
var videoEl; |
|||
switch (prov) { |
|||
case 'yt': |
|||
videoEl = this.renderYoutube(); |
|||
break; |
|||
case 'vi': |
|||
videoEl = this.renderVimeo(); |
|||
break; |
|||
default: |
|||
videoEl = this.renderSource(); |
|||
} |
|||
this.videoEl = videoEl; |
|||
return videoEl; |
|||
}, |
|||
|
|||
renderSource: function() { |
|||
var el = document.createElement('video'); |
|||
el.src = this.model.get('src'); |
|||
this.initVideoEl(el); |
|||
return el; |
|||
}, |
|||
renderSource: function() { |
|||
var el = document.createElement('video'); |
|||
el.src = this.model.get('src'); |
|||
this.initVideoEl(el); |
|||
return el; |
|||
}, |
|||
|
|||
renderYoutube: function() { |
|||
var el = document.createElement('iframe'); |
|||
el.src = this.model.getYoutubeSrc(); |
|||
el.frameBorder = 0; |
|||
el.setAttribute('allowfullscreen', true); |
|||
this.initVideoEl(el); |
|||
return el; |
|||
}, |
|||
renderYoutube: function() { |
|||
var el = document.createElement('iframe'); |
|||
el.src = this.model.getYoutubeSrc(); |
|||
el.frameBorder = 0; |
|||
el.setAttribute('allowfullscreen', true); |
|||
this.initVideoEl(el); |
|||
return el; |
|||
}, |
|||
|
|||
renderVimeo: function() { |
|||
var el = document.createElement('iframe'); |
|||
el.src = this.model.getVimeoSrc(); |
|||
el.frameBorder = 0; |
|||
el.setAttribute('allowfullscreen', true); |
|||
this.initVideoEl(el); |
|||
return el; |
|||
}, |
|||
renderVimeo: function() { |
|||
var el = document.createElement('iframe'); |
|||
el.src = this.model.getVimeoSrc(); |
|||
el.frameBorder = 0; |
|||
el.setAttribute('allowfullscreen', true); |
|||
this.initVideoEl(el); |
|||
return el; |
|||
}, |
|||
|
|||
initVideoEl: function(el){ |
|||
el.className = this.ppfx + 'no-pointer'; |
|||
el.style.height = '100%'; |
|||
el.style.width = '100%'; |
|||
}, |
|||
initVideoEl: function(el){ |
|||
el.className = this.ppfx + 'no-pointer'; |
|||
el.style.height = '100%'; |
|||
el.style.width = '100%'; |
|||
}, |
|||
|
|||
render: function() { |
|||
ComponentView.prototype.render.apply(this, arguments); |
|||
this.updateClasses(); |
|||
var prov = this.model.get('provider'); |
|||
this.el.appendChild(this.renderByProvider(prov)); |
|||
return this; |
|||
}, |
|||
render: function() { |
|||
ComponentView.prototype.render.apply(this, arguments); |
|||
this.updateClasses(); |
|||
var prov = this.model.get('provider'); |
|||
this.el.appendChild(this.renderByProvider(prov)); |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,397 +1,394 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var ComponentsView = require('./ComponentsView'); |
|||
|
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
events: { |
|||
'click': 'initResize', |
|||
}, |
|||
|
|||
className : function(){ |
|||
return this.getClasses(); |
|||
}, |
|||
|
|||
tagName: function(){ |
|||
return this.model.get('tagName'); |
|||
}, |
|||
|
|||
initialize: function(opt) { |
|||
var model = this.model; |
|||
this.opts = opt || {}; |
|||
this.config = this.opts.config || {}; |
|||
this.em = this.config.em || ''; |
|||
this.pfx = this.config.stylePrefix || ''; |
|||
this.ppfx = this.config.pStylePrefix || ''; |
|||
this.components = model.get('components'); |
|||
this.attr = model.get("attributes"); |
|||
this.classe = this.attr.class || []; |
|||
this.listenTo(model, 'destroy remove', this.remove); |
|||
this.listenTo(model, 'change:style', this.updateStyle); |
|||
this.listenTo(model, 'change:attributes', this.updateAttributes); |
|||
this.listenTo(model, 'change:status', this.updateStatus); |
|||
this.listenTo(model, 'change:state', this.updateState); |
|||
this.listenTo(model, 'change:script', this.render); |
|||
this.listenTo(model, 'change', this.handleChange); |
|||
this.listenTo(model.get('classes'), 'add remove change', this.updateClasses); |
|||
this.$el.data('model', model); |
|||
model.view = this; |
|||
this.$el.data("collection", this.components); |
|||
|
|||
if(model.get('classes').length) |
|||
this.importClasses(); |
|||
|
|||
this.init(); |
|||
}, |
|||
|
|||
/** |
|||
* Initialize callback |
|||
*/ |
|||
init: function () {}, |
|||
|
|||
/** |
|||
* Handle any property change |
|||
* @private |
|||
*/ |
|||
handleChange: function () { |
|||
var em = this.em; |
|||
if(em) { |
|||
var model = this.model; |
|||
em.trigger('component:update', model); |
|||
|
|||
for(var prop in model.changed) { |
|||
em.trigger('component:update:' + prop, model); |
|||
var Backbone = require('backbone'); |
|||
var ComponentsView = require('./ComponentsView'); |
|||
|
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
events: { |
|||
'click': 'initResize', |
|||
}, |
|||
|
|||
className : function(){ |
|||
return this.getClasses(); |
|||
}, |
|||
|
|||
tagName: function(){ |
|||
return this.model.get('tagName'); |
|||
}, |
|||
|
|||
initialize: function(opt) { |
|||
var model = this.model; |
|||
this.opts = opt || {}; |
|||
this.config = this.opts.config || {}; |
|||
this.em = this.config.em || ''; |
|||
this.pfx = this.config.stylePrefix || ''; |
|||
this.ppfx = this.config.pStylePrefix || ''; |
|||
this.components = model.get('components'); |
|||
this.attr = model.get("attributes"); |
|||
this.classe = this.attr.class || []; |
|||
this.listenTo(model, 'destroy remove', this.remove); |
|||
this.listenTo(model, 'change:style', this.updateStyle); |
|||
this.listenTo(model, 'change:attributes', this.updateAttributes); |
|||
this.listenTo(model, 'change:status', this.updateStatus); |
|||
this.listenTo(model, 'change:state', this.updateState); |
|||
this.listenTo(model, 'change:script', this.render); |
|||
this.listenTo(model, 'change', this.handleChange); |
|||
this.listenTo(model.get('classes'), 'add remove change', this.updateClasses); |
|||
this.$el.data('model', model); |
|||
model.view = this; |
|||
this.$el.data("collection", this.components); |
|||
|
|||
if(model.get('classes').length) |
|||
this.importClasses(); |
|||
|
|||
this.init(); |
|||
}, |
|||
|
|||
/** |
|||
* Initialize callback |
|||
*/ |
|||
init: function () {}, |
|||
|
|||
/** |
|||
* Handle any property change |
|||
* @private |
|||
*/ |
|||
handleChange: function () { |
|||
var em = this.em; |
|||
if(em) { |
|||
var model = this.model; |
|||
em.trigger('component:update', model); |
|||
|
|||
for(var prop in model.changed) { |
|||
em.trigger('component:update:' + prop, model); |
|||
} |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Import, if possible, classes inside main container |
|||
* @private |
|||
* */ |
|||
importClasses: function(){ |
|||
var clm = this.config.em.get('SelectorManager'); |
|||
|
|||
if(clm){ |
|||
this.model.get('classes').each(function(m){ |
|||
clm.add(m.get('name')); |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Fires on state update. If the state is not empty will add a helper class |
|||
* @param {Event} e |
|||
* @private |
|||
* */ |
|||
updateState: function(e){ |
|||
var cl = 'hc-state'; |
|||
var state = this.model.get('state'); |
|||
|
|||
if(state){ |
|||
this.$el.addClass(cl); |
|||
}else{ |
|||
this.$el.removeClass(cl); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Update item on status change |
|||
* @param {Event} e |
|||
* @private |
|||
* */ |
|||
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'); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Get classes from attributes. |
|||
* This method is called before initialize |
|||
* |
|||
* @return {Array}|null |
|||
* @private |
|||
* */ |
|||
getClasses: function(){ |
|||
var attr = this.model.get("attributes"), |
|||
classes = attr['class'] || []; |
|||
if(classes.length){ |
|||
return classes.join(" "); |
|||
}else |
|||
return null; |
|||
}, |
|||
|
|||
/** |
|||
* Update attributes |
|||
* @private |
|||
* */ |
|||
updateAttributes: function() { |
|||
var model = this.model; |
|||
var attributes = {}, |
|||
attr = model.get("attributes"); |
|||
for(var key in attr) { |
|||
if(attr.hasOwnProperty(key)) |
|||
attributes[key] = attr[key]; |
|||
} |
|||
|
|||
// Update src
|
|||
if(model.get('src')) |
|||
attributes.src = model.get('src'); |
|||
|
|||
if(model.get('highlightable')) |
|||
attributes['data-highlightable'] = 1; |
|||
|
|||
var styleStr = this.getStyleString(); |
|||
|
|||
if(styleStr) |
|||
attributes.style = styleStr; |
|||
|
|||
this.$el.attr(attributes); |
|||
}, |
|||
|
|||
/** |
|||
* Update style attribute |
|||
* @private |
|||
* */ |
|||
updateStyle: function(){ |
|||
this.$el.attr('style', this.getStyleString()); |
|||
}, |
|||
|
|||
/** |
|||
* Return style string |
|||
* @return {string} |
|||
* @private |
|||
* */ |
|||
getStyleString: function(){ |
|||
var style = ''; |
|||
this.style = this.model.get('style'); |
|||
for(var key in this.style) { |
|||
if(this.style.hasOwnProperty(key)) |
|||
style += key + ':' + this.style[key] + ';'; |
|||
} |
|||
|
|||
return style; |
|||
}, |
|||
|
|||
/** |
|||
* Update classe attribute |
|||
* @private |
|||
* */ |
|||
updateClasses: function(){ |
|||
var str = ''; |
|||
|
|||
this.model.get('classes').each(function(model){ |
|||
str += model.get('name') + ' '; |
|||
}); |
|||
str = str.trim(); |
|||
|
|||
if(str) |
|||
this.$el.attr('class', str); |
|||
else |
|||
this.$el.removeAttr('class'); |
|||
|
|||
// Regenerate status class
|
|||
this.updateStatus(); |
|||
}, |
|||
|
|||
/** |
|||
* Reply to event call |
|||
* @param object Event that generated the request |
|||
* @private |
|||
* */ |
|||
eventCall: function(event){ |
|||
event.viewResponse = this; |
|||
}, |
|||
|
|||
/** |
|||
* Init component for resizing |
|||
*/ |
|||
initResize: function () { |
|||
var em = this.opts.config.em; |
|||
var editor = em ? em.get('Editor') : ''; |
|||
var config = em ? em.get('Config') : ''; |
|||
var pfx = config.stylePrefix || ''; |
|||
var attrName = 'data-' + pfx + 'handler'; |
|||
var resizeClass = pfx + 'resizing'; |
|||
var model = this.model; |
|||
var modelToStyle; |
|||
|
|||
var toggleBodyClass = function(method, e, opts) { |
|||
var handlerAttr = e.target.getAttribute(attrName); |
|||
var resizeHndClass = pfx + 'resizing-' + handlerAttr; |
|||
var classToAdd = resizeClass;// + ' ' +resizeHndClass;
|
|||
if (opts.docs) { |
|||
opts.docs.find('body')[method](classToAdd); |
|||
} |
|||
}; |
|||
|
|||
if(editor && this.model.get('resizable')) { |
|||
editor.runCommand('resize', { |
|||
el: this.el, |
|||
options: { |
|||
onStart: function (e, opts) { |
|||
toggleBodyClass('addClass', e, opts); |
|||
modelToStyle = em.get('StyleManager').getModelToStyle(model); |
|||
}, |
|||
// Update all positioned elements (eg. component toolbar)
|
|||
onMove: function () { |
|||
editor.trigger('change:canvasOffset'); |
|||
}, |
|||
onEnd: function (e, opts) { |
|||
toggleBodyClass('removeClass', e, opts); |
|||
editor.trigger('change:canvasOffset'); |
|||
}, |
|||
updateTarget: function(el, rect, store) { |
|||
if (!modelToStyle) { |
|||
return; |
|||
} |
|||
var unit = 'px'; |
|||
var style = _.clone(modelToStyle.get('style')); |
|||
var width = rect.w + (store ? 1 : 0); |
|||
style.width = width + unit; |
|||
style.height = rect.h + unit; |
|||
modelToStyle.set('style', style, {avoidStore: 1}); |
|||
em.trigger('targetStyleUpdated'); |
|||
|
|||
// This trick will trigger the Undo Manager. To trigger "change:style"
|
|||
// 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
|
|||
// above I've added + 1 to width if store required)
|
|||
if(store) { |
|||
var style3 = _.clone(style); |
|||
style3.width = (width - 1) + unit; |
|||
modelToStyle.set('style', style3); |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Import, if possible, classes inside main container |
|||
* @private |
|||
* */ |
|||
importClasses: function(){ |
|||
var clm = this.config.em.get('SelectorManager'); |
|||
|
|||
if(clm){ |
|||
this.model.get('classes').each(function(m){ |
|||
clm.add(m.get('name')); |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Fires on state update. If the state is not empty will add a helper class |
|||
* @param {Event} e |
|||
* @private |
|||
* */ |
|||
updateState: function(e){ |
|||
var cl = 'hc-state'; |
|||
var state = this.model.get('state'); |
|||
|
|||
if(state){ |
|||
this.$el.addClass(cl); |
|||
}else{ |
|||
this.$el.removeClass(cl); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Update item on status change |
|||
* @param {Event} e |
|||
* @private |
|||
* */ |
|||
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'); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Get classes from attributes. |
|||
* This method is called before initialize |
|||
* |
|||
* @return {Array}|null |
|||
* @private |
|||
* */ |
|||
getClasses: function(){ |
|||
var attr = this.model.get("attributes"), |
|||
classes = attr['class'] || []; |
|||
if(classes.length){ |
|||
return classes.join(" "); |
|||
}else |
|||
return null; |
|||
}, |
|||
|
|||
/** |
|||
* Update attributes |
|||
* @private |
|||
* */ |
|||
updateAttributes: function() { |
|||
var model = this.model; |
|||
var attributes = {}, |
|||
attr = model.get("attributes"); |
|||
for(var key in attr) { |
|||
if(attr.hasOwnProperty(key)) |
|||
attributes[key] = attr[key]; |
|||
} |
|||
|
|||
// Update src
|
|||
if(model.get('src')) |
|||
attributes.src = model.get('src'); |
|||
|
|||
if(model.get('highlightable')) |
|||
attributes['data-highlightable'] = 1; |
|||
|
|||
var styleStr = this.getStyleString(); |
|||
|
|||
if(styleStr) |
|||
attributes.style = styleStr; |
|||
|
|||
this.$el.attr(attributes); |
|||
}, |
|||
|
|||
/** |
|||
* Update style attribute |
|||
* @private |
|||
* */ |
|||
updateStyle: function(){ |
|||
this.$el.attr('style', this.getStyleString()); |
|||
}, |
|||
|
|||
/** |
|||
* Return style string |
|||
* @return {string} |
|||
* @private |
|||
* */ |
|||
getStyleString: function(){ |
|||
var style = ''; |
|||
this.style = this.model.get('style'); |
|||
for(var key in this.style) { |
|||
if(this.style.hasOwnProperty(key)) |
|||
style += key + ':' + this.style[key] + ';'; |
|||
} |
|||
|
|||
return style; |
|||
}, |
|||
|
|||
/** |
|||
* Update classe attribute |
|||
* @private |
|||
* */ |
|||
updateClasses: function(){ |
|||
var str = ''; |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Prevent default helper |
|||
* @param {Event} e |
|||
* @private |
|||
*/ |
|||
prevDef: function (e) { |
|||
e.preventDefault(); |
|||
}, |
|||
|
|||
/** |
|||
* Render component's script |
|||
* @private |
|||
*/ |
|||
updateScript: function () { |
|||
var em = this.em; |
|||
if(em) { |
|||
var canvas = em.get('Canvas'); |
|||
canvas.getCanvasView().updateScript(this); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Return children container |
|||
* Differently from a simple component where children container is the |
|||
* component itself |
|||
* <my-comp> |
|||
* <!-- |
|||
* <child></child> ... |
|||
* --> |
|||
* </my-comp> |
|||
* You could have the children container more deeper |
|||
* <my-comp> |
|||
* <div></div> |
|||
* <div></div> |
|||
* <div> |
|||
* <div> |
|||
* <!-- |
|||
* <child></child> ... |
|||
* --> |
|||
* </div> |
|||
* </div> |
|||
* </my-comp> |
|||
* @return HTMLElement |
|||
* @private |
|||
*/ |
|||
getChildrenContainer: function() { |
|||
var container = this.el; |
|||
|
|||
if (typeof this.getChildrenSelector == 'function') { |
|||
container = this.el.querySelector(this.getChildrenSelector()); |
|||
} else if (typeof this.getTemplate == 'function') { |
|||
// Need to find deepest first child
|
|||
} |
|||
|
|||
return container; |
|||
}, |
|||
|
|||
/** |
|||
* Render children components |
|||
* @private |
|||
*/ |
|||
renderChildren: function() { |
|||
var view = new ComponentsView({ |
|||
collection: this.model.get('components'), |
|||
config: this.config, |
|||
defaultTypes: this.opts.defaultTypes, |
|||
componentTypes: this.opts.componentTypes, |
|||
}); |
|||
|
|||
this.model.get('classes').each(function(model){ |
|||
str += model.get('name') + ' '; |
|||
}); |
|||
str = str.trim(); |
|||
|
|||
if(str) |
|||
this.$el.attr('class', str); |
|||
else |
|||
this.$el.removeAttr('class'); |
|||
|
|||
// Regenerate status class
|
|||
this.updateStatus(); |
|||
}, |
|||
|
|||
/** |
|||
* Reply to event call |
|||
* @param object Event that generated the request |
|||
* @private |
|||
* */ |
|||
eventCall: function(event){ |
|||
event.viewResponse = this; |
|||
}, |
|||
|
|||
/** |
|||
* Init component for resizing |
|||
*/ |
|||
initResize: function () { |
|||
var em = this.opts.config.em; |
|||
var editor = em ? em.get('Editor') : ''; |
|||
var config = em ? em.get('Config') : ''; |
|||
var pfx = config.stylePrefix || ''; |
|||
var attrName = 'data-' + pfx + 'handler'; |
|||
var resizeClass = pfx + 'resizing'; |
|||
var model = this.model; |
|||
var modelToStyle; |
|||
|
|||
var toggleBodyClass = function(method, e, opts) { |
|||
var handlerAttr = e.target.getAttribute(attrName); |
|||
var resizeHndClass = pfx + 'resizing-' + handlerAttr; |
|||
var classToAdd = resizeClass;// + ' ' +resizeHndClass;
|
|||
if (opts.docs) { |
|||
opts.docs.find('body')[method](classToAdd); |
|||
var container = this.getChildrenContainer(); |
|||
var childNodes = view.render($(container)).el.childNodes; |
|||
childNodes = Array.prototype.slice.call(childNodes); |
|||
|
|||
for (var i = 0, len = childNodes.length ; i < len; i++) { |
|||
container.appendChild(childNodes.shift()); |
|||
} |
|||
|
|||
// If the children container is not the same as the component
|
|||
// (so likely fetched with getChildrenSelector()) is necessary
|
|||
// to disable pointer-events for all nested components as they
|
|||
// might prevent the component to be selected
|
|||
if (container !== this.el) { |
|||
var disableNode = function(el) { |
|||
var children = Array.prototype.slice.call(el.children); |
|||
children.forEach(function (el) { |
|||
el.style['pointer-events'] = 'none'; |
|||
if (container !== el) { |
|||
disableNode(el); |
|||
} |
|||
}; |
|||
|
|||
if(editor && this.model.get('resizable')) { |
|||
editor.runCommand('resize', { |
|||
el: this.el, |
|||
options: { |
|||
onStart: function (e, opts) { |
|||
toggleBodyClass('addClass', e, opts); |
|||
modelToStyle = em.get('StyleManager').getModelToStyle(model); |
|||
}, |
|||
// Update all positioned elements (eg. component toolbar)
|
|||
onMove: function () { |
|||
editor.trigger('change:canvasOffset'); |
|||
}, |
|||
onEnd: function (e, opts) { |
|||
toggleBodyClass('removeClass', e, opts); |
|||
editor.trigger('change:canvasOffset'); |
|||
}, |
|||
updateTarget: function(el, rect, store) { |
|||
if (!modelToStyle) { |
|||
return; |
|||
} |
|||
var unit = 'px'; |
|||
var style = _.clone(modelToStyle.get('style')); |
|||
var width = rect.w + (store ? 1 : 0); |
|||
style.width = width + unit; |
|||
style.height = rect.h + unit; |
|||
modelToStyle.set('style', style, {avoidStore: 1}); |
|||
em.trigger('targetStyleUpdated'); |
|||
|
|||
// This trick will trigger the Undo Manager. To trigger "change:style"
|
|||
// 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
|
|||
// above I've added + 1 to width if store required)
|
|||
if(store) { |
|||
var style3 = _.clone(style); |
|||
style3.width = (width - 1) + unit; |
|||
modelToStyle.set('style', style3); |
|||
} |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Prevent default helper |
|||
* @param {Event} e |
|||
* @private |
|||
*/ |
|||
prevDef: function (e) { |
|||
e.preventDefault(); |
|||
}, |
|||
|
|||
/** |
|||
* Render component's script |
|||
* @private |
|||
*/ |
|||
updateScript: function () { |
|||
var em = this.em; |
|||
if(em) { |
|||
var canvas = em.get('Canvas'); |
|||
canvas.getCanvasView().updateScript(this); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Return children container |
|||
* Differently from a simple component where children container is the |
|||
* component itself |
|||
* <my-comp> |
|||
* <!-- |
|||
* <child></child> ... |
|||
* --> |
|||
* </my-comp> |
|||
* You could have the children container more deeper |
|||
* <my-comp> |
|||
* <div></div> |
|||
* <div></div> |
|||
* <div> |
|||
* <div> |
|||
* <!-- |
|||
* <child></child> ... |
|||
* --> |
|||
* </div> |
|||
* </div> |
|||
* </my-comp> |
|||
* @return HTMLElement |
|||
* @private |
|||
*/ |
|||
getChildrenContainer: function() { |
|||
var container = this.el; |
|||
|
|||
if (typeof this.getChildrenSelector == 'function') { |
|||
container = this.el.querySelector(this.getChildrenSelector()); |
|||
} else if (typeof this.getTemplate == 'function') { |
|||
// Need to find deepest first child
|
|||
} |
|||
|
|||
return container; |
|||
}, |
|||
|
|||
/** |
|||
* Render children components |
|||
* @private |
|||
*/ |
|||
renderChildren: function() { |
|||
var view = new ComponentsView({ |
|||
collection: this.model.get('components'), |
|||
config: this.config, |
|||
defaultTypes: this.opts.defaultTypes, |
|||
componentTypes: this.opts.componentTypes, |
|||
}); |
|||
|
|||
var container = this.getChildrenContainer(); |
|||
var childNodes = view.render($(container)).el.childNodes; |
|||
childNodes = Array.prototype.slice.call(childNodes); |
|||
|
|||
for (var i = 0, len = childNodes.length ; i < len; i++) { |
|||
container.appendChild(childNodes.shift()); |
|||
} |
|||
|
|||
// If the children container is not the same as the component
|
|||
// (so likely fetched with getChildrenSelector()) is necessary
|
|||
// to disable pointer-events for all nested components as they
|
|||
// might prevent the component to be selected
|
|||
if (container !== this.el) { |
|||
var disableNode = function(el) { |
|||
var children = Array.prototype.slice.call(el.children); |
|||
children.forEach(function (el) { |
|||
el.style['pointer-events'] = 'none'; |
|||
if (container !== el) { |
|||
disableNode(el); |
|||
} |
|||
}); |
|||
}; |
|||
disableNode(this.el); |
|||
} |
|||
}, |
|||
|
|||
renderAttributes: function() { |
|||
this.updateAttributes(); |
|||
this.updateClasses(); |
|||
}, |
|||
|
|||
render: function() { |
|||
this.renderAttributes(); |
|||
var model = this.model; |
|||
var container = this.getChildrenContainer(); |
|||
container.innerHTML = model.get('content'); |
|||
this.renderChildren(); |
|||
|
|||
// Render script
|
|||
if(model.get('script')) { |
|||
this.updateScript(); |
|||
} |
|||
|
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}; |
|||
disableNode(this.el); |
|||
} |
|||
}, |
|||
|
|||
renderAttributes: function() { |
|||
this.updateAttributes(); |
|||
this.updateClasses(); |
|||
}, |
|||
|
|||
render: function() { |
|||
this.renderAttributes(); |
|||
var model = this.model; |
|||
var container = this.getChildrenContainer(); |
|||
container.innerHTML = model.get('content'); |
|||
this.renderChildren(); |
|||
|
|||
// Render script
|
|||
if(model.get('script')) { |
|||
this.updateScript(); |
|||
} |
|||
|
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
|
|||
@ -1,115 +1,112 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var Backbone = require('backbone'); |
|||
|
|||
module.exports = Backbone.View.extend({ |
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
initialize: function(o) { |
|||
this.opts = o || {}; |
|||
this.config = o.config || {}; |
|||
this.listenTo( this.collection, 'add', this.addTo ); |
|||
this.listenTo( this.collection, 'reset', this.render ); |
|||
}, |
|||
initialize: function(o) { |
|||
this.opts = o || {}; |
|||
this.config = o.config || {}; |
|||
this.listenTo( this.collection, 'add', this.addTo ); |
|||
this.listenTo( this.collection, 'reset', this.render ); |
|||
}, |
|||
|
|||
/** |
|||
* Add to collection |
|||
* @param {Object} Model |
|||
* |
|||
* @return void |
|||
* @private |
|||
* */ |
|||
addTo: function(model) { |
|||
var i = this.collection.indexOf(model); |
|||
this.addToCollection(model, null, i); |
|||
/** |
|||
* Add to collection |
|||
* @param {Object} Model |
|||
* |
|||
* @return void |
|||
* @private |
|||
* */ |
|||
addTo: function(model) { |
|||
var i = this.collection.indexOf(model); |
|||
this.addToCollection(model, null, i); |
|||
|
|||
var em = this.config.em; |
|||
if(em) { |
|||
// OLD
|
|||
em.trigger('add:component', model); |
|||
em.trigger('component:add', model); |
|||
} |
|||
}, |
|||
var em = this.config.em; |
|||
if(em) { |
|||
// OLD
|
|||
em.trigger('add:component', model); |
|||
em.trigger('component:add', model); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Add new object to collection |
|||
* @param {Object} Model |
|||
* @param {Object} Fragment collection |
|||
* @param {Integer} Index of append |
|||
* |
|||
* @return {Object} Object rendered |
|||
* @private |
|||
* */ |
|||
addToCollection: function(model, fragmentEl, index){ |
|||
if(!this.compView) |
|||
this.compView = require('./ComponentView'); |
|||
var fragment = fragmentEl || null, |
|||
viewObject = this.compView; |
|||
//console.log('Add to collection', model, 'Index',i);
|
|||
/** |
|||
* Add new object to collection |
|||
* @param {Object} Model |
|||
* @param {Object} Fragment collection |
|||
* @param {Integer} Index of append |
|||
* |
|||
* @return {Object} Object rendered |
|||
* @private |
|||
* */ |
|||
addToCollection: function(model, fragmentEl, index){ |
|||
if(!this.compView) |
|||
this.compView = require('./ComponentView'); |
|||
var fragment = fragmentEl || null, |
|||
viewObject = this.compView; |
|||
//console.log('Add to collection', model, 'Index',i);
|
|||
|
|||
var dt = this.opts.defaultTypes; |
|||
var ct = this.opts.componentTypes; |
|||
var dt = this.opts.defaultTypes; |
|||
var ct = this.opts.componentTypes; |
|||
|
|||
var type = model.get('type'); |
|||
var type = model.get('type'); |
|||
|
|||
for (var it = 0; it < dt.length; it++) { |
|||
var dtId = dt[it].id; |
|||
if(dtId == type) { |
|||
viewObject = dt[it].view; |
|||
break; |
|||
} |
|||
for (var it = 0; it < dt.length; it++) { |
|||
var dtId = dt[it].id; |
|||
if(dtId == type) { |
|||
viewObject = dt[it].view; |
|||
break; |
|||
} |
|||
//viewObject = dt[type] ? dt[type].view : dt.default.view;
|
|||
} |
|||
//viewObject = dt[type] ? dt[type].view : dt.default.view;
|
|||
|
|||
var view = new viewObject({ |
|||
model: model, |
|||
config: this.config, |
|||
defaultTypes: dt, |
|||
componentTypes: ct, |
|||
}); |
|||
var rendered = view.render().el; |
|||
if(view.model.get('type') == 'textnode') |
|||
rendered = document.createTextNode(view.model.get('content')); |
|||
var view = new viewObject({ |
|||
model: model, |
|||
config: this.config, |
|||
defaultTypes: dt, |
|||
componentTypes: ct, |
|||
}); |
|||
var rendered = view.render().el; |
|||
if(view.model.get('type') == 'textnode') |
|||
rendered = document.createTextNode(view.model.get('content')); |
|||
|
|||
if(fragment){ |
|||
fragment.appendChild(rendered); |
|||
}else{ |
|||
var p = this.$parent; |
|||
var pc = p.children; |
|||
if(typeof index != 'undefined'){ |
|||
var method = 'before'; |
|||
// If the added model is the last of collection
|
|||
// need to change the logic of append
|
|||
if(pc && p.children().length == index){ |
|||
index--; |
|||
method = 'after'; |
|||
} |
|||
// In case the added is new in the collection index will be -1
|
|||
if(index < 0) { |
|||
p.append(rendered); |
|||
}else { |
|||
if(pc) { |
|||
p.children().eq(index)[method](rendered); |
|||
} |
|||
} |
|||
}else{ |
|||
if(fragment){ |
|||
fragment.appendChild(rendered); |
|||
}else{ |
|||
var p = this.$parent; |
|||
var pc = p.children; |
|||
if(typeof index != 'undefined'){ |
|||
var method = 'before'; |
|||
// If the added model is the last of collection
|
|||
// need to change the logic of append
|
|||
if(pc && p.children().length == index){ |
|||
index--; |
|||
method = 'after'; |
|||
} |
|||
// In case the added is new in the collection index will be -1
|
|||
if(index < 0) { |
|||
p.append(rendered); |
|||
}else { |
|||
if(pc) { |
|||
p.children().eq(index)[method](rendered); |
|||
} |
|||
} |
|||
}else{ |
|||
p.append(rendered); |
|||
} |
|||
} |
|||
|
|||
return rendered; |
|||
}, |
|||
return rendered; |
|||
}, |
|||
|
|||
render: function($p) { |
|||
var fragment = document.createDocumentFragment(); |
|||
this.$parent = $p || this.$el; |
|||
this.$el.empty(); |
|||
this.collection.each(function(model){ |
|||
this.addToCollection(model, fragment); |
|||
},this); |
|||
this.$el.append(fragment); |
|||
render: function($p) { |
|||
var fragment = document.createDocumentFragment(); |
|||
this.$parent = $p || this.$el; |
|||
this.$el.empty(); |
|||
this.collection.each(function(model){ |
|||
this.addToCollection(model, fragment); |
|||
},this); |
|||
this.$el.append(fragment); |
|||
|
|||
return this; |
|||
} |
|||
return this; |
|||
} |
|||
|
|||
}); |
|||
}); |
|||
|
|||
@ -1,38 +1,34 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var Backbone = require('backbone'); |
|||
|
|||
module.exports = Backbone.View.extend({ |
|||
module.exports = Backbone.View.extend({ |
|||
events: { |
|||
'mousedown': 'handleClick', |
|||
}, |
|||
|
|||
events: { |
|||
'mousedown': 'handleClick', |
|||
}, |
|||
attributes: function () { |
|||
return this.model.get('attributes'); |
|||
}, |
|||
|
|||
attributes: function () { |
|||
return this.model.get('attributes'); |
|||
}, |
|||
initialize: function(opts) { |
|||
this.editor = opts.config.editor; |
|||
}, |
|||
|
|||
initialize: function(opts) { |
|||
this.editor = opts.config.editor; |
|||
}, |
|||
handleClick: function() { |
|||
var command = this.model.get('command'); |
|||
|
|||
handleClick: function() { |
|||
var command = this.model.get('command'); |
|||
if (typeof command === 'function') { |
|||
command(this.editor); |
|||
} |
|||
|
|||
if (typeof command === 'function') { |
|||
command(this.editor); |
|||
} |
|||
if (typeof command === 'string') { |
|||
this.editor.runCommand(command); |
|||
} |
|||
}, |
|||
|
|||
if (typeof command === 'string') { |
|||
this.editor.runCommand(command); |
|||
} |
|||
}, |
|||
render: function () { |
|||
var config = this.editor.getConfig(); |
|||
this.el.className += ' ' + config.stylePrefix + 'toolbar-item'; |
|||
return this; |
|||
}, |
|||
|
|||
render: function () { |
|||
var config = this.editor.getConfig(); |
|||
this.el.className += ' ' + config.stylePrefix + 'toolbar-item'; |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,85 +1,82 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var inputTemplate = require('text!./templates/input.html'); |
|||
var Backbone = require('backbone'); |
|||
var inputTemplate = require('text!./templates/input.html'); |
|||
|
|||
module.exports = Backbone.View.extend({ |
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
events: { |
|||
'change': 'handleChange', |
|||
}, |
|||
events: { |
|||
'change': 'handleChange', |
|||
}, |
|||
|
|||
template: _.template(inputTemplate), |
|||
template: _.template(inputTemplate), |
|||
|
|||
initialize: function(opts) { |
|||
var opt = opts || {}; |
|||
var ppfx = opt.ppfx || ''; |
|||
this.target = opt.target || {}; |
|||
this.inputClass = ppfx + 'field'; |
|||
this.inputHolderClass = ppfx + 'input-holder'; |
|||
this.ppfx = ppfx; |
|||
this.listenTo(this.model, 'change:value', this.handleModelChange); |
|||
}, |
|||
initialize: function(opts) { |
|||
var opt = opts || {}; |
|||
var ppfx = opt.ppfx || ''; |
|||
this.target = opt.target || {}; |
|||
this.inputClass = ppfx + 'field'; |
|||
this.inputHolderClass = ppfx + 'input-holder'; |
|||
this.ppfx = ppfx; |
|||
this.listenTo(this.model, 'change:value', this.handleModelChange); |
|||
}, |
|||
|
|||
/** |
|||
* Handled when the view is changed |
|||
*/ |
|||
handleChange: function (e) { |
|||
e.stopPropagation(); |
|||
this.setValue(this.getInputEl().value); |
|||
}, |
|||
/** |
|||
* Handled when the view is changed |
|||
*/ |
|||
handleChange: function (e) { |
|||
e.stopPropagation(); |
|||
this.setValue(this.getInputEl().value); |
|||
}, |
|||
|
|||
/** |
|||
* Set value to the model |
|||
* @param {string} value |
|||
* @param {Object} opts |
|||
*/ |
|||
setValue: function(value, opts) { |
|||
var opt = opts || {}; |
|||
var model = this.model; |
|||
model.set({ |
|||
value: value || model.get('defaults') |
|||
}, opt); |
|||
/** |
|||
* Set value to the model |
|||
* @param {string} value |
|||
* @param {Object} opts |
|||
*/ |
|||
setValue: function(value, opts) { |
|||
var opt = opts || {}; |
|||
var model = this.model; |
|||
model.set({ |
|||
value: value || model.get('defaults') |
|||
}, opt); |
|||
|
|||
// Generally I get silent when I need to reflect data to view without
|
|||
// reupdating the target
|
|||
if(opt.silent) { |
|||
this.handleModelChange(); |
|||
} |
|||
}, |
|||
// Generally I get silent when I need to reflect data to view without
|
|||
// reupdating the target
|
|||
if(opt.silent) { |
|||
this.handleModelChange(); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Updates the view when the model is changed |
|||
* */ |
|||
handleModelChange: function() { |
|||
this.getInputEl().value = this.model.get('value'); |
|||
}, |
|||
/** |
|||
* Updates the view when the model is changed |
|||
* */ |
|||
handleModelChange: function() { |
|||
this.getInputEl().value = this.model.get('value'); |
|||
}, |
|||
|
|||
/** |
|||
* Get the input element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getInputEl: function() { |
|||
if(!this.inputEl) { |
|||
this.inputEl = $('<input>', { |
|||
type: 'text', |
|||
class: this.inputCls, |
|||
placeholder: this.model.get('defaults') |
|||
}); |
|||
} |
|||
return this.inputEl.get(0); |
|||
}, |
|||
/** |
|||
* Get the input element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getInputEl: function() { |
|||
if(!this.inputEl) { |
|||
this.inputEl = $('<input>', { |
|||
type: 'text', |
|||
class: this.inputCls, |
|||
placeholder: this.model.get('defaults') |
|||
}); |
|||
} |
|||
return this.inputEl.get(0); |
|||
}, |
|||
|
|||
render: function() { |
|||
var el = this.$el; |
|||
el.addClass(this.inputClass); |
|||
el.html(this.template({ |
|||
holderClass: this.inputHolderClass, |
|||
ppfx: this.ppfx |
|||
})); |
|||
el.find('.'+ this.inputHolderClass).html(this.getInputEl()); |
|||
return this; |
|||
} |
|||
render: function() { |
|||
var el = this.$el; |
|||
el.addClass(this.inputClass); |
|||
el.html(this.template({ |
|||
holderClass: this.inputHolderClass, |
|||
ppfx: this.ppfx |
|||
})); |
|||
el.find('.'+ this.inputHolderClass).html(this.getInputEl()); |
|||
return this; |
|||
} |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,78 +1,75 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var Input = require('./Input'); |
|||
var Spectrum = require('Spectrum'); |
|||
var inputTemplate = require('text!./templates/inputColor.html'); |
|||
var Backbone = require('backbone'); |
|||
var Input = require('./Input'); |
|||
var Spectrum = require('Spectrum'); |
|||
var inputTemplate = require('text!./templates/inputColor.html'); |
|||
|
|||
module.exports = Input.extend({ |
|||
module.exports = Input.extend({ |
|||
|
|||
template: _.template(inputTemplate), |
|||
template: _.template(inputTemplate), |
|||
|
|||
initialize: function(opts) { |
|||
Input.prototype.initialize.apply(this, arguments); |
|||
var ppfx = this.ppfx; |
|||
this.colorCls = ppfx + 'field-color-picker'; |
|||
this.inputClass = ppfx + 'field ' + ppfx + 'field-color'; |
|||
this.colorHolderClass = ppfx + 'field-colorp-c'; |
|||
initialize: function(opts) { |
|||
Input.prototype.initialize.apply(this, arguments); |
|||
var ppfx = this.ppfx; |
|||
this.colorCls = ppfx + 'field-color-picker'; |
|||
this.inputClass = ppfx + 'field ' + ppfx + 'field-color'; |
|||
this.colorHolderClass = ppfx + 'field-colorp-c'; |
|||
|
|||
this.listenTo(this.model, 'change:value', this.handleModelChange); |
|||
}, |
|||
this.listenTo(this.model, 'change:value', this.handleModelChange); |
|||
}, |
|||
|
|||
/** |
|||
* Updates the view when the model is changed |
|||
* */ |
|||
handleModelChange: function() { |
|||
Input.prototype.handleModelChange.apply(this, arguments); |
|||
/** |
|||
* Updates the view when the model is changed |
|||
* */ |
|||
handleModelChange: function() { |
|||
Input.prototype.handleModelChange.apply(this, arguments); |
|||
|
|||
var value = this.model.get('value'); |
|||
var colorEl = this.getColorEl(); |
|||
var value = this.model.get('value'); |
|||
var colorEl = this.getColorEl(); |
|||
|
|||
// If no color selected I will set white for the picker
|
|||
value = value === 'none' ? '#fff' : value; |
|||
colorEl.spectrum('set', value); |
|||
colorEl.get(0).style.backgroundColor = value; |
|||
}, |
|||
// If no color selected I will set white for the picker
|
|||
value = value === 'none' ? '#fff' : value; |
|||
colorEl.spectrum('set', value); |
|||
colorEl.get(0).style.backgroundColor = value; |
|||
}, |
|||
|
|||
/** |
|||
* Get the color input element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getColorEl: function() { |
|||
if(!this.colorEl) { |
|||
var model = this.model; |
|||
var colorEl = $('<div>', {class: this.colorCls}); |
|||
var cpStyle = colorEl.get(0).style; |
|||
var elToAppend = this.target && this.target.config ? this.target.config.el : ''; |
|||
colorEl.spectrum({ |
|||
appendTo: elToAppend || 'body', |
|||
maxSelectionSize: 8, |
|||
showPalette: true, |
|||
showAlpha: true, |
|||
chooseText: 'Ok', |
|||
cancelText: '⨯', |
|||
palette: [], |
|||
move: function(color) { |
|||
var c = color.getAlpha() == 1 ? color.toHexString() : color.toRgbString(); |
|||
cpStyle.backgroundColor = c; |
|||
}, |
|||
change: function(color) { |
|||
var c = color.getAlpha() == 1 ? color.toHexString() : color.toRgbString(); |
|||
c = c.replace(/ /g,''); |
|||
cpStyle.backgroundColor = c; |
|||
model.set('value', c); |
|||
} |
|||
}); |
|||
this.colorEl = colorEl; |
|||
} |
|||
return this.colorEl; |
|||
}, |
|||
/** |
|||
* Get the color input element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getColorEl: function() { |
|||
if(!this.colorEl) { |
|||
var model = this.model; |
|||
var colorEl = $('<div>', {class: this.colorCls}); |
|||
var cpStyle = colorEl.get(0).style; |
|||
var elToAppend = this.target && this.target.config ? this.target.config.el : ''; |
|||
colorEl.spectrum({ |
|||
appendTo: elToAppend || 'body', |
|||
maxSelectionSize: 8, |
|||
showPalette: true, |
|||
showAlpha: true, |
|||
chooseText: 'Ok', |
|||
cancelText: '⨯', |
|||
palette: [], |
|||
move: function(color) { |
|||
var c = color.getAlpha() == 1 ? color.toHexString() : color.toRgbString(); |
|||
cpStyle.backgroundColor = c; |
|||
}, |
|||
change: function(color) { |
|||
var c = color.getAlpha() == 1 ? color.toHexString() : color.toRgbString(); |
|||
c = c.replace(/ /g,''); |
|||
cpStyle.backgroundColor = c; |
|||
model.set('value', c); |
|||
} |
|||
}); |
|||
this.colorEl = colorEl; |
|||
} |
|||
return this.colorEl; |
|||
}, |
|||
|
|||
render: function() { |
|||
Input.prototype.render.apply(this, arguments); |
|||
this.$el.find('.' + this.colorHolderClass).html(this.getColorEl()); |
|||
return this; |
|||
} |
|||
render: function() { |
|||
Input.prototype.render.apply(this, arguments); |
|||
this.$el.find('.' + this.colorHolderClass).html(this.getColorEl()); |
|||
return this; |
|||
} |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,250 +1,247 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var inputTemplate = require('text!./templates/inputNumber.html'); |
|||
|
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
events: {}, |
|||
|
|||
template: _.template(inputTemplate), |
|||
|
|||
initialize: function(opts) { |
|||
_.bindAll(this, 'moveIncrement', 'upIncrement'); |
|||
var opt = opts || {}; |
|||
var ppfx = opt.ppfx || ''; |
|||
var contClass = opt.contClass || (ppfx + 'field'); |
|||
this.ppfx = ppfx; |
|||
this.docEl = $(document); |
|||
this.inputCls = ppfx + 'input-number'; |
|||
this.unitCls = ppfx + 'input-unit'; |
|||
this.contClass = contClass; |
|||
this.events['click .' + ppfx + 'field-arrow-u'] = 'upArrowClick'; |
|||
this.events['click .' + ppfx + 'field-arrow-d'] = 'downArrowClick'; |
|||
this.events['mousedown .' + ppfx + 'field-arrows'] = 'downIncrement'; |
|||
this.events['change .' + this.inputCls] = 'handleChange'; |
|||
this.events['change .' + this.unitCls] = 'handleUnitChange'; |
|||
|
|||
this.listenTo(this.model, 'change:unit change:value', this.handleModelChange); |
|||
this.delegateEvents(); |
|||
}, |
|||
|
|||
/** |
|||
* Set value to the model |
|||
* @param {string} value |
|||
* @param {Object} opts |
|||
*/ |
|||
setValue: function(value, opts) { |
|||
var opt = opts || {}; |
|||
var valid = this.validateInputValue(value, {deepCheck: 1}); |
|||
var validObj = {value: valid.value}; |
|||
|
|||
// If found some unit value
|
|||
if(valid.unit || valid.force) { |
|||
validObj.unit = valid.unit; |
|||
} |
|||
var Backbone = require('backbone'); |
|||
var inputTemplate = require('text!./templates/inputNumber.html'); |
|||
|
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
events: {}, |
|||
|
|||
template: _.template(inputTemplate), |
|||
|
|||
initialize: function(opts) { |
|||
_.bindAll(this, 'moveIncrement', 'upIncrement'); |
|||
var opt = opts || {}; |
|||
var ppfx = opt.ppfx || ''; |
|||
var contClass = opt.contClass || (ppfx + 'field'); |
|||
this.ppfx = ppfx; |
|||
this.docEl = $(document); |
|||
this.inputCls = ppfx + 'input-number'; |
|||
this.unitCls = ppfx + 'input-unit'; |
|||
this.contClass = contClass; |
|||
this.events['click .' + ppfx + 'field-arrow-u'] = 'upArrowClick'; |
|||
this.events['click .' + ppfx + 'field-arrow-d'] = 'downArrowClick'; |
|||
this.events['mousedown .' + ppfx + 'field-arrows'] = 'downIncrement'; |
|||
this.events['change .' + this.inputCls] = 'handleChange'; |
|||
this.events['change .' + this.unitCls] = 'handleUnitChange'; |
|||
|
|||
this.listenTo(this.model, 'change:unit change:value', this.handleModelChange); |
|||
this.delegateEvents(); |
|||
}, |
|||
|
|||
/** |
|||
* Set value to the model |
|||
* @param {string} value |
|||
* @param {Object} opts |
|||
*/ |
|||
setValue: function(value, opts) { |
|||
var opt = opts || {}; |
|||
var valid = this.validateInputValue(value, {deepCheck: 1}); |
|||
var validObj = {value: valid.value}; |
|||
|
|||
// If found some unit value
|
|||
if(valid.unit || valid.force) { |
|||
validObj.unit = valid.unit; |
|||
} |
|||
|
|||
this.model.set(validObj, opt); |
|||
this.model.set(validObj, opt); |
|||
|
|||
// Generally I get silent when I need to reflect data to view without
|
|||
// reupdating the target
|
|||
if(opt.silent) { |
|||
this.handleModelChange(); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Handled when the view is changed |
|||
*/ |
|||
handleChange: function (e) { |
|||
e.stopPropagation(); |
|||
this.setValue(this.getInputEl().value); |
|||
}, |
|||
|
|||
/** |
|||
* Handled when the view is changed |
|||
*/ |
|||
handleUnitChange: function (e) { |
|||
e.stopPropagation(); |
|||
var value = this.getUnitEl().value; |
|||
this.model.set('unit', value); |
|||
}, |
|||
|
|||
/** |
|||
* Updates the view when the model is changed |
|||
* */ |
|||
handleModelChange: function() { |
|||
var m = this.model; |
|||
this.getInputEl().value = m.get('value'); |
|||
var unit = this.getUnitEl(); |
|||
|
|||
if (unit) { |
|||
unit.value = m.get('unit'); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Get the input element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getInputEl: function() { |
|||
if(!this.inputEl) { |
|||
this.inputEl = $('<input>', { |
|||
type: 'text', |
|||
class: this.inputCls, |
|||
placeholder: this.model.get('defaults') |
|||
}); |
|||
} |
|||
return this.inputEl.get(0); |
|||
}, |
|||
|
|||
/** |
|||
* Get the unit element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getUnitEl: function() { |
|||
if(!this.unitEl) { |
|||
var model = this.model; |
|||
var units = model.get('units') || []; |
|||
if(units.length){ |
|||
var unitStr = '<select class="' + this.unitCls + '">'; |
|||
_.each(units, function(unit){ |
|||
var selected = unit == model.get('unit') ? 'selected': ''; |
|||
unitStr += '<option ' + selected + ' >' + unit + '</option>'; |
|||
}); |
|||
unitStr += '</select>'; |
|||
this.unitEl = $(unitStr); |
|||
} |
|||
} |
|||
return this.unitEl && this.unitEl.get(0); |
|||
}, |
|||
|
|||
/** |
|||
* Invoked when the up arrow is clicked |
|||
* */ |
|||
upArrowClick: function() { |
|||
var value = this.model.get('value'); |
|||
value = isNaN(value) ? 1 : parseInt(value, 10) + 1; |
|||
var valid = this.validateInputValue(value); |
|||
this.model.set('value', valid.value); |
|||
}, |
|||
|
|||
/** |
|||
* Invoked when the down arrow is clicked |
|||
* */ |
|||
downArrowClick: function(){ |
|||
var value = this.model.get('value'); |
|||
value = isNaN(value) ? 0 : parseInt(value, 10) - 1; |
|||
var valid = this.validateInputValue(value); |
|||
this.model.set('value', valid.value); |
|||
}, |
|||
|
|||
/** |
|||
* Change easily integer input value with click&drag method |
|||
* @param Event |
|||
* |
|||
* @return void |
|||
* */ |
|||
downIncrement: function(e) { |
|||
e.preventDefault(); |
|||
this.moved = 0; |
|||
var value = this.model.get('value'); |
|||
value = isNaN(value) ? 0 : parseInt(value, 10); |
|||
var current = {y: e.pageY, val: value }; |
|||
this.docEl.mouseup(current, this.upIncrement); |
|||
this.docEl.mousemove(current, this.moveIncrement); |
|||
}, |
|||
|
|||
/** While the increment is clicked, moving the mouse will update input value |
|||
* @param Object |
|||
* |
|||
* @return bool |
|||
* */ |
|||
moveIncrement: function (ev) { |
|||
this.moved = 1; |
|||
var pos = parseInt(ev.data.val - ev.pageY + ev.data.y, 10); |
|||
this.prValue = this.validateInputValue(pos).value;//Math.max(this.min, Math.min(this.max, pos) );
|
|||
this.model.set('value', this.prValue, {avoidStore: 1}); |
|||
return false; |
|||
}, |
|||
|
|||
/** |
|||
* Stop moveIncrement method |
|||
* @param Object |
|||
* |
|||
* @return void |
|||
* */ |
|||
upIncrement: function (e) { |
|||
this.docEl.off('mouseup', this.upIncrement); |
|||
this.docEl.off('mousemove', this.moveIncrement); |
|||
|
|||
if(this.prValue && this.moved) { |
|||
var value = this.prValue - 1; |
|||
this.model.set('value', value, {avoidStore: 1}) |
|||
.set('value', value + 1); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Validate input value |
|||
* @param {String} value Raw value |
|||
* @param {Object} opts Options |
|||
* @return {Object} Validated string |
|||
*/ |
|||
validateInputValue: function(value, opts) { |
|||
var force = 0; |
|||
var opt = opts || {}; |
|||
// Generally I get silent when I need to reflect data to view without
|
|||
// reupdating the target
|
|||
if(opt.silent) { |
|||
this.handleModelChange(); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Handled when the view is changed |
|||
*/ |
|||
handleChange: function (e) { |
|||
e.stopPropagation(); |
|||
this.setValue(this.getInputEl().value); |
|||
}, |
|||
|
|||
/** |
|||
* Handled when the view is changed |
|||
*/ |
|||
handleUnitChange: function (e) { |
|||
e.stopPropagation(); |
|||
var value = this.getUnitEl().value; |
|||
this.model.set('unit', value); |
|||
}, |
|||
|
|||
/** |
|||
* Updates the view when the model is changed |
|||
* */ |
|||
handleModelChange: function() { |
|||
var m = this.model; |
|||
this.getInputEl().value = m.get('value'); |
|||
var unit = this.getUnitEl(); |
|||
|
|||
if (unit) { |
|||
unit.value = m.get('unit'); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Get the input element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getInputEl: function() { |
|||
if(!this.inputEl) { |
|||
this.inputEl = $('<input>', { |
|||
type: 'text', |
|||
class: this.inputCls, |
|||
placeholder: this.model.get('defaults') |
|||
}); |
|||
} |
|||
return this.inputEl.get(0); |
|||
}, |
|||
|
|||
/** |
|||
* Get the unit element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getUnitEl: function() { |
|||
if(!this.unitEl) { |
|||
var model = this.model; |
|||
var val = value || model.get('defaults'); |
|||
var units = model.get('units') || []; |
|||
var unit = model.get('unit') || (units.length && units[0]) || ''; |
|||
var max = model.get('max'); |
|||
var min = model.get('min'); |
|||
|
|||
if(opt.deepCheck) { |
|||
var fixed = model.get('fixedValues') || []; |
|||
|
|||
if (val) { |
|||
// If the value is one of the fixed values I leave it as it is
|
|||
var regFixed = new RegExp('^' + fixed.join('|'), 'g'); |
|||
if (fixed.length && regFixed.test(val)) { |
|||
val = val.match(regFixed)[0]; |
|||
unit = ''; |
|||
force = 1; |
|||
} else { |
|||
var valCopy = val + ''; |
|||
val += ''; // Make it suitable for replace
|
|||
val = parseFloat(val.replace(',', '.')); |
|||
val = !isNaN(val) ? val : model.get('defaults'); |
|||
var uN = valCopy.replace(val, ''); |
|||
// Check if exists as unit
|
|||
if(_.indexOf(units, uN) >= 0) |
|||
unit = uN; |
|||
} |
|||
if(units.length){ |
|||
var unitStr = '<select class="' + this.unitCls + '">'; |
|||
_.each(units, function(unit){ |
|||
var selected = unit == model.get('unit') ? 'selected': ''; |
|||
unitStr += '<option ' + selected + ' >' + unit + '</option>'; |
|||
}); |
|||
unitStr += '</select>'; |
|||
this.unitEl = $(unitStr); |
|||
} |
|||
} |
|||
return this.unitEl && this.unitEl.get(0); |
|||
}, |
|||
|
|||
/** |
|||
* Invoked when the up arrow is clicked |
|||
* */ |
|||
upArrowClick: function() { |
|||
var value = this.model.get('value'); |
|||
value = isNaN(value) ? 1 : parseInt(value, 10) + 1; |
|||
var valid = this.validateInputValue(value); |
|||
this.model.set('value', valid.value); |
|||
}, |
|||
|
|||
/** |
|||
* Invoked when the down arrow is clicked |
|||
* */ |
|||
downArrowClick: function(){ |
|||
var value = this.model.get('value'); |
|||
value = isNaN(value) ? 0 : parseInt(value, 10) - 1; |
|||
var valid = this.validateInputValue(value); |
|||
this.model.set('value', valid.value); |
|||
}, |
|||
|
|||
/** |
|||
* Change easily integer input value with click&drag method |
|||
* @param Event |
|||
* |
|||
* @return void |
|||
* */ |
|||
downIncrement: function(e) { |
|||
e.preventDefault(); |
|||
this.moved = 0; |
|||
var value = this.model.get('value'); |
|||
value = isNaN(value) ? 0 : parseInt(value, 10); |
|||
var current = {y: e.pageY, val: value }; |
|||
this.docEl.mouseup(current, this.upIncrement); |
|||
this.docEl.mousemove(current, this.moveIncrement); |
|||
}, |
|||
|
|||
/** While the increment is clicked, moving the mouse will update input value |
|||
* @param Object |
|||
* |
|||
* @return bool |
|||
* */ |
|||
moveIncrement: function (ev) { |
|||
this.moved = 1; |
|||
var pos = parseInt(ev.data.val - ev.pageY + ev.data.y, 10); |
|||
this.prValue = this.validateInputValue(pos).value;//Math.max(this.min, Math.min(this.max, pos) );
|
|||
this.model.set('value', this.prValue, {avoidStore: 1}); |
|||
return false; |
|||
}, |
|||
|
|||
/** |
|||
* Stop moveIncrement method |
|||
* @param Object |
|||
* |
|||
* @return void |
|||
* */ |
|||
upIncrement: function (e) { |
|||
this.docEl.off('mouseup', this.upIncrement); |
|||
this.docEl.off('mousemove', this.moveIncrement); |
|||
|
|||
if(this.prValue && this.moved) { |
|||
var value = this.prValue - 1; |
|||
this.model.set('value', value, {avoidStore: 1}) |
|||
.set('value', value + 1); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Validate input value |
|||
* @param {String} value Raw value |
|||
* @param {Object} opts Options |
|||
* @return {Object} Validated string |
|||
*/ |
|||
validateInputValue: function(value, opts) { |
|||
var force = 0; |
|||
var opt = opts || {}; |
|||
var model = this.model; |
|||
var val = value || model.get('defaults'); |
|||
var units = model.get('units') || []; |
|||
var unit = model.get('unit') || (units.length && units[0]) || ''; |
|||
var max = model.get('max'); |
|||
var min = model.get('min'); |
|||
|
|||
if(opt.deepCheck) { |
|||
var fixed = model.get('fixedValues') || []; |
|||
|
|||
if (val) { |
|||
// If the value is one of the fixed values I leave it as it is
|
|||
var regFixed = new RegExp('^' + fixed.join('|'), 'g'); |
|||
if (fixed.length && regFixed.test(val)) { |
|||
val = val.match(regFixed)[0]; |
|||
unit = ''; |
|||
force = 1; |
|||
} else { |
|||
var valCopy = val + ''; |
|||
val += ''; // Make it suitable for replace
|
|||
val = parseFloat(val.replace(',', '.')); |
|||
val = !isNaN(val) ? val : model.get('defaults'); |
|||
var uN = valCopy.replace(val, ''); |
|||
// Check if exists as unit
|
|||
if(_.indexOf(units, uN) >= 0) |
|||
unit = uN; |
|||
} |
|||
} |
|||
|
|||
if(typeof max !== 'undefined' && max !== '') |
|||
val = val > max ? max : val; |
|||
|
|||
if(typeof min !== 'undefined' && min !== '') |
|||
val = val < min ? min : val; |
|||
|
|||
return { |
|||
force: force, |
|||
value: val, |
|||
unit: unit |
|||
}; |
|||
}, |
|||
|
|||
render: function() { |
|||
var ppfx = this.ppfx; |
|||
this.$el.html(this.template({ppfx: ppfx})); |
|||
this.$el.find('.'+ ppfx +'input-holder').html(this.getInputEl()); |
|||
this.$el.find('.' + ppfx + 'field-units').html(this.getUnitEl()); |
|||
this.$el.addClass(this.contClass); |
|||
return this; |
|||
} |
|||
|
|||
}); |
|||
}); |
|||
if(typeof max !== 'undefined' && max !== '') |
|||
val = val > max ? max : val; |
|||
|
|||
if(typeof min !== 'undefined' && min !== '') |
|||
val = val < min ? min : val; |
|||
|
|||
return { |
|||
force: force, |
|||
value: val, |
|||
unit: unit |
|||
}; |
|||
}, |
|||
|
|||
render: function() { |
|||
var ppfx = this.ppfx; |
|||
this.$el.html(this.template({ppfx: ppfx})); |
|||
this.$el.find('.'+ ppfx +'input-holder').html(this.getInputEl()); |
|||
this.$el.find('.' + ppfx + 'field-units').html(this.getUnitEl()); |
|||
this.$el.addClass(this.contClass); |
|||
return this; |
|||
} |
|||
|
|||
}); |
|||
|
|||
@ -1,70 +1,67 @@ |
|||
define(function(require, exports, module){ |
|||
'use strict'; |
|||
var Backbone = require('backbone'); |
|||
var Backbone = require('backbone'); |
|||
|
|||
module.exports = Backbone.View.extend({ |
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
// Default view
|
|||
itemView: '', |
|||
// Default view
|
|||
itemView: '', |
|||
|
|||
// Defines the View per type
|
|||
itemsView: '', |
|||
// Defines the View per type
|
|||
itemsView: '', |
|||
|
|||
itemType: 'type', |
|||
itemType: 'type', |
|||
|
|||
initialize: function(opts, config) { |
|||
this.config = config || {}; |
|||
}, |
|||
initialize: function(opts, config) { |
|||
this.config = config || {}; |
|||
}, |
|||
|
|||
|
|||
/** |
|||
* Add new model to the collection |
|||
* @param {Model} model |
|||
* @private |
|||
* */ |
|||
addTo: function(model){ |
|||
this.add(model); |
|||
}, |
|||
/** |
|||
* Add new model to the collection |
|||
* @param {Model} model |
|||
* @private |
|||
* */ |
|||
addTo: function(model){ |
|||
this.add(model); |
|||
}, |
|||
|
|||
/** |
|||
* Render new model inside the view |
|||
* @param {Model} model |
|||
* @param {Object} fragment Fragment collection |
|||
* @private |
|||
* */ |
|||
add: function(model, fragment){ |
|||
var frag = fragment || null; |
|||
var itemView = this.itemView; |
|||
var typeField = model.get(this.itemType); |
|||
if(this.itemsView && this.itemsView[typeField]){ |
|||
itemView = this.itemsView[typeField]; |
|||
} |
|||
var view = new itemView({ |
|||
model: model, |
|||
config: this.config |
|||
}, this.config); |
|||
var rendered = view.render().el; |
|||
/** |
|||
* Render new model inside the view |
|||
* @param {Model} model |
|||
* @param {Object} fragment Fragment collection |
|||
* @private |
|||
* */ |
|||
add: function(model, fragment){ |
|||
var frag = fragment || null; |
|||
var itemView = this.itemView; |
|||
var typeField = model.get(this.itemType); |
|||
if(this.itemsView && this.itemsView[typeField]){ |
|||
itemView = this.itemsView[typeField]; |
|||
} |
|||
var view = new itemView({ |
|||
model: model, |
|||
config: this.config |
|||
}, this.config); |
|||
var rendered = view.render().el; |
|||
|
|||
if(frag) |
|||
frag.appendChild(rendered); |
|||
else |
|||
this.$el.append(rendered); |
|||
}, |
|||
if(frag) |
|||
frag.appendChild(rendered); |
|||
else |
|||
this.$el.append(rendered); |
|||
}, |
|||
|
|||
|
|||
|
|||
render: function() { |
|||
var frag = document.createDocumentFragment(); |
|||
this.$el.empty(); |
|||
render: function() { |
|||
var frag = document.createDocumentFragment(); |
|||
this.$el.empty(); |
|||
|
|||
if(this.collection.length) |
|||
this.collection.each(function(model){ |
|||
this.add(model, frag); |
|||
}, this); |
|||
if(this.collection.length) |
|||
this.collection.each(function(model){ |
|||
this.add(model, frag); |
|||
}, this); |
|||
|
|||
this.$el.append(frag); |
|||
return this; |
|||
}, |
|||
this.$el.append(frag); |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
@ -1,295 +1,292 @@ |
|||
define(function () { |
|||
var blkStyle = '.blk-row::after{ content: ""; clear: both; display: block;} .blk-row{padding: 10px;}'; |
|||
return { |
|||
var blkStyle = '.blk-row::after{ content: ""; clear: both; display: block;} .blk-row{padding: 10px;}'; |
|||
module.exports = { |
|||
// Style prefix
|
|||
stylePrefix: 'gjs-', |
|||
|
|||
// Style prefix
|
|||
stylePrefix: 'gjs-', |
|||
//TEMP
|
|||
components: '', |
|||
|
|||
//TEMP
|
|||
components: '', |
|||
// Enable/Disable possibility to copy(ctrl + c) & paste(ctrl + v) components
|
|||
copyPaste: true, |
|||
|
|||
// Enable/Disable possibility to copy(ctrl + c) & paste(ctrl + v) components
|
|||
copyPaste: true, |
|||
// Show an alert before unload the page with unsaved changes
|
|||
noticeOnUnload: true, |
|||
|
|||
// Show an alert before unload the page with unsaved changes
|
|||
noticeOnUnload: true, |
|||
// Enable/Disable undo manager
|
|||
undoManager: true, |
|||
|
|||
// Enable/Disable undo manager
|
|||
undoManager: true, |
|||
// Show paddings and margins
|
|||
showOffsets: false, |
|||
|
|||
// Show paddings and margins
|
|||
showOffsets: false, |
|||
// Show paddings and margins on selected component
|
|||
showOffsetsSelected: false, |
|||
|
|||
// Show paddings and margins on selected component
|
|||
showOffsetsSelected: false, |
|||
// Clear the canvas when editor.render() is called
|
|||
clearOnRender: false, |
|||
|
|||
// Clear the canvas when editor.render() is called
|
|||
clearOnRender: false, |
|||
// Return JS of components inside HTML from 'editor.getHtml()'
|
|||
jsInHtml: true, |
|||
|
|||
// Return JS of components inside HTML from 'editor.getHtml()'
|
|||
jsInHtml: true, |
|||
// On creation of a new Component (via object), if the 'style' attribute is not
|
|||
// empty, all those roles will be moved in its new class
|
|||
forceClass: true, |
|||
|
|||
// On creation of a new Component (via object), if the 'style' attribute is not
|
|||
// empty, all those roles will be moved in its new class
|
|||
forceClass: true, |
|||
// Height for the editor container
|
|||
height: '900px', |
|||
|
|||
// Height for the editor container
|
|||
height: '900px', |
|||
// Width for the editor container
|
|||
width: '100%', |
|||
|
|||
// Width for the editor container
|
|||
width: '100%', |
|||
// CSS that could only be seen (for instance, inside the code viewer)
|
|||
protectedCss: '', |
|||
|
|||
// CSS that could only be seen (for instance, inside the code viewer)
|
|||
protectedCss: '', |
|||
|
|||
// 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
|
|||
defaultCommand: 'select-comp', |
|||
|
|||
// Show a toolbar when the component is selected
|
|||
showToolbar: 1, |
|||
|
|||
// Allow script tag importing
|
|||
allowScripts: 0, |
|||
|
|||
// If true render a select of available devices
|
|||
showDevices: 1, |
|||
|
|||
// When enabled, on device change media rules won't be created
|
|||
devicePreviewMode: 0, |
|||
|
|||
// This option makes available custom component types also for loaded
|
|||
// elements inside canvas
|
|||
loadCompsOnRender: 1, |
|||
|
|||
// Dom element
|
|||
el: '', |
|||
|
|||
//Configurations for Asset Manager
|
|||
assetManager: {}, |
|||
|
|||
//Configurations for Canvas
|
|||
canvas: {}, |
|||
|
|||
//Configurations for Layers
|
|||
layers: {}, |
|||
|
|||
//Configurations for Storage Manager
|
|||
storageManager: {}, |
|||
|
|||
//Configurations for Rich Text Editor
|
|||
rte: {}, |
|||
|
|||
//Configurations for DomComponents
|
|||
domComponents: {}, |
|||
|
|||
//Configurations for Modal Dialog
|
|||
modal: {}, |
|||
|
|||
//Configurations for Code Manager
|
|||
codeManager: {}, |
|||
|
|||
//Configurations for Panels
|
|||
panels: {}, |
|||
|
|||
//Configurations for Commands
|
|||
commands: {}, |
|||
|
|||
//Configurations for Css Composer
|
|||
cssComposer: {}, |
|||
|
|||
//Configurations for Selector Manager
|
|||
selectorManager: {}, |
|||
|
|||
//Configurations for Device Manager
|
|||
deviceManager: { |
|||
'devices': [{ |
|||
name: 'Desktop', |
|||
width: '', |
|||
},{ |
|||
name: 'Tablet', |
|||
width: '992px', |
|||
},{ |
|||
name: 'Mobile landscape', |
|||
width: '768px', |
|||
},{ |
|||
name: 'Mobile portrait', |
|||
width: '480px', |
|||
// 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
|
|||
defaultCommand: 'select-comp', |
|||
|
|||
// Show a toolbar when the component is selected
|
|||
showToolbar: 1, |
|||
|
|||
// Allow script tag importing
|
|||
allowScripts: 0, |
|||
|
|||
// If true render a select of available devices
|
|||
showDevices: 1, |
|||
|
|||
// When enabled, on device change media rules won't be created
|
|||
devicePreviewMode: 0, |
|||
|
|||
// This option makes available custom component types also for loaded
|
|||
// elements inside canvas
|
|||
loadCompsOnRender: 1, |
|||
|
|||
// Dom element
|
|||
el: '', |
|||
|
|||
//Configurations for Asset Manager
|
|||
assetManager: {}, |
|||
|
|||
//Configurations for Canvas
|
|||
canvas: {}, |
|||
|
|||
//Configurations for Layers
|
|||
layers: {}, |
|||
|
|||
//Configurations for Storage Manager
|
|||
storageManager: {}, |
|||
|
|||
//Configurations for Rich Text Editor
|
|||
rte: {}, |
|||
|
|||
//Configurations for DomComponents
|
|||
domComponents: {}, |
|||
|
|||
//Configurations for Modal Dialog
|
|||
modal: {}, |
|||
|
|||
//Configurations for Code Manager
|
|||
codeManager: {}, |
|||
|
|||
//Configurations for Panels
|
|||
panels: {}, |
|||
|
|||
//Configurations for Commands
|
|||
commands: {}, |
|||
|
|||
//Configurations for Css Composer
|
|||
cssComposer: {}, |
|||
|
|||
//Configurations for Selector Manager
|
|||
selectorManager: {}, |
|||
|
|||
//Configurations for Device Manager
|
|||
deviceManager: { |
|||
'devices': [{ |
|||
name: 'Desktop', |
|||
width: '', |
|||
},{ |
|||
name: 'Tablet', |
|||
width: '992px', |
|||
},{ |
|||
name: 'Mobile landscape', |
|||
width: '768px', |
|||
},{ |
|||
name: 'Mobile portrait', |
|||
width: '480px', |
|||
}], |
|||
}, |
|||
|
|||
//Configurations for Style Manager
|
|||
styleManager: { |
|||
|
|||
sectors: [{ |
|||
name: 'General', |
|||
open: false, |
|||
buildProps: ['float', 'display', 'position', 'top', 'right', 'left', 'bottom'], |
|||
},{ |
|||
name: 'Dimension', |
|||
open: false, |
|||
buildProps: ['width', 'height', 'max-width', 'min-height', 'margin', 'padding'], |
|||
},{ |
|||
name: 'Typography', |
|||
open: false, |
|||
buildProps: ['font-family', 'font-size', 'font-weight', 'letter-spacing', 'color', 'line-height', 'text-align', 'text-shadow'], |
|||
properties: [{ |
|||
property: 'text-align', |
|||
list : [ |
|||
{value: 'left', className: 'fa fa-align-left'}, |
|||
{value: 'center', className: 'fa fa-align-center' }, |
|||
{value: 'right', className: 'fa fa-align-right'}, |
|||
{value: 'justify', className: 'fa fa-align-justify'} |
|||
], |
|||
}] |
|||
},{ |
|||
name: 'Decorations', |
|||
open: false, |
|||
buildProps: ['border-radius-c', 'background-color', 'border-radius', 'border', 'box-shadow', 'background'], |
|||
},{ |
|||
name: 'Extra', |
|||
open: false, |
|||
buildProps: ['transition', 'perspective', 'transform'], |
|||
}], |
|||
}, |
|||
|
|||
//Configurations for Style Manager
|
|||
styleManager: { |
|||
|
|||
sectors: [{ |
|||
name: 'General', |
|||
open: false, |
|||
buildProps: ['float', 'display', 'position', 'top', 'right', 'left', 'bottom'], |
|||
},{ |
|||
name: 'Dimension', |
|||
open: false, |
|||
buildProps: ['width', 'height', 'max-width', 'min-height', 'margin', 'padding'], |
|||
},{ |
|||
name: 'Typography', |
|||
open: false, |
|||
buildProps: ['font-family', 'font-size', 'font-weight', 'letter-spacing', 'color', 'line-height', 'text-align', 'text-shadow'], |
|||
properties: [{ |
|||
property: 'text-align', |
|||
list : [ |
|||
{value: 'left', className: 'fa fa-align-left'}, |
|||
{value: 'center', className: 'fa fa-align-center' }, |
|||
{value: 'right', className: 'fa fa-align-right'}, |
|||
{value: 'justify', className: 'fa fa-align-justify'} |
|||
], |
|||
}] |
|||
},{ |
|||
name: 'Decorations', |
|||
open: false, |
|||
buildProps: ['border-radius-c', 'background-color', 'border-radius', 'border', 'box-shadow', 'background'], |
|||
},{ |
|||
name: 'Extra', |
|||
open: false, |
|||
buildProps: ['transition', 'perspective', 'transform'], |
|||
}], |
|||
|
|||
}, |
|||
|
|||
//Configurations for Block Manager
|
|||
blockManager: { |
|||
'blocks': [{ |
|||
id: 'b1', |
|||
label: '1 Block', |
|||
content: '<div class="blk-row"><div class="blk1"></div></div><style>'+ blkStyle +'.blk1{width: 100%;padding: 10px;min-height: 75px;}</style>', |
|||
attributes: {class:'gjs-fonts gjs-f-b1'} |
|||
},{ |
|||
id: 'b2', |
|||
label: '2 Blocks', |
|||
content: '<div class="blk-row"><div class="blk2"></div><div class="blk2"></div></div><style>'+ blkStyle +'.blk2{float: left;width: 50%;padding: 10px;min-height: 75px;}</style>', |
|||
attributes: {class:'gjs-fonts gjs-f-b2'} |
|||
},{ |
|||
id: 'b3', |
|||
label: '3 Blocks', |
|||
content: '<div class="blk-row"><div class="blk3"></div><div class="blk3"></div><div class="blk3"></div></div><style>'+ blkStyle +'.blk3{float: left;width: 33.3333%;padding: 10px;min-height: 75px;}</style>', |
|||
attributes: {class:'gjs-fonts gjs-f-b3'} |
|||
},{ |
|||
id: 'b4', |
|||
label: '3/7 Block', |
|||
content: '<div class="blk-row"><div class="blk37l"></div><div class="blk37r"></div></div></div><style>'+ blkStyle +'.blk37l{float: left;width: 30%;padding: 10px;min-height: 75px;}.blk37r{float: left;width: 70%;padding: 10px;min-height: 75px;}</style>', |
|||
attributes: {class:'gjs-fonts gjs-f-b37'} |
|||
},{ |
|||
id: 'hero', |
|||
label: 'Hero section', |
|||
content: '<header class="header-banner"> <div class="container-width">'+ |
|||
'<div class="logo-container"><div class="logo">GrapesJS</div></div>'+ |
|||
'<nav class="navbar">'+ |
|||
'<div class="menu-item">BUILDER</div><div class="menu-item">TEMPLATE</div><div class="menu-item">WEB</div>'+ |
|||
'</nav><div class="clearfix"></div>'+ |
|||
'<div class="lead-title">Build your templates without coding</div>'+ |
|||
'<div class="lead-btn">Try it now</div></div></header>', |
|||
attributes: {class:'gjs-fonts gjs-f-hero'} |
|||
},{ |
|||
id: 'h1p', |
|||
label: 'Text section', |
|||
content: '<h1 class="heading">Insert title here</h1><p class="paragraph">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua</p>', |
|||
attributes: {class:'gjs-fonts gjs-f-h1p'} |
|||
},{ |
|||
id: '3ba', |
|||
label: 'Badges', |
|||
content: '<div class="badges">'+ |
|||
'<div class="badge">'+ |
|||
'<div class="badge-header"></div>'+ |
|||
'<img class="badge-avatar" src="img/team1.jpg">'+ |
|||
'<div class="badge-body">'+ |
|||
'<div class="badge-name">Adam Smith</div><div class="badge-role">CEO</div><div class="badge-desc">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore ipsum dolor sit</div>'+ |
|||
'</div>'+ |
|||
'<div class="badge-foot"><span class="badge-link">f</span><span class="badge-link">t</span><span class="badge-link">ln</span></div>'+ |
|||
|
|||
}, |
|||
|
|||
//Configurations for Block Manager
|
|||
blockManager: { |
|||
'blocks': [{ |
|||
id: 'b1', |
|||
label: '1 Block', |
|||
content: '<div class="blk-row"><div class="blk1"></div></div><style>'+ blkStyle +'.blk1{width: 100%;padding: 10px;min-height: 75px;}</style>', |
|||
attributes: {class:'gjs-fonts gjs-f-b1'} |
|||
},{ |
|||
id: 'b2', |
|||
label: '2 Blocks', |
|||
content: '<div class="blk-row"><div class="blk2"></div><div class="blk2"></div></div><style>'+ blkStyle +'.blk2{float: left;width: 50%;padding: 10px;min-height: 75px;}</style>', |
|||
attributes: {class:'gjs-fonts gjs-f-b2'} |
|||
},{ |
|||
id: 'b3', |
|||
label: '3 Blocks', |
|||
content: '<div class="blk-row"><div class="blk3"></div><div class="blk3"></div><div class="blk3"></div></div><style>'+ blkStyle +'.blk3{float: left;width: 33.3333%;padding: 10px;min-height: 75px;}</style>', |
|||
attributes: {class:'gjs-fonts gjs-f-b3'} |
|||
},{ |
|||
id: 'b4', |
|||
label: '3/7 Block', |
|||
content: '<div class="blk-row"><div class="blk37l"></div><div class="blk37r"></div></div></div><style>'+ blkStyle +'.blk37l{float: left;width: 30%;padding: 10px;min-height: 75px;}.blk37r{float: left;width: 70%;padding: 10px;min-height: 75px;}</style>', |
|||
attributes: {class:'gjs-fonts gjs-f-b37'} |
|||
},{ |
|||
id: 'hero', |
|||
label: 'Hero section', |
|||
content: '<header class="header-banner"> <div class="container-width">'+ |
|||
'<div class="logo-container"><div class="logo">GrapesJS</div></div>'+ |
|||
'<nav class="navbar">'+ |
|||
'<div class="menu-item">BUILDER</div><div class="menu-item">TEMPLATE</div><div class="menu-item">WEB</div>'+ |
|||
'</nav><div class="clearfix"></div>'+ |
|||
'<div class="lead-title">Build your templates without coding</div>'+ |
|||
'<div class="lead-btn">Try it now</div></div></header>', |
|||
attributes: {class:'gjs-fonts gjs-f-hero'} |
|||
},{ |
|||
id: 'h1p', |
|||
label: 'Text section', |
|||
content: '<h1 class="heading">Insert title here</h1><p class="paragraph">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua</p>', |
|||
attributes: {class:'gjs-fonts gjs-f-h1p'} |
|||
},{ |
|||
id: '3ba', |
|||
label: 'Badges', |
|||
content: '<div class="badges">'+ |
|||
'<div class="badge">'+ |
|||
'<div class="badge-header"></div>'+ |
|||
'<img class="badge-avatar" src="img/team1.jpg">'+ |
|||
'<div class="badge-body">'+ |
|||
'<div class="badge-name">Adam Smith</div><div class="badge-role">CEO</div><div class="badge-desc">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore ipsum dolor sit</div>'+ |
|||
'</div>'+ |
|||
'<div class="badge-foot"><span class="badge-link">f</span><span class="badge-link">t</span><span class="badge-link">ln</span></div>'+ |
|||
'</div>'+ |
|||
'<div class="badge">'+ |
|||
'<div class="badge-header"></div>'+ |
|||
'<img class="badge-avatar" src="img/team2.jpg">'+ |
|||
'<div class="badge-body">'+ |
|||
'<div class="badge-name">John Black</div><div class="badge-role">Software Engineer</div><div class="badge-desc">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore ipsum dolor sit</div>'+ |
|||
'</div>'+ |
|||
'<div class="badge-foot"><span class="badge-link">f</span><span class="badge-link">t</span><span class="badge-link">ln</span></div>'+ |
|||
'</div>'+ |
|||
'<div class="badge">'+ |
|||
'<div class="badge-header"></div>'+ |
|||
'<img class="badge-avatar" src="img/team3.jpg">'+ |
|||
'<div class="badge-body">'+ |
|||
'<div class="badge-name">Jessica White</div><div class="badge-role">Web Designer</div><div class="badge-desc">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore ipsum dolor sit</div>'+ |
|||
'</div>'+ |
|||
'<div class="badge">'+ |
|||
'<div class="badge-header"></div>'+ |
|||
'<img class="badge-avatar" src="img/team2.jpg">'+ |
|||
'<div class="badge-body">'+ |
|||
'<div class="badge-name">John Black</div><div class="badge-role">Software Engineer</div><div class="badge-desc">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore ipsum dolor sit</div>'+ |
|||
'</div>'+ |
|||
'<div class="badge-foot"><span class="badge-link">f</span><span class="badge-link">t</span><span class="badge-link">ln</span></div>'+ |
|||
'<div class="badge-foot"><span class="badge-link">f</span><span class="badge-link">t</span><span class="badge-link">ln</span>'+ |
|||
'</div>'+ |
|||
'<div class="badge">'+ |
|||
'<div class="badge-header"></div>'+ |
|||
'<img class="badge-avatar" src="img/team3.jpg">'+ |
|||
'<div class="badge-body">'+ |
|||
'<div class="badge-name">Jessica White</div><div class="badge-role">Web Designer</div><div class="badge-desc">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore ipsum dolor sit</div>'+ |
|||
'</div>'+ |
|||
'<div class="badge-foot"><span class="badge-link">f</span><span class="badge-link">t</span><span class="badge-link">ln</span>'+ |
|||
'</div>'+ |
|||
'</div></div>', |
|||
attributes: {class:'gjs-fonts gjs-f-3ba'} |
|||
},{ |
|||
id: 'text', |
|||
label: 'Text', |
|||
attributes: {class:'gjs-fonts gjs-f-text'}, |
|||
content: { |
|||
type:'text', |
|||
content:'Insert your text here', |
|||
style: {padding: '10px' }, |
|||
activeOnRender: 1 |
|||
}, |
|||
},{ |
|||
id: 'image', |
|||
label: 'Image', |
|||
attributes: {class:'gjs-fonts gjs-f-image'}, |
|||
content: { |
|||
style: {color: 'black'}, |
|||
type:'image', |
|||
activeOnRender: 1 |
|||
}, |
|||
},{ |
|||
id: 'quo', |
|||
label: 'Quote', |
|||
content: '<blockquote class="quote">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore ipsum dolor sit</blockquote>', |
|||
attributes: {class:'fa fa-quote-right'} |
|||
},{ |
|||
id: 'link', |
|||
label: 'Link', |
|||
attributes: {class:'fa fa-link'}, |
|||
content: { |
|||
type:'link', |
|||
content:'Link', |
|||
style:{color: '#d983a6'} |
|||
}, |
|||
},{ |
|||
id: 'map', |
|||
label: 'Map', |
|||
attributes: {class:'fa fa-map-o'}, |
|||
content: { |
|||
type: 'map', |
|||
style: {height: '350px'} |
|||
}, |
|||
},{ |
|||
id: 'video', |
|||
label: 'Video', |
|||
attributes: {class:'fa fa-youtube-play'}, |
|||
content: { |
|||
type: 'video', |
|||
src: 'img/video2.webm', |
|||
style: { |
|||
height: '350px', |
|||
width: '615px', |
|||
} |
|||
}, |
|||
}/*,{ |
|||
id: 'table', |
|||
label: 'Table', |
|||
attributes: {class:'fa fa-table'}, |
|||
content: { |
|||
type: 'table', |
|||
columns: 3, |
|||
rows: 5, |
|||
style: {height: '150px', width: '100%'} |
|||
}, |
|||
}*/], |
|||
}, |
|||
|
|||
}; |
|||
}); |
|||
'</div></div>', |
|||
attributes: {class:'gjs-fonts gjs-f-3ba'} |
|||
},{ |
|||
id: 'text', |
|||
label: 'Text', |
|||
attributes: {class:'gjs-fonts gjs-f-text'}, |
|||
content: { |
|||
type:'text', |
|||
content:'Insert your text here', |
|||
style: {padding: '10px' }, |
|||
activeOnRender: 1 |
|||
}, |
|||
},{ |
|||
id: 'image', |
|||
label: 'Image', |
|||
attributes: {class:'gjs-fonts gjs-f-image'}, |
|||
content: { |
|||
style: {color: 'black'}, |
|||
type:'image', |
|||
activeOnRender: 1 |
|||
}, |
|||
},{ |
|||
id: 'quo', |
|||
label: 'Quote', |
|||
content: '<blockquote class="quote">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore ipsum dolor sit</blockquote>', |
|||
attributes: {class:'fa fa-quote-right'} |
|||
},{ |
|||
id: 'link', |
|||
label: 'Link', |
|||
attributes: {class:'fa fa-link'}, |
|||
content: { |
|||
type:'link', |
|||
content:'Link', |
|||
style:{color: '#d983a6'} |
|||
}, |
|||
},{ |
|||
id: 'map', |
|||
label: 'Map', |
|||
attributes: {class:'fa fa-map-o'}, |
|||
content: { |
|||
type: 'map', |
|||
style: {height: '350px'} |
|||
}, |
|||
},{ |
|||
id: 'video', |
|||
label: 'Video', |
|||
attributes: {class:'fa fa-youtube-play'}, |
|||
content: { |
|||
type: 'video', |
|||
src: 'img/video2.webm', |
|||
style: { |
|||
height: '350px', |
|||
width: '615px', |
|||
} |
|||
}, |
|||
}/*,{ |
|||
id: 'table', |
|||
label: 'Table', |
|||
attributes: {class:'fa fa-table'}, |
|||
content: { |
|||
type: 'table', |
|||
columns: 3, |
|||
rows: 5, |
|||
style: {height: '150px', width: '100%'} |
|||
}, |
|||
}*/], |
|||
}, |
|||
|
|||
}; |
|||
|
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue