fabric 4.5.1-browser → 5.0.0-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.
Files changed (49) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/CONTRIBUTING.md +14 -0
  3. package/HEADER.js +1 -1
  4. package/README.md +3 -6
  5. package/SECURITY.md +5 -0
  6. package/build.js +1 -0
  7. package/dist/fabric.js +1160 -668
  8. package/dist/fabric.min.js +1 -1
  9. package/lib/event.js +7 -3
  10. package/package.json +9 -3
  11. package/publish-next.js +15 -0
  12. package/publish.js +3 -0
  13. package/src/brushes/base_brush.class.js +3 -5
  14. package/src/brushes/pattern_brush.class.js +7 -5
  15. package/src/brushes/pencil_brush.class.js +49 -37
  16. package/src/canvas.class.js +27 -57
  17. package/src/filters/saturate_filter.class.js +9 -1
  18. package/src/filters/vibrance_filter.class.js +122 -0
  19. package/src/mixins/animation.mixin.js +20 -25
  20. package/src/mixins/canvas_events.mixin.js +30 -59
  21. package/src/mixins/canvas_grouping.mixin.js +4 -4
  22. package/src/mixins/collection.mixin.js +11 -2
  23. package/src/mixins/eraser_brush.mixin.js +495 -452
  24. package/src/mixins/itext_behavior.mixin.js +7 -1
  25. package/src/mixins/itext_key_behavior.mixin.js +7 -1
  26. package/src/mixins/object_geometry.mixin.js +5 -35
  27. package/src/mixins/object_interactivity.mixin.js +18 -7
  28. package/src/mixins/object_straightening.mixin.js +4 -9
  29. package/src/mixins/observable.mixin.js +22 -0
  30. package/src/parser.js +13 -9
  31. package/src/shapes/circle.class.js +22 -19
  32. package/src/shapes/ellipse.class.js +2 -2
  33. package/src/shapes/group.class.js +24 -32
  34. package/src/shapes/image.class.js +3 -25
  35. package/src/shapes/itext.class.js +10 -0
  36. package/src/shapes/line.class.js +5 -21
  37. package/src/shapes/object.class.js +67 -32
  38. package/src/shapes/path.class.js +17 -18
  39. package/src/shapes/polygon.class.js +11 -10
  40. package/src/shapes/polyline.class.js +33 -24
  41. package/src/shapes/rect.class.js +0 -18
  42. package/src/shapes/text.class.js +120 -58
  43. package/src/shapes/triangle.class.js +0 -15
  44. package/src/static_canvas.class.js +43 -20
  45. package/src/util/animate.js +149 -16
  46. package/src/util/animate_color.js +2 -1
  47. package/src/util/lang_object.js +5 -1
  48. package/src/util/misc.js +193 -42
  49. package/src/util/path.js +89 -52
@@ -866,7 +866,13 @@
866
866
  this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle);
867
867
  }
868
868
  else if (copiedStyle) {
869
- this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0];
869
+ // this test is required in order to close #6841
870
+ // when a pasted buffer begins with a newline then
871
+ // this.styles[cursorLoc.lineIndex + i] and copiedStyle[0]
872
+ // may be undefined for some reason
873
+ if (this.styles[cursorLoc.lineIndex + i] && copiedStyle[0]) {
874
+ this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0];
875
+ }
870
876
  }
871
877
  copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1);
872
878
  }
@@ -17,7 +17,13 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
17
17
  this.hiddenTextarea.style.cssText = 'position: absolute; top: ' + style.top +
18
18
  '; left: ' + style.left + '; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px;' +
19
19
  ' paddingーtop: ' + style.fontSize + ';';
20
- fabric.document.body.appendChild(this.hiddenTextarea);
20
+
21
+ if (this.hiddenTextareaContainer) {
22
+ this.hiddenTextareaContainer.appendChild(this.hiddenTextarea);
23
+ }
24
+ else {
25
+ fabric.document.body.appendChild(this.hiddenTextarea);
26
+ }
21
27
 
