fabric 5.2.1 → 5.2.4-browser
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HEADER.js +1 -1
- package/dist/fabric.js +153 -55
- package/dist/fabric.min.js +1 -1
- package/package.json +88 -91
- package/src/mixins/canvas_events.mixin.js +0 -8
- package/src/mixins/itext.svg_export.js +1 -1
- package/src/mixins/itext_behavior.mixin.js +3 -0
- package/src/mixins/itext_key_behavior.mixin.js +1 -1
- package/src/shapes/group.class.js +11 -4
- package/src/shapes/itext.class.js +9 -6
- package/src/shapes/path.class.js +9 -1
- package/src/shapes/text.class.js +3 -31
- package/src/shapes/textbox.class.js +4 -1
- package/src/util/dom_style.js +1 -1
- package/src/util/misc.js +110 -0
package/package.json
CHANGED
|
@@ -1,92 +1,89 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
"main": "./dist/fabric.js",
|
|
91
|
-
"dependencies": {}
|
|
92
|
-
}
|
|
2
|
+
"name": "fabric",
|
|
3
|
+
"description": "Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.",
|
|
4
|
+
"homepage": "http://fabricjs.com/",
|
|
5
|
+
"version": "5.2.4-browser",
|
|
6
|
+
"author": "Juriy Zaytsev <kangax@gmail.com>",
|
|
7
|
+
"contributors": [
|
|
8
|
+
{
|
|
9
|
+
"name": "Andrea Bogazzi",
|
|
10
|
+
"email": "andreabogazzi79@gmail.com"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"name": "Steve Eberhardt",
|
|
14
|
+
"email": "melchiar2@gmail.com"
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"keywords": [
|
|
18
|
+
"canvas",
|
|
19
|
+
"graphic",
|
|
20
|
+
"graphics",
|
|
21
|
+
"SVG",
|
|
22
|
+
"node-canvas",
|
|
23
|
+
"parser",
|
|
24
|
+
"HTML5",
|
|
25
|
+
"object model"
|
|
26
|
+
],
|
|
27
|
+
"browser": {
|
|
28
|
+
"canvas": false,
|
|
29
|
+
"fs": false,
|
|
30
|
+
"jsdom": false,
|
|
31
|
+
"jsdom/lib/jsdom/living/generated/utils": false,
|
|
32
|
+
"jsdom/lib/jsdom/utils": false,
|
|
33
|
+
"http": false,
|
|
34
|
+
"https": false,
|
|
35
|
+
"xmldom": false,
|
|
36
|
+
"url": false
|
|
37
|
+
},
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "https://github.com/fabricjs/fabric.js"
|
|
41
|
+
},
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/fabricjs/fabric.js/issues"
|
|
44
|
+
},
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"scripts": {
|
|
47
|
+
"changelog": "auto-changelog -o change-output.md --unreleased-only",
|
|
48
|
+
"build": "node build.js modules=ALL requirejs exclude=gestures,accessors,erasing",
|
|
49
|
+
"build:fast": "node build.js modules=ALL requirejs fast exclude=gestures,accessors,erasing",
|
|
50
|
+
"build:watch": "onchange 'src/**/**' 'HEADER.js' 'lib/**/**' -- npm run build_export",
|
|
51
|
+
"link:watch": "onchange 'src/**/**' 'HEADER.js' 'lib/**/**' -- npm link",
|
|
52
|
+
"build_with_gestures": "node build.js modules=ALL exclude=accessors",
|
|
53
|
+
"build_export": "npm run build:fast && npm run export_dist_to_site",
|
|
54
|
+
"test:single": "qunit test/node_test_setup.js test/lib",
|
|
55
|
+
"test:coverage": "nyc --silent qunit test/node_test_setup.js test/lib test/unit",
|
|
56
|
+
"test:visual:coverage": "nyc --silent --no-clean qunit test/node_test_setup.js test/lib test/visual",
|
|
57
|
+
"coverage:report": "nyc report --reporter=lcov --reporter=text",
|
|
58
|
+
"test": "qunit --require ./test/node_test_setup.js test/lib test/unit",
|
|
59
|
+
"test:visual": "qunit test/node_test_setup.js test/lib test/visual",
|
|
60
|
+
"test:visual:single": "qunit test/node_test_setup.js test/lib",
|
|
61
|
+
"test:all": "npm run test && npm run test:visual",
|
|
62
|
+
"lint": "eslint --config .eslintrc.json src",
|
|
63
|
+
"lint_tests": "eslint test/unit --config .eslintrc_tests && eslint test/visual --config .eslintrc_tests",
|
|
64
|
+
"export_gesture_to_site": "cp dist/fabric.js ../fabricjs.com/lib/fabric_with_gestures.js",
|
|
65
|
+
"export_dist_to_site": "cp dist/fabric.js ../fabricjs.com/lib/fabric.js && cp package.json ../fabricjs.com/lib/package.json && cp -r src HEADER.js lib ../fabricjs.com/build/files/",
|
|
66
|
+
"export_tests_to_site": "cp test/unit/*.js ../fabricjs.com/test/unit && cp -r test/visual/* ../fabricjs.com/test/visual && cp -r test/fixtures/* ../fabricjs.com/test/fixtures && cp -r test/lib/* ../fabricjs.com/test/lib",
|
|
67
|
+
"all": "npm run build && npm run test && npm run test:visual && npm run lint && npm run lint_tests && npm run export_dist_to_site && npm run export_tests_to_site",
|
|
68
|
+
"testem": "testem .",
|
|
69
|
+
"testem:ci": "testem ci"
|
|
70
|
+
},
|
|
71
|
+
"optionalDependencies": {},
|
|
72
|
+
"devDependencies": {
|
|
73
|
+
"auto-changelog": "^2.3.0",
|
|
74
|
+
"chalk": "^2.4.1",
|
|
75
|
+
"deep-object-diff": "^1.1.7",
|
|
76
|
+
"eslint": "4.18.x",
|
|
77
|
+
"nyc": "^15.1.0",
|
|
78
|
+
"onchange": "^7.1.0",
|
|
79
|
+
"pixelmatch": "^4.0.2",
|
|
80
|
+
"qunit": "^2.17.2",
|
|
81
|
+
"testem": "^3.2.0",
|
|
82
|
+
"uglify-js": "3.3.x"
|
|
83
|
+
},
|
|
84
|
+
"engines": {
|
|
85
|
+
"node": ">=14.0.0"
|
|
86
|
+
},
|
|
87
|
+
"main": "./dist/fabric.js",
|
|
88
|
+
"dependencies": {}
|
|
89
|
+
}
|
|
@@ -152,14 +152,6 @@
|
|
|
152
152
|
_target && target.fire('mouseout', { e: e });
|
|
153
153
|
});
|
|
154
154
|
this._hoveredTargets = [];
|
|
155
|
-
|
|
156
|
-
if (this._iTextInstances) {
|
|
157
|
-
this._iTextInstances.forEach(function(obj) {
|
|
158
|
-
if (obj.isEditing) {
|
|
159
|
-
obj.hiddenTextarea.focus();
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
155
|
},
|
|
164
156
|
|
|
165
157
|
/**
|
|
@@ -142,7 +142,7 @@
|
|
|
142
142
|
// if we have charSpacing, we render char by char
|
|
143
143
|
actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);
|
|
144
144
|
nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);
|
|
145
|
-
timeToRender =
|
|
145
|
+
timeToRender = fabric.util.hasStyleChanged(actualStyle, nextStyle, true);
|
|
146
146
|
}
|
|
147
147
|
if (timeToRender) {
|
|
148
148
|
style = this._getStyleDeclaration(lineIndex, i) || { };
|
|
@@ -386,6 +386,9 @@
|
|
|
386
386
|
return;
|
|
387
387
|
}
|
|
388
388
|
|
|
389
|
+
// regain focus
|
|
390
|
+
document.activeElement !== this.hiddenTextarea && this.hiddenTextarea.focus();
|
|
391
|
+
|
|
389
392
|
var newSelectionStart = this.getSelectionStartFromPointer(options.e),
|
|
390
393
|
currentStart = this.selectionStart,
|
|
391
394
|
currentEnd = this.selectionEnd;
|
|
@@ -520,7 +520,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
|
|
|
520
520
|
this[prop] += direction === 'Left' ? -1 : 1;
|
|
521
521
|
return true;
|
|
522
522
|
}
|
|
523
|
-
if (typeof newValue !== undefined && this[prop] !== newValue) {
|
|
523
|
+
if (typeof newValue !== 'undefined' && this[prop] !== newValue) {
|
|
524
524
|
this[prop] = newValue;
|
|
525
525
|
return true;
|
|
526
526
|
}
|
|
@@ -569,18 +569,25 @@
|
|
|
569
569
|
// it has to be an url or something went wrong.
|
|
570
570
|
fabric.loadSVGFromURL(objects, function (elements) {
|
|
571
571
|
var group = fabric.util.groupSVGElements(elements, object, objects);
|
|
572
|
+
var clipPath = options.clipPath;
|
|
573
|
+
delete options.clipPath;
|
|
572
574
|
group.set(options);
|
|
573
|
-
|
|
575
|
+
if (clipPath) {
|
|
576
|
+
fabric.util.enlivenObjects([clipPath], function(elivenedObjects) {
|
|
577
|
+
group.clipPath = elivenedObjects[0];
|
|
578
|
+
callback && callback(group);
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
else {
|
|
582
|
+
callback && callback(group);
|
|
583
|
+
}
|
|
574
584
|
});
|
|
575
585
|
return;
|
|
576
586
|
}
|
|
577
587
|
fabric.util.enlivenObjects(objects, function (enlivenedObjects) {
|
|
578
|
-
var options = fabric.util.object.clone(object, true);
|
|
579
|
-
delete options.objects;
|
|
580
588
|
fabric.util.enlivenObjectEnlivables(object, options, function () {
|
|
581
589
|
callback && callback(new fabric.Group(enlivenedObjects, options, true));
|
|
582
590
|
});
|
|
583
591
|
});
|
|
584
592
|
};
|
|
585
|
-
|
|
586
593
|
})(typeof exports !== 'undefined' ? exports : this);
|
|
@@ -510,14 +510,17 @@
|
|
|
510
510
|
* @param {function} [callback] invoked with new instance as argument
|
|
511
511
|
*/
|
|
512
512
|
fabric.IText.fromObject = function(object, callback) {
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
513
|
+
var styles = fabric.util.stylesFromArray(object.styles, object.text);
|
|
514
|
+
//copy object to prevent mutation
|
|
515
|
+
var objCopy = Object.assign({}, object, { styles: styles });
|
|
516
|
+
parseDecoration(objCopy);
|
|
517
|
+
if (objCopy.styles) {
|
|
518
|
+
for (var i in objCopy.styles) {
|
|
519
|
+
for (var j in objCopy.styles[i]) {
|
|
520
|
+
parseDecoration(objCopy.styles[i][j]);
|
|
518
521
|
}
|
|
519
522
|
}
|
|
520
523
|
}
|
|
521
|
-
fabric.Object._fromObject('IText',
|
|
524
|
+
fabric.Object._fromObject('IText', objCopy, callback, 'text');
|
|
522
525
|
};
|
|
523
526
|
})();
|
package/src/shapes/path.class.js
CHANGED
|
@@ -340,7 +340,15 @@
|
|
|
340
340
|
fabric.loadSVGFromURL(pathUrl, function (elements) {
|
|
341
341
|
var path = elements[0];
|
|
342
342
|
path.setOptions(object);
|
|
343
|
-
|
|
343
|
+
if (object.clipPath) {
|
|
344
|
+
fabric.util.enlivenObjects([object.clipPath], function(elivenedObjects) {
|
|
345
|
+
path.clipPath = elivenedObjects[0];
|
|
346
|
+
callback && callback(path);
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
callback && callback(path);
|
|
351
|
+
}
|
|
344
352
|
});
|
|
345
353
|
}
|
|
346
354
|
else {
|
package/src/shapes/text.class.js
CHANGED
|
@@ -1079,7 +1079,7 @@
|
|
|
1079
1079
|
// if we have charSpacing, we render char by char
|
|
1080
1080
|
actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);
|
|
1081
1081
|
nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);
|
|
1082
|
-
timeToRender =
|
|
1082
|
+
timeToRender = fabric.util.hasStyleChanged(actualStyle, nextStyle, false);
|
|
1083
1083
|
}
|
|
1084
1084
|
if (timeToRender) {
|
|
1085
1085
|
if (path) {
|
|
@@ -1249,34 +1249,6 @@
|
|
|
1249
1249
|
return this;
|
|
1250
1250
|
},
|
|
1251
1251
|
|
|
1252
|
-
/**
|
|
1253
|
-
* @private
|
|
1254
|
-
* @param {Object} prevStyle
|
|
1255
|
-
* @param {Object} thisStyle
|
|
1256
|
-
*/
|
|
1257
|
-
_hasStyleChanged: function(prevStyle, thisStyle) {
|
|
1258
|
-
return prevStyle.fill !== thisStyle.fill ||
|
|
1259
|
-
prevStyle.stroke !== thisStyle.stroke ||
|
|
1260
|
-
prevStyle.strokeWidth !== thisStyle.strokeWidth ||
|
|
1261
|
-
prevStyle.fontSize !== thisStyle.fontSize ||
|
|
1262
|
-
prevStyle.fontFamily !== thisStyle.fontFamily ||
|
|
1263
|
-
prevStyle.fontWeight !== thisStyle.fontWeight ||
|
|
1264
|
-
prevStyle.fontStyle !== thisStyle.fontStyle ||
|
|
1265
|
-
prevStyle.deltaY !== thisStyle.deltaY;
|
|
1266
|
-
},
|
|
1267
|
-
|
|
1268
|
-
/**
|
|
1269
|
-
* @private
|
|
1270
|
-
* @param {Object} prevStyle
|
|
1271
|
-
* @param {Object} thisStyle
|
|
1272
|
-
*/
|
|
1273
|
-
_hasStyleChangedForSvg: function(prevStyle, thisStyle) {
|
|
1274
|
-
return this._hasStyleChanged(prevStyle, thisStyle) ||
|
|
1275
|
-
prevStyle.overline !== thisStyle.overline ||
|
|
1276
|
-
prevStyle.underline !== thisStyle.underline ||
|
|
1277
|
-
prevStyle.linethrough !== thisStyle.linethrough;
|
|
1278
|
-
},
|
|
1279
|
-
|
|
1280
1252
|
/**
|
|
1281
1253
|
* @private
|
|
1282
1254
|
* @param {Number} lineIndex index text line
|
|
@@ -1538,8 +1510,7 @@
|
|
|
1538
1510
|
toObject: function(propertiesToInclude) {
|
|
1539
1511
|
var allProperties = additionalProps.concat(propertiesToInclude);
|
|
1540
1512
|
var obj = this.callSuper('toObject', allProperties);
|
|
1541
|
-
|
|
1542
|
-
obj.styles = clone(this.styles, true);
|
|
1513
|
+
obj.styles = fabric.util.stylesToArray(this.styles, this.text);
|
|
1543
1514
|
if (obj.path) {
|
|
1544
1515
|
obj.path = this.path.toObject();
|
|
1545
1516
|
}
|
|
@@ -1705,6 +1676,7 @@
|
|
|
1705
1676
|
var objectCopy = clone(object), path = object.path;
|
|
1706
1677
|
delete objectCopy.path;
|
|
1707
1678
|
return fabric.Object._fromObject('Text', objectCopy, function(textInstance) {
|
|
1679
|
+
textInstance.styles = fabric.util.stylesFromArray(object.styles, object.text);
|
|
1708
1680
|
if (path) {
|
|
1709
1681
|
fabric.Object._fromObject('Path', path, function(pathInstance) {
|
|
1710
1682
|
textInstance.set('path', pathInstance);
|
|
@@ -453,6 +453,9 @@
|
|
|
453
453
|
* @param {Function} [callback] Callback to invoke when an fabric.Textbox instance is created
|
|
454
454
|
*/
|
|
455
455
|
fabric.Textbox.fromObject = function(object, callback) {
|
|
456
|
-
|
|
456
|
+
var styles = fabric.util.stylesFromArray(object.styles, object.text);
|
|
457
|
+
//copy object to prevent mutation
|
|
458
|
+
var objCopy = Object.assign({}, object, { styles: styles });
|
|
459
|
+
return fabric.Object._fromObject('Textbox', objCopy, callback, 'text');
|
|
457
460
|
};
|
|
458
461
|
})(typeof exports !== 'undefined' ? exports : this);
|
package/src/util/dom_style.js
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
var normalizedProperty = (property === 'float' || property === 'cssFloat')
|
|
27
27
|
? (typeof elementStyle.styleFloat === 'undefined' ? 'cssFloat' : 'styleFloat')
|
|
28
28
|
: property;
|
|
29
|
-
elementStyle
|
|
29
|
+
elementStyle.setProperty(normalizedProperty, styles[property]);
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
return element;
|
package/src/util/misc.js
CHANGED
|
@@ -651,6 +651,9 @@
|
|
|
651
651
|
groupSVGElements: function(elements, options, path) {
|
|
652
652
|
var object;
|
|
653
653
|
if (elements && elements.length === 1) {
|
|
654
|
+
if (typeof path !== 'undefined') {
|
|
655
|
+
elements[0].sourcePath = path;
|
|
656
|
+
}
|
|
654
657
|
return elements[0];
|
|
655
658
|
}
|
|
656
659
|
if (options) {
|
|
@@ -1215,5 +1218,112 @@
|
|
|
1215
1218
|
}
|
|
1216
1219
|
return new fabric.Group([a], { clipPath: b, inverted: inverted });
|
|
1217
1220
|
},
|
|
1221
|
+
|
|
1222
|
+
/**
|
|
1223
|
+
* @memberOf fabric.util
|
|
1224
|
+
* @param {Object} prevStyle first style to compare
|
|
1225
|
+
* @param {Object} thisStyle second style to compare
|
|
1226
|
+
* @param {boolean} forTextSpans whether to check overline, underline, and line-through properties
|
|
1227
|
+
* @return {boolean} true if the style changed
|
|
1228
|
+
*/
|
|
1229
|
+
hasStyleChanged: function(prevStyle, thisStyle, forTextSpans) {
|
|
1230
|
+
forTextSpans = forTextSpans || false;
|
|
1231
|
+
return (prevStyle.fill !== thisStyle.fill ||
|
|
1232
|
+
prevStyle.stroke !== thisStyle.stroke ||
|
|
1233
|
+
prevStyle.strokeWidth !== thisStyle.strokeWidth ||
|
|
1234
|
+
prevStyle.fontSize !== thisStyle.fontSize ||
|
|
1235
|
+
prevStyle.fontFamily !== thisStyle.fontFamily ||
|
|
1236
|
+
prevStyle.fontWeight !== thisStyle.fontWeight ||
|
|
1237
|
+
prevStyle.fontStyle !== thisStyle.fontStyle ||
|
|
1238
|
+
prevStyle.deltaY !== thisStyle.deltaY) ||
|
|
1239
|
+
(forTextSpans &&
|
|
1240
|
+
(prevStyle.overline !== thisStyle.overline ||
|
|
1241
|
+
prevStyle.underline !== thisStyle.underline ||
|
|
1242
|
+
prevStyle.linethrough !== thisStyle.linethrough));
|
|
1243
|
+
},
|
|
1244
|
+
|
|
1245
|
+
/**
|
|
1246
|
+
* Returns the array form of a text object's inline styles property with styles grouped in ranges
|
|
1247
|
+
* rather than per character. This format is less verbose, and is better suited for storage
|
|
1248
|
+
* so it is used in serialization (not during runtime).
|
|
1249
|
+
* @memberOf fabric.util
|
|
1250
|
+
* @param {object} styles per character styles for a text object
|
|
1251
|
+
* @param {String} text the text string that the styles are applied to
|
|
1252
|
+
* @return {{start: number, end: number, style: object}[]}
|
|
1253
|
+
*/
|
|
1254
|
+
stylesToArray: function(styles, text) {
|
|
1255
|
+
// clone style structure to prevent mutation
|
|
1256
|
+
var styles = fabric.util.object.clone(styles, true),
|
|
1257
|
+
textLines = text.split('\n'),
|
|
1258
|
+
charIndex = -1, prevStyle = {}, stylesArray = [];
|
|
1259
|
+
//loop through each textLine
|
|
1260
|
+
for (var i = 0; i < textLines.length; i++) {
|
|
1261
|
+
if (!styles[i]) {
|
|
1262
|
+
//no styles exist for this line, so add the line's length to the charIndex total
|
|
1263
|
+
charIndex += textLines[i].length;
|
|
1264
|
+
continue;
|
|
1265
|
+
}
|
|
1266
|
+
//loop through each character of the current line
|
|
1267
|
+
for (var c = 0; c < textLines[i].length; c++) {
|
|
1268
|
+
charIndex++;
|
|
1269
|
+
var thisStyle = styles[i][c];
|
|
1270
|
+
//check if style exists for this character
|
|
1271
|
+
if (thisStyle) {
|
|
1272
|
+
var styleChanged = fabric.util.hasStyleChanged(prevStyle, thisStyle, true);
|
|
1273
|
+
if (styleChanged) {
|
|
1274
|
+
stylesArray.push({
|
|
1275
|
+
start: charIndex,
|
|
1276
|
+
end: charIndex + 1,
|
|
1277
|
+
style: thisStyle
|
|
1278
|
+
});
|
|
1279
|
+
}
|
|
1280
|
+
else {
|
|
1281
|
+
//if style is the same as previous character, increase end index
|
|
1282
|
+
stylesArray[stylesArray.length - 1].end++;
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
prevStyle = thisStyle || {};
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
return stylesArray;
|
|
1289
|
+
},
|
|
1290
|
+
|
|
1291
|
+
/**
|
|
1292
|
+
* Returns the object form of the styles property with styles that are assigned per
|
|
1293
|
+
* character rather than grouped by range. This format is more verbose, and is
|
|
1294
|
+
* only used during runtime (not for serialization/storage)
|
|
1295
|
+
* @memberOf fabric.util
|
|
1296
|
+
* @param {Array} styles the serialized form of a text object's styles
|
|
1297
|
+
* @param {String} text the text string that the styles are applied to
|
|
1298
|
+
* @return {Object}
|
|
1299
|
+
*/
|
|
1300
|
+
stylesFromArray: function(styles, text) {
|
|
1301
|
+
if (!Array.isArray(styles)) {
|
|
1302
|
+
return styles;
|
|
1303
|
+
}
|
|
1304
|
+
var textLines = text.split('\n'),
|
|
1305
|
+
charIndex = -1, styleIndex = 0, stylesObject = {};
|
|
1306
|
+
//loop through each textLine
|
|
1307
|
+
for (var i = 0; i < textLines.length; i++) {
|
|
1308
|
+
//loop through each character of the current line
|
|
1309
|
+
for (var c = 0; c < textLines[i].length; c++) {
|
|
1310
|
+
charIndex++;
|
|
1311
|
+
//check if there's a style collection that includes the current character
|
|
1312
|
+
if (styles[styleIndex]
|
|
1313
|
+
&& styles[styleIndex].start <= charIndex
|
|
1314
|
+
&& charIndex < styles[styleIndex].end) {
|
|
1315
|
+
//create object for line index if it doesn't exist
|
|
1316
|
+
stylesObject[i] = stylesObject[i] || {};
|
|
1317
|
+
//assign a style at this character's index
|
|
1318
|
+
stylesObject[i][c] = Object.assign({}, styles[styleIndex].style);
|
|
1319
|
+
//if character is at the end of the current style collection, move to the next
|
|
1320
|
+
if (charIndex === styles[styleIndex].end - 1) {
|
|
1321
|
+
styleIndex++;
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
return stylesObject;
|
|
1327
|
+
}
|
|
1218
1328
|
};
|
|
1219
1329
|
})(typeof exports !== 'undefined' ? exports : this);
|