Skip to content

Commit

Permalink
fix: create a clone of the ghost element instead of applying styling …
Browse files Browse the repository at this point in the history
…to the host

BREAKING CHANGE: `enableResizeStyling` has been renamed to `enableGhostResize`

Closes #15
  • Loading branch information
Matt Lewis committed Jul 15, 2016
1 parent dedc3bb commit fa73345
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 59 deletions.
66 changes: 24 additions & 42 deletions src/resizable.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ export class ResizeHandle {
* For example
*
* ```
* <div mwl-resizable [resizeEdges]="{bottom: true, right: true, top: true, left: true}" [enableResizeStyling]="true"></div>
* <div mwl-resizable [resizeEdges]="{bottom: true, right: true, top: true, left: true}" [enableGhostResize]="true"></div>
* ```
*/
@Directive({
Expand All @@ -241,7 +241,7 @@ export class Resizable implements OnInit, AfterViewInit {
/**
* Set to `true` to enable a temporary resizing effect of the element in between the `onResizeStart` and `onResizeEnd` events.
*/
@Input() enableResizeStyling: boolean = false;
@Input() enableGhostResize: boolean = false;

/**
* A snap grid that resize events will be locked to.
Expand Down Expand Up @@ -299,25 +299,13 @@ export class Resizable implements OnInit, AfterViewInit {
edges: Edges,
startingRect: BoundingRectangle,
currentRect: BoundingRectangle,
originalStyles: {
position: string,
left: string,
top: string,
width: string,
height: string,
'user-drag': string,
'-webkit-user-drag': string
}
clonedNode?: HTMLElement
};

const resetElementStyles: Function = (): void => {
if (this.enableResizeStyling) {
for (let key in currentResize.originalStyles) {
const value: string = currentResize.originalStyles[key];
if (typeof value !== 'undefined') {
this.renderer.setElementStyle(this.elm.nativeElement, key, currentResize.originalStyles[key]);
}
}
const removeGhostElement: Function = (): void => {
if (currentResize.clonedNode) {
this.elm.nativeElement.parentElement.removeChild(currentResize.clonedNode);
this.renderer.setElementStyle(this.elm.nativeElement, 'visibility', 'inherit');
}
};

Expand Down Expand Up @@ -407,11 +395,11 @@ export class Resizable implements OnInit, AfterViewInit {
}) : true;
}).subscribe((newBoundingRect: BoundingRectangle) => {

if (this.enableResizeStyling) {
this.renderer.setElementStyle(this.elm.nativeElement, 'height', `${newBoundingRect.height}px`);
this.renderer.setElementStyle(this.elm.nativeElement, 'width', `${newBoundingRect.width}px`);
this.renderer.setElementStyle(this.elm.nativeElement, 'top', `${newBoundingRect.top}px`);
this.renderer.setElementStyle(this.elm.nativeElement, 'left', `${newBoundingRect.left}px`);
if (currentResize.clonedNode) {
this.renderer.setElementStyle(currentResize.clonedNode, 'height', `${newBoundingRect.height}px`);
this.renderer.setElementStyle(currentResize.clonedNode, 'width', `${newBoundingRect.width}px`);
this.renderer.setElementStyle(currentResize.clonedNode, 'top', `${newBoundingRect.top}px`);
this.renderer.setElementStyle(currentResize.clonedNode, 'left', `${newBoundingRect.left}px`);
}

this.onResize.emit({
Expand All @@ -433,29 +421,23 @@ export class Resizable implements OnInit, AfterViewInit {
return Object.keys(edges).length > 0;
}).subscribe((edges: Edges) => {
if (currentResize) {
resetElementStyles();
removeGhostElement();
}
const startingRect: BoundingRectangle = this.elm.nativeElement.getBoundingClientRect();
currentResize = {
edges,
startingRect,
currentRect: startingRect,
originalStyles: {
position: this.elm.nativeElement.style.position,
left: this.elm.nativeElement.style.left,
top: this.elm.nativeElement.style.top,
width: `${startingRect.width}px`,
height: `${startingRect.height}px`,
'user-drag': this.elm.nativeElement.style['user-drag'],
'-webkit-user-drag': this.elm.nativeElement.style['-webkit-user-drag']
}
currentRect: startingRect
};
if (this.enableResizeStyling) {
this.renderer.setElementStyle(this.elm.nativeElement, 'position', 'fixed');
this.renderer.setElementStyle(this.elm.nativeElement, 'left', `${currentResize.startingRect.left}px`);
this.renderer.setElementStyle(this.elm.nativeElement, 'top', `${currentResize.startingRect.top}px`);
this.renderer.setElementStyle(this.elm.nativeElement, 'user-drag', 'none');
this.renderer.setElementStyle(this.elm.nativeElement, '-webkit-user-drag', 'none');
if (this.enableGhostResize) {
currentResize.clonedNode = this.elm.nativeElement.cloneNode(true);
this.elm.nativeElement.parentElement.appendChild(currentResize.clonedNode);
this.renderer.setElementStyle(this.elm.nativeElement, 'visibility', 'hidden');
this.renderer.setElementStyle(currentResize.clonedNode, 'position', 'fixed');
this.renderer.setElementStyle(currentResize.clonedNode, 'left', `${currentResize.startingRect.left}px`);
this.renderer.setElementStyle(currentResize.clonedNode, 'top', `${currentResize.startingRect.top}px`);
this.renderer.setElementStyle(currentResize.clonedNode, 'user-drag', 'none');
this.renderer.setElementStyle(currentResize.clonedNode, '-webkit-user-drag', 'none');
}
this.onResizeStart.emit({
edges: getEdgesDiff({edges, initialRectangle: startingRect, newRectangle: startingRect}),
Expand All @@ -473,7 +455,7 @@ export class Resizable implements OnInit, AfterViewInit {
}),
rectangle: currentResize.currentRect
});
resetElementStyles();
removeGhostElement();
currentResize = null;
}
});
Expand Down
25 changes: 8 additions & 17 deletions test/resizable.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe('resizable directive', () => {
mwl-resizable
[validateResize]="validate"
[resizeEdges]="resizeEdges"
[enableResizeStyling]="enableResizeStyling"
[enableGhostResize]="enableGhostResize"
[resizeSnapGrid]="resizeSnapGrid"
(onResizeStart)="onResizeStart($event)"
(onResize)="onResize($event)"
Expand All @@ -47,7 +47,7 @@ describe('resizable directive', () => {
public onResizeEnd: Function = sinon.spy();
public validate: Function = sinon.stub().returns(true);
public resizeEdges: Edges = {top: true, bottom: true, left: true, right: true};
public enableResizeStyling: boolean = true;
public enableGhostResize: boolean = true;
public resizeSnapGrid: Object = {};

}
Expand Down Expand Up @@ -474,11 +474,11 @@ describe('resizable directive', () => {
domEvents.forEach(event => {
triggerDomEvent(event.name, elm, event.data);
if (event.name !== 'mouseup') {
expect(elm.style.position).to.equal('fixed');
expect(elm.nextSibling['style'].position).to.equal('fixed');
}
if (event.style) {
Object.keys(event.style).forEach(styleKey => {
expect(elm.style[styleKey]).to.equal(event.style[styleKey]);
expect(elm.nextSibling['style'][styleKey]).to.equal(event.style[styleKey]);
});
}
});
Expand Down Expand Up @@ -544,14 +544,13 @@ describe('resizable directive', () => {
clientX: 98,
clientY: 205
});
expect(elm.style.width).to.equal('302px');
expect(elm.nextSibling['style'].width).to.equal('302px');
fixture.componentInstance.onResizeEnd.reset();
triggerDomEvent('mousedown', elm, {
clientX: 100,
clientY: 205
});
expect(fixture.componentInstance.onResizeEnd).not.to.have.been.called;
expect(elm.style.width).to.equal('300px');
expect(fixture.componentInstance.onResizeStart).to.have.been.calledWith({
edges: {
left: 0
Expand Down Expand Up @@ -607,21 +606,13 @@ describe('resizable directive', () => {
clientY: 199
});
let elmStyle: CSSStyleDeclaration = getComputedStyle(elm);
expect(elmStyle.position).to.equal('fixed');
expect(elmStyle.top).to.equal('199px');
expect(elmStyle.left).to.equal('99px');
expect(elmStyle.height).to.equal('151px');
expect(elmStyle.width).to.equal('301px');
expect(elmStyle.visibility).to.equal('hidden');
triggerDomEvent('mouseup', elm, {
clientX: 99,
clientY: 199
});
elmStyle = getComputedStyle(elm);
expect(elmStyle.position).to.equal('relative');
expect(elmStyle.top).to.equal('200px');
expect(elmStyle.left).to.equal('100px');
expect(elmStyle.height).to.equal('150px');
expect(elmStyle.width).to.equal('300px');
expect(elmStyle.visibility).to.equal('visible');
});

}));
Expand Down Expand Up @@ -882,7 +873,7 @@ describe('resizable directive', () => {
it('should disable the temporary resize effect applied to the element', async(() => {

createComponent().then((fixture: ComponentFixture<TestCmp>) => {
fixture.componentInstance.enableResizeStyling = false;
fixture.componentInstance.enableGhostResize = false;
fixture.detectChanges();
const elm: HTMLElement = fixture.componentInstance.resizable.elm.nativeElement;
triggerDomEvent('mousedown', elm, {
Expand Down

0 comments on commit fa73345

Please sign in to comment.