22
28
  fabric.util.addListener(this.hiddenTextarea, 'keydown', this.onKeyDown.bind(this));
23
29
  fabric.util.addListener(this.hiddenTextarea, 'keyup', this.onKeyUp.bind(this));
@@ -45,7 +45,7 @@
45
45
  /**
46
46
  * Describe object's corner position in canvas element coordinates.
47
47
  * includes padding. Used of object detection.
48
- * set and refreshed with setCoords and calcCoords.
48
+ * set and refreshed with setCoords.
49
49
  * @memberOf fabric.Object.prototype
50
50
  */
51
51
  lineCoords: null,
@@ -429,21 +429,6 @@
429
429
  return this.scale(value / this.height / boundingRectFactor);
430
430
  },
431
431
 
432
- /**
433
- * Calculates and returns the .coords of an object.
434
- * unused by the library, only for the end dev.
435
- * @return {Object} Object with tl, tr, br, bl ....
436
- * @chainable
437
- * @deprecated
438
- */
439
- calcCoords: function(absolute) {
440
- // this is a compatibility function to avoid removing calcCoords now.
441
- if (absolute) {
442
- return this.calcACoords();
443
- }
444
- return this.calcOCoords();
445
- },
446
-
447
432
  calcLineCoords: function() {
448
433
  var vpt = this.getViewportTransform(),
449
434
  padding = this.padding, angle = degreesToRadians(this.angle),
@@ -518,7 +503,8 @@
518
503
  * oCoords are used to find the corners
519
504
  * aCoords are used to quickly find an object on the canvas
520
505
  * lineCoords are used to quickly find object during pointer events.
521
- * See {@link https://github.com/kangax/fabric.js/wiki/When-to-call-setCoords|When-to-call-setCoords}
506
+ * See {@link https://github.com/fabricjs/fabric.js/wiki/When-to-call-setCoords} and {@link http://fabricjs.com/fabric-gotchas}
507
+ *
522
508
  * @param {Boolean} [skipCorners] skip calculation of oCoords.
523
509
  * @return {fabric.Object} thisArg
524
510
  * @chainable
@@ -615,23 +601,6 @@
615
601
  return cache.value;
616
602
  },
617
603
 
618
- /*
619
- * Calculate object dimensions from its properties
620
- * @private
621
- * @deprecated since 3.4.0, please use fabric.util._calcDimensionsTransformMatrix
622
- * not including or including flipX, flipY to emulate the flipping boolean
623
- * @return {Object} .x width dimension
624
- * @return {Object} .y height dimension
625
- */
626
- _calcDimensionsTransformMatrix: function(skewX, skewY, flipping) {
627
- return util.calcDimensionsMatrix({
628
- skewX: skewX,
629
- skewY: skewY,
630
- scaleX: this.scaleX * (flipping && this.flipX ? -1 : 1),
631
- scaleY: this.scaleY * (flipping && this.flipY ? -1 : 1)
632
- });
633
- },
634
-
635
604
  /*
636
605
  * Calculate object dimensions from its properties
637
606
  * @private
@@ -660,7 +629,7 @@
660
629
  if (typeof skewY === 'undefined') {
661
630
  skewY = this.skewY;
662
631
  }
663
- var dimensions = this._getNonTransformedDimensions(), dimX, dimY,
632
+ var dimensions, dimX, dimY,
664
633
  noSkew = skewX === 0 && skewY === 0;
665
634
 
666
635
  if (this.strokeUniform) {
@@ -668,6 +637,7 @@
668
637
  dimY = this.height;
669
638
  }
670
639
  else {
640
+ dimensions = this._getNonTransformedDimensions();
671
641
  dimX = dimensions.x;
672
642
  dimY = dimensions.y;
673
643
  }
@@ -133,7 +133,7 @@
133
133
 
134
134
  ctx.save();
135
135
  ctx.strokeStyle = styleOverride.borderColor || this.borderColor;
136
- this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null);
136
+ this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray);
137
137
 
138
138
  ctx.strokeRect(
139
139
  -width / 2,
@@ -186,7 +186,7 @@
186
186
  height =
187
187
  bbox.y + strokeWidth * (strokeUniform ? this.canvas.getZoom() : options.scaleY) + borderScaleFactor;
188
188
  ctx.save();
189
- this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null);
189
+ this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray);
190
190
  ctx.strokeStyle = styleOverride.borderColor || this.borderColor;
191
191
  ctx.strokeRect(
192
192
  -width / 2,
@@ -211,18 +211,29 @@
211
211
  drawControls: function(ctx, styleOverride) {
212
212
  styleOverride = styleOverride || {};
213
213
  ctx.save();
214
- ctx.setTransform(this.canvas.getRetinaScaling(), 0, 0, this.canvas.getRetinaScaling(), 0, 0);
214
+ var retinaScaling = this.canvas.getRetinaScaling(), matrix, p;
215
+ ctx.setTransform(retinaScaling, 0, 0, retinaScaling, 0, 0);
215
216
  ctx.strokeStyle = ctx.fillStyle = styleOverride.cornerColor || this.cornerColor;
216
217
  if (!this.transparentCorners) {
217
218
  ctx.strokeStyle = styleOverride.cornerStrokeColor || this.cornerStrokeColor;
218
219
  }
219
- this._setLineDash(ctx, styleOverride.cornerDashArray || this.cornerDashArray, null);
220
+ this._setLineDash(ctx, styleOverride.cornerDashArray || this.cornerDashArray);
220
221
  this.setCoords();
222
+ if (this.group) {
223
+ // fabricJS does not really support drawing controls inside groups,
224
+ // this piece of code here helps having at least the control in places.
225
+ // If an application needs to show some objects as selected because of some UI state
226
+ // can still call Object._renderControls() on any object they desire, independently of groups.
227
+ // using no padding, circular controls and hiding the rotating cursor is higly suggested,
228
+ matrix = this.group.calcTransformMatrix();
229
+ }
221
230
  this.forEachControl(function(control, key, fabricObject) {
231
+ p = fabricObject.oCoords[key];
222
232
  if (control.getVisibility(fabricObject, key)) {
223
- control.render(ctx,
224
- fabricObject.oCoords[key].x,
225
- fabricObject.oCoords[key].y, styleOverride, fabricObject);
233
+ if (matrix) {
234
+ p = fabric.util.transformPoint(p, matrix);
235
+ }
236
+ control.render(ctx, p.x, p.y, styleOverride, fabricObject);
226
237
  }
227
238
  });
228
239
  ctx.restore();
@@ -18,8 +18,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
18
18
  * @chainable
19
19
  */
20
20
  straighten: function() {
21
- this.rotate(this._getAngleValueForStraighten());
22
- return this;
21
+ return this.rotate(this._getAngleValueForStraighten());
23
22
  },
24
23
 
25
24
  /**
@@ -28,7 +27,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
28
27
  * @param {Function} [callbacks.onComplete] Invoked on completion
29
28
  * @param {Function} [callbacks.onChange] Invoked on every step of animation
30
29
  * @return {fabric.Object} thisArg
31
- * @chainable
32
30
  */
33
31
  fxStraighten: function(callbacks) {
34
32
  callbacks = callbacks || { };
@@ -38,7 +36,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
38
36
  onChange = callbacks.onChange || empty,
39
37
  _this = this;
40
38
 
41
- fabric.util.animate({
39
+ return fabric.util.animate({
40
+ target: this,
42
41
  startValue: this.get('angle'),
43
42
  endValue: this._getAngleValueForStraighten(),
44
43
  duration: this.FX_DURATION,
@@ -51,8 +50,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
51
50
  onComplete();
52
51
  },
53
52
  });
54
-
55
- return this;
56
53
  }
57
54
  });
58
55
 
@@ -74,12 +71,10 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
74
71
  * Same as {@link fabric.Canvas.prototype.straightenObject}, but animated
75
72
  * @param {fabric.Object} object Object to straighten
76
73
  * @return {fabric.Canvas} thisArg
77
- * @chainable
78
74
  */
79
75
  fxStraightenObject: function (object) {
80
- object.fxStraighten({
76
+ return object.fxStraighten({
81
77
  onChange: this.requestRenderAllBound
82
78
  });
83
- return this;
84
79
  }
85
80
  });
@@ -46,6 +46,27 @@
46
46
  return this;
47
47
  }
