Browse Source

feat(core): add fromLazyLoad utility function

pull/3453/head
Arman Ozak 7 years ago
parent
commit
b55bc42779
  1. 105
      npm/ng-packs/packages/core/src/lib/tests/lazy-load-utils.spec.ts
  2. 1
      npm/ng-packs/packages/core/src/lib/utils/index.ts
  3. 54
      npm/ng-packs/packages/core/src/lib/utils/lazy-load-utils.ts

105
npm/ng-packs/packages/core/src/lib/tests/lazy-load-utils.spec.ts

@ -0,0 +1,105 @@
import { DomStrategy, DOM_STRATEGY } from '../strategies';
import { CrossOriginStrategy, CROSS_ORIGIN_STRATEGY } from '../strategies/cross-origin.strategy';
import { uuid } from '../utils';
import { fromLazyLoad } from '../utils/lazy-load-utils';
describe('Lazy Load Utils', () => {
describe('#fromLazyLoad', () => {
afterEach(() => {
jest.clearAllMocks();
});
it('should append to head by default', () => {
const element = document.createElement('link');
const spy = jest.spyOn(document.head, 'insertAdjacentElement');
fromLazyLoad(element);
expect(spy).toHaveBeenCalledWith('beforeend', element);
});
it('should allow setting a dom strategy', () => {
const element = document.createElement('link');
const spy = jest.spyOn(document.head, 'insertAdjacentElement');
fromLazyLoad(element, DOM_STRATEGY.PrependToHead());
expect(spy).toHaveBeenCalledWith('afterbegin', element);
});
it('should set crossorigin to "anonymous" by default', () => {
const element = document.createElement('link');
fromLazyLoad(element);
expect(element.crossOrigin).toBe('anonymous');
});
it('should allow setting a crossorigin strategy', () => {
const element = document.createElement('link');
const integrity = uuid();
fromLazyLoad(element, undefined, CROSS_ORIGIN_STRATEGY.UseCredentials(integrity));
expect(element.crossOrigin).toBe('use-credentials');
expect(element.getAttribute('integrity')).toBe(integrity);
});
it('should emit error event on fail and clear callbacks', done => {
const error = new CustomEvent('error');
const parentNode = { removeChild: jest.fn() };
const element = ({ parentNode } as any) as HTMLLinkElement;
fromLazyLoad(
element,
{
insertElement(el: HTMLLinkElement) {
expect(el).toBe(element);
setTimeout(() => {
el.onerror(error);
}, 0);
},
} as DomStrategy,
{
setCrossOrigin(el: HTMLLinkElement) {},
} as CrossOriginStrategy,
).subscribe({
error: value => {
expect(value).toBe(error);
expect(parentNode.removeChild).toHaveBeenCalledWith(element);
expect(element.onerror).toBeNull();
done();
},
});
});
it('should emit load event on success and clear callbacks', done => {
const success = new CustomEvent('load');
const parentNode = { removeChild: jest.fn() };
const element = ({ parentNode } as any) as HTMLLinkElement;
fromLazyLoad(
element,
{
insertElement(el: HTMLLinkElement) {
expect(el).toBe(element);
setTimeout(() => {
el.onload(success);
}, 0);
},
} as DomStrategy,
{
setCrossOrigin(el: HTMLLinkElement) {},
} as CrossOriginStrategy,
).subscribe({
next: value => {
expect(value).toBe(success);
expect(parentNode.removeChild).not.toHaveBeenCalled();
expect(element.onload).toBeNull();
done();
},
});
});
});
});

1
npm/ng-packs/packages/core/src/lib/utils/index.ts

@ -1,5 +1,6 @@
export * from './common-utils';
export * from './generator-utils';
export * from './initial-utils';
export * from './lazy-load-utils';
export * from './route-utils';
export * from './rxjs-utils';

54
npm/ng-packs/packages/core/src/lib/utils/lazy-load-utils.ts

@ -0,0 +1,54 @@
import { Observable, Observer } from 'rxjs';
import {
CrossOriginStrategy,
CROSS_ORIGIN_STRATEGY,
DomStrategy,
DOM_STRATEGY,
} from '../strategies';
export function fromLazyLoad<T extends Event>(
element: HTMLScriptElement | HTMLLinkElement,
domStrategy: DomStrategy = DOM_STRATEGY.AppendToHead(),
crossOriginStrategy: CrossOriginStrategy = CROSS_ORIGIN_STRATEGY.Anonymous(),
): Observable<T> {
crossOriginStrategy.setCrossOrigin(element);
domStrategy.insertElement(element);
return Observable.create((observer: Observer<Event>) => {
element.onload = event => {
clearCallbacks(element);
observer.next(event);
observer.complete();
};
const handleError = createErrorHandler(observer, element);
element.onerror = handleError;
element.onabort = handleError;
element.onemptied = handleError;
element.onstalled = handleError;
element.onsuspend = handleError;
return () => {
clearCallbacks(element);
observer.complete();
};
});
}
function createErrorHandler(observer: Observer<Event>, element: HTMLElement) {
return function(event: Event | string) {
clearCallbacks(element);
element.parentNode.removeChild(element);
observer.error(event);
};
}
function clearCallbacks(element: HTMLElement) {
element.onload = null;
element.onerror = null;
element.onabort = null;
element.onemptied = null;
element.onstalled = null;
element.onsuspend = null;
}
Loading…
Cancel
Save