diff --git a/README.md b/README.md
index 84075ace5..95b46aa0f 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,6 @@
-# [GrapesJS](http://grapesjs.com) [](https://travis-ci.org/artf/grapesjs)
+# [GrapesJS](http://grapesjs.com)
+
+[](https://travis-ci.org/artf/grapesjs)

@@ -8,7 +10,7 @@ Be aware that is not a 'Website Builder' but a tool to create only structure and
Try it here: http://grapesjs.com/demo.html
-### Features
+## Features
* Style Manager, for component styling

@@ -27,12 +29,12 @@ Try it here: http://grapesjs.com/demo.html
* Default built-in commands (basically for creating and managing different components)
-### Installation
+## Installation
You can get GrapesJS with `bower install grapesjs` or via `git clone https://github.com/artf/grapesjs.git` to directly use it. For development purpose you should follow instructions below.
-### Development
+## Development
GrapesJS uses [RequireJS](http://requirejs.org/) to organize its files inside `src` folder and [Grunt](http://gruntjs.com/) for build them to `dist`
@@ -67,7 +69,8 @@ Tests are already available inside browser on `localhost:8000/test`
If [Grunt](http://gruntjs.com/) is already installed globally you could change the port by using `grunt dev --port 9000`
-### Usage
+## Usage
+
JQuery is the only hard dependency so you have to include it before use GrapesJS.
```html
@@ -92,7 +95,7 @@ Unfortunately with the configuration above you wouldn't see a lot. This because
The section below will explain some basic configurations but for a more practical example I suggest to look up the code inside this demo: http://grapesjs.com/demo.html
-### Configuration
+## Configuration
For now I only show up some general settings, for more details check source or demo. Examples will be available soon
@@ -142,12 +145,12 @@ var config = {
```
-### API
+## API
At the moment `render()` is the only available method but others will be public very soon...
-### Testing
+## Testing
**ATTENTION: tests are pretty far away from being complete**
@@ -157,7 +160,7 @@ Tests are run by [PhantomJS](http://phantomjs.org/) using [Mocha](https://mochaj
$ npm run test
```
-### Acknowledgements
+## Acknowledgements
GrapesJS is built on top of this amazing open source projects:
@@ -169,7 +172,7 @@ GrapesJS is built on top of this amazing open source projects:
* [FontAwesome] - the iconic font and CSS framework
-### Contributing
+## Contributing
Any kind of help is welcome. At the moment there is no generic guidelines so use usual pull requests and push to `dev` branch
diff --git a/src/class_manager/view/ClassTagView.js b/src/class_manager/view/ClassTagView.js
index 4297f2fe8..6a379bcc5 100644
--- a/src/class_manager/view/ClassTagView.js
+++ b/src/class_manager/view/ClassTagView.js
@@ -7,10 +7,29 @@ define(['backbone', 'text!./../template/classTag.html'],
template: _.template(tagTemplate),
+ events: {},
+
initialize: function(o) {
this.config = o.config || {};
this.pfx = this.config.stylePrefix;
this.className = this.pfx + 'tag';
+ this.closeId = this.pfx + 'close';
+ this.events['click #' + this.closeId ] = 'removeTag';
+
+ this.delegateEvents();
+ },
+
+ /**
+ * Remove tag from the selected component
+ * @param {Object} e
+ */
+ removeTag: function(e){
+ var comp = this.config.target.get('selectedComponent');
+
+ if(comp)
+ comp.get('classes').remove(this.model);
+
+ this.remove();
},
/** @inheritdoc */
diff --git a/src/class_manager/view/ClassTagsView.js b/src/class_manager/view/ClassTagsView.js
index 52a54de13..b4c40ce23 100644
--- a/src/class_manager/view/ClassTagsView.js
+++ b/src/class_manager/view/ClassTagsView.js
@@ -18,8 +18,8 @@ define(['backbone', 'text!./../template/classTags.html', './ClassTagView'],
this.addBtnId = this.pfx + 'add-tag';
this.newInputId = this.pfx + 'new';
this.events['click #' + this.addBtnId] = 'startNewTag';
- this.events['blur #'+this.newInputId] = 'endNewTag';
- this.events['keyup #'+this.newInputId] = 'onInputKeyUp';
+ this.events['blur #' + this.newInputId] = 'endNewTag';
+ this.events['keyup #' + this.newInputId] = 'onInputKeyUp';
this.target = this.config.target;
@@ -106,11 +106,9 @@ define(['backbone', 'text!./../template/classTags.html', './ClassTagView'],
var cm = this.target.get('ClassManager');
var model = cm.addClass(name);
- if(this.compTarget){
+ if(this.compTarget)
this.compTarget.get('classes').add(model);
- }
- console.log(this.compTarget);
}
this.endNewTag();
},
diff --git a/src/code_manager/model/JsonGenerator.js b/src/code_manager/model/JsonGenerator.js
index d8920f5f7..67c2e5f61 100644
--- a/src/code_manager/model/JsonGenerator.js
+++ b/src/code_manager/model/JsonGenerator.js
@@ -1,21 +1,22 @@
-define(['backbone'],
+define(['backbone'],
function (Backbone) {
/**
* @class JsonGenerator
* */
return Backbone.Model.extend({
-
+
/** @inheritdoc */
getId : function()
{
- return 'json';
+ return 'json';
},
-
+
/** @inheritdoc */
build: function(model)
{
var json = model.toJSON();
-
+ this.beforeEach(json);
+
// Avoid jshint 'loopfunc' error
_.each(json,function(v, attr){
var obj = json[attr];
@@ -30,11 +31,19 @@ define(['backbone'],
}, this);
}
}
-
+
}, this);
-
+
return json;
},
-
+
+ /**
+ * Execute on each object
+ * @param {Object} obj
+ */
+ beforeEach: function(obj) {
+ delete obj.status;
+ }
+
});
});
diff --git a/src/dom_components/view/ComponentView.js b/src/dom_components/view/ComponentView.js
index a3c531b94..2e53786e2 100644
--- a/src/dom_components/view/ComponentView.js
+++ b/src/dom_components/view/ComponentView.js
@@ -113,9 +113,11 @@ define(['backbone', './ComponentsView'],
* */
updateClasses: function(){
var str = '';
+
this.model.get('classes').each(function(model){
str += model.get('name') + ' ';
});
+
this.$el.attr('class',str.trim());
// Regenerate status class
@@ -132,12 +134,14 @@ define(['backbone', './ComponentsView'],
render: function() {
this.updateAttributes();
+ this.updateClasses();
this.$el.html(this.model.get('content'));
var view = new ComponentsView({
collection : this.components,
config : this.config,
});
this.$components = view;
+
// With childNodes lets avoid wrapping 'div'
this.$el.append(view.render(this.$el).el.childNodes);
return this;
diff --git a/src/editor/model/Editor.js b/src/editor/model/Editor.js
index 785087eb5..40ea36186 100644
--- a/src/editor/model/Editor.js
+++ b/src/editor/model/Editor.js
@@ -274,16 +274,23 @@ define([
/**
* Triggered when components are updated
+ * @param {Object} model
+ * @param {Mixed} val Value
+ * @param {Object} opt Options
* */
- componentsUpdated: function()
+ componentsUpdated: function(model, val, opt)
{
- var updatedCount = this.get('changesCount') + 1;
+ var updatedCount = this.get('changesCount') + 1,
+ avSt = opt ? opt.avoidStore : 0;
this.set('changesCount', updatedCount);
if(this.stm.isAutosave() && updatedCount < this.stm.getChangesBeforeSave()){
return;
}
- this.storeComponents();
- this.set('changesCount', 0 );
+
+ if(!avSt){
+ this.storeComponents();
+ this.set('changesCount', 0);
+ }
},
/**
@@ -338,6 +345,7 @@ define([
* */
updateComponents: function(model, val, opt){
var comps = model.get('components'),
+ classes = model.get('classes'),
avSt = opt ? opt.avoidStore : 0;
// Observe component with Undo Manager
@@ -350,8 +358,12 @@ define([
this.listenTo(comps, 'add', this.updateComponents);
this.listenTo(comps, 'remove', this.rmComponents);
- this.stopListening(model, 'change:style change:content', this.updateComponents);
- this.listenTo(model, 'change:style change:content', this.updateComponents);
+ this.stopListening(classes, 'add remove', this.componentsUpdated);
+ this.listenTo(classes, 'add remove', this.componentsUpdated);
+
+ var evn = 'change:style change:content';
+ this.stopListening(model, evn, this.componentsUpdated);
+ this.listenTo(model, evn, this.componentsUpdated);
if(!avSt)
this.componentsUpdated();