Fix i-text style copy-pasting (doesn't work with multiline yet)

This commit is contained in:
kangax 2013-11-25 21:31:52 +01:00
parent f84ac95f75
commit ae11740f82
8 changed files with 201 additions and 39 deletions

62
dist/all.js vendored
View file

@ -18484,13 +18484,25 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
/**
* Gets style of a current selection/cursor (at the start position)
* @return {Object} styles Style object at a cursor position
* @param {Number} [startIndex] Start index to get styles at
* @param {Number} [endIndex] End index to get styles at
* @return {Object} styles Style object at a specified (or current) index
*/
getSelectionStyles: function() {
var loc = this.get2DCursorLocation();
getSelectionStyles: function(startIndex, endIndex) {
if (arguments.length === 2) {
var styles = [ ];
for (var i = startIndex; i < endIndex; i++) {
styles.push(this.getSelectionStyles(i));
}
return styles;
}
var loc = this.get2DCursorLocation(startIndex);
if (this.styles[loc.lineIndex]) {
return this.styles[loc.lineIndex][loc.charIndex] || { };
}
return { };
},
@ -19709,11 +19721,11 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
this.text.slice(this.selectionEnd);
if (this.selectionStart === this.selectionEnd) {
this.insertStyleObject(_chars, isEndOfLine);
this.insertStyleObjects(_chars, isEndOfLine, this.copiedStyles);
}
else if (this.selectionEnd - this.selectionStart > 1) {
// TODO: replace styles properly
// console.log('replacing MORE than 1 char');
console.log('replacing MORE than 1 char');
}
this.selectionStart += _chars.length;
@ -19770,13 +19782,14 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
* Inserts style object for a given line/char index
* @param {Number} lineIndex Index of a line
* @param {Number} charIndex Index of a char
* @param {Object} [style] Style object to insert, if given
*/
insertCharStyleObject: function(lineIndex, charIndex) {
insertCharStyleObject: function(lineIndex, charIndex, style) {
var currentLineStyles = this.styles[lineIndex],
currentLineStylesCloned = clone(currentLineStyles);
if (charIndex === 0) {
if (charIndex === 0 && !style) {
charIndex = 1;
}
@ -19789,15 +19802,18 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
//delete currentLineStyles[index];
}
}
this.styles[lineIndex][charIndex] = clone(currentLineStyles[charIndex - 1]);
this.styles[lineIndex][charIndex] =
style || clone(currentLineStyles[charIndex - 1]);
},
/**
* Inserts style object
* Inserts style object(s)
* @param {String} _chars Characters at the location where style is inserted
* @param {Boolean} isEndOfLine True if it's end of line
* @param {Array} [styles] Styles to insert
*/
insertStyleObject: function(_chars, isEndOfLine) {
insertStyleObjects: function(_chars, isEndOfLine, styles) {
// short-circuit
if (this.isEmptyStyles()) return;
@ -19814,8 +19830,27 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
this.insertNewlineStyleObject(lineIndex, charIndex, isEndOfLine);
}
else {
// TODO: support multiple style insertion if _chars.length > 1
this.insertCharStyleObject(lineIndex, charIndex);
if (styles) {
this._insertStyles(styles);
}
else {
// TODO: support multiple style insertion if _chars.length > 1
this.insertCharStyleObject(lineIndex, charIndex);
}
}
},
/**
* @private
*/
_insertStyles: function(styles) {
for (var i = 0, len = styles.length; i < len; i++) {
var cursorLocation = this.get2DCursorLocation(this.selectionStart + i),
lineIndex = cursorLocation.lineIndex,
charIndex = cursorLocation.charIndex;
this.insertCharStyleObject(lineIndex, charIndex, styles[i]);
}
},
@ -20246,6 +20281,9 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
copy: function() {
var selectedText = this.getSelectedText();
this.copiedText = selectedText;
this.copiedStyles = this.getSelectionStyles(
this.selectionStart,
this.selectionEnd);
},
/**

4
dist/all.min.js vendored

File diff suppressed because one or more lines are too long

BIN
dist/all.min.js.gz vendored

Binary file not shown.

62
dist/all.require.js vendored
View file

@ -18484,13 +18484,25 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
/**
* Gets style of a current selection/cursor (at the start position)
* @return {Object} styles Style object at a cursor position
* @param {Number} [startIndex] Start index to get styles at
* @param {Number} [endIndex] End index to get styles at
* @return {Object} styles Style object at a specified (or current) index
*/
getSelectionStyles: function() {
var loc = this.get2DCursorLocation();
getSelectionStyles: function(startIndex, endIndex) {
if (arguments.length === 2) {
var styles = [ ];
for (var i = startIndex; i < endIndex; i++) {
styles.push(this.getSelectionStyles(i));
}
return styles;
}
var loc = this.get2DCursorLocation(startIndex);
if (this.styles[loc.lineIndex]) {
return this.styles[loc.lineIndex][loc.charIndex] || { };
}
return { };
},
@ -19709,11 +19721,11 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
this.text.slice(this.selectionEnd);
if (this.selectionStart === this.selectionEnd) {
this.insertStyleObject(_chars, isEndOfLine);
this.insertStyleObjects(_chars, isEndOfLine, this.copiedStyles);
}
else if (this.selectionEnd - this.selectionStart > 1) {
// TODO: replace styles properly
// console.log('replacing MORE than 1 char');
console.log('replacing MORE than 1 char');
}
this.selectionStart += _chars.length;
@ -19770,13 +19782,14 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
* Inserts style object for a given line/char index
* @param {Number} lineIndex Index of a line
* @param {Number} charIndex Index of a char
* @param {Object} [style] Style object to insert, if given
*/
insertCharStyleObject: function(lineIndex, charIndex) {
insertCharStyleObject: function(lineIndex, charIndex, style) {
var currentLineStyles = this.styles[lineIndex],
currentLineStylesCloned = clone(currentLineStyles);
if (charIndex === 0) {
if (charIndex === 0 && !style) {
charIndex = 1;
}
@ -19789,15 +19802,18 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
//delete currentLineStyles[index];
}
}
this.styles[lineIndex][charIndex] = clone(currentLineStyles[charIndex - 1]);
this.styles[lineIndex][charIndex] =
style || clone(currentLineStyles[charIndex - 1]);
},
/**
* Inserts style object
* Inserts style object(s)
* @param {String} _chars Characters at the location where style is inserted
* @param {Boolean} isEndOfLine True if it's end of line
* @param {Array} [styles] Styles to insert
*/
insertStyleObject: function(_chars, isEndOfLine) {
insertStyleObjects: function(_chars, isEndOfLine, styles) {
// short-circuit
if (this.isEmptyStyles()) return;
@ -19814,8 +19830,27 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
this.insertNewlineStyleObject(lineIndex, charIndex, isEndOfLine);
}
else {
// TODO: support multiple style insertion if _chars.length > 1
this.insertCharStyleObject(lineIndex, charIndex);
if (styles) {
this._insertStyles(styles);
}
else {
// TODO: support multiple style insertion if _chars.length > 1
this.insertCharStyleObject(lineIndex, charIndex);
}
}
},
/**
* @private
*/
_insertStyles: function(styles) {
for (var i = 0, len = styles.length; i < len; i++) {
var cursorLocation = this.get2DCursorLocation(this.selectionStart + i),
lineIndex = cursorLocation.lineIndex,
charIndex = cursorLocation.charIndex;
this.insertCharStyleObject(lineIndex, charIndex, styles[i]);
}
},
@ -20246,6 +20281,9 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
copy: function() {
var selectedText = this.getSelectedText();
this.copiedText = selectedText;
this.copiedStyles = this.getSelectionStyles(
this.selectionStart,
this.selectionEnd);
},
/**

View file

@ -454,11 +454,11 @@
this.text.slice(this.selectionEnd);
if (this.selectionStart === this.selectionEnd) {
this.insertStyleObject(_chars, isEndOfLine);
this.insertStyleObjects(_chars, isEndOfLine, this.copiedStyles);
}
else if (this.selectionEnd - this.selectionStart > 1) {
// TODO: replace styles properly
// console.log('replacing MORE than 1 char');
console.log('replacing MORE than 1 char');
}
this.selectionStart += _chars.length;
@ -515,13 +515,14 @@
* Inserts style object for a given line/char index
* @param {Number} lineIndex Index of a line
* @param {Number} charIndex Index of a char
* @param {Object} [style] Style object to insert, if given
*/
insertCharStyleObject: function(lineIndex, charIndex) {
insertCharStyleObject: function(lineIndex, charIndex, style) {
var currentLineStyles = this.styles[lineIndex],
currentLineStylesCloned = clone(currentLineStyles);
if (charIndex === 0) {
if (charIndex === 0 && !style) {
charIndex = 1;
}
@ -534,15 +535,18 @@
//delete currentLineStyles[index];
}
}
this.styles[lineIndex][charIndex] = clone(currentLineStyles[charIndex - 1]);
this.styles[lineIndex][charIndex] =
style || clone(currentLineStyles[charIndex - 1]);
},
/**
* Inserts style object
* Inserts style object(s)
* @param {String} _chars Characters at the location where style is inserted
* @param {Boolean} isEndOfLine True if it's end of line
* @param {Array} [styles] Styles to insert
*/
insertStyleObject: function(_chars, isEndOfLine) {
insertStyleObjects: function(_chars, isEndOfLine, styles) {
// short-circuit
if (this.isEmptyStyles()) return;
@ -559,8 +563,27 @@
this.insertNewlineStyleObject(lineIndex, charIndex, isEndOfLine);
}
else {
// TODO: support multiple style insertion if _chars.length > 1
this.insertCharStyleObject(lineIndex, charIndex);
if (styles) {
this._insertStyles(styles);
}
else {
// TODO: support multiple style insertion if _chars.length > 1
this.insertCharStyleObject(lineIndex, charIndex);
}
}
},
/**
* @private
*/
_insertStyles: function(styles) {
for (var i = 0, len = styles.length; i < len; i++) {
var cursorLocation = this.get2DCursorLocation(this.selectionStart + i),
lineIndex = cursorLocation.lineIndex,
charIndex = cursorLocation.charIndex;
this.insertCharStyleObject(lineIndex, charIndex, styles[i]);
}
},

View file

@ -82,6 +82,9 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
copy: function() {
var selectedText = this.getSelectedText();
this.copiedText = selectedText;
this.copiedStyles = this.getSelectionStyles(
this.selectionStart,
this.selectionEnd);
},
/**

View file

@ -220,13 +220,25 @@
/**
* Gets style of a current selection/cursor (at the start position)
* @return {Object} styles Style object at a cursor position
* @param {Number} [startIndex] Start index to get styles at
* @param {Number} [endIndex] End index to get styles at
* @return {Object} styles Style object at a specified (or current) index
*/
getSelectionStyles: function() {
var loc = this.get2DCursorLocation();
getSelectionStyles: function(startIndex, endIndex) {
if (arguments.length === 2) {
var styles = [ ];
for (var i = startIndex; i < endIndex; i++) {
styles.push(this.getSelectionStyles(i));
}
return styles;
}
var loc = this.get2DCursorLocation(startIndex);
if (this.styles[loc.lineIndex]) {
return this.styles[loc.lineIndex][loc.charIndex] || { };
}
return { };
},

View file

@ -332,7 +332,7 @@
equal(iText.getNumNewLinesInSelectedText(), 1);
});
test('getSelectionStyles', function() {
test('getSelectionStyles with no arguments', function() {
var iText = new fabric.IText('test foo bar-baz\nqux', {
styles: {
0: {
@ -372,6 +372,54 @@
});
});
test('getSelectionStyles with 1 arg', function() {
var iText = new fabric.IText('test foo bar-baz\nqux', {
styles: {
0: {
0: { textDecoration: 'underline' },
2: { textDecoration: 'overline' },
4: { textBackgroundColor: '#ffc' }
},
1: {
0: { fill: 'red' },
1: { fill: 'green' },
2: { fill: 'blue' }
}
}
});
iText.selectionStart = 17;
iText.selectionStart = 17;
deepEqual(iText.getSelectionStyles(2), {
textDecoration: 'overline'
});
});
test('getSelectionStyles with 2 args', function() {
var iText = new fabric.IText('test foo bar-baz\nqux', {
styles: {
0: {
0: { textDecoration: 'underline' },
2: { textDecoration: 'overline' },
4: { textBackgroundColor: '#ffc' }
},
1: {
0: { fill: 'red' },
1: { fill: 'green' },
2: { fill: 'blue' }
}
}
});
deepEqual(iText.getSelectionStyles(0, 2), [
{ textDecoration: 'underline' },
{ },
{ textDecoration: 'overline' }
]);
});
test('setSelectionStyles', function() {
var iText = new fabric.IText('test foo bar-baz\nqux', {
styles: {