48
48
 
49
+ function _once(eventName, handler) {
50
+ var _handler = function () {
51
+ handler.apply(this, arguments);
52
+ this.off(eventName, _handler);
53
+ }.bind(this);
54
+ this.on(eventName, _handler);
55
+ }
56
+
57
+ function once(eventName, handler) {
58
+ // one object with key/value pairs was passed
59
+ if (arguments.length === 1) {
60
+ for (var prop in eventName) {
61
+ _once.call(this, prop, eventName[prop]);
62
+ }
63
+ }
64
+ else {
65
+ _once.call(this, eventName, handler);
66
+ }
67
+ return this;
68
+ }
69
+
49
70
  /**
50
71
  * Stops event observing for a particular event handler. Calling this method
51
72
  * without arguments removes all handlers for all events
@@ -114,6 +135,7 @@
114
135
  fabric.Observable = {
115
136
  fire: fire,
116
137
  on: on,
138
+ once: once,
117
139
  off: off,
118
140
  };
119
141
  })();
package/src/parser.js CHANGED
@@ -1001,22 +1001,26 @@
1001
1001
  if (styleContents.trim() === '') {
1002
1002
  continue;
1003
1003
  }
1004
- rules = styleContents.match(/[^{]*\{[\s\S]*?\}/g);
1005
- rules = rules.map(function(rule) { return rule.trim(); });
1004
+ // recovers all the rule in this form `body { style code... }`
1005
+ // rules = styleContents.match(/[^{]*\{[\s\S]*?\}/g);
1006
+ rules = styleContents.split('}');
1007
+ // remove empty rules.
1008
+ rules = rules.filter(function(rule) { return rule.trim(); });
1009
+ // at this point we have hopefully an array of rules `body { style code... `
1006
1010
  // eslint-disable-next-line no-loop-func
1007
1011
  rules.forEach(function(rule) {
1008
1012
 
1009
- var match = rule.match(/([\s\S]*?)\s*\{([^}]*)\}/),
1010
- ruleObj = { }, declaration = match[2].trim(),
1011
- propertyValuePairs = declaration.replace(/;$/, '').split(/\s*;\s*/);
1013
+ var match = rule.split('{'),
1014
+ ruleObj = { }, declaration = match[1].trim(),
1015
+ propertyValuePairs = declaration.split(';').filter(function(pair) { return pair.trim(); });
1012
1016
 
