Browse Source

Add rte toolbar

pull/36/head
Artur Arseniev 10 years ago
parent
commit
4407b9fb3e
  1. 48
      src/canvas/view/CanvasView.js
  2. 16
      src/dom_components/view/ComponentTextView.js
  3. 4
      src/editor/model/Editor.js
  4. 130
      src/rich_text_editor/main.js
  5. 1
      styles/css/main.css
  6. 1
      styles/scss/main.scss

48
src/canvas/view/CanvasView.js

@ -13,6 +13,17 @@ function(Backbone, FrameView) {
this.frame = new FrameView({ model: this.model.get('frame')});
},
/**
* 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;
},
/**
* Render inside frame's body
* @private
@ -33,9 +44,46 @@ function(Backbone, FrameView) {
if(protCss)
body.append('<style>' + frameCss + protCss + '</style>');
this.config.em.trigger('loaded');
this.frame.el.contentWindow.onscroll = this.onFrameScroll.bind(this);
}
},
/**
* 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
};
},
/**
* Returns element's data info
* @param {HTMLElement} el
* @return {Object}
* @private
*/
getElementPos: function(el){
if(!this.frmOff)
this.frmOff = this.offset(this.frame.el);
if(!this.cvsOff)
this.cvsOff = this.offset(this.el);
var eo = this.offset(el);
var top = eo.top + this.frmOff.top - this.cvsOff.top;
var left = eo.left + this.frmOff.left - this.cvsOff.left;
return {
top: top,
left: left,
height: el.offsetHeight,
width: el.offsetWidth
};
},
render: function() {
this.wrapper = this.model.get('wrapper');

16
src/dom_components/view/ComponentTextView.js

@ -15,26 +15,24 @@ define(['backbone', './ComponentView'],
},
/**
* Enable this component to be editable,
* load also the mini toolbar for quick editing
* Enable the component to be editable
* @param {Event} e
* @private
* */
enableEditing: function(e){
if(this.rte)
this.rte.bind(this);
this.rte.attach(this);
this.toggleEvents(1);
},
/**
* Disable this component to be editable
* @param Event
* @param {Event}
* @private
* */
disableEditing: function(e){
if(this.rte){
this.rte.unbind(this);
}
if(this.rte)
this.rte.detach(this);
this.toggleEvents();
this.updateContents();
},
@ -52,7 +50,7 @@ define(['backbone', './ComponentView'],
* Update contents of the element
* @private
**/
updateContents : function(){
updateContents: function(){
this.model.set('content', this.el.innerHTML);
},
@ -63,7 +61,7 @@ define(['backbone', './ComponentView'],
toggleEvents: function(enable) {
var method = enable ? 'on' : 'off';
// The ownerDocument is from the frame
var elDocs = [this.el.ownerDocument, document];
var elDocs = [this.el.ownerDocument, document, this.rte];
$(elDocs)[method]('mousedown', this.disableEditing);
// Avoid closing edit mode on component click
this.$el[method]('mousedown', this.disablePropagation);

4
src/editor/model/Editor.js

@ -272,7 +272,9 @@ define([
initRichTextEditor: function() {
var cfg = this.config.rte,
rteStylePfx = cfg.stylePrefix || 'rte-';
cfg.stylePrefix = this.config.stylePrefix + rteStylePfx;
cfg.pStylePrefix = this.config.stylePrefix;
cfg.stylePrefix = cfg.pStylePrefix + rteStylePfx;
cfg.em = this;
this.rte = new RichTextEditor(cfg);
this.set('RichTextEditor', this.rte);
},

130
src/rich_text_editor/main.js

@ -1,64 +1,44 @@
define(function(require) {
/**
* @class RichTextEditor
* @param {Object} Configurations
*
* @return {Object}
* */
function RichTextEditor(config)
{
var c = config || {},
defaults = require('./config/config'),
rte = require('./view/TextEditorView'),
CommandButtons = require('./model/CommandButtons'),
CommandButtonsView = require('./view/CommandButtonsView');
return function(config) {
var c = config || {},
defaults = require('./config/config'),
rte = require('./view/TextEditorView'),
CommandButtons = require('./model/CommandButtons'),
CommandButtonsView = require('./view/CommandButtonsView');
for (var name in defaults) {
if (!(name in c))
c[name] = defaults[name];
}
this.tlbPfx = c.stylePrefix;
this.commands = new CommandButtons(c.commands);
var obj = {
collection : this.commands,
config : c,
};
this.toolbar = new CommandButtonsView(obj);
this.$toolbar = this.toolbar.render().$el;
}
var tlbPfx = c.stylePrefix;
var toolbar = new CommandButtonsView({
collection: new CommandButtons(c.commands),
config: c,
});
RichTextEditor.prototype = {
/**
* Render toolbar
* @return {HTMLElement}
*/
render: function(){
return this.toolbar.render().el;
},
/**
* Return toolbar element
* @return {HTMLElement}
*/
getToolbarEl: function() {
return this.$toolbar;
},
return {
/**
* Bind rich text editor to element
* @param {View} view
* */
bind: function(view){
attach: function(view){
view.$el.wysiwyg({hotKeys: {}}).focus();
this.updatePosition(view.$el);
if(c.em){
var u = 'px';
var cvsView = c.em.get('Canvas').CanvasView;
var dims = cvsView.getElementPos(view.el);
var toolEl = toolbar.el;
var toolS = toolbar.el.style;
toolS.top = (dims.top - toolbar.$el.outerHeight()) + u;
toolS.left = dims.left + u;
}
this.bindToolbar(view).show();
//Avoid closing edit mode clicking on toolbar
this.$toolbar.on('mousedown', this.disableProp);
toolbar.$el.on('mousedown', this.disableProp);
},
/**
@ -66,63 +46,42 @@ define(function(require) {
* @param {Object} view
*
* */
unbind: function(view){
detach: function(view){
view.$el.wysiwyg('destroy');
this.hide();
this.$toolbar.off('mousedown', this.disableProp);
toolbar.$el.off('mousedown', this.disableProp);
},
/**
* Bind toolbar to element
* @param {Object} view
*
* @return this
* @param {Object} view
* @return {this}
* */
bindToolbar: function(view){
var id = this.tlbPfx + view.model.cid,
dId = this.tlbPfx + 'inited';
var id = tlbPfx + view.model.cid,
dId = tlbPfx + 'inited';
if(!view.$el.data(dId)){
view.$el.data(dId, 1);
view.$el.attr('id',id);
}
this.toolbar.updateTarget('#' + id);
toolbar.updateTarget('#' + id);
return this;
},
/**
* Update toolbar position
* @param {Object} $el Element
*
*/
updatePosition: function($el){
var cOffset = this.$container.offset(),
cTop = cOffset ? cOffset.top : 0,
cLeft = cOffset ? cOffset.left : 0,
eOffset = $el.offset(),
rTop = eOffset.top - cTop + this.$container.scrollTop(),
rLeft = eOffset.left - cLeft + this.$container.scrollLeft();
if(!this.tlbH)
this.tlbH = this.$toolbar.outerHeight();
this.$toolbar.css({
top : (rTop - this.tlbH - 5),
left : rLeft
});
},
/**
* Show toolbar
*
* */
show : function(){
this.$toolbar.show();
show: function(){
toolbar.el.style.display = 'block';
},
/**
* Hide toolbar
*
* */
hide : function(){
this.$toolbar.hide();
hide: function(){
toolbar.el.style.display = 'none';
},
/**
@ -132,7 +91,24 @@ define(function(require) {
disableProp: function(e){
e.stopPropagation();
},
/**
* Return toolbar element
* @return {HTMLElement}
*/
getToolbarEl: function() {
return toolbar.el;
},
/**
* Render toolbar
* @return {HTMLElement}
*/
render: function(){
return toolbar.render().el;
}
};
};
return RichTextEditor;
});

1
styles/css/main.css

@ -3534,6 +3534,7 @@ ol.example li.placeholder:before {
position: absolute;
border-radius: 3px;
overflow: hidden;
display: none;
z-index: 5; }
#wte-rte-toolbar .wte-rte-btn {
color: #eee;

1
styles/scss/main.scss

@ -1148,6 +1148,7 @@ $uploadPadding: 150px 10px;
position: absolute;
border-radius: 3px;
overflow: hidden;
display: none;
z-index: 5;
.#{$rte-prefix}btn {

Loading…
Cancel
Save