Browse Source

Update rte module and fix input styles

pull/36/head
Artur Arseniev 10 years ago
parent
commit
05aee801a2
  1. 2
      index.html
  2. 15
      src/rich_text_editor/config/config.js
  3. 37
      src/rich_text_editor/main.js
  4. 12
      src/rich_text_editor/model/CommandButton.js
  5. 34
      src/rich_text_editor/view/CommandButtonSelectView.js
  6. 8
      src/rich_text_editor/view/CommandButtonView.js
  7. 70
      src/rich_text_editor/view/CommandButtonsView.js
  8. 41
      src/rich_text_editor/view/TextEditorView.js
  9. 2
      src/selector_manager/template/classTags.html
  10. 2
      src/selector_manager/view/ClassTagsView.js
  11. 28
      styles/css/main.css
  12. 34
      styles/scss/main.scss

2
index.html

@ -707,7 +707,7 @@
}
.badge-header{
height: 115px;
background-image:url("./img/bg-gr-v.png"), url("./img/work-desk.jpg");
background-image:url("http://grapesjs.com/img/bg-gr-v.png"), url("http://grapesjs.com/img/work-desk.jpg");
background-position:left top, center center;
background-attachment:scroll, fixed;
overflow: hidden;

15
src/rich_text_editor/config/config.js

@ -7,17 +7,26 @@ define(function () {
command: 'bold',
title: 'Bold',
class: 'fa fa-bold',
group: 'format'
},{
command: 'italic',
title: 'Italic',
class: 'fa fa-italic',
group: 'format'
},{
command: 'underline',
title: 'Underline',
class: 'fa fa-underline',
},{
command: 'strikethrough',
title: 'Strikethrough',
class: 'fa fa-strikethrough',
group: 'format'
},],
}/*,{
command: 'fontSize',
options: [
{name: 'Huge', value: '100px'},
{name: 'Normal', value: '14px'},
{value: '5px'}
]
}*/],
};
});

37
src/rich_text_editor/main.js