1013
1017
  for (i = 0, len = propertyValuePairs.length; i < len; i++) {
1014
- var pair = propertyValuePairs[i].split(/\s*:\s*/),
1015
- property = pair[0],
1016
- value = pair[1];
1018
+ var pair = propertyValuePairs[i].split(':'),
1019
+ property = pair[0].trim(),
1020
+ value = pair[1].trim();
1017
1021
  ruleObj[property] = value;
1018
1022
  }
1019
- rule = match[1];
1023
+ rule = match[0].trim();
1020
1024
  rule.split(',').forEach(function(_rule) {
1021
1025
  _rule = _rule.replace(/^svg/i, '').trim();
1022
1026
  if (_rule === '') {
@@ -3,7 +3,7 @@
3
3
  'use strict';
4
4
 
5
5
  var fabric = global.fabric || (global.fabric = { }),
6
- pi = Math.PI;
6
+ degreesToRadians = fabric.util.degreesToRadians;
7
7
 
8
8
  if (fabric.Circle) {
9
9
  fabric.warn('fabric.Circle is already defined.');
@@ -33,22 +33,20 @@
33
33
  radius: 0,
34
34
 
35
35
  /**
36
- * Start angle of the circle, moving clockwise
37
- * deprecated type, this should be in degree, this was an oversight.
36
+ * degrees of start of the circle.
38
37
  * probably will change to degrees in next major version
39
- * @type Number
38
+ * @type Number 0 - 359
40
39
  * @default 0
41
40
  */
42
41
  startAngle: 0,
43
42
 
44
43
  /**
45
44
  * End angle of the circle
46
- * deprecated type, this should be in degree, this was an oversight.
47
45
  * probably will change to degrees in next major version
48
- * @type Number
49
- * @default 2Pi
46
+ * @type Number 1 - 360
47
+ * @default 360
50
48
  */
51
- endAngle: pi * 2,
49
+ endAngle: 360,
52
50
 
53
51
  cacheProperties: fabric.Object.prototype.cacheProperties.concat('radius', 'startAngle', 'endAngle'),
54
52
 
@@ -86,7 +84,7 @@
86
84
  */
87
85
  _toSVG: function() {
88
86
  var svgString, x = 0, y = 0,
89
- angle = (this.endAngle - this.startAngle) % ( 2 * pi);
87
+ angle = (this.endAngle - this.startAngle) % 360;
90
88
 
91
89
  if (angle === 0) {
92
90
  svgString = [
@@ -97,14 +95,17 @@
97
95
  ];
98
96
  }
99
97
  else {
100
- var startX = fabric.util.cos(this.startAngle) * this.radius,
101
- startY = fabric.util.sin(this.startAngle) * this.radius,
102
- endX = fabric.util.cos(this.endAngle) * this.radius,
103
- endY = fabric.util.sin(this.endAngle) * this.radius,
104
- largeFlag = angle > pi ? '1' : '0';
98
+ var start = degreesToRadians(this.startAngle),
99
+ end = degreesToRadians(this.endAngle),
100
+ radius = this.radius,
101
+ startX = fabric.util.cos(start) * radius,
102
+ startY = fabric.util.sin(start) * radius,
103
+ endX = fabric.util.cos(end) * radius,
104
+ endY = fabric.util.sin(end) * radius,
105
+ largeFlag = angle > 180 ? '1' : '0';
105
106
  svgString = [
106
107
  '<path d="M ' + startX + ' ' + startY,
107
- ' A ' + this.radius + ' ' + this.radius,
108
+ ' A ' + radius + ' ' + radius,
108
109
  ' 0 ', +largeFlag + ' 1', ' ' + endX + ' ' + endY,
109
110
  '" ', 'COMMON_PARTS', ' />\n'
110
111
  ];
@@ -123,8 +124,10 @@
123
124
  0,
124
125
  0,
125
126
  this.radius,
126
- this.startAngle,
127
- this.endAngle, false);
127
+ degreesToRadians(this.startAngle),
128
+ degreesToRadians(this.endAngle),
129
+ false
130
+ );
128
131
  this._renderPaintInOrder(ctx);
129
132
  },
130
133
 
@@ -198,10 +201,10 @@
198
201
  * @memberOf fabric.Circle
199
202
  * @param {Object} object Object to create an instance from
200
203
  * @param {function} [callback] invoked with new instance as first argument
201
- * @return {Object} Instance of fabric.Circle
204
+ * @return {void}
202
205
  */
203
206
  fabric.Circle.fromObject = function(object, callback) {
204
- return fabric.Object._fromObject('Circle', object, callback);
207
+ fabric.Object._fromObject('Circle', object, callback);
205
208
  };
206
209
 
207
210
  })(typeof exports !== 'undefined' ? exports : this);
@@ -172,10 +172,10 @@
172
172
  * @memberOf fabric.Ellipse
173
173
  * @param {Object} object Object to create an instance from
174
174
  * @param {function} [callback] invoked with new instance as first argument
175
- * @return {fabric.Ellipse}
175
+ * @return {void}
176
176
  */
177
177
  fabric.Ellipse.fromObject = function(object, callback) {
178
- return fabric.Object._fromObject('Ellipse', object, callback);
178
+ fabric.Object._fromObject('Ellipse', object, callback);
179
179
  };
180
180
 
181
181
  })(typeof exports !== 'undefined' ? exports : this);
