Browse Source

Avoid style remove on blur from the text component. Fixes #3069

pull/3073/head
Artur Arseniev 6 years ago
parent
commit
75cc3e1aa6
  1. 24
      src/dom_components/model/Component.js
  2. 24
      src/dom_components/model/Components.js
  3. 26
      src/dom_components/view/ComponentTextView.js
  4. 7
      src/dom_components/view/ComponentView.js
  5. 5
      src/parser/model/ParserHtml.js
  6. 3
      test/specs/parser/model/ParserHtml.js

24
src/dom_components/model/Component.js

@ -179,7 +179,7 @@ const Component = Backbone.Model.extend(Styleable).extend(
...(this.defaults.attributes || {}),
...(this.get('attributes') || {})
});
this.ccid = Component.createId(this);
this.ccid = Component.createId(this, opt);
this.initClasses();
this.initTraits();
this.initComponents();
@ -1290,13 +1290,13 @@ const Component = Backbone.Model.extend(Styleable).extend(
* @return {string}
* @private
*/
createId(model) {
createId(model, opts = {}) {
const list = Component.getList(model);
let { id } = model.get('attributes');
let nextId;
if (id) {
nextId = Component.getIncrementId(id, list);
nextId = Component.getIncrementId(id, list, opts);
model.setId(nextId);
} else {
nextId = Component.getNewId(list);
@ -1320,13 +1320,16 @@ const Component = Backbone.Model.extend(Styleable).extend(
return newId;
},
getIncrementId(id, list) {
getIncrementId(id, list, opts = {}) {
const { keepIds = [] } = opts;
let counter = 1;
let newId = id;
while (list[newId]) {
counter++;
newId = `${id}-${counter}`;
if (keepIds.indexOf(id) < 0) {
while (list[newId]) {
counter++;
newId = `${id}-${counter}`;
}
}
return newId;
@ -1347,14 +1350,15 @@ const Component = Backbone.Model.extend(Styleable).extend(
* (are not Components/CSSRules yet), for duplicated id and fixes them
* This method is used in Components.js just after the parsing
*/
checkId(components, styles = [], list = {}) {
checkId(components, styles = [], list = {}, opts = {}) {
const comps = isArray(components) ? components : [components];
const { keepIds = [] } = opts;
comps.forEach(comp => {
const { attributes = {}, components } = comp;
const { id } = attributes;
// Check if we have collisions with current components
if (id && list[id]) {
if (id && list[id] && keepIds.indexOf(id) < 0) {
const newId = Component.getIncrementId(id, list);
attributes.id = newId;
// Update passed styles
@ -1367,7 +1371,7 @@ const Component = Backbone.Model.extend(Styleable).extend(
});
}
components && Component.checkId(components, styles, list);
components && Component.checkId(components, styles, list, opts);
});
}
}

24
src/dom_components/model/Components.js

@ -11,6 +11,11 @@ import {
let Component;
const getIdsToKeep = prev => {
const pr = prev || [];
return pr.map(comp => comp.getId());
};
export default Backbone.Collection.extend({
initialize(models, opt = {}) {
this.opt = opt;
@ -24,8 +29,10 @@ export default Backbone.Collection.extend({
resetChildren(models, opts = {}) {
const coll = this;
const { previousModels = [] } = opts;
previousModels.forEach(md => this.removeChildren(md, coll, opts));
const prev = opts.previousModels || [];
const toRemove = prev.filter(prev => !models.get(prev.cid));
opts.keepIds = getIdsToKeep(prev);
toRemove.forEach(md => this.removeChildren(md, coll, opts));
models.each(model => this.onAdd(model));
},
@ -44,12 +51,15 @@ export default Backbone.Collection.extend({
const id = removed.getId();
const sels = em.get('SelectorManager').getAll();
const rules = em.get('CssComposer').getAll();
const canRemoveStyle = (opts.keepIds || []).indexOf(id) < 0;
delete allByID[id];
// Remove all component related styles
const rulesRemoved = rules.remove(
rules.filter(r => r.getSelectors().getFullString() === `#${id}`)
);
const rulesRemoved = canRemoveStyle
? rules.remove(
rules.filter(r => r.getSelectors().getFullString() === `#${id}`)
)
: [];
// Clean selectors
sels.remove(rulesRemoved.map(rule => rule.getSelectors().at(0)));
@ -117,7 +127,7 @@ export default Backbone.Collection.extend({
const parsed = em.get('Parser').parseHtml(value);
// We need this to avoid duplicate IDs
if (!Component) Component = require('./Component').default;
Component.checkId(parsed.html, parsed.css, domc.componentsById);
Component.checkId(parsed.html, parsed.css, domc.componentsById, opt);
if (parsed.css && cssc && !opt.temporary) {
cssc.addCollection(parsed.css, {
@ -130,6 +140,8 @@ export default Backbone.Collection.extend({
},
add(models, opt = {}) {
opt.keepIds = getIdsToKeep(opt.previousModels);
if (isString(models)) {
models = this.parseString(models, opt);
} else if (isArray(models)) {

26
src/dom_components/view/ComponentTextView.js

@ -102,12 +102,12 @@ export default ComponentView.extend({
const content = this.getContent();
const comps = model.components();
const contentOpt = { fromDisable: 1, ...opts };
comps.length && comps.reset(null, opts);
model.set('content', '', contentOpt);
// If there is a custom RTE the content is just baked staticly
// inside 'content'
if (rte.customRte) {
comps.length && comps.reset(null, opts);
model.set('content', content, contentOpt);
} else {
const clean = model => {
@ -133,34 +133,12 @@ export default ComponentView.extend({
// Avoid re-render on reset with silent option
!opts.silent && model.trigger('change:content', model, '', contentOpt);
comps.add(content, opts);
comps.reset(content, opts);
comps.each(model => clean(model));
comps.trigger('resetNavigator');
}
},
/*
getModelsFromEl(el) {
const result = [];
const children = (el || this.el).childNodes;
for (let index = 0; index < children.length; index++) {
const child = children[index];
const model = child.__cashData && child.__cashData.model;
if (model) {
model.attributes.components = this.getModelsFromEl(child);
if (model.get('content')) {
model.attributes.content = child.textContent;
}
result.push(model);
}
}
return result;
},
*/
/**
* Callback on input event
* @param {Event} e

7
src/dom_components/view/ComponentView.js

@ -241,13 +241,14 @@ export default Backbone.View.extend({
const { model, em, el } = this;
if (em && em.getConfig('avoidInlineStyle')) {
if (model.get('_innertext')) {
const style = model.getStyle();
const empty = isEmpty(style);
!empty && model.setStyle(style);
if (model.get('_innertext') && empty) {
el.removeAttribute('id');
} else {
el.id = model.getId();
}
const style = model.getStyle();
!isEmpty(style) && model.setStyle(style);
} else {
this.setAttribute('style', model.styleToString());
}

5
src/parser/model/ParserHtml.js

@ -299,7 +299,10 @@ export default config => {
}
const result = this.parseNode(el);
res.html = result;
// I have to keep it otherwise it breaks the DomComponents.addComponent (returns always array)
const resHtml =
result.length === 1 && !c.returnArray ? result[0] : result;
res.html = resHtml;
em && em.trigger('parse:html', { input: str, output: res });
return res;

3
test/specs/parser/model/ParserHtml.js

@ -9,7 +9,8 @@ describe('ParserHtml', () => {
var dom = new DomComponents();
obj = new ParserHtml({
textTags: ['br', 'b', 'i', 'u'],
pStylePrefix: 'gjs-'
pStylePrefix: 'gjs-',
returnArray: 1
});
obj.compTypes = dom.componentTypes;
});

Loading…
Cancel
Save