Insert a method to insert text programmatically (#4551)

* sofar

* test
This commit is contained in:
Andrea Bogazzi 2017-12-10 21:13:38 +01:00 committed by GitHub
parent d9fc639002
commit fb13ed0bdf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 96 additions and 2 deletions

View file

@ -841,7 +841,12 @@
linesLenght && this.insertNewlineStyleObject(
cursorLoc.lineIndex, cursorLoc.charIndex + addedLines[0], linesLenght);
for (var i = 1; i < linesLenght; i++) {
this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle);
if (addedLines[i] > 0) {
this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle);
}
else if (copiedStyle) {
this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0];
}
copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1);
}
// we use i outside the loop to get it like linesLength

View file

@ -605,11 +605,42 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
this._text.splice(start, end - start);
this.text = this._text.join('');
this.set('dirty', true);
this._removeExtraneousStyles();
if (this._shouldClearDimensionCache()) {
this.initDimensions();
this.setCoords();
}
this._removeExtraneousStyles();
},
/**
* insert characters at start position, before start position.
* start equal 1 it means the text get inserted between actual grapheme 0 and 1
* if style array is provided, it must be as the same length of text in graphemes
* if end is provided and is bigger than start, old text is replaced.
* start/end ar per grapheme position in _text array.
*
* @param {String} text text to insert
* @param {Array} style array of style objects
* @param {Number} start
* @param {Number} end default to start + 1
*/
insertChars: function(text, style, start, end) {
if (typeof end === 'undefined') {
end = start;
}
if (end > start) {
this.removeStyleFromTo(start, end);
}
var graphemes = fabric.util.string.graphemeSplit(text);
this.insertNewStyleBlock(graphemes, start, style);
this._text = [].concat(this._text.slice(0, start), graphemes, this._text.slice(end));
this.text = this._text.join('');
this.set('dirty', true);
if (this._shouldClearDimensionCache()) {
this.initDimensions();
this.setCoords();
}
this._removeExtraneousStyles();
},
});

View file

@ -47,6 +47,7 @@ testrunner.run({
'./test/unit/intersection.js',
'./test/unit/stateful.js'
],
tests: ['./test/unit/itext_key_behaviour.js',]
}, function(err, report) {
if (err) {
console.log(err);

View file

@ -280,4 +280,61 @@
assert.deepEqual(iText._text, ['t','t'], 'text has been remoed');
assert.equal(iText.styles[0][1], undefined, 'style has been removed');
});
QUnit.test('insertChars', function(assert) {
var iText = new fabric.IText('test');
assert.ok(typeof iText.insertChars === 'function');
iText.insertChars('ab', null, 1);
assert.equal(iText.text, 'tabest', 'text has been added');
assert.deepEqual(iText._text.join(''), 'tabest', '_text has been updated');
});
QUnit.test('insertChars can remove chars', function(assert) {
var iText = new fabric.IText('test');
iText.insertChars('ab', null, 1, 2);
assert.equal(iText.text, 'tabst', 'text has added');
assert.deepEqual(iText._text.join(''), 'tabst', '_text has been updated');
var iText = new fabric.IText('test');
iText.insertChars('ab', null, 1, 4);
assert.equal(iText.text, 'tab', 'text has added');
assert.deepEqual(iText._text.join(''), 'tab', '_text has been updated');
});
QUnit.test('insertChars pick up the style of the character behind and replicates it', function(assert) {
var iText = new fabric.IText('test', { fontSize: 25, styles: { 0: { 0: { fill: 'red' }, 1: { fill: 'blue' }}}});
iText.insertChars('ab', null, 1);
assert.equal(iText.styles[0][0].fill, 'red', 'style 0 0 did not change');
assert.equal(iText.styles[0][1].fill, 'red', 'style 0 1 has been inserted red');
assert.equal(iText.styles[0][2].fill, 'red', 'style 0 2 has been inserted red');
assert.equal(iText.styles[0][3].fill, 'blue', 'style 0 3 was the old blue moved 2 char later');
});
QUnit.test('insertChars removes style from the removed text', function(assert) {
var iText = new fabric.IText('test', { fontSize: 25, styles: { 0: { 0: { fill: 'red' }, 1: { fill: 'blue' }}}});
iText.insertChars('ab', null, 1, 2);
assert.equal(iText.styles[0][0].fill, 'red', 'style 0 0 did not change');
assert.equal(iText.styles[0][1].fill, 'red', 'style 0 1 has been inserted red');
assert.equal(iText.styles[0][2].fill, 'red', 'style 0 2 has been inserted red');
assert.equal(iText.styles[0][3], undefined, 'style 0 3 has been removed');
});
QUnit.test('insertChars handles new lines correctly', function(assert) {
var iText = new fabric.IText('test', { fontSize: 25, styles: { 0: { 0: { fill: 'red' }, 1: { fill: 'blue' }}}});
iText.insertChars('ab\n\n', null, 1);
assert.equal(iText.styles[0][0].fill, 'red', 'style 0 0 did not change');
assert.equal(iText.styles[0][1].fill, 'red', 'style 0 1 has been inserted red');
assert.equal(iText.styles[0][2].fill, 'red', 'style 0 2 has been inserted red');
assert.equal(iText.styles[2][0].fill, 'blue', 'blue has been moved down');
});
QUnit.test('insertChars can accept some style for the new text', function(assert) {
var iText = new fabric.IText('test', { fontSize: 25, styles: { 0: { 0: { fill: 'red' }, 1: { fill: 'blue' }}}});
iText.insertChars('ab\n\na', [{ fill: 'col1'},{ fill: 'col2'},{ fill: 'col3'},{ fill: 'col4'},{ fill: 'col5'}], 1);
assert.equal(iText.styles[0][0].fill, 'red', 'style 0 0 did not change');
assert.equal(iText.styles[0][1].fill, 'col1', 'style 0 1 has been inserted col1');
assert.equal(iText.styles[0][2].fill, 'col2', 'style 0 2 has been inserted col2');
assert.equal(iText.styles[1][0].fill, 'col4', 'style 1 0 has been inserted col4');
assert.equal(iText.styles[2][0].fill, 'col5', 'style 2 0 has been inserted col5');
assert.equal(iText.styles[2][1].fill, 'blue', 'style 2 1 has been inserted blue');
});
})();