@@ -240,13 +240,17 @@
240
240
  */
241
241
  toObject: function(propertiesToInclude) {
242
242
  var _includeDefaultValues = this.includeDefaultValues;
243
- var objsToObject = this._objects.map(function(obj) {
244
- var originalDefaults = obj.includeDefaultValues;
245
- obj.includeDefaultValues = _includeDefaultValues;
246
- var _obj = obj.toObject(propertiesToInclude);
247
- obj.includeDefaultValues = originalDefaults;
248
- return _obj;
249
- });
243
+ var objsToObject = this._objects
244
+ .filter(function (obj) {
245
+ return !obj.excludeFromExport;
246
+ })
247
+ .map(function (obj) {
248
+ var originalDefaults = obj.includeDefaultValues;
249
+ obj.includeDefaultValues = _includeDefaultValues;
250
+ var _obj = obj.toObject(propertiesToInclude);
251
+ obj.includeDefaultValues = originalDefaults;
252
+ return _obj;
253
+ });
250
254
  var obj = fabric.Object.prototype.toObject.call(this, propertiesToInclude);
251
255
  obj.objects = objsToObject;
252
256
  return obj;
@@ -339,7 +343,7 @@
339
343
  for (var i = 0, len = this._objects.length; i < len; i++) {
340
344
  this._objects[i].render(ctx);
341
345
  }
342
- this._drawClipPath(ctx);
346
+ this._drawClipPath(ctx, this.clipPath);
343
347
  },