@ -4,13 +4,22 @@
* * [getAll](#getall)
* * [remove](#remove)
*
* This module allows to customize the toolbar of the Rich Text Editor
*
* styleWithCSS
* removeFormat
*
*
* This module allows to customize the toolbar of the Rich Text Editor. It's highly recommended
* to keep this toolbar as small as possible, especially from styling commands (eg. 'fontSize')
* and leave this task to the Style Manager.
*
* Before using methods you should get first the module from the editor instance, in this way:
*
* ```js
* var rte = editor.RichTextEditor;
* ```
* Complete list of commands
* https://developer.mozilla.org/it/docs/Web/API/Document/execCommand
* http://www.quirksmode.org/dom/execCommand.html
* @module RichTextEditor
*/
@ -59,9 +68,10 @@ define(function(require) {
},
/**
* Add new command to the toolbar
* @param {string} command Command name
* Add a new command to the toolbar
* @param {string} command Command name
* @param {Object} opts Command options
* @return {Model} Added command
* @example
* var cm = rte.add('bold', {
* title: 'Make bold',
@ -70,7 +80,7 @@ define(function(require) {
* // With arguments
* var cm = rte.add('fontSize', {
* title: 'Font size',
* arguments: [
* options: [
* {name: 'Big', value: 5},
* {name: 'Normal', value: 3},
* {name: 'Small', value: 1}
@ -83,6 +93,25 @@ define(function(require) {
return commands.add(obj);
},
/**
* Get the command by its name
* @param {string} command Command name
* @return {Model}
* @example
* var cm = rte.get('fontSize');
*/
get: function(command) {
return commands.where({command: command})[0];
},
/**
* Returns the collection of commands
* @return {Collection}
*/
getAll: function(){
return commands;
},
/**
* Triggered when the offset of the editro is changed
* @private

12
src/rich_text_editor/model/CommandButton.js

@ -2,12 +2,20 @@ define(['backbone'],
function (Backbone) {
return Backbone.Model.extend({
idAttribute: 'command',
defaults: {
command: '',
type: '',
title: '',
class: '',
group: '',
arguments: [],
options: [],
},
initialize: function() {
var opts = this.get('options');
if(opts.length)
this.set('type', 'select');
},
});

34
src/rich_text_editor/view/CommandButtonSelectView.js

@ -0,0 +1,34 @@
define(['backbone'],
function (Backbone) {
return Backbone.View.extend({
initialize: function(o, config){
this.config = config || {};
this.className = this.config.stylePrefix + 'btn ' + this.model.get('class');
},
getInput: function(){
var m = this.model;
if(!this.input){
var cmd = m.get('command');
var input = '<select data-edit="' + cmd +'">';
var opts = m.get('options');
for(var i = 0, len = opts.length; i < len; i++){
var opt = opts[i];
var value = opt.value;
var name = opt.name || value;
input += '<option value="' + value + '">' + name + '</option>';
}
input += '</select>';
this.input = $(input);
}
return this.input;
},
render: function() {
this.$el.addClass(this.className);
this.$el.html(this.getInput());
return this;
}
});
});

8
src/rich_text_editor/view/CommandButtonView.js

@ -4,13 +4,13 @@ define(['backbone'],
tagName: 'a',
initialize: function(o){
this.config = o.config || {};
this.className = this.config.stylePrefix + 'btn ' + this.model.get('class');
initialize: function(o, config){
this.config = config || {};
this.className = this.config.stylePrefix + 'btn ' + this.model.get('class');
},
render: function() {
this.$el.attr('class', _.result( this, 'className' ) );
this.$el.addClass(this.className);
return this;
}
});

70
src/rich_text_editor/view/CommandButtonsView.js

@ -1,5 +1,5 @@
define(['backbone','./CommandButtonView'],
function (Backbone, CommandButtonView) {
define(['backbone','./CommandButtonView', './CommandButtonSelectView'],
function (Backbone, CommandButtonView, CommandButtonSelectView) {
return Backbone.View.extend({
attributes : {
@ -8,27 +8,63 @@ define(['backbone','./CommandButtonView'],
initialize: function(o){
this.config = o.config || {};
this.id = this.config.stylePrefix + this.config.toolbarId;
var pfx = this.config.stylePrefix || '';
this.id = pfx + this.config.toolbarId;
this.listenTo(this.collection, 'add', this.addTo);
this.$el.data('helper', 1);
},
/**
* 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 viewObj = CommandButtonView;
switch (model.get('type')) {
case 'select':
viewObj = CommandButtonSelectView;
break;
}
var view = new viewObj({
model: model,
attributes: {
'title': model.get('title'),
'data-edit': model.get('command'),
},
}, this.config);
var rendered = view.render().el;
if(frag)
frag.appendChild(rendered);
else
this.$el.append(rendered);
},
render: function() {
var fragment = document.createDocumentFragment();
var frag = document.createDocumentFragment();
this.$el.empty();
this.collection.each(function(item){
var view = new CommandButtonView({
model: item,
config: this.config,
attributes: {
'title': item.get('title'),
'data-edit': item.get('command'),
},
});
fragment.appendChild(view.render().el);
},this);
this.$el.append(fragment);
this.$el.attr('id', _.result( this, 'id' ) );
this.collection.each(function(model){
this.add(model, frag);
}, this);
this.$el.append(frag);
this.$el.attr('id', this.id );
return this;
}

41
src/rich_text_editor/view/TextEditorView.js

@ -23,13 +23,16 @@ define(['jquery'],
options,
toolbarBtnSelector,
updateToolbar = function () {
if (options.activeToolbarClass) {
var actCls = options.activeToolbarClass;
if (actCls) {
$(options.toolbarSelector).find(toolbarBtnSelector).each(function () {
var command = $(this).data(options.commandRole);
if (document.queryCommandState(command)) {
$(this).addClass(options.activeToolbarClass);
var el = $(this);
var command = el.data(options.commandRole);
var doc = editor.get(0).ownerDocument;
if (doc.queryCommandState(command)) {
el.addClass(actCls);
} else {
$(this).removeClass(options.activeToolbarClass);
el.removeClass(actCls);
}
});
}
@ -38,7 +41,9 @@ define(['jquery'],
var commandArr = commandWithArgs.split(' '),
command = commandArr.shift(),
args = commandArr.join(' ') + (valueArg || '');
document.execCommand(command, 0, args);
//document.execCommand("insertHTML", false, "<span class='own-class'>"+ document.getSelection()+"</span>");
editor.get(0).ownerDocument.execCommand("styleWithCSS", false, true);
editor.get(0).ownerDocument.execCommand(command, 0, args);
updateToolbar();
},
/*
@ -106,13 +111,24 @@ define(['jquery'],
bindToolbar = function (toolbar, options) {
toolbar.find(toolbarBtnSelector).unbind().click(function () {
restoreSelection();
editor.focus();
//editor.focus(); // cause defocus on selects
editor.get(0).ownerDocument.execCommand($(this).data(options.commandRole));
saveSelection();
});
toolbar.find('[data-toggle=dropdown]').click(restoreSelection);
toolbar.find('input[type=text][data-' + options.commandRole + ']').on('webkitspeechchange change', function () {
var dName = '[data-' + options.commandRole + ']';
toolbar.find('select'+dName).on('webkitspeechchange change', function(){
var newValue = this.value;
restoreSelection();
if (newValue) {
editor.focus();
execCommand($(this).data(options.commandRole), newValue);
}
console.log('change isolated2 ', newValue);
saveSelection();
});
toolbar.find('input[type=text]'+dName,', select'+dName).on('webkitspeechchange change', function () {
console.log('on changed ', newValue);
var newValue = this.value; /* ugly but prevents fake double-calls due to selection restoration */
this.value = '';
restoreSelection();
@ -122,8 +138,10 @@ define(['jquery'],
}
saveSelection();
}).on('focus', function () {
console.log('on focus ');
var input = $(this);
if (!input.data(options.selectionMarker)) {
console.log('i have no ', options.selectionMarker);
markSelection(input, options.selectionColor);
input.focus();
}
@ -161,7 +179,8 @@ define(['jquery'],
return this;
}
options = $.extend({}, $.fn.wysiwyg.defaults, userOptions);
toolbarBtnSelector = 'a[data-' + options.commandRole + '],button[data-' + options.commandRole + '],input[type=button][data-' + options.commandRole + ']';
var dName = '[data-' + options.commandRole + ']';
toolbarBtnSelector = 'a'+dName+',button'+dName+',input[type=button]'+dName+', select'+dName;
//bindHotkeys(options.hotKeys);
if (options.dragAndDropImages) {
initFileDrops();
@ -183,6 +202,7 @@ define(['jquery'],
return this;
};
$.fn.wysiwyg.defaults = {
/*
hotKeys: {
'ctrl+b meta+b': 'bold',
'ctrl+i meta+i': 'italic',
@ -196,6 +216,7 @@ define(['jquery'],
'shift+tab': 'outdent',
'tab': 'indent'
},
*/
toolbarSelector: '[data-role=editor-toolbar]',
commandRole: 'edit',
activeToolbarClass: 'btn-info',

2
src/selector_manager/template/classTags.html

@ -2,7 +2,7 @@
<div id="<%= pfx %>label"><%= label %></div>
<div id="<%= pfx %>status-c">
<span id="<%= pfx %>input-c">
<div class="<%= pfx %>field <%= pfx %>select">
<div class="<%= pfx %>field <%= ppfx %>select">
<span id="<%= pfx %>input-holder">
<select id="<%= pfx %>states">
<option value=""><%= statesLabel %></option>

2
src/selector_manager/view/ClassTagsView.js

@ -12,6 +12,7 @@ define(['backbone', 'text!./../template/classTags.html', './ClassTagView'],
initialize: function(o) {
this.config = o.config || {};
this.pfx = this.config.stylePrefix || '';
this.ppfx = this.config.pStylePrefix || '';
this.className = this.pfx + 'tags';
this.addBtnId = this.pfx + 'add-tag';
this.newInputId = this.pfx + 'new';
@ -264,6 +265,7 @@ define(['backbone', 'text!./../template/classTags.html', './ClassTagView'],
label: this.config.label,
statesLabel: this.config.statesLabel,
pfx: this.pfx,
ppfx: this.ppfx
}));
this.$input = this.$el.find('input#' + this.newInputId);
this.$addBtn = this.$el.find('#' + this.addBtnId);

28
styles/css/main.css

@ -2687,7 +2687,7 @@ $fontColorActive: #4f8ef7;
.gjs-btn-prim:active {
background-color: rgba(255, 255, 255, 0.1); }
.gjs-input {
.gjs-input, .gjs-select {
background-color: rgba(0, 0, 0, 0.3);
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 2px;
@ -2696,6 +2696,21 @@ $fontColorActive: #4f8ef7;
color: #ddd;
padding: 0.5em 1em; }
div.gjs-select {
padding: 0; }
.gjs-select:-moz-focusring,
.gjs-select select:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 rgba(255, 255, 255, 0.7); }
.gjs-input:focus, .gjs-select:focus,
.gjs-button:focus,
.gjs-btn-prim:focus,
.gjs-select:focus,
.gjs-select select:focus {
outline: none; }
/************* CANVAS ****************/
.gjs-cv-canvas {
background-color: rgba(0, 0, 0, 0.15);
@ -3202,10 +3217,8 @@ ol.example li.placeholder:before {
background: none;
border: none;
color: rgba(255, 255, 255, 0.7);
color: transparent;
width: 100%;
padding: 2px 10px 2px 0;
text-shadow: 0 0 0 rgba(255, 255, 255, 0.7);
padding: 2px 10px 2px 2px;
position: relative;
z-index: 1;
-webkit-appearance: none;
@ -3213,6 +3226,11 @@ ol.example li.placeholder:before {
appearance: none; }
.gjs-sm-sector .gjs-sm-field select::-ms-expand, .gjs-clm-tags .gjs-sm-field select::-ms-expand, .gjs-sm-sector .gjs-clm-field select::-ms-expand, .gjs-clm-tags .gjs-clm-field select::-ms-expand {
display: none; }
.gjs-sm-sector .gjs-sm-field select:-moz-focusring, .gjs-clm-tags .gjs-sm-field select:-moz-focusring, .gjs-sm-sector .gjs-clm-field select:-moz-focusring, .gjs-clm-tags .gjs-clm-field select:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 rgba(255, 255, 255, 0.7); }
.gjs-sm-sector .gjs-sm-field select:focus, .gjs-clm-tags .gjs-sm-field select:focus, .gjs-sm-sector .gjs-clm-field select:focus, .gjs-clm-tags .gjs-clm-field select:focus, .gjs-sm-sector .gjs-sm-field input:focus, .gjs-clm-tags .gjs-sm-field input:focus, .gjs-sm-sector .gjs-clm-field input:focus, .gjs-clm-tags .gjs-clm-field input:focus {
outline: none; }
.gjs-sm-sector .gjs-sm-field .gjs-sm-unit, .gjs-clm-tags .gjs-sm-field .gjs-sm-unit, .gjs-sm-sector .gjs-clm-field .gjs-sm-unit, .gjs-clm-tags .gjs-clm-field .gjs-sm-unit {
position: absolute;
right: 10px;
@ -3729,7 +3747,7 @@ ol.example li.placeholder:before {
z-index: 5; }
#gjs-rte-toolbar .gjs-rte-btn {
padding: 5px;
width: 25px;
min-width: 25px;
border-right: 1px solid rgba(0, 0, 0, 0.3);
text-align: center;
cursor: pointer;

34
styles/scss/main.scss

@ -188,7 +188,25 @@ $fontV: 5;//random(1000)
color: $fontColor;
padding: 0.5em 1em;
}
.#{$app-prefix}select{
@extend .#{$app-prefix}input;
}
div.#{$app-prefix}select{
padding: 0;
}
.#{$app-prefix}select:-moz-focusring,
.#{$app-prefix}select select:-moz-focusring{
color: transparent;
text-shadow: 0 0 0 $mainLhlColor;
}
.#{$app-prefix}input:focus,
.#{$app-prefix}button:focus,
.#{$app-prefix}btn-prim:focus,
.#{$app-prefix}select:focus,
.#{$app-prefix}select select:focus {
outline: none;
}
/************* CANVAS ****************/
.#{$cv-prefix}canvas {
background-color: rgba(0, 0, 0, 0.15);
@ -746,9 +764,8 @@ $arrowColor: $mainLhlColor; /*b1b1b1*/
select {
background: none; border: none;
color: $inputFontColor;
color: transparent;
width: 100%; padding: 2px 10px 2px 0;
text-shadow: 0 0 0 $inputFontColor;
width: 100%;
padding: 2px 10px 2px 2px;
position: relative;
z-index:1;
@include appearance(none);
@ -756,6 +773,15 @@ $arrowColor: $mainLhlColor; /*b1b1b1*/
&::-ms-expand { display: none;}
}
select:-moz-focusring{
color: transparent;
text-shadow: 0 0 0 $inputFontColor;
}
select:focus, input:focus{
outline: none;
}
.#{$sm-prefix}unit {
position: absolute;
right: 10px; top: 3px;
@ -1390,7 +1416,7 @@ $uploadPadding: 150px 10px;
.#{$rte-prefix}btn {
@extend .#{$app-prefix}color-main;
padding: 5px;
width: 25px;
min-width: 25px;
border-right: 1px solid $mainDkColor;
text-align: center;
cursor: pointer;

Loading…
Cancel
Save