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/package.json CHANGED
@@ -1,92 +1,89 @@
1
1
  {
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.1",
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
- "canvas": "^2.8.0",
73
- "jsdom": "^19.0.0"
74
- },
75
- "devDependencies": {
76
- "auto-changelog": "^2.3.0",
77
- "chalk": "^2.4.1",
78
- "deep-object-diff": "^1.1.7",
79
- "eslint": "4.18.x",
80
- "nyc": "^15.1.0",
81
- "onchange": "^7.1.0",
82
- "pixelmatch": "^4.0.2",
83
- "qunit": "^2.17.2",
84
- "testem": "^3.2.0",
85
- "uglify-js": "3.3.x"
86
- },
87
- "engines": {
88
- "node": ">=14.0.0"
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 = this._hasStyleChangedForSvg(actualStyle, nextStyle);
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
- callback && callback(group);
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
- parseDecoration(object);
514
- if (object.styles) {
515
- for (var i in object.styles) {
516
- for (var j in object.styles[i]) {
517
- parseDecoration(object.styles[i][j]);
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', object, callback, 'text');
524
+ fabric.Object._fromObject('IText', objCopy, callback, 'text');
522
525
  };
523
526
  })();
@@ -340,7 +340,15 @@
340
340
  fabric.loadSVGFromURL(pathUrl, function (elements) {
341
341
  var path = elements[0];
342
342
  path.setOptions(object);
343
- callback && callback(path);
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 {
@@ -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 = this._hasStyleChanged(actualStyle, nextStyle);
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
- // styles will be overridden with a properly cloned structure
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
- return fabric.Object._fromObject('Textbox', object, callback, 'text');
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);
@@ -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[normalizedProperty] = styles[property];
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);