344
348
 
345
349
  /**
@@ -385,25 +389,6 @@
385
389
  return this;
386
390
  },
387
391
 
388
- /**
389
- * Realises the transform from this group onto the supplied object
390
- * i.e. it tells you what would happen if the supplied object was in
391
- * the group, and then the group was destroyed. It mutates the supplied
392
- * object.
393
- * Warning: this method is not useful anymore, it has been kept to no break the api.
394
- * is not used in the fabricJS codebase
395
- * this method will be reduced to using the utility.
396
- * @private
397
- * @deprecated
398
- * @param {fabric.Object} object
399
- * @param {Array} parentMatrix parent transformation
400
- * @return {fabric.Object} transformedObject
401
- */
402
- realizeTransform: function(object, parentMatrix) {
403
- fabric.util.addTransformToObject(object, parentMatrix);
404
- return object;
405
- },
406
-
407
392
  /**
408
393
  * Destroys a group (restoring state of its objects)
409
394
  * @return {fabric.Group} thisArg
@@ -418,6 +403,14 @@
418
403
  return this._restoreObjectsState();
419
404
  },
420
405
 
406
+ dispose: function () {
407
+ this.callSuper('dispose');
408
+ this.forEachObject(function (object) {
409
+ object.dispose && object.dispose();
410
+ });
411
+ this._objects = [];
412
+ },
413
+
421
414
  /**
422
415
  * make a group an active selection, remove the group from canvas
423
416
  * the group has to be on canvas for this to work.
@@ -581,11 +574,10 @@
581
574
  });
582
575
  return;
583
576
  }
584
- fabric.util.enlivenObjects(objects, function(enlivenedObjects) {
585
- fabric.util.enlivenObjects([object.clipPath], function(enlivedClipPath) {
586
- var options = fabric.util.object.clone(object, true);
587
- options.clipPath = enlivedClipPath[0];
588
- delete options.objects;
577
+ fabric.util.enlivenObjects(objects, function (enlivenedObjects) {
578
+ var options = fabric.util.object.clone(object, true);
579
+ delete options.objects;
580
+ fabric.util.enlivenObjectEnlivables(object, options, function () {
589
581
  callback && callback(new fabric.Group(enlivenedObjects, options, true));
590
582
  });
591
583
  });
@@ -202,7 +202,8 @@
202
202
  /**
203
203
  * Delete textures, reference to elements and eventually JSDOM cleanup
204
204
  */
