Comparing version 6.0.0-beta7 to 6.0.0-beta8
@@ -12,2 +12,4 @@ export { getEnv, getFabricDocument, getFabricWindow, setEnv } from './src/env'; | ||
export { Canvas } from './src/canvas/Canvas'; | ||
export { CanvasDOMManager } from './src/canvas/DOMManagers/CanvasDOMManager'; | ||
export { StaticCanvasDOMManager } from './src/canvas/DOMManagers/StaticCanvasDOMManager'; | ||
export type { XY } from './src/Point'; | ||
@@ -42,2 +44,3 @@ export { Point } from './src/Point'; | ||
export { Textbox } from './src/shapes/Textbox'; | ||
export type { TextStyleDeclaration, TextStyle, } from './src/shapes/Text/StyledText'; | ||
export { Group } from './src/shapes/Group'; | ||
@@ -44,0 +47,0 @@ export { ActiveSelection } from './src/shapes/ActiveSelection'; |
@@ -8,3 +8,2 @@ import type { JpegConfig, PngConfig } from 'canvas'; | ||
createJPEGStream(opts?: JpegConfig): import("canvas").JPEGStream; | ||
destroy(): void; | ||
} | ||
@@ -21,4 +20,3 @@ /** | ||
createJPEGStream(opts?: JpegConfig): import("canvas").JPEGStream; | ||
destroy(): void; | ||
} | ||
//# sourceMappingURL=index.node.d.ts.map |
import { Point } from '../Point'; | ||
import { FabricObject } from '../shapes/Object/FabricObject'; | ||
import type { CanvasEvents, ModifierKey, TOptionalModifierKey, TPointerEvent, Transform } from '../EventTypeDefs'; | ||
import type { TCanvasSizeOptions } from './StaticCanvas'; | ||
import { StaticCanvas } from './StaticCanvas'; | ||
@@ -9,3 +10,3 @@ import type { AssertKeys, TMat2D, TOriginX, TOriginY, TSize } from '../typedefs'; | ||
import { ActiveSelection } from '../shapes/ActiveSelection'; | ||
import type { TCanvasSizeOptions } from './StaticCanvas'; | ||
import { CanvasDOMManager } from './DOMManagers/CanvasDOMManager'; | ||
export declare const DefaultCanvasProperties: { | ||
@@ -294,2 +295,3 @@ uniformScaling: boolean; | ||
* @default | ||
* @deprecated customize {@link CanvasDOMManager} instead or access {@link elements} directly | ||
*/ | ||
@@ -431,7 +433,8 @@ containerClass: string; | ||
static getDefaults(): Record<string, any>; | ||
upperCanvasEl: HTMLCanvasElement; | ||
contextTop: CanvasRenderingContext2D; | ||
wrapperEl: HTMLDivElement; | ||
protected pixelFindCanvasEl: HTMLCanvasElement; | ||
protected pixelFindContext: CanvasRenderingContext2D; | ||
elements: CanvasDOMManager; | ||
get upperCanvasEl(): HTMLCanvasElement; | ||
get contextTop(): CanvasRenderingContext2D; | ||
get wrapperEl(): HTMLDivElement; | ||
private pixelFindCanvasEl; | ||
private pixelFindContext; | ||
protected _isCurrentlyDrawing: boolean; | ||
@@ -443,3 +446,2 @@ freeDrawingBrush?: BaseBrush; | ||
protected initElements(el: string | HTMLCanvasElement): void; | ||
protected _initRetinaScaling(): void; | ||
/** | ||
@@ -615,29 +617,4 @@ * @private | ||
protected _setDimensionsImpl(dimensions: TSize, options?: TCanvasSizeOptions): void; | ||
/** | ||
* Helper for setting width/height | ||
* @private | ||
* @param {String} prop property (width|height) | ||
* @param {Number} value value to set property to | ||
*/ | ||
_setBackstoreDimension(prop: keyof TSize, value: number): void; | ||
/** | ||
* Helper for setting css width/height | ||
* @private | ||
* @param {String} prop property (width|height) | ||
* @param {String} value value to set property to | ||
*/ | ||
_setCssDimension(prop: keyof TSize, value: string): void; | ||
/** | ||
* @private | ||
* @throws {CANVAS_INIT_ERROR} If canvas can not be initialized | ||
*/ | ||
protected _createUpperCanvas(): void; | ||
protected _createCacheCanvas(): void; | ||
protected _initWrapperElement(): void; | ||
/** | ||
* @private | ||
* @param {HTMLCanvasElement} element canvas element to apply styles on | ||
*/ | ||
protected _applyCanvasStyle(element: HTMLCanvasElement): void; | ||
/** | ||
* Returns context of top canvas where interactions are drawn | ||
@@ -722,3 +699,2 @@ * @returns {CanvasRenderingContext2D} | ||
setViewportTransform(vpt: TMat2D): void; | ||
protected cleanupDOM(): void; | ||
/** | ||
@@ -725,0 +701,0 @@ * @override clears active selection ref and interactive canvas elements and contexts |
@@ -8,2 +8,4 @@ import type { CanvasEvents, StaticCanvasEvents } from '../EventTypeDefs'; | ||
import type { EnlivenObjectOptions } from '../util/misc/objectEnlive'; | ||
import { StaticCanvasDOMManager } from './DOMManagers/StaticCanvasDOMManager'; | ||
import type { CSSDimensions } from './DOMManagers/util'; | ||
export type TCanvasSizeOptions = { | ||
@@ -56,3 +58,8 @@ backstoreOnly?: boolean; | ||
item(index: number): FabricObject; | ||
isEmpty(): boolean; | ||
isEmpty(): boolean; /** | ||
* Indicates whether toObject/toDatalessObject should include default values | ||
* if set to false, takes precedence over the object value. | ||
* @type Boolean | ||
* @default | ||
*/ | ||
size(): number; | ||
@@ -216,4 +223,4 @@ contains(object: FabricObject, deep?: boolean | undefined): boolean; | ||
*/ | ||
lowerCanvasEl: HTMLCanvasElement; | ||
contextContainer: CanvasRenderingContext2D; | ||
get lowerCanvasEl(): HTMLCanvasElement; | ||
get contextContainer(): CanvasRenderingContext2D; | ||
/** | ||
@@ -243,8 +250,2 @@ * Width in virtual/logical pixels of the canvas. | ||
disposed?: boolean; | ||
/** | ||
* Keeps a copy of the canvas style before setting retina scaling and other potions | ||
* in order to return it to original state on dispose | ||
* @type string | ||
*/ | ||
_originalCanvasStyle?: string; | ||
_offset: { | ||
@@ -256,2 +257,3 @@ left: number; | ||
protected nextRenderHandle: number; | ||
elements: StaticCanvasDOMManager; | ||
static ownDefaults: Record<string, any>; | ||
@@ -280,4 +282,2 @@ protected __cleanupTask?: { | ||
getRetinaScaling(): number; | ||
protected _initRetinaScaling(): void; | ||
protected __initRetinaScaling(canvas: HTMLCanvasElement, context: CanvasRenderingContext2D): void; | ||
/** | ||
@@ -292,8 +292,2 @@ * Calculates canvas element offset relative to the document | ||
/** | ||
* Creates a bottom canvas | ||
* @private | ||
* @param {HTMLElement} [canvasEl] | ||
*/ | ||
protected _createLowerCanvas(canvasEl: HTMLCanvasElement | string): void; | ||
/** | ||
* Returns canvas width (in px) | ||
@@ -330,3 +324,3 @@ * @return {Number} | ||
*/ | ||
protected _setDimensionsImpl(dimensions: Partial<TSize>, { cssOnly, backstoreOnly }?: TCanvasSizeOptions): void; | ||
protected _setDimensionsImpl(dimensions: Partial<TSize | CSSDimensions>, { cssOnly, backstoreOnly }?: TCanvasSizeOptions): void; | ||
/** | ||
@@ -343,18 +337,2 @@ * Sets dimensions (width, height) of this canvas instance. when options.cssOnly flag active you should also supply the unit of measure (px/%/em) | ||
/** | ||
* Helper for setting width/height | ||
* @private | ||
* @param {String} prop property (width|height) | ||
* @param {Number} value value to set property to | ||
* @todo subclass in canvas and handle upperCanvasEl there. | ||
*/ | ||
_setBackstoreDimension(prop: keyof TSize, value: number): void; | ||
/** | ||
* Helper for setting css width/height | ||
* @private | ||
* @param {String} prop property (width|height) | ||
* @param {String} value value to set property to | ||
* @todo subclass in canvas and handle upperCanvasEl there. | ||
*/ | ||
_setCssDimension(prop: keyof TSize, value: string): void; | ||
/** | ||
* Returns canvas zoom level | ||
@@ -757,6 +735,2 @@ * @return {Number} | ||
/** | ||
* Invoked as part of the **sync** operation of {@link dispose}. | ||
*/ | ||
protected cleanupDOM(): void; | ||
/** | ||
* Clears the canvas element, disposes objects and frees resources. | ||
@@ -763,0 +737,0 @@ * |
@@ -20,2 +20,3 @@ import type { TMat2D } from './typedefs'; | ||
export declare const NONE = "none"; | ||
export declare const reNewline: RegExp; | ||
//# sourceMappingURL=constants.d.ts.map |
import type { TPointerEvent, TPointerEventInfo } from '../../EventTypeDefs'; | ||
import type { XY } from '../../Point'; | ||
import { Point } from '../../Point'; | ||
import type { DragMethods } from '../Object/InteractiveObject'; | ||
@@ -68,8 +67,2 @@ import { DraggableTextDelegate } from './DraggableTextDelegate'; | ||
/** | ||
* Returns coordinates of a pointer relative to object's top left corner in object's plane | ||
* @param {Point} [pointer] Pointer to operate upon | ||
* @return {Point} Coordinates of a pointer (x, y) | ||
*/ | ||
getLocalPointer(pointer: Point): Point; | ||
/** | ||
* Returns index of a character corresponding to where an object was clicked | ||
@@ -76,0 +69,0 @@ * @param {TPointerEvent} e Event object |
/** | ||
* Wraps element with another element | ||
* @param {HTMLElement} element Element to wrap | ||
* @param {HTMLElement|String} wrapper Element to wrap with | ||
* @param {Object} [attributes] Attributes to set on a wrapper | ||
* @return {HTMLElement} wrapper | ||
*/ | ||
export declare function wrapElement(element: HTMLElement, wrapper: HTMLDivElement): HTMLDivElement; | ||
/** | ||
* Returns element scroll offsets | ||
@@ -18,25 +10,4 @@ * @param {HTMLElement} element Element to operate on | ||
}; | ||
/** | ||
* Returns offset for a given element | ||
* @param {HTMLElement} element Element to get offset for | ||
* @return {Object} Object with "left" and "top" properties | ||
*/ | ||
export declare function getElementOffset(element: HTMLElement): { | ||
left: number; | ||
top: number; | ||
}; | ||
/** | ||
* Makes element unselectable | ||
* @param {HTMLElement} element Element to make unselectable | ||
* @return {HTMLElement} Element that was passed in | ||
*/ | ||
export declare function makeElementUnselectable(element: HTMLElement): HTMLElement; | ||
/** | ||
* Makes element selectable | ||
* @param {HTMLElement} element Element to make selectable | ||
* @return {HTMLElement} Element that was passed in | ||
*/ | ||
export declare function makeElementSelectable(element: HTMLElement): HTMLElement; | ||
export declare const getDocumentFromElement: (el: HTMLElement) => Document; | ||
export declare const getWindowFromElement: (el: HTMLElement) => (Window & typeof globalThis) | null; | ||
//# sourceMappingURL=dom_misc.d.ts.map |
@@ -27,3 +27,2 @@ export { cos } from './misc/cos'; | ||
export { isTouchEvent, getPointer } from './dom_event'; | ||
export { getElementOffset, makeElementUnselectable, makeElementSelectable, } from './dom_misc'; | ||
export { isTransparent } from './misc/isTransparent'; | ||
@@ -36,5 +35,4 @@ export { mergeClipPaths } from './misc/mergeClipPaths'; | ||
export { getRandomInt } from './internals/getRandomInt'; | ||
export { wrapElement } from './dom_misc'; | ||
export { request } from './dom_request'; | ||
export { removeTransformMatrixForSvgParsing } from './transform_matrix_removal'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -15,2 +15,4 @@ export { getEnv, getFabricDocument, getFabricWindow, setEnv } from './src/env'; | ||
export { Canvas } from './src/canvas/Canvas'; | ||
export { CanvasDOMManager } from './src/canvas/DOMManagers/CanvasDOMManager'; | ||
export { StaticCanvasDOMManager } from './src/canvas/DOMManagers/StaticCanvasDOMManager'; | ||
@@ -50,2 +52,6 @@ export type { XY } from './src/Point'; | ||
export { Textbox } from './src/shapes/Textbox'; | ||
export type { | ||
TextStyleDeclaration, | ||
TextStyle, | ||
} from './src/shapes/Text/StyledText'; | ||
export { Group } from './src/shapes/Group'; | ||
@@ -52,0 +58,0 @@ export { ActiveSelection } from './src/shapes/ActiveSelection'; |
// first we set the env variable by importing the node env file | ||
import { getNodeCanvas, dispose } from './src/env/node'; | ||
import { getNodeCanvas } from './src/env/node'; | ||
@@ -17,3 +17,3 @@ import type { JpegConfig, PngConfig } from 'canvas'; | ||
getNodeCanvas() { | ||
return getNodeCanvas(this.lowerCanvasEl); | ||
return getNodeCanvas(this.getElement()); | ||
} | ||
@@ -26,7 +26,2 @@ createPNGStream(opts?: PngConfig) { | ||
} | ||
destroy(): void { | ||
const canvasElement = this.lowerCanvasEl!; | ||
super.destroy(); | ||
dispose(canvasElement); | ||
} | ||
} | ||
@@ -42,3 +37,3 @@ | ||
getNodeCanvas() { | ||
return getNodeCanvas(this.lowerCanvasEl); | ||
return getNodeCanvas(this.getElement()); | ||
} | ||
@@ -51,9 +46,2 @@ createPNGStream(opts?: PngConfig) { | ||
} | ||
destroy(): void { | ||
const upperCanvasEl = this.upperCanvasEl!; | ||
const pixelFindCanvasEl = this.pixelFindCanvasEl!; | ||
super.destroy(); | ||
dispose(upperCanvasEl); | ||
dispose(pixelFindCanvasEl); | ||
} | ||
} |
@@ -5,3 +5,3 @@ { | ||
"homepage": "http://fabricjs.com/", | ||
"version": "6.0.0-beta7", | ||
"version": "6.0.0-beta8", | ||
"author": "Juriy Zaytsev <kangax@gmail.com>", | ||
@@ -8,0 +8,0 @@ "contributors": [ |
@@ -1,2 +0,1 @@ | ||
import { getFabricDocument } from '../env'; | ||
import { dragHandler } from '../controls/drag'; | ||
@@ -18,2 +17,3 @@ import { getActionFromCorner } from '../controls/util'; | ||
} from '../util/misc/objectTransforms'; | ||
import type { TCanvasSizeOptions } from './StaticCanvas'; | ||
import { StaticCanvas } from './StaticCanvas'; | ||
@@ -33,4 +33,2 @@ import { isCollection } from '../util/typeAssertions'; | ||
import type { IText } from '../shapes/IText/IText'; | ||
import { makeElementUnselectable, wrapElement } from '../util/dom_misc'; | ||
import { setStyle } from '../util/dom_style'; | ||
import type { BaseBrush } from '../brushes/BaseBrush'; | ||
@@ -41,4 +39,4 @@ import { pick } from '../util/misc/pick'; | ||
import { ActiveSelection } from '../shapes/ActiveSelection'; | ||
import type { TCanvasSizeOptions } from './StaticCanvas'; | ||
import { createCanvasElement } from '../util'; | ||
import { CanvasDOMManager } from './DOMManagers/CanvasDOMManager'; | ||
import { BOTTOM, CENTER, LEFT, NONE, RIGHT, TOP } from '../constants'; | ||
@@ -352,2 +350,3 @@ | ||
* @default | ||
* @deprecated customize {@link CanvasDOMManager} instead or access {@link elements} directly | ||
*/ | ||
@@ -512,7 +511,14 @@ declare containerClass: string; | ||
declare upperCanvasEl: HTMLCanvasElement; | ||
declare contextTop: CanvasRenderingContext2D; | ||
declare wrapperEl: HTMLDivElement; | ||
protected declare pixelFindCanvasEl: HTMLCanvasElement; | ||
protected declare pixelFindContext: CanvasRenderingContext2D; | ||
declare elements: CanvasDOMManager; | ||
get upperCanvasEl() { | ||
return this.elements.upper?.el; | ||
} | ||
get contextTop() { | ||
return this.elements.upper?.ctx; | ||
} | ||
get wrapperEl() { | ||
return this.elements.container; | ||
} | ||
private declare pixelFindCanvasEl: HTMLCanvasElement; | ||
private declare pixelFindContext: CanvasRenderingContext2D; | ||
@@ -530,14 +536,9 @@ protected declare _isCurrentlyDrawing: boolean; | ||
protected initElements(el: string | HTMLCanvasElement) { | ||
super.initElements(el); | ||
this._applyCanvasStyle(this.lowerCanvasEl); | ||
this._initWrapperElement(); | ||
this._createUpperCanvas(); | ||
this.elements = new CanvasDOMManager(el, { | ||
allowTouchScrolling: this.allowTouchScrolling, | ||
containerClass: this.containerClass, | ||
}); | ||
this._createCacheCanvas(); | ||
} | ||
protected _initRetinaScaling() { | ||
super._initRetinaScaling(); | ||
this.__initRetinaScaling(this.upperCanvasEl, this.contextTop); | ||
} | ||
/** | ||
@@ -606,3 +607,3 @@ * @private | ||
(this._objectsToRender = this._chooseObjectsToRender()); | ||
this.renderCanvas(this.contextContainer, this._objectsToRender); | ||
this.renderCanvas(this.getContext(), this._objectsToRender); | ||
} | ||
@@ -1178,51 +1179,2 @@ | ||
/** | ||
* Helper for setting width/height | ||
* @private | ||
* @param {String} prop property (width|height) | ||
* @param {Number} value value to set property to | ||
*/ | ||
_setBackstoreDimension(prop: keyof TSize, value: number) { | ||
super._setBackstoreDimension(prop, value); | ||
this.upperCanvasEl[prop] = value; | ||
} | ||
/** | ||
* Helper for setting css width/height | ||
* @private | ||
* @param {String} prop property (width|height) | ||
* @param {String} value value to set property to | ||
*/ | ||
_setCssDimension(prop: keyof TSize, value: string) { | ||
super._setCssDimension(prop, value); | ||
this.upperCanvasEl.style[prop] = value; | ||
this.wrapperEl.style[prop] = value; | ||
} | ||
/** | ||
* @private | ||
* @throws {CANVAS_INIT_ERROR} If canvas can not be initialized | ||
*/ | ||
protected _createUpperCanvas() { | ||
const lowerCanvasEl = this.lowerCanvasEl; | ||
// if there is no upperCanvas (most common case) we create one. | ||
if (!this.upperCanvasEl) { | ||
this.upperCanvasEl = createCanvasElement(); | ||
} | ||
const upperCanvasEl = this.upperCanvasEl; | ||
// we assign the same classname of the lowerCanvas | ||
upperCanvasEl.className = lowerCanvasEl.className; | ||
// but then we remove the lower-canvas specific className | ||
upperCanvasEl.classList.remove('lower-canvas'); | ||
// we add the specific upper-canvas class | ||
upperCanvasEl.classList.add('upper-canvas'); | ||
upperCanvasEl.setAttribute('data-fabric', 'top'); | ||
this.wrapperEl.appendChild(upperCanvasEl); | ||
upperCanvasEl.style.cssText = lowerCanvasEl.style.cssText; | ||
this._applyCanvasStyle(upperCanvasEl); | ||
upperCanvasEl.setAttribute('draggable', 'true'); | ||
this.contextTop = upperCanvasEl.getContext('2d')!; | ||
} | ||
protected _createCacheCanvas() { | ||
@@ -1236,38 +1188,3 @@ this.pixelFindCanvasEl = createCanvasElement(); | ||
protected _initWrapperElement() { | ||
const container = getFabricDocument().createElement('div'); | ||
container.classList.add(this.containerClass); | ||
this.wrapperEl = wrapElement(this.lowerCanvasEl, container); | ||
this.wrapperEl.setAttribute('data-fabric', 'wrapper'); | ||
setStyle(this.wrapperEl, { | ||
width: `${this.width}px`, | ||
height: `${this.height}px`, | ||
position: 'relative', | ||
}); | ||
makeElementUnselectable(this.wrapperEl); | ||
} | ||
/** | ||
* @private | ||
* @param {HTMLCanvasElement} element canvas element to apply styles on | ||
*/ | ||
protected _applyCanvasStyle(element: HTMLCanvasElement) { | ||
const width = this.width || element.width, | ||
height = this.height || element.height; | ||
setStyle(element, { | ||
position: 'absolute', | ||
width: width + 'px', | ||
height: height + 'px', | ||
left: 0, | ||
top: 0, | ||
'touch-action': this.allowTouchScrolling ? 'manipulation' : NONE, | ||
'-ms-touch-action': this.allowTouchScrolling ? 'manipulation' : NONE, | ||
}); | ||
element.width = width; | ||
element.height = height; | ||
makeElementUnselectable(element); | ||
} | ||
/** | ||
* Returns context of top canvas where interactions are drawn | ||
@@ -1277,3 +1194,3 @@ * @returns {CanvasRenderingContext2D} | ||
getTopContext(): CanvasRenderingContext2D { | ||
return this.contextTop; | ||
return this.elements.upper.ctx; | ||
} | ||
@@ -1287,3 +1204,3 @@ | ||
getSelectionContext(): CanvasRenderingContext2D { | ||
return this.contextTop; | ||
return this.elements.upper.ctx; | ||
} | ||
@@ -1296,3 +1213,3 @@ | ||
getSelectionElement(): HTMLCanvasElement { | ||
return this.upperCanvasEl; | ||
return this.elements.upper.el; | ||
} | ||
@@ -1501,14 +1418,2 @@ | ||
protected cleanupDOM(): void { | ||
const wrapperEl = this.wrapperEl!, | ||
lowerCanvasEl = this.lowerCanvasEl!, | ||
upperCanvasEl = this.upperCanvasEl!; | ||
super.cleanupDOM(); | ||
wrapperEl.removeChild(upperCanvasEl); | ||
wrapperEl.removeChild(lowerCanvasEl); | ||
if (wrapperEl.parentNode) { | ||
wrapperEl.parentNode.replaceChild(lowerCanvasEl, wrapperEl); | ||
} | ||
} | ||
/** | ||
@@ -1529,8 +1434,2 @@ * @override clears active selection ref and interactive canvas elements and contexts | ||
// top canvas | ||
// @ts-expect-error disposing | ||
this.contextTop = null; | ||
// @ts-expect-error disposing | ||
this.upperCanvasEl = undefined; | ||
// pixel find canvas | ||
@@ -1541,5 +1440,2 @@ // @ts-expect-error disposing | ||
this.pixelFindCanvasEl = undefined; | ||
// @ts-expect-error disposing | ||
this.wrapperEl = undefined; | ||
} | ||
@@ -1546,0 +1442,0 @@ |
@@ -1,2 +0,1 @@ | ||
import { getFabricDocument } from '../env'; | ||
import { config } from '../config'; | ||
@@ -29,5 +28,4 @@ import { CENTER, iMatrix, VERSION } from '../constants'; | ||
} from '../util/animation/AnimationFrameProvider'; | ||
import { getElementOffset } from '../util/dom_misc'; | ||
import { uid } from '../util/internals/uid'; | ||
import { createCanvasElement, isHTMLCanvas, toDataURL } from '../util/misc/dom'; | ||
import { createCanvasElement, toDataURL } from '../util/misc/dom'; | ||
import { invertTransform, transformPoint } from '../util/misc/matrix'; | ||
@@ -48,2 +46,4 @@ import type { EnlivenObjectOptions } from '../util/misc/objectEnlive'; | ||
} from '../util/typeAssertions'; | ||
import { StaticCanvasDOMManager } from './DOMManagers/StaticCanvasDOMManager'; | ||
import type { CSSDimensions } from './DOMManagers/util'; | ||
@@ -248,5 +248,9 @@ export type TCanvasSizeOptions = { | ||
*/ | ||
declare lowerCanvasEl: HTMLCanvasElement; | ||
get lowerCanvasEl() { | ||
return this.elements.lower?.el; | ||
} | ||
declare contextContainer: CanvasRenderingContext2D; | ||
get contextContainer() { | ||
return this.elements.lower?.ctx; | ||
} | ||
@@ -281,9 +285,2 @@ /** | ||
/** | ||
* Keeps a copy of the canvas style before setting retina scaling and other potions | ||
* in order to return it to original state on dispose | ||
* @type string | ||
*/ | ||
declare _originalCanvasStyle?: string; | ||
declare _offset: { left: number; top: number }; | ||
@@ -293,2 +290,4 @@ protected declare hasLostContext: boolean; | ||
declare elements: StaticCanvasDOMManager; | ||
static ownDefaults: Record<string, any> = StaticCanvasDefaults; | ||
@@ -315,4 +314,4 @@ | ||
this._setDimensionsImpl({ | ||
width: this.width || this.lowerCanvasEl.width || 0, | ||
height: this.height || this.lowerCanvasEl.height || 0, | ||
width: this.width || this.elements.lower.el.width || 0, | ||
height: this.height || this.elements.lower.el.height || 0, | ||
}); | ||
@@ -324,4 +323,3 @@ this.viewportTransform = [...this.viewportTransform]; | ||
protected initElements(el: string | HTMLCanvasElement) { | ||
this._createLowerCanvas(el); | ||
this._originalCanvasStyle = this.lowerCanvasEl.style.cssText; | ||
this.elements = new StaticCanvasDOMManager(el); | ||
} | ||
@@ -388,16 +386,2 @@ | ||
protected _initRetinaScaling() { | ||
this.__initRetinaScaling(this.lowerCanvasEl, this.contextContainer); | ||
} | ||
protected __initRetinaScaling( | ||
canvas: HTMLCanvasElement, | ||
context: CanvasRenderingContext2D | ||
) { | ||
const scaleRatio = config.devicePixelRatio; | ||
canvas.setAttribute('width', (this.width * scaleRatio).toString()); | ||
canvas.setAttribute('height', (this.height * scaleRatio).toString()); | ||
context.scale(scaleRatio, scaleRatio); | ||
} | ||
/** | ||
@@ -408,32 +392,6 @@ * Calculates canvas element offset relative to the document | ||
calcOffset() { | ||
return (this._offset = getElementOffset(this.lowerCanvasEl)); | ||
return (this._offset = this.elements.calcOffset()); | ||
} | ||
/** | ||
* Creates a bottom canvas | ||
* @private | ||
* @param {HTMLElement} [canvasEl] | ||
*/ | ||
protected _createLowerCanvas(canvasEl: HTMLCanvasElement | string) { | ||
// canvasEl === 'HTMLCanvasElement' does not work on jsdom/node | ||
if (isHTMLCanvas(canvasEl)) { | ||
this.lowerCanvasEl = canvasEl; | ||
} else { | ||
this.lowerCanvasEl = | ||
(getFabricDocument().getElementById(canvasEl) as HTMLCanvasElement) || | ||
createCanvasElement(); | ||
} | ||
if (this.lowerCanvasEl.hasAttribute('data-fabric')) { | ||
/* _DEV_MODE_START_ */ | ||
throw new Error( | ||
'fabric.js: trying to initialize a canvas that has already been initialized' | ||
); | ||
/* _DEV_MODE_END_ */ | ||
} | ||
this.lowerCanvasEl.classList.add('lower-canvas'); | ||
this.lowerCanvasEl.setAttribute('data-fabric', 'main'); | ||
this.contextContainer = this.lowerCanvasEl.getContext('2d')!; | ||
} | ||
/** | ||
* Returns canvas width (in px) | ||
@@ -483,20 +441,20 @@ * @return {Number} | ||
protected _setDimensionsImpl( | ||
dimensions: Partial<TSize>, | ||
dimensions: Partial<TSize | CSSDimensions>, | ||
{ cssOnly = false, backstoreOnly = false }: TCanvasSizeOptions = {} | ||
) { | ||
Object.entries(dimensions).forEach(([prop, value]) => { | ||
let cssValue = `${value}`; | ||
if (!cssOnly) { | ||
const size = { | ||
width: this.width, | ||
height: this.height, | ||
...(dimensions as Partial<TSize>), | ||
}; | ||
this.elements.setDimensions(size, this.getRetinaScaling()); | ||
this.hasLostContext = true; | ||
this.width = size.width; | ||
this.height = size.height; | ||
} | ||
if (!backstoreOnly) { | ||
this.elements.setCSSDimensions(dimensions); | ||
} | ||
if (!cssOnly) { | ||
this._setBackstoreDimension(prop as keyof TSize, value); | ||
cssValue += 'px'; | ||
this.hasLostContext = true; | ||
} | ||
if (!backstoreOnly) { | ||
this._setCssDimension(prop as keyof TSize, cssValue); | ||
} | ||
}); | ||
this._isRetinaScaling() && this._initRetinaScaling(); | ||
this.calcOffset(); | ||
@@ -528,25 +486,2 @@ } | ||
/** | ||
* Helper for setting width/height | ||
* @private | ||
* @param {String} prop property (width|height) | ||
* @param {Number} value value to set property to | ||
* @todo subclass in canvas and handle upperCanvasEl there. | ||
*/ | ||
_setBackstoreDimension(prop: keyof TSize, value: number) { | ||
this.lowerCanvasEl[prop] = value; | ||
this[prop] = value; | ||
} | ||
/** | ||
* Helper for setting css width/height | ||
* @private | ||
* @param {String} prop property (width|height) | ||
* @param {String} value value to set property to | ||
* @todo subclass in canvas and handle upperCanvasEl there. | ||
*/ | ||
_setCssDimension(prop: keyof TSize, value: string) { | ||
this.lowerCanvasEl.style[prop] = value; | ||
} | ||
/** | ||
* Returns canvas zoom level | ||
@@ -641,3 +576,3 @@ * @return {Number} | ||
getElement(): HTMLCanvasElement { | ||
return this.lowerCanvasEl; | ||
return this.elements.lower.el; | ||
} | ||
@@ -658,3 +593,3 @@ | ||
getContext(): CanvasRenderingContext2D { | ||
return this.contextContainer; | ||
return this.elements.lower.ctx; | ||
} | ||
@@ -671,3 +606,3 @@ | ||
this.overlayColor = ''; | ||
this.clearContext(this.contextContainer); | ||
this.clearContext(this.getContext()); | ||
this.fire('canvas:cleared'); | ||
@@ -685,3 +620,3 @@ this.renderOnAddRemove && this.requestRenderAll(); | ||
} | ||
this.renderCanvas(this.contextContainer, this._objects); | ||
this.renderCanvas(this.getContext(), this._objects); | ||
} | ||
@@ -1652,3 +1587,4 @@ | ||
dispose() { | ||
!this.disposed && this.cleanupDOM(); | ||
!this.disposed && | ||
this.elements.cleanupDOM({ width: this.width, height: this.height }); | ||
this.disposed = true; | ||
@@ -1676,17 +1612,2 @@ return new Promise<boolean>((resolve, reject) => { | ||
/** | ||
* Invoked as part of the **sync** operation of {@link dispose}. | ||
*/ | ||
protected cleanupDOM() { | ||
const canvasElement = this.lowerCanvasEl!; | ||
// restore canvas style and attributes | ||
canvasElement.classList.remove('lower-canvas'); | ||
canvasElement.removeAttribute('data-fabric'); | ||
// restore canvas size to original size in case retina scaling was applied | ||
canvasElement.setAttribute('width', `${this.width}`); | ||
canvasElement.setAttribute('height', `${this.height}`); | ||
canvasElement.style.cssText = this._originalCanvasStyle || ''; | ||
this._originalCanvasStyle = undefined; | ||
} | ||
/** | ||
* Clears the canvas element, disposes objects and frees resources. | ||
@@ -1718,6 +1639,3 @@ * | ||
this.overlayImage = null; | ||
// @ts-expect-error disposing | ||
this.contextContainer = null; | ||
// @ts-expect-error disposing | ||
this.lowerCanvasEl = undefined; | ||
this.elements.dispose(); | ||
} | ||
@@ -1724,0 +1642,0 @@ |
import type { TPointerEvent } from '../EventTypeDefs'; | ||
import type { ITextBehavior } from '../shapes/IText/ITextBehavior'; | ||
import { removeFromArray } from '../util/internals'; | ||
import { isInteractiveTextObject } from '../util/typeAssertions'; | ||
import type { Canvas } from './Canvas'; | ||
@@ -15,3 +16,8 @@ | ||
constructor(canvas: Canvas) { | ||
const cb = () => this.target?.hiddenTextarea?.focus(); | ||
const cb = () => { | ||
const activeObject = canvas.getActiveObject(); | ||
if (isInteractiveTextObject(activeObject)) { | ||
activeObject.hiddenTextarea && activeObject.hiddenTextarea.focus(); | ||
} | ||
}; | ||
const el = canvas.upperCanvasEl; | ||
@@ -18,0 +24,0 @@ el.addEventListener('click', cb); |
@@ -28,1 +28,3 @@ import type { TMat2D } from './typedefs'; | ||
export const NONE = 'none'; | ||
export const reNewline = /\r?\n/; |
@@ -6,3 +6,3 @@ import type { TPointerEvent, TPointerEventInfo } from '../../EventTypeDefs'; | ||
import { stopEvent } from '../../util/dom_event'; | ||
import { invertTransform, transformPoint } from '../../util/misc/matrix'; | ||
import { invertTransform } from '../../util/misc/matrix'; | ||
import { DraggableTextDelegate } from './DraggableTextDelegate'; | ||
@@ -235,14 +235,2 @@ import type { ITextEvents } from './ITextBehavior'; | ||
/** | ||
* Returns coordinates of a pointer relative to object's top left corner in object's plane | ||
* @param {Point} [pointer] Pointer to operate upon | ||
* @return {Point} Coordinates of a pointer (x, y) | ||
*/ | ||
getLocalPointer(pointer: Point): Point { | ||
return transformPoint( | ||
pointer, | ||
invertTransform(this.calcTransformMatrix()) | ||
).add(new Point(this.width / 2, this.height / 2)); | ||
} | ||
/** | ||
* Returns index of a character corresponding to where an object was clicked | ||
@@ -253,3 +241,5 @@ * @param {TPointerEvent} e Event object | ||
getSelectionStartFromPointer(e: TPointerEvent): number { | ||
const mouseOffset = this.getLocalPointer(this.canvas!.getPointer(e)); | ||
const mouseOffset = this.canvas!.getPointer(e) | ||
.transform(invertTransform(this.calcTransformMatrix())) | ||
.add(new Point(-this._getLeftOffset(), -this._getTopOffset())); | ||
let height = 0, | ||
@@ -273,9 +263,2 @@ charIndex = 0, | ||
const jlen = this._textLines[lineIndex].length; | ||
// handling of RTL: in order to get things work correctly, | ||
// we assume RTL writing is mirrored compared to LTR writing. | ||
// so in position detection we mirror the X offset, and when is time | ||
// of rendering it, we mirror it again. | ||
if (this.direction === 'rtl') { | ||
mouseOffset.x = this.width - mouseOffset.x; | ||
} | ||
let prevWidth = 0; | ||
@@ -282,0 +265,0 @@ for (let j = 0; j < jlen; j++) { |
@@ -1,2 +0,2 @@ | ||
import { LEFT } from '../../constants'; | ||
import { LEFT, reNewline } from '../../constants'; | ||
import type { TClassProperties } from '../../typedefs'; | ||
@@ -66,3 +66,3 @@ import type { Text } from './Text'; | ||
export const textDefaultValues: Partial<TClassProperties<Text>> = { | ||
_reNewline: /\r?\n/, | ||
_reNewline: reNewline, | ||
_reSpacesAndTabs: /[ \t\r]/g, | ||
@@ -69,0 +69,0 @@ _reSpaceAndTab: /[ \t\r]/, |
@@ -1,19 +0,2 @@ | ||
import { LEFT, TOP, NONE } from '../constants'; | ||
/** | ||
* Wraps element with another element | ||
* @param {HTMLElement} element Element to wrap | ||
* @param {HTMLElement|String} wrapper Element to wrap with | ||
* @param {Object} [attributes] Attributes to set on a wrapper | ||
* @return {HTMLElement} wrapper | ||
*/ | ||
export function wrapElement(element: HTMLElement, wrapper: HTMLDivElement) { | ||
if (element.parentNode) { | ||
element.parentNode.replaceChild(wrapper, element); | ||
} | ||
wrapper.appendChild(element); | ||
return wrapper; | ||
} | ||
/** | ||
* Returns element scroll offsets | ||
@@ -57,68 +40,2 @@ * @param {HTMLElement} element Element to operate on | ||
/** | ||
* Returns offset for a given element | ||
* @param {HTMLElement} element Element to get offset for | ||
* @return {Object} Object with "left" and "top" properties | ||
*/ | ||
export function getElementOffset(element: HTMLElement) { | ||
let box = { left: 0, top: 0 }; | ||
const doc = element && getDocumentFromElement(element), | ||
offset = { left: 0, top: 0 }, | ||
offsetAttributes = { | ||
borderLeftWidth: LEFT, | ||
borderTopWidth: TOP, | ||
paddingLeft: LEFT, | ||
paddingTop: TOP, | ||
} as const; | ||
if (!doc) { | ||
return offset; | ||
} | ||
const elemStyle = | ||
getWindowFromElement(element)?.getComputedStyle(element, null) || {}; | ||
for (const attr in offsetAttributes) { | ||
// @ts-expect-error TS learn to iterate! | ||
offset[offsetAttributes[attr]] += parseInt(elemStyle[attr], 10) || 0; | ||
} | ||
const docElem = doc.documentElement; | ||
if (typeof element.getBoundingClientRect !== 'undefined') { | ||
box = element.getBoundingClientRect(); | ||
} | ||
const scrollLeftTop = getScrollLeftTop(element); | ||
return { | ||
left: | ||
box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left, | ||
top: box.top + scrollLeftTop.top - (docElem.clientTop || 0) + offset.top, | ||
}; | ||
} | ||
/** | ||
* Makes element unselectable | ||
* @param {HTMLElement} element Element to make unselectable | ||
* @return {HTMLElement} Element that was passed in | ||
*/ | ||
export function makeElementUnselectable(element: HTMLElement) { | ||
if (typeof element.onselectstart !== 'undefined') { | ||
element.onselectstart = () => false; | ||
} | ||
element.style.userSelect = NONE; | ||
return element; | ||
} | ||
/** | ||
* Makes element selectable | ||
* @param {HTMLElement} element Element to make selectable | ||
* @return {HTMLElement} Element that was passed in | ||
*/ | ||
export function makeElementSelectable(element: HTMLElement) { | ||
if (typeof element.onselectstart !== 'undefined') { | ||
element.onselectstart = null; | ||
} | ||
element.style.userSelect = ''; | ||
return element; | ||
} | ||
export const getDocumentFromElement = (el: HTMLElement) => | ||
@@ -125,0 +42,0 @@ el.ownerDocument || null; |
@@ -93,8 +93,2 @@ export { cos } from './misc/cos'; | ||
export { isTouchEvent, getPointer } from './dom_event'; | ||
export { | ||
// getScrollLeftTop, | ||
getElementOffset, | ||
makeElementUnselectable, | ||
makeElementSelectable, | ||
} from './dom_misc'; | ||
export { isTransparent } from './misc/isTransparent'; | ||
@@ -110,3 +104,2 @@ export { mergeClipPaths } from './misc/mergeClipPaths'; | ||
export { getRandomInt } from './internals/getRandomInt'; | ||
export { wrapElement } from './dom_misc'; | ||
export { request } from './dom_request'; | ||
@@ -113,0 +106,0 @@ |
@@ -0,1 +1,2 @@ | ||
import { reNewline } from '../../constants'; | ||
import type { | ||
@@ -104,3 +105,3 @@ TextStyle, | ||
} | ||
const textLines = text.split('\n'), | ||
const textLines = text.split(reNewline), | ||
stylesObject: TextStyle = {}; | ||
@@ -107,0 +108,0 @@ let charIndex = -1, |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
14137105
532
162335
12