Browse Source

Refactor ComponentTextView

pull/415/head
Artur Arseniev 9 years ago
parent
commit
608a1751fa
  1. 92
      src/dom_components/view/ComponentTextView.js
  2. 42
      src/dom_components/view/ComponentView.js
  3. 61
      src/dom_components/view/ComponentsView.js
  4. 6
      src/utils/extender.js

92
src/dom_components/view/ComponentTextView.js

@ -6,18 +6,16 @@ module.exports = ComponentView.extend({
events: {
'dblclick': 'enableEditing',
'change': 'parseRender',
},
initialize(o) {
ComponentView.prototype.initialize.apply(this, arguments);
_.bindAll(this,'disableEditing');
this.disableEditing = this.disableEditing.bind(this);
const model = this.model;
this.listenTo(model, 'focus active', this.enableEditing);
this.listenTo(model, 'change:content', this.updateContent);
this.rte = this.config.rte || '';
this.activeRte = null;
this.em = this.config.em;
},
/**
@ -26,15 +24,18 @@ module.exports = ComponentView.extend({
* @private
* */
enableEditing(e) {
var editable = this.model.get('editable');
if(this.rte && editable) {
const editable = this.model.get('editable');
const rte = this.rte;
if (rte && editable) {
try {
this.activeRte = this.rte.attach(this, this.activeRte);
this.rte.focus(this, this.activeRte);
this.activeRte = rte.attach(this, this.activeRte);
rte.focus(this, this.activeRte);
} catch (err) {
console.error(err);
}
}
this.toggleEvents(1);
},
@ -44,23 +45,46 @@ module.exports = ComponentView.extend({
* @private
* */
disableEditing(e) {
var model = this.model;
var editable = model.get('editable');
const model = this.model;
const editable = model.get('editable');
const rte = this.rte;
if(this.rte && editable) {
if (rte && editable) {
try {
this.rte.detach(this, this.activeRte);
rte.detach(this, this.activeRte);
} catch (err) {
console.error(err);
}
var el = this.getChildrenContainer();
// Avoid double content by removing its children components
model.get('components').reset();
model.set('content', el.innerHTML);
}
if(!this.rte.customRte && editable) {
this.parseRender();
const content = this.getChildrenContainer().innerHTML;
const comps = model.get('components');
// If there is a custom RTE the content is just baked staticly
// inside 'content'
if (rte.customRte) {
// Avoid double content by removing its children components
comps.reset();
model.set('content', content);
} else {
const clean = model => {
model.set({
highlightable: 0,
removable: 0,
draggable: 0,
copyable: 0,
toolbar: '',
});
model.get('components').each(model => clean(model));
}
// Avoid re-render on reset with silent option
model.set('content', '');
comps.reset();
comps.add(content);
comps.each(model => clean(model));
// With rerender is possible to see changes applied after clean
this.render();
}
}
this.toggleEvents();
@ -75,38 +99,6 @@ module.exports = ComponentView.extend({
e.stopPropagation();
},
/**
* Parse content and re-render it
* @private
*/
parseRender() {
const model = this.model;
var el = this.getChildrenContainer();
var comps = model.get('components');
var opts = {silent: true};
const clean = model => {
model.set({
highlightable: 0,
removable: 0,
draggable: 0,
copyable: 0,
toolbar: '',
}, opts);
model.get('components').each(model => clean(model));
}
// Avoid re-render on reset with silent option
comps.reset(null, opts);
comps.add(el.innerHTML, opts);
comps.each(model => clean(model));
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

42
src/dom_components/view/ComponentView.js

@ -1,5 +1,4 @@
const ComponentsView = require('./ComponentsView');
const $ = Backbone.$;
module.exports = Backbone.View.extend({
@ -12,15 +11,16 @@ module.exports = Backbone.View.extend({
},
initialize(opt) {
var model = this.model;
const 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.attr = model.get('attributes');
this.classe = this.attr.class || [];
const $el = this.$el;
const classes = model.get('classes');
this.listenTo(model, 'destroy remove', this.remove);
this.listenTo(model, 'change:style', this.updateStyle);
this.listenTo(model, 'change:attributes', this.updateAttributes);
@ -28,26 +28,20 @@ module.exports = Backbone.View.extend({
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);
const $el = this.$el;
const el = this.el;
const em = this.em;
this.listenTo(classes, 'add remove change', this.updateClasses);
$el.data('model', model);
$el.data('collection', this.components);
$el.data('collection', model.get('components'));
model.view = this;
if (em) {
em.data(el, 'model', model);
em.data(el, 'collection', model.get('components'));
}
if(model.get('classes').length)
this.importClasses();
classes.length && this.importClasses();
this.init();
},
remove() {
Backbone.View.prototype.remove.apply(this);
const children = this.childrenView;
children && children.stopListening();
},
/**
* Initialize callback
*/
@ -309,15 +303,16 @@ module.exports = Backbone.View.extend({
* @private
*/
renderChildren() {
var view = new ComponentsView({
const container = this.getChildrenContainer();
const view = new ComponentsView({
collection: this.model.get('components'),
config: this.config,
componentTypes: this.opts.componentTypes,
});
var container = this.getChildrenContainer();
var childNodes = view.render($(container)).el.childNodes;
childNodes = Array.prototype.slice.call(childNodes);
view.render(container);
this.childrenView = view;
const childNodes = Array.prototype.slice.call(view.el.childNodes);
for (var i = 0, len = childNodes.length ; i < len; i++) {
container.appendChild(childNodes.shift());
@ -348,7 +343,6 @@ module.exports = Backbone.View.extend({
render() {
this.renderAttributes();
var model = this.model;
this.updateContent();
this.renderChildren();
this.updateScript();

61
src/dom_components/view/ComponentsView.js

@ -1,12 +1,13 @@
var Backbone = require('backbone');
import { isUndefined } from 'underscore'
module.exports = Backbone.View.extend({
initialize(o) {
this.opts = o || {};
this.config = o.config || {};
this.listenTo( this.collection, 'add', this.addTo );
this.listenTo( this.collection, 'reset', this.render );
const coll = this.collection;
this.listenTo(coll, 'add', this.addTo);
this.listenTo(coll, 'reset', this.resetChildren);
},
/**
@ -17,7 +18,7 @@ module.exports = Backbone.View.extend({
* @private
* */
addTo(model) {
var i = this.collection.indexOf(model);
var i = this.collection.indexOf(model);
this.addToCollection(model, null, i);
var em = this.config.em;
@ -42,7 +43,6 @@ module.exports = Backbone.View.extend({
this.compView = require('./ComponentView');
var fragment = fragmentEl || null,
viewObject = this.compView;
//console.log('Add to collection', model, 'Index',i);
var dt = this.opts.componentTypes;
@ -66,44 +66,47 @@ module.exports = Backbone.View.extend({
if(view.model.get('type') == 'textnode')
rendered = document.createTextNode(view.model.get('content'));
if(fragment){
if (fragment) {
fragment.appendChild(rendered);
}else{
var p = this.$parent;
var pc = p.children;
if(typeof index != 'undefined'){
var method = 'before';
} else {
const parent = this.parentEl;
const children = parent.childNodes;
if (!isUndefined(index)) {
const lastIndex = children.length == index;
// If the added model is the last of collection
// need to change the logic of append
if(pc && p.children().length == index){
if (lastIndex) {
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);
}
if (lastIndex || !children.length) {
parent.appendChild(rendered);
} else {
parent.insertBefore(rendered, children[index]);
}
}else{
p.append(rendered);
} else {
parent.appendChild(rendered);
}
}
return rendered;
},
render($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);
resetChildren() {
this.parentEl.innerHTML = '';
this.collection.each(model => this.addToCollection(model));
},
render(parent) {
const el = this.el;
const frag = document.createDocumentFragment();
this.parentEl = parent || this.el;
this.collection.each(model => this.addToCollection(model, frag));
el.innerHTML = '';
el.appendChild(frag);
return this;
}

6
src/utils/extender.js

@ -213,6 +213,12 @@ module.exports = ({$, Backbone}) => {
return this;
}
fn.remove = function () {
return this.each(node => {
return node.parentNode && node.parentNode.removeChild(node);
});
},
// For spectrum compatibility
fn.bind = function(ev, h) {
return this.on(ev, h);

Loading…
Cancel
Save