-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(rx): add creation functions for intersection-, resize-, and muta…
…tion observer
- Loading branch information
1 parent
77b2d88
commit a71a0ff
Showing
9 changed files
with
214 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# @code-workers.io/angular-kit/rx/platform | ||
|
||
A set of reactive helpers wrapping browser APIs. |
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 |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"lib": { | ||
"entryFile": "src/index.ts" | ||
} | ||
} |
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 |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export * from './lib/create-resize-observer'; | ||
export * from './lib/create-intersection-observer'; | ||
export * from './lib/create-mutation-observer'; | ||
|
||
export * from './lib/directives/observe-resize.directive'; | ||
export * from './lib/directives/observe-intersection.directive'; |
26 changes: 26 additions & 0 deletions
26
libs/rx/platform/src/lib/create-intersection-observer.spec.ts
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 |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import {createElementRef, mockIntersectionObserver} from '@angular-kit/testing'; | ||
import {createIntersectionObserver} from './create-intersection-observer'; | ||
import {subscribeSpyTo} from '@hirez_io/observer-spy'; | ||
import {fakeAsync, tick} from '@angular/core/testing'; | ||
|
||
describe('createIntersectionObserver', () => { | ||
describe('supported', () => { | ||
beforeEach(() => mockIntersectionObserver()); | ||
it('should create', () => { | ||
const observer = createIntersectionObserver(createElementRef()); | ||
expect(observer).toBeTruthy(); | ||
}); | ||
|
||
it('should emit on intersect', fakeAsync(() => { | ||
const elementRef = createElementRef(); | ||
const observer = createIntersectionObserver(elementRef); | ||
|
||
const result = subscribeSpyTo(observer); | ||
elementRef.nativeElement.dispatchEvent(new Event('intersect')); | ||
|
||
tick(1000); | ||
|
||
expect(result.getValues().length).toEqual(1); | ||
})); | ||
}); | ||
}); |
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 |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import {debounceTime, Observable, ReplaySubject, SchedulerLike, share} from 'rxjs'; | ||
import {ElementRef} from '@angular/core'; | ||
|
||
const DEFAULT_THROTTLE_TIME = 125; | ||
|
||
export function supportsIntersectionObserver() { | ||
return typeof window.IntersectionObserver !== 'undefined'; | ||
} | ||
|
||
export function createIntersectionObserver( | ||
observeElement: ElementRef, | ||
options?: IntersectionObserverInit, | ||
cfg?: { | ||
throttleMs?: number; | ||
scheduler?: SchedulerLike; | ||
} | ||
): Observable<IntersectionObserverEntry[]> { | ||
if (!supportsIntersectionObserver()) { | ||
throw new Error('[AngularKit] IntersectionObserver is not supported in this browser'); | ||
} | ||
const obs$ = new Observable<IntersectionObserverEntry[]>((subscriber) => { | ||
const intersectionObserver = new IntersectionObserver((entries) => { | ||
subscriber.next(entries); | ||
}, options ?? {}); | ||
|
||
intersectionObserver.observe(observeElement.nativeElement); | ||
|
||
return () => intersectionObserver.disconnect(); | ||
}); | ||
|
||
return obs$.pipe( | ||
cfg?.throttleMs ? debounceTime(cfg?.throttleMs, cfg?.scheduler) : debounceTime(DEFAULT_THROTTLE_TIME), | ||
share({ | ||
connector: () => new ReplaySubject(1), | ||
resetOnComplete: false, | ||
resetOnError: false, | ||
resetOnRefCountZero: false, | ||
}) | ||
); | ||
} |
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 |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import {createMutationObserver} from './create-mutation-observer'; | ||
import {subscribeSpyTo} from '@hirez_io/observer-spy'; | ||
import {createElementRef, mockMutationObserver} from '@angular-kit/testing'; | ||
import {fakeAsync, tick} from '@angular/core/testing'; | ||
|
||
describe('createMutationObserver', () => { | ||
describe('supported', () => { | ||
beforeEach(() => mockMutationObserver()); | ||
it('should create', () => { | ||
const observer = createMutationObserver(createElementRef()); | ||
expect(observer).toBeTruthy(); | ||
}); | ||
|
||
it('should emit on resize', fakeAsync(() => { | ||
const elementRef = createElementRef(); | ||
const observer = createMutationObserver(elementRef); | ||
|
||
const result = subscribeSpyTo(observer); | ||
elementRef.nativeElement.dispatchEvent(new Event('mutate')); | ||
|
||
tick(1000); | ||
|
||
expect(result.getValues().length).toEqual(1); | ||
})); | ||
}); | ||
}); |
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 |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import {debounceTime, Observable, ReplaySubject, SchedulerLike, share} from 'rxjs'; | ||
import {ElementRef} from '@angular/core'; | ||
|
||
const DEFAULT_THROTTLE_TIME = 125; | ||
|
||
export function supportsMutationObserver() { | ||
return typeof window.MutationObserver !== 'undefined'; | ||
} | ||
|
||
export function createMutationObserver( | ||
observeElement: ElementRef, | ||
options?: MutationObserverInit, | ||
cfg?: { | ||
throttleMs?: number; | ||
scheduler?: SchedulerLike; | ||
} | ||
): Observable<MutationRecord[]> { | ||
if (!supportsMutationObserver()) { | ||
throw new Error('[AngularKit] MutationObserver is not supported in this browser'); | ||
} | ||
const obs$ = new Observable<MutationRecord[]>((subscriber) => { | ||
const mutationObserver = new MutationObserver((entries) => { | ||
subscriber.next(entries); | ||
}); | ||
|
||
mutationObserver.observe(observeElement.nativeElement, options ?? {}); | ||
|
||
return () => mutationObserver.disconnect(); | ||
}); | ||
|
||
return obs$.pipe( | ||
cfg?.throttleMs ? debounceTime(cfg?.throttleMs, cfg?.scheduler) : debounceTime(DEFAULT_THROTTLE_TIME), | ||
share({ | ||
connector: () => new ReplaySubject(1), | ||
resetOnComplete: false, | ||
resetOnError: false, | ||
resetOnRefCountZero: false, | ||
}) | ||
); | ||
} |
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 |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import {createResizeObserver} from './create-resize-observer'; | ||
import {fakeAsync, tick} from '@angular/core/testing'; | ||
import {subscribeSpyTo} from '@hirez_io/observer-spy'; | ||
import {createElementRef, mockResizeObserver} from '@angular-kit/testing'; | ||
|
||
describe('createResizeObserver', () => { | ||
describe('supported', () => { | ||
beforeEach(() => mockResizeObserver()); | ||
it('should create', () => { | ||
const observer = createResizeObserver(createElementRef()); | ||
expect(observer).toBeTruthy(); | ||
}); | ||
|
||
it('should emit on resize', fakeAsync(() => { | ||
const elementRef = createElementRef(); | ||
const observer = createResizeObserver(elementRef); | ||
|
||
const result = subscribeSpyTo(observer); | ||
elementRef.nativeElement.dispatchEvent(new Event('resize')); | ||
|
||
tick(1000); | ||
|
||
expect(result.getValues().length).toEqual(1); | ||
})); | ||
}); | ||
}); |
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 |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import {ElementRef} from '@angular/core'; | ||
import {debounceTime, distinctUntilChanged, Observable, ReplaySubject, SchedulerLike, share} from 'rxjs'; | ||
|
||
const DEFAULT_THROTTLE_TIME = 50; | ||
|
||
export function supportsResizeObserver() { | ||
return typeof window.ResizeObserver !== 'undefined'; | ||
} | ||
|
||
export type ResizeObserverConfig = { | ||
throttleMs?: number; | ||
scheduler?: SchedulerLike; | ||
}; | ||
|
||
export function createResizeObserver( | ||
observeElement: ElementRef, | ||
cfg?: ResizeObserverConfig | ||
): Observable<ResizeObserverEntry[]> { | ||
if (!supportsResizeObserver()) { | ||
throw new Error('[AngularKit] ResizeObserver is not supported in this browser'); | ||
} | ||
const obs$ = new Observable<ResizeObserverEntry[]>((subscriber) => { | ||
const resizeObserver = new ResizeObserver((entries) => { | ||
subscriber.next(entries); | ||
}); | ||
|
||
resizeObserver.observe(observeElement.nativeElement); | ||
|
||
return () => resizeObserver.disconnect(); | ||
}); | ||
|
||
return obs$.pipe( | ||
distinctUntilChanged(), | ||
cfg?.throttleMs ? debounceTime(cfg?.throttleMs, cfg?.scheduler) : debounceTime(DEFAULT_THROTTLE_TIME), | ||
share({ | ||
connector: () => new ReplaySubject(1), | ||
resetOnComplete: false, | ||
resetOnError: false, | ||
resetOnRefCountZero: false, | ||
}) | ||
); | ||
} |