205
- dispose: function() {
205
+ dispose: function () {
206
+ this.callSuper('dispose');
206
207
  this.removeTexture(this.cacheKey);
207
208
  this.removeTexture(this.cacheKey + '_filtered');
208
209
  this._cacheContext = undefined;
@@ -249,28 +250,6 @@
249
250
  ctx.closePath();
250
251
  },
251
252
 
252
- /**
253
- * @private
254
- * @param {CanvasRenderingContext2D} ctx Context to render on
255
- */
256
- _renderDashedStroke: function(ctx) {
257
- var x = -this.width / 2,
258
- y = -this.height / 2,
259
- w = this.width,
260
- h = this.height;
261
-
262
- ctx.save();
263
- this._setStrokeStyles(ctx, this);
264
-
265
- ctx.beginPath();
266
- fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray);
267
- fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray);
268
- fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray);
269
- fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray);
270
- ctx.closePath();
271
- ctx.restore();
272
- },
273
-
274
253
  /**
275
254
  * Returns object representation of an instance
276
255
  * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
@@ -734,8 +713,7 @@
734
713
  object.filters = filters || [];
735
714
  fabric.Image.prototype._initFilters.call(object, [object.resizeFilter], function(resizeFilters) {
736
715
  object.resizeFilter = resizeFilters[0];
737
- fabric.util.enlivenObjects([object.clipPath], function(enlivedProps) {
738
- object.clipPath = enlivedProps[0];
716
+ fabric.util.enlivenObjectEnlivables(object, object, function () {
739
717
  var image = new fabric.Image(img, object);
740
718
  callback(image, false);
741
719
  });
@@ -144,6 +144,16 @@
144
144
  */
145
145
  caching: true,
146
146
 
147
+ /**
148
+ * DOM container to append the hiddenTextarea.
149
+ * An alternative to attaching to the document.body.
150
+ * Useful to reduce laggish redraw of the full document.body tree and
151
+ * also with modals event capturing that won't let the textarea take focus.
152
+ * @type HTMLElement
153
+ * @default
154
+ */
155
+ hiddenTextareaContainer: null,
156
+
147
157
  /**
148
158
  * @private
149
159
  */
@@ -5,8 +5,7 @@
5
5
  var fabric = global.fabric || (global.fabric = { }),
6
6
  extend = fabric.util.object.extend,
7
7
  clone = fabric.util.object.clone,
8
- coordProps = { x1: 1, x2: 1, y1: 1, y2: 1 },
9
- supportsLineDash = fabric.StaticCanvas.supports('setLineDash');
8
+ coordProps = { x1: 1, x2: 1, y1: 1, y2: 1 };
10
9
 
11
10
  if (fabric.Line) {
12
11
  fabric.warn('fabric.Line is already defined');
@@ -154,13 +153,10 @@
154
153
  _render: function(ctx) {
155
154
  ctx.beginPath();
156
155
 
157
- if (!this.strokeDashArray || this.strokeDashArray && supportsLineDash) {
158
- // move from center (of virtual box) to its left/top corner
159
- // we can't assume x1, y1 is top left and x2, y2 is bottom right
160
- var p = this.calcLinePoints();
161
- ctx.moveTo(p.x1, p.y1);
162
- ctx.lineTo(p.x2, p.y2);
163
- }
156
+
157
+ var p = this.calcLinePoints();
158
+ ctx.moveTo(p.x1, p.y1);
159
+ ctx.lineTo(p.x2, p.y2);
164
160
 
165
161
  ctx.lineWidth = this.strokeWidth;
166
162
 
@@ -173,18 +169,6 @@
173
169
  ctx.strokeStyle = origStrokeStyle;
174
170
  },
175
171
 
176
- /**
177
- * @private
178
- * @param {CanvasRenderingContext2D} ctx Context to render on
179
- */
180
- _renderDashedStroke: function(ctx) {
181
- var p = this.calcLinePoints();
182
-
183
- ctx.beginPath();
184
- fabric.util.drawDashedLine(ctx, p.x1, p.y1, p.x2, p.y2, this.strokeDashArray);
185
- ctx.closePath();
186
- },
187
-
188
172
  /**
189
173
  * This function is an helper for svg import. it returns the center of the object in the svg
190
174
  * untransformed coordinates