forked from fabricjs/fabric.js
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(TS): Migrate fabric.Collection (fabricjs#8433)
Co-authored-by: Andrea Bogazzi <andreabogazzi79@gmail.com>
- Loading branch information
1 parent
9092cfb
commit f748d9d
Showing
11 changed files
with
362 additions
and
467 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,167 +1,155 @@ | ||
//@ts-nocheck | ||
(function (global) { | ||
var fabric = global.fabric; | ||
/** | ||
* @namespace fabric.Collection | ||
*/ | ||
fabric.Collection = { | ||
import { fabric } from '../../HEADER'; | ||
import type { FabricObject } from '../shapes/fabricObject.class'; | ||
|
||
export function createCollectionMixin(Klass: { new (...args: any[]): any }) { | ||
return class Collection extends Klass { | ||
/** | ||
* @type {fabric.Object[]} | ||
* @type {FabricObject[]} | ||
*/ | ||
_objects: [], | ||
_objects: FabricObject[] = []; | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
_onObjectAdded(object: FabricObject) { | ||
// subclasses should override this method | ||
} | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
_onObjectRemoved(object: FabricObject) { | ||
// subclasses should override this method | ||
} | ||
|
||
/** | ||
* Adds objects to collection, Canvas or Group, then renders canvas | ||
* (if `renderOnAddRemove` is not `false`). | ||
* Objects should be instances of (or inherit from) fabric.Object | ||
* @private | ||
* @param {fabric.Object[]} objects to add | ||
* @param {(object:fabric.Object) => any} [callback] | ||
* Adds objects to collection | ||
* Objects should be instances of (or inherit from) FabricObject | ||
* @param {...FabricObject[]} objects to add | ||
* @returns {number} new array length | ||
*/ | ||
add: function (objects, callback) { | ||
var size = this._objects.push.apply(this._objects, objects); | ||
if (callback) { | ||
for (var i = 0; i < objects.length; i++) { | ||
callback.call(this, objects[i]); | ||
} | ||
} | ||
add(...objects: FabricObject[]) { | ||
const size = this._objects.push(...objects); | ||
objects.forEach((object) => this._onObjectAdded(object)); | ||
return size; | ||
}, | ||
} | ||
|
||
/** | ||
* Inserts an object into collection at specified index, then renders canvas (if `renderOnAddRemove` is not `false`) | ||
* An object should be an instance of (or inherit from) fabric.Object | ||
* @private | ||
* @param {fabric.Object|fabric.Object[]} objects Object(s) to insert | ||
* @param {Number} index Index to insert object at | ||
* @param {(object:fabric.Object) => any} [callback] | ||
* Inserts an object into collection at specified index | ||
* @param {number} index Index to insert object at | ||
* @param {...FabricObject[]} objects Object(s) to insert | ||
* @returns {number} new array length | ||
*/ | ||
insertAt: function (objects, index, callback) { | ||
var args = [index, 0].concat(objects); | ||
this._objects.splice.apply(this._objects, args); | ||
if (callback) { | ||
for (var i = 2; i < args.length; i++) { | ||
callback.call(this, args[i]); | ||
} | ||
} | ||
insertAt(index: number, ...objects: FabricObject[]) { | ||
this._objects.splice(index, 0, ...objects); | ||
objects.forEach((object) => this._onObjectAdded(object)); | ||
return this._objects.length; | ||
}, | ||
} | ||
|
||
/** | ||
* Removes objects from a collection, then renders canvas (if `renderOnAddRemove` is not `false`) | ||
* @private | ||
* @param {fabric.Object[]} objectsToRemove objects to remove | ||
* @param {(object:fabric.Object) => any} [callback] function to call for each object removed | ||
* @returns {fabric.Object[]} removed objects | ||
* @param {...FabricObject[]} objects objects to remove | ||
* @returns {FabricObject[]} removed objects | ||
*/ | ||
remove: function (objectsToRemove, callback) { | ||
var objects = this._objects, | ||
removed = []; | ||
for (var i = 0, object, index; i < objectsToRemove.length; i++) { | ||
object = objectsToRemove[i]; | ||
index = objects.indexOf(object); | ||
remove(...objects: FabricObject[]) { | ||
const array = this._objects, | ||
removed: FabricObject[] = []; | ||
objects.forEach((object) => { | ||
const index = array.indexOf(object); | ||
// only call onObjectRemoved if an object was actually removed | ||
if (index !== -1) { | ||
objects.splice(index, 1); | ||
array.splice(index, 1); | ||
removed.push(object); | ||
callback && callback.call(this, object); | ||
this._onObjectRemoved(object); | ||
} | ||
} | ||
}); | ||
return removed; | ||
}, | ||
} | ||
|
||
/** | ||
* Executes given function for each object in this group | ||
* A simple shortcut for getObjects().forEach, before es6 was more complicated, | ||
* now is just a shortcut. | ||
* @param {Function} callback | ||
* Callback invoked with current object as first argument, | ||
* index - as second and an array of all objects - as third. | ||
* Callback is invoked in a context of Global Object (e.g. `window`) | ||
* when no `context` argument is given | ||
* | ||
* @param {Object} context Context (aka thisObject) | ||
* @return {Self} thisArg | ||
* @chainable | ||
*/ | ||
forEachObject: function (callback, context) { | ||
var objects = this.getObjects(); | ||
for (var i = 0; i < objects.length; i++) { | ||
callback.call(context, objects[i], i, objects); | ||
} | ||
return this; | ||
}, | ||
forEachObject( | ||
callback: ( | ||
object: FabricObject, | ||
index: number, | ||
array: FabricObject[] | ||
) => any | ||
) { | ||
this.getObjects().forEach((object, index, objects) => | ||
callback(object, index, objects) | ||
); | ||
} | ||
|
||
/** | ||
* Returns an array of children objects of this instance | ||
* @param {...String} [types] When specified, only objects of these types are returned | ||
* @return {Array} | ||
*/ | ||
getObjects: function () { | ||
if (arguments.length === 0) { | ||
return this._objects.concat(); | ||
getObjects(...types: string[]) { | ||
if (types.length === 0) { | ||
return [...this._objects]; | ||
} | ||
var types = Array.from(arguments); | ||
return this._objects.filter(function (o) { | ||
return types.indexOf(o.type) > -1; | ||
}); | ||
}, | ||
return this._objects.filter((o) => types.includes(o.type)); | ||
} | ||
|
||
/** | ||
* Returns object at specified index | ||
* @param {Number} index | ||
* @return {Object} object at index | ||
*/ | ||
item: function (index) { | ||
item(index: number) { | ||
return this._objects[index]; | ||
}, | ||
} | ||
|
||
/** | ||
* Returns true if collection contains no objects | ||
* @return {Boolean} true if collection is empty | ||
*/ | ||
isEmpty: function () { | ||
isEmpty() { | ||
return this._objects.length === 0; | ||
}, | ||
} | ||
|
||
/** | ||
* Returns a size of a collection (i.e: length of an array containing its objects) | ||
* @return {Number} Collection size | ||
*/ | ||
size: function () { | ||
size() { | ||
return this._objects.length; | ||
}, | ||
} | ||
|
||
/** | ||
* Returns true if collection contains an object.\ | ||
* **Prefer using {@link `fabric.Object#isDescendantOf`} for performance reasons** | ||
* **Prefer using {@link `FabricObject#isDescendantOf`} for performance reasons** | ||
* instead of a.contains(b) use b.isDescendantOf(a) | ||
* @param {Object} object Object to check against | ||
* @param {Boolean} [deep=false] `true` to check all descendants, `false` to check only `_objects` | ||
* @return {Boolean} `true` if collection contains an object | ||
*/ | ||
contains: function (object, deep) { | ||
if (this._objects.indexOf(object) > -1) { | ||
contains(object: FabricObject, deep?: boolean): boolean { | ||
if (this._objects.includes(object)) { | ||
return true; | ||
} else if (deep) { | ||
return this._objects.some(function (obj) { | ||
return ( | ||
typeof obj.contains === 'function' && obj.contains(object, true) | ||
); | ||
}); | ||
return this._objects.some( | ||
(obj) => obj instanceof Collection && obj.contains(object, true) | ||
); | ||
} | ||
return false; | ||
}, | ||
} | ||
|
||
/** | ||
* Returns number representation of a collection complexity | ||
* @return {Number} complexity | ||
*/ | ||
complexity: function () { | ||
return this._objects.reduce(function (memo, current) { | ||
complexity() { | ||
return this._objects.reduce((memo, current) => { | ||
memo += current.complexity ? current.complexity() : 0; | ||
return memo; | ||
}, 0); | ||
}, | ||
} | ||
}; | ||
})(typeof exports !== 'undefined' ? exports : window); | ||
} | ||
|
||
fabric.createCollectionMixin = createCollectionMixin; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.