mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
				
	
	
		
			150 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
			
		
		
	
	
			150 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
| import { deprecationWarning, urlUtil } from '@grafana/data';
 | |
| import { locationSearchToObject, locationService, navigationLogger } from '@grafana/runtime';
 | |
| 
 | |
| // Ref: https://github.com/angular/angular.js/blob/ae8e903edf88a83fedd116ae02c0628bf72b150c/src/ng/location.js#L5
 | |
| const DEFAULT_PORTS: Record<string, number> = { http: 80, https: 443, ftp: 21 };
 | |
| 
 | |
| export class AngularLocationWrapper {
 | |
|   constructor() {
 | |
|     this.absUrl = this.wrapInDeprecationWarning(this.absUrl);
 | |
|     this.hash = this.wrapInDeprecationWarning(this.hash);
 | |
|     this.host = this.wrapInDeprecationWarning(this.host);
 | |
|     this.path = this.wrapInDeprecationWarning(this.path);
 | |
|     this.port = this.wrapInDeprecationWarning(this.port, 'window.location');
 | |
|     this.protocol = this.wrapInDeprecationWarning(this.protocol, 'window.location');
 | |
|     this.replace = this.wrapInDeprecationWarning(this.replace);
 | |
|     this.search = this.wrapInDeprecationWarning(this.search);
 | |
|     this.state = this.wrapInDeprecationWarning(this.state);
 | |
|     this.url = this.wrapInDeprecationWarning(this.url);
 | |
|   }
 | |
| 
 | |
|   wrapInDeprecationWarning(fn: Function, replacement?: string) {
 | |
|     let self = this;
 | |
| 
 | |
|     return function wrapper() {
 | |
|       deprecationWarning('$location', fn.name, replacement || 'locationService');
 | |
|       return fn.apply(self, arguments);
 | |
|     };
 | |
|   }
 | |
| 
 | |
|   absUrl(): string {
 | |
|     return `${window.location.origin}${this.url()}`;
 | |
|   }
 | |
| 
 | |
|   hash(newHash?: string | null) {
 | |
|     navigationLogger('AngularLocationWrapper', false, 'Angular compat layer: hash');
 | |
| 
 | |
|     if (!newHash) {
 | |
|       return locationService.getLocation().hash.slice(1);
 | |
|     } else {
 | |
|       throw new Error('AngularLocationWrapper method not implemented.');
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   host(): string {
 | |
|     return new URL(window.location.href).hostname;
 | |
|   }
 | |
| 
 | |
|   path(pathname?: any) {
 | |
|     navigationLogger('AngularLocationWrapper', false, 'Angular compat layer: path');
 | |
| 
 | |
|     const location = locationService.getLocation();
 | |
| 
 | |
|     if (pathname !== undefined && pathname !== null) {
 | |
|       let parsedPath = String(pathname);
 | |
|       parsedPath = parsedPath.startsWith('/') ? parsedPath : `/${parsedPath}`;
 | |
|       const url = new URL(`${window.location.origin}${parsedPath}`);
 | |
| 
 | |
|       locationService.push({
 | |
|         pathname: url.pathname,
 | |
|         search: url.search.length > 0 ? url.search : location.search,
 | |
|         hash: url.hash.length > 0 ? url.hash : location.hash,
 | |
|       });
 | |
|       return this;
 | |
|     }
 | |
| 
 | |
|     if (pathname === null) {
 | |
|       locationService.push('/');
 | |
|       return this;
 | |
|     }
 | |
| 
 | |
|     return location.pathname;
 | |
|   }
 | |
| 
 | |
|   port(): number | null {
 | |
|     const url = new URL(window.location.href);
 | |
|     return parseInt(url.port, 10) || DEFAULT_PORTS[url.protocol] || null;
 | |
|   }
 | |
| 
 | |
|   protocol(): string {
 | |
|     return new URL(window.location.href).protocol.slice(0, -1);
 | |
|   }
 | |
| 
 | |
|   replace() {
 | |
|     throw new Error('AngularLocationWrapper method not implemented.');
 | |
|   }
 | |
| 
 | |
|   search(search?: any, paramValue?: any) {
 | |
|     navigationLogger('AngularLocationWrapper', false, 'Angular compat layer: search');
 | |
|     if (!search) {
 | |
|       return locationService.getSearchObject();
 | |
|     }
 | |
| 
 | |
|     if (search && arguments.length > 1) {
 | |
|       locationService.partial({
 | |
|         [search]: paramValue,
 | |
|       });
 | |
| 
 | |
|       return this;
 | |
|     }
 | |
| 
 | |
|     if (search) {
 | |
|       let newQuery;
 | |
| 
 | |
|       if (typeof search === 'object') {
 | |
|         newQuery = { ...search };
 | |
|       } else {
 | |
|         newQuery = locationSearchToObject(search);
 | |
|       }
 | |
| 
 | |
|       for (const key in newQuery) {
 | |
|         // removing params with null | undefined
 | |
|         if (newQuery[key] === null || newQuery[key] === undefined) {
 | |
|           delete newQuery[key];
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       const updatedUrl = urlUtil.renderUrl(locationService.getLocation().pathname, newQuery);
 | |
|       locationService.push(updatedUrl);
 | |
|     }
 | |
| 
 | |
|     return this;
 | |
|   }
 | |
| 
 | |
|   state(state?: any) {
 | |
|     navigationLogger('AngularLocationWrapper', false, 'Angular compat layer: state');
 | |
|     throw new Error('AngularLocationWrapper method not implemented.');
 | |
|   }
 | |
| 
 | |
|   url(newUrl?: any) {
 | |
|     navigationLogger('AngularLocationWrapper', false, 'Angular compat layer: url');
 | |
| 
 | |
|     if (newUrl !== undefined) {
 | |
|       if (newUrl.startsWith('#')) {
 | |
|         locationService.push({ ...locationService.getLocation(), hash: newUrl });
 | |
|       } else if (newUrl.startsWith('?')) {
 | |
|         locationService.push({ ...locationService.getLocation(), search: newUrl });
 | |
|       } else if (newUrl.trim().length === 0) {
 | |
|         locationService.push('/');
 | |
|       } else {
 | |
|         locationService.push(newUrl);
 | |
|       }
 | |
| 
 | |
|       return locationService;
 | |
|     }
 | |
| 
 | |
|     const location = locationService.getLocation();
 | |
|     return `${location.pathname}${location.search}${location.hash}`;
 | |
|   }
 | |
| }
 |