|
1 | | -//@ts-nocheck |
2 | | -(function (global) { |
3 | | - var fabric = global.fabric; |
4 | | - /** |
5 | | - * @namespace fabric.Collection |
6 | | - */ |
7 | | - fabric.Collection = { |
| 1 | +import { fabric } from '../../HEADER'; |
| 2 | +import type { FabricObject } from '../shapes/fabricObject.class'; |
| 3 | + |
| 4 | +export function createCollectionMixin(Klass: { new (...args: any[]): any }) { |
| 5 | + return class Collection extends Klass { |
8 | 6 | /** |
9 | | - * @type {fabric.Object[]} |
| 7 | + * @type {FabricObject[]} |
10 | 8 | */ |
11 | | - _objects: [], |
| 9 | + _objects: FabricObject[] = []; |
| 10 | + |
| 11 | + // eslint-disable-next-line @typescript-eslint/no-unused-vars |
| 12 | + _onObjectAdded(object: FabricObject) { |
| 13 | + // subclasses should override this method |
| 14 | + } |
| 15 | + |
| 16 | + // eslint-disable-next-line @typescript-eslint/no-unused-vars |
| 17 | + _onObjectRemoved(object: FabricObject) { |
| 18 | + // subclasses should override this method |
| 19 | + } |
12 | 20 |
|
13 | 21 | /** |
14 | | - * Adds objects to collection, Canvas or Group, then renders canvas |
15 | | - * (if `renderOnAddRemove` is not `false`). |
16 | | - * Objects should be instances of (or inherit from) fabric.Object |
17 | | - * @private |
18 | | - * @param {fabric.Object[]} objects to add |
19 | | - * @param {(object:fabric.Object) => any} [callback] |
| 22 | + * Adds objects to collection |
| 23 | + * Objects should be instances of (or inherit from) FabricObject |
| 24 | + * @param {...FabricObject[]} objects to add |
20 | 25 | * @returns {number} new array length |
21 | 26 | */ |
22 | | - add: function (objects, callback) { |
23 | | - var size = this._objects.push.apply(this._objects, objects); |
24 | | - if (callback) { |
25 | | - for (var i = 0; i < objects.length; i++) { |
26 | | - callback.call(this, objects[i]); |
27 | | - } |
28 | | - } |
| 27 | + add(...objects: FabricObject[]) { |
| 28 | + const size = this._objects.push(...objects); |
| 29 | + objects.forEach((object) => this._onObjectAdded(object)); |
29 | 30 | return size; |
30 | | - }, |
| 31 | + } |
31 | 32 |
|
32 | 33 | /** |
33 | | - * Inserts an object into collection at specified index, then renders canvas (if `renderOnAddRemove` is not `false`) |
34 | | - * An object should be an instance of (or inherit from) fabric.Object |
35 | | - * @private |
36 | | - * @param {fabric.Object|fabric.Object[]} objects Object(s) to insert |
37 | | - * @param {Number} index Index to insert object at |
38 | | - * @param {(object:fabric.Object) => any} [callback] |
| 34 | + * Inserts an object into collection at specified index |
| 35 | + * @param {number} index Index to insert object at |
| 36 | + * @param {...FabricObject[]} objects Object(s) to insert |
39 | 37 | * @returns {number} new array length |
40 | 38 | */ |
41 | | - insertAt: function (objects, index, callback) { |
42 | | - var args = [index, 0].concat(objects); |
43 | | - this._objects.splice.apply(this._objects, args); |
44 | | - if (callback) { |
45 | | - for (var i = 2; i < args.length; i++) { |
46 | | - callback.call(this, args[i]); |
47 | | - } |
48 | | - } |
| 39 | + insertAt(index: number, ...objects: FabricObject[]) { |
| 40 | + this._objects.splice(index, 0, ...objects); |
| 41 | + objects.forEach((object) => this._onObjectAdded(object)); |
49 | 42 | return this._objects.length; |
50 | | - }, |
| 43 | + } |
51 | 44 |
|
52 | 45 | /** |
53 | 46 | * Removes objects from a collection, then renders canvas (if `renderOnAddRemove` is not `false`) |
54 | 47 | * @private |
55 | | - * @param {fabric.Object[]} objectsToRemove objects to remove |
56 | | - * @param {(object:fabric.Object) => any} [callback] function to call for each object removed |
57 | | - * @returns {fabric.Object[]} removed objects |
| 48 | + * @param {...FabricObject[]} objects objects to remove |
| 49 | + * @returns {FabricObject[]} removed objects |
58 | 50 | */ |
59 | | - remove: function (objectsToRemove, callback) { |
60 | | - var objects = this._objects, |
61 | | - removed = []; |
62 | | - for (var i = 0, object, index; i < objectsToRemove.length; i++) { |
63 | | - object = objectsToRemove[i]; |
64 | | - index = objects.indexOf(object); |
| 51 | + remove(...objects: FabricObject[]) { |
| 52 | + const array = this._objects, |
| 53 | + removed: FabricObject[] = []; |
| 54 | + objects.forEach((object) => { |
| 55 | + const index = array.indexOf(object); |
65 | 56 | // only call onObjectRemoved if an object was actually removed |
66 | 57 | if (index !== -1) { |
67 | | - objects.splice(index, 1); |
| 58 | + array.splice(index, 1); |
68 | 59 | removed.push(object); |
69 | | - callback && callback.call(this, object); |
| 60 | + this._onObjectRemoved(object); |
70 | 61 | } |
71 | | - } |
| 62 | + }); |
72 | 63 | return removed; |
73 | | - }, |
| 64 | + } |
74 | 65 |
|
75 | 66 | /** |
76 | 67 | * Executes given function for each object in this group |
| 68 | + * A simple shortcut for getObjects().forEach, before es6 was more complicated, |
| 69 | + * now is just a shortcut. |
77 | 70 | * @param {Function} callback |
78 | 71 | * Callback invoked with current object as first argument, |
79 | 72 | * index - as second and an array of all objects - as third. |
80 | | - * Callback is invoked in a context of Global Object (e.g. `window`) |
81 | | - * when no `context` argument is given |
82 | | - * |
83 | | - * @param {Object} context Context (aka thisObject) |
84 | | - * @return {Self} thisArg |
85 | | - * @chainable |
86 | 73 | */ |
87 | | - forEachObject: function (callback, context) { |
88 | | - var objects = this.getObjects(); |
89 | | - for (var i = 0; i < objects.length; i++) { |
90 | | - callback.call(context, objects[i], i, objects); |
91 | | - } |
92 | | - return this; |
93 | | - }, |
| 74 | + forEachObject( |
| 75 | + callback: ( |
| 76 | + object: FabricObject, |
| 77 | + index: number, |
| 78 | + array: FabricObject[] |
| 79 | + ) => any |
| 80 | + ) { |
| 81 | + this.getObjects().forEach((object, index, objects) => |
| 82 | + callback(object, index, objects) |
| 83 | + ); |
| 84 | + } |
94 | 85 |
|
95 | 86 | /** |
96 | 87 | * Returns an array of children objects of this instance |
97 | 88 | * @param {...String} [types] When specified, only objects of these types are returned |
98 | 89 | * @return {Array} |
99 | 90 | */ |
100 | | - getObjects: function () { |
101 | | - if (arguments.length === 0) { |
102 | | - return this._objects.concat(); |
| 91 | + getObjects(...types: string[]) { |
| 92 | + if (types.length === 0) { |
| 93 | + return [...this._objects]; |
103 | 94 | } |
104 | | - var types = Array.from(arguments); |
105 | | - return this._objects.filter(function (o) { |
106 | | - return types.indexOf(o.type) > -1; |
107 | | - }); |
108 | | - }, |
| 95 | + return this._objects.filter((o) => types.includes(o.type)); |
| 96 | + } |
109 | 97 |
|
110 | 98 | /** |
111 | 99 | * Returns object at specified index |
112 | 100 | * @param {Number} index |
113 | 101 | * @return {Object} object at index |
114 | 102 | */ |
115 | | - item: function (index) { |
| 103 | + item(index: number) { |
116 | 104 | return this._objects[index]; |
117 | | - }, |
| 105 | + } |
118 | 106 |
|
119 | 107 | /** |
120 | 108 | * Returns true if collection contains no objects |
121 | 109 | * @return {Boolean} true if collection is empty |
122 | 110 | */ |
123 | | - isEmpty: function () { |
| 111 | + isEmpty() { |
124 | 112 | return this._objects.length === 0; |
125 | | - }, |
| 113 | + } |
126 | 114 |
|
127 | 115 | /** |
128 | 116 | * Returns a size of a collection (i.e: length of an array containing its objects) |
129 | 117 | * @return {Number} Collection size |
130 | 118 | */ |
131 | | - size: function () { |
| 119 | + size() { |
132 | 120 | return this._objects.length; |
133 | | - }, |
| 121 | + } |
134 | 122 |
|
135 | 123 | /** |
136 | 124 | * Returns true if collection contains an object.\ |
137 | | - * **Prefer using {@link `fabric.Object#isDescendantOf`} for performance reasons** |
| 125 | + * **Prefer using {@link `FabricObject#isDescendantOf`} for performance reasons** |
138 | 126 | * instead of a.contains(b) use b.isDescendantOf(a) |
139 | 127 | * @param {Object} object Object to check against |
140 | 128 | * @param {Boolean} [deep=false] `true` to check all descendants, `false` to check only `_objects` |
141 | 129 | * @return {Boolean} `true` if collection contains an object |
142 | 130 | */ |
143 | | - contains: function (object, deep) { |
144 | | - if (this._objects.indexOf(object) > -1) { |
| 131 | + contains(object: FabricObject, deep?: boolean): boolean { |
| 132 | + if (this._objects.includes(object)) { |
145 | 133 | return true; |
146 | 134 | } else if (deep) { |
147 | | - return this._objects.some(function (obj) { |
148 | | - return ( |
149 | | - typeof obj.contains === 'function' && obj.contains(object, true) |
150 | | - ); |
151 | | - }); |
| 135 | + return this._objects.some( |
| 136 | + (obj) => obj instanceof Collection && obj.contains(object, true) |
| 137 | + ); |
152 | 138 | } |
153 | 139 | return false; |
154 | | - }, |
| 140 | + } |
155 | 141 |
|
156 | 142 | /** |
157 | 143 | * Returns number representation of a collection complexity |
158 | 144 | * @return {Number} complexity |
159 | 145 | */ |
160 | | - complexity: function () { |
161 | | - return this._objects.reduce(function (memo, current) { |
| 146 | + complexity() { |
| 147 | + return this._objects.reduce((memo, current) => { |
162 | 148 | memo += current.complexity ? current.complexity() : 0; |
163 | 149 | return memo; |
164 | 150 | }, 0); |
165 | | - }, |
| 151 | + } |
166 | 152 | }; |
167 | | -})(typeof exports !== 'undefined' ? exports : window); |
| 153 | +} |
| 154 | + |
| 155 | +fabric.createCollectionMixin = createCollectionMixin; |
0 commit comments