75 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			75 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								import { Observable } from 'rx';
							 | 
						||
| 
								 | 
							
								import { ajax$ } from '../../common/utils/ajax-stream';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// value used to break browser ajax caching
							 | 
						||
| 
								 | 
							
								const cacheBreakerValue = Math.random();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export function _fetchScript(
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    src,
							 | 
						||
| 
								 | 
							
								    cacheBreaker = false,
							 | 
						||
| 
								 | 
							
								    crossDomain = true
							 | 
						||
| 
								 | 
							
								  } = {},
							 | 
						||
| 
								 | 
							
								) {
							 | 
						||
| 
								 | 
							
								  if (!src) {
							 | 
						||
| 
								 | 
							
								    throw new Error('No source provided for script');
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  if (this.cache.has(src)) {
							 | 
						||
| 
								 | 
							
								    return this.cache.get(src);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  const url = cacheBreaker ?
							 | 
						||
| 
								 | 
							
								    `${src}?cacheBreaker=${cacheBreakerValue}` :
							 | 
						||
| 
								 | 
							
								    src;
							 | 
						||
| 
								 | 
							
								  const script = ajax$({ url, crossDomain })
							 | 
						||
| 
								 | 
							
								    .doOnNext(res => {
							 | 
						||
| 
								 | 
							
								      if (res.status !== 200) {
							 | 
						||
| 
								 | 
							
								        throw new Error('Request errror: ' + res.status);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								    .map(({ response }) => response)
							 | 
						||
| 
								 | 
							
								    .map(script => `<script>${script}</script>`)
							 | 
						||
| 
								 | 
							
								    .shareReplay();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this.cache.set(src, script);
							 | 
						||
| 
								 | 
							
								  return script;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								export const fetchScript = _fetchScript.bind({ cache: new Map() });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export function _fetchLink(
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    link: href,
							 | 
						||
| 
								 | 
							
								    raw = false,
							 | 
						||
| 
								 | 
							
								    crossDomain = true
							 | 
						||
| 
								 | 
							
								  } = {},
							 | 
						||
| 
								 | 
							
								) {
							 | 
						||
| 
								 | 
							
								  if (!href) {
							 | 
						||
| 
								 | 
							
								    return Observable.throw(new Error('No source provided for link'));
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  if (this.cache.has(href)) {
							 | 
						||
| 
								 | 
							
								    return this.cache.get(href);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  // css files with `url(...` may not work in style tags
							 | 
						||
| 
								 | 
							
								  // so we put them in raw links
							 | 
						||
| 
								 | 
							
								  if (raw) {
							 | 
						||
| 
								 | 
							
								    const link = Observable.just(`<link href=${href} rel='stylesheet' />`)
							 | 
						||
| 
								 | 
							
								      .shareReplay();
							 | 
						||
| 
								 | 
							
								    this.cache.set(href, link);
							 | 
						||
| 
								 | 
							
								    return link;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  const link = ajax$({ url: href, crossDomain })
							 | 
						||
| 
								 | 
							
								    .doOnNext(res => {
							 | 
						||
| 
								 | 
							
								      if (res.status !== 200) {
							 | 
						||
| 
								 | 
							
								        throw new Error('Request error: ' + res.status);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								    .map(({ response }) => response)
							 | 
						||
| 
								 | 
							
								    .map(script => `<style>${script}</style>`)
							 | 
						||
| 
								 | 
							
								    .catch(() => Observable.just(''))
							 | 
						||
| 
								 | 
							
								    .shareReplay();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this.cache.set(href, link);
							 | 
						||
| 
								 | 
							
								  return link;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export const fetchLink = _fetchLink.bind({ cache: new Map() });
							 |