add cleanStyle, removeStyle (#4060)

* add cleanStyle, removeStyle
* added semi colons
This commit is contained in:
Andrea Bogazzi 2017-07-03 12:20:27 +02:00 committed by GitHub
parent c41ef91fca
commit 4c2e83d089
2 changed files with 135 additions and 1 deletions

View file

@ -492,7 +492,7 @@
* @return {Boolean}
*/
styleHas: function(property, lineIndex) {
if (!this.styles) {
if (!this.styles || !property || property === '') {
return false;
}
if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {
@ -511,6 +511,86 @@
return false;
},
/**
* Check if characters in a text have a value for a property
* whose value matches the textbox's value for that property. If so,
* the character-level property is deleted. If the character
* has no other properties, then it is also deleted. Finally,
* if the line containing that character has no other characters
* then it also is deleted.
*
* @param {string} property The property to compare between characters and text.
*/
cleanStyle: function(property) {
if (!this.styles || !property || property === '') {
return false;
}
var obj = this.styles, stylesCount = 0, letterCount, foundStyle = false, style,
canBeSwapped = true, graphemeCount = 0;
// eslint-disable-next-line
for (var p1 in obj) {
letterCount = 0;
// eslint-disable-next-line
for (var p2 in obj[p1]) {
stylesCount++;
if (!foundStyle) {
style = obj[p1][p2][property];
foundStyle = true;
}
else if (obj[p1][p2][property] !== style) {
canBeSwapped = false;
}
if (obj[p1][p2][property] === this[property]) {
delete obj[p1][p2][property];
}
if (Object.keys(obj[p1][p2]).length !== 0) {
letterCount++;
}
else {
delete obj[p1][p2];
}
}
if (letterCount === 0) {
delete obj[p1];
}
}
// if every grapheme has the same style set then
// delete those styles and set it on the parent
for (var i = 0; i < this._textLines.length; i++) {
graphemeCount += this._textLines[i].length;
}
if (canBeSwapped && stylesCount === graphemeCount) {
this[property] = style;
this.removeStyle(property);
}
},
/**
* Remove a style property or properties from all individual character styles
* in a text object. Deletes the character style object if it contains no other style
* props. Deletes a line style object if it contains no other character styles.
*
* @param {String} props The property to remove from character styles.
*/
removeStyle: function(property) {
if (!this.styles || !property || property === '') {
return;
}
var obj = this.styles, line, lineNum, charNum;
for (lineNum in obj) {
var line = obj[lineNum];
for (charNum in line) {
delete line[charNum][property];
if (Object.keys(line[charNum]).length === 0) {
delete line[charNum];
}
}
if (Object.keys(line).length === 0) {
delete obj[lineNum];
}
}
},
/**
* @private
*/

View file

@ -332,4 +332,58 @@
equal(removeTranslate(text.toSVG()), removeTranslate(TEXT_SVG_JUSTIFIED));
});
test('text styleHas', function() {
var text = new fabric.Text('xxxxxx\nx y');
text.styles = { };
ok(typeof text.styleHas === 'function');
equal(text.styleHas('stroke'), false, 'the text style has no stroke');
text.styles = { 1: { 0: { stroke: 'red' }}};
equal(text.styleHas('stroke'), true, 'the text style has stroke');
});
test('text cleanStyle', function() {
var text = new fabric.Text('xxxxxx\nx y');
text.styles = { 1: { 0: { stroke: 'red' }}};
text.stroke = 'red';
ok(typeof text.cleanStyle === 'function');
text.cleanStyle('stroke');
equal(text.styles[1], undefined, 'the style has been cleaned since stroke was equal to text property');
text.styles = { 1: { 0: { stroke: 'blue' }}};
text.stroke = 'red';
text.cleanStyle('stroke');
equal(text.styles[1][0].stroke, 'blue', 'nothing to clean, style untouched');
});
test('text cleanStyle with empty styles', function() {
var text = new fabric.Text('xxxxxx\nx y');
text.styles = { 1: { 0: { }, 1: { }}, 2: { }, 3: { 4: { }}};
text.cleanStyle('any');
equal(text.styles[1], undefined, 'the style has been cleaned since there were no usefull informations');
equal(text.styles[2], undefined, 'the style has been cleaned since there were no usefull informations');
equal(text.styles[3], undefined, 'the style has been cleaned since there were no usefull informations');
});
test('text cleanStyle with full style', function() {
var text = new fabric.Text('xxx');
text.styles = { 0: { 0: { fill: 'blue' }, 1: { fill: 'blue' }, 2: { fill: 'blue' }}};
text.fill = 'black';
text.cleanStyle('fill');
equal(text.fill, 'blue', 'the fill has been changed to blue');
equal(text.styles[0], undefined, 'all the style has been removed');
});
test('text removeStyle with some style', function() {
var text = new fabric.Text('xxx');
text.styles = { 0: { 0: { stroke: 'black', fill: 'blue' }, 1: { fill: 'blue' }, 2: { fill: 'blue' }}};
ok(typeof text.removeStyle === 'function');
text.fill = 'red';
text.removeStyle('fill');
equal(text.fill, 'red', 'the fill has not been changed');
equal(text.styles[0][0].stroke, 'black', 'the non fill part of the style is still there');
equal(text.styles[0][0].fill, undefined, 'the fill part of the style has been removed');
text.styles = { 0: { 0: { fill: 'blue' }, 1: { fill: 'blue' }, 2: { fill: 'blue' }}};
text.removeStyle('fill');
equal(text.styles[0], undefined, 'the styles got empty and has been removed');
});
})();