Browse Source

Refactor inputs view

pull/36/head
Artur Arseniev 9 years ago
parent
commit
15f234c94b
  1. 2
      bower.json
  2. 16
      dist/grapes.min.js
  3. 12
      index.html
  4. 2
      package.json
  5. 17
      src/dom_components/model/Component.js
  6. 240
      src/domain_abstract/ui/InputNumber.js
  7. 6
      src/domain_abstract/ui/templates/inputNumber.html
  8. 3
      src/style_manager/model/PropertyFactory.js
  9. 175
      src/style_manager/view/PropertyIntegerView.js

2
bower.json

@ -1,7 +1,7 @@
{
"name": "grapesjs",
"description": "Open source Web Template Editor",
"version": "0.3.35",
"version": "0.3.36",
"author": "Artur Arseniev",
"homepage": "http://grapesjs.com",
"main": [

16
dist/grapes.min.js

File diff suppressed because one or more lines are too long

12
index.html

@ -9,6 +9,18 @@
</head>
<style>
body, html{ height: 100%; margin: 0;}
#gjs ::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.1);
}
#gjs ::-webkit-scrollbar-thumb {
background-color: rgba(255, 255, 255, 0.2);
}
#gjs ::-webkit-scrollbar {
width: 7px;
}
</style>
<body>

2
package.json

@ -1,7 +1,7 @@
{
"name": "grapesjs",
"description": "Open source Web Template Editor",
"version": "0.3.35",
"version": "0.3.36",
"author": "Artur Arseniev",
"license": "BSD-3-Clause",
"homepage": "http://grapesjs.com",

17
src/dom_components/model/Component.js

@ -7,20 +7,31 @@ define(['backbone','./Components', 'SelectorManager/model/Selectors', 'TraitMana
tagName: 'div',
type: '',
editable: false,
// True if the component is removable from the canvas
removable: true,
// Indicates if it's possible to drag the component inside other
// TODO: Indicate an array of selectors where it could be dropped inside
// Tip: Indicate an array of selectors where it could be dropped inside
draggable: true,
// Indicates if it's possible to drop other components inside
// TODO: Indicate an array of selectors which could be dropped inside
// Tip: Indicate an array of selectors which could be dropped inside
droppable: true,
mirror: '',
// 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 is possible to style
stylable: true,
// True if it's possible to clone the component
copyable: true,
// TODO
mirror: '',
void: false,
state: '',
status: '',

240
src/domain_abstract/ui/InputNumber.js

@ -0,0 +1,240 @@
define(['backbone', 'text!./templates/inputNumber.html'],
function (Backbone, inputTemplate) {
return Backbone.View.extend({
events: {},
template: _.template(inputTemplate),
initialize: function(opts) {
_.bindAll(this, 'moveIncrement', 'upIncrement');
var ppfx = opts.ppfx || '';
this.ppfx = ppfx;
this.docEl = $(document);
this.inputCls = ppfx + 'input-number';
this.unitCls = ppfx + 'input-unit';
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);
// 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>', {
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(e){
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)
this.model.set('value', this.prValue - 1, {silent:1}).set('value', this.prValue + 1);
},
/**
* Validate input value
* @param {String} value Raw value
* @param {Object} opts Options
* @return {Object} Validated string
*/
validateInputValue: function(value, opts) {
var unit = '';
var val = value;
var force = 0;
var opt = opts || {};
var model = this.model;
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 {
// Make it suitable for replace
val += '';
val = parseFloat(val.replace(',', '.'));
val = !isNaN(val) ? val : model.get('defaults');
var uN = value.replace(val, '');
// Check if exists as unit
if(_.indexOf(model.get('units'), uN) >= 0)
unit = uN;
}
}
}
if(typeof max !== 'undefined')
val = val > max ? max : val;
if(typeof min !== 'undefined')
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(ppfx + 'field');
return this;
}
});
});

6
src/domain_abstract/ui/templates/inputNumber.html

@ -0,0 +1,6 @@
<span class='<%= ppfx %>input-holder'></span>
<span class='<%= ppfx %>field-units'></span>
<div class="<%= ppfx %>field-arrows">
<div class="<%= ppfx %>field-arrow-u"></div>
<div class="<%= ppfx %>field-arrow-d"></div>
</div>

3
src/style_manager/model/PropertyFactory.js

@ -31,6 +31,9 @@ define(['backbone'],
// Fixed values
switch(prop){
case 'margin-top': case 'margin-right': case 'margin-bottom': case 'margin-left':
case 'padding-top': case 'padding-right': case 'padding-bottom': case 'padding-left':
case 'width': case 'max-width': case 'min-width':
case 'height': case 'max-height': case 'min-height':
obj.fixedValues = ['initial', 'inherit', 'auto'];
break;
}

175
src/style_manager/view/PropertyIntegerView.js

@ -1,49 +1,11 @@
define(['backbone','./PropertyView', 'text!./../templates/propertyInteger.html'],
function (Backbone, PropertyView, propertyTemplate) {
/**
* @class PropertyIntegerView
* */
return PropertyView.extend({
define(['backbone','./PropertyView', 'Abstract/ui/InputNumber'],
function (Backbone, PropertyView, InputNumber) {
template: _.template(propertyTemplate),
return PropertyView.extend({
initialize: function(options) {
PropertyView.prototype.initialize.apply(this, arguments);
_.bindAll(this, 'moveIncrement', 'upIncrement');
this.min = this.model.get('min') || this.model.get('min')===0 ? this.model.get('min') : null;
this.max = this.model.get('max') || this.model.get('max')===0 ? this.model.get('max') : null;
this.units = this.model.get('units');
this.unit = this.model.get('unit') ? this.model.get('unit') : (this.units.length ? this.units[0] : '');
this.events['click .'+this.ppfx+'field-arrow-u'] = 'upArrowClick';
this.events['click .'+this.ppfx+'field-arrow-d'] = 'downArrowClick';
this.events['mousedown .'+this.ppfx+'field-arrows'] = 'downIncrement';
this.listenTo( this.model ,'change:unit', this.valueChanged);
this.delegateEvents();
},
/**
* Fired when the input value is updated
*/
valueUpdated: function(){
if(this.$input && this.$unit)
this.model.set({
value: this.validateValue(this.$input.val()),
unit: this.$unit.val()
});
},
/**
* Validate input value
* @param {integer|float} value Raw value
* @return {string} Validated string
*/
validateValue: function(value){
var val = value;
if(this.max !== null)
val = val > this.max ? this.max : val;
if(this.min !== null)
val = val < this.min ? this.min : val;
return val;
},
/**
@ -54,132 +16,21 @@ define(['backbone','./PropertyView', 'text!./../templates/propertyInteger.html']
return this.model.get('value') + this.model.get('unit');
},
/**
* Invoked when the up arrow is clicked
* @param Event
*
* @return void
* */
upArrowClick: function(e){
var value = this.model.get('value');
value = isNaN(value) ? 1 : parseInt(value,10) + 1;
if(this.max !== null)
value = value > this.max ? this.max : value;
this.model.set('value',value);
},
/**
* Invoked when the down arrow is clicked
* @param Event
*
* @return void
* */
downArrowClick: function(e){
var value = this.model.get('value');
value = isNaN(value) ? 0 : parseInt(value,10) - 1;
if(this.min !== null)
value = value < this.min ? this.min : value;
this.model.set('value',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 };
$(document).mouseup(current, this.upIncrement);
$(document).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.validateValue(pos);//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) {
$(document).off('mouseup', this.upIncrement);
$(document).off('mousemove', this.moveIncrement);
if(this.prValue && this.moved)
this.model.set('value', this.prValue - 1, {silent:1}).set('value', this.prValue + 1);
},
/** @inheritdoc */
renderInput: function() {
var pfx = this.pfx;
var ppfx = this.ppfx;
if(!this.$input){
this.$input = $('<input>', {placeholder: 'auto', type: 'text' });
this.$el.find('#'+ pfx +'input-holder').html(this.$input);
}
if(!this.$unit){
if(this.units && this.units.length){
this.unitS = '<select>';
_.each(this.units,function(unit){
var selected = unit == this.selectedUnit ? 'selected': '';
this.unitS += '<option ' + selected + ' >' + unit + '</option>';
},this);
this.unitS += '</select>';
this.$unit = $(this.unitS);
this.$el.find('.' + ppfx + 'field-units').html(this.$unit);
}
if (!this.input) {
var inputNumber = new InputNumber({
model: this.model,
ppfx: this.ppfx
});
this.input = inputNumber.render();
this.$el.append(this.input.$el);
}
this.setValue(this.componentValue);
this.input.setValue(this.componentValue, {silent: 1});
},
/** @inheritdoc */
setValue: function(value){
var model = this.model;
var u = this.unit;
var v = model.get('value') || this.defaultValue;
var fixed = model.get('fixedValues') || [];
renderTemplate: function(){},
if (value) {
// 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(value)) {
v = value.match(regFixed)[0];
u = '';
} else {
// Make it suitable for replace
value += '';
v = parseFloat(value.replace(',', '.'));
v = !isNaN(v) ? v : this.defaultValue;
var uN = value.replace(v, '');
// Check if exists as unit
if(_.indexOf(this.units, uN) > -1)
u = uN;
}
}
if(this.$input)
this.$input.val(v);
if(this.$unit)
this.$unit.val(u);
model.set({value: v, unit: u,}, {silent: true});
},
setValue: function() {},
});
});

Loading…
Cancel
Save