-
-
Save v-fedorov/945e33ffec6c7ad74133436aa23dd56c to your computer and use it in GitHub Desktop.
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
import { NgModule, ModuleWithProviders } from '@angular/core'; | |
// angular | |
import {Injectable} from '@angular/core'; | |
// nativescript | |
import {knownFolders} from 'file-system'; | |
// libs | |
import {BehaviorSubject} from 'rxjs/BehaviorSubject'; | |
import {Pipe, PipeTransform, OnDestroy, ChangeDetectorRef } from '@angular/core'; | |
@Pipe({ | |
name: 'fonticon', | |
pure: false | |
}) | |
export class TNSFontIconPipe implements PipeTransform, OnDestroy { | |
private _collectionName: string; | |
private _value: ''; | |
private _iconSub: any; | |
constructor(private fonticon: TNSFontIconService, private _ref: ChangeDetectorRef) { } | |
transform(className: string, args: any[]) { | |
if (!this._collectionName) | |
this._collectionName = getCollectionName(className, args); | |
if (!this._value || (this.fonticon.css && this.fonticon.css[this._collectionName] && this._value !== this.fonticon.css[this._collectionName][className])) { | |
// only subscribe if value is changing | |
// if there is a subscription to iconSub, clean it | |
this._dispose(); | |
this._iconSub = this.fonticon.filesLoaded.subscribe((data: any) => { | |
if (data && data[this._collectionName] && data[this._collectionName][className]) { | |
if (this._value !== data[this._collectionName][className]) { | |
// only markForCheck if value has changed | |
this._value = data[this._collectionName][className]; | |
this._ref.markForCheck(); | |
this._dispose(); | |
} | |
} | |
}); | |
} | |
return this._value; | |
} | |
_dispose(): void { | |
if (this._iconSub) { | |
this._iconSub.unsubscribe(); | |
this._iconSub = undefined; | |
} | |
} | |
ngOnDestroy(): void { | |
this._dispose(); | |
} | |
} | |
function getCollectionName(className: string, args: any[]): string { | |
if (args && args.length && args[0] !== null) { | |
return args[0]; | |
} else if (className && className.indexOf('-') > -1) { | |
// derive from classname | |
return className.split('-')[0]; | |
} else { | |
return ''; | |
} | |
} | |
@Injectable() | |
export class TNSFontIconService { | |
public static config: any = {}; | |
public static debug: boolean = false; | |
public filesLoaded: BehaviorSubject<any>; | |
public css: any = {}; // font icon collections containing maps of classnames to unicode | |
private _currentName: string; // current collection name | |
constructor() { | |
TNSFontIconService.config = { | |
'fa': 'font-awesome.css' | |
}; | |
this.filesLoaded = new BehaviorSubject(null); | |
this.loadCss(); | |
} | |
public loadCss(): void { | |
let cnt = 0; | |
let fontIconCollections = Object.keys(TNSFontIconService.config); | |
if (TNSFontIconService.debug) { | |
console.log(`Collections to load: ${fontIconCollections}`); | |
} | |
let initCollection = () => { | |
this._currentName = fontIconCollections[cnt]; | |
this.css[this._currentName] = {}; | |
}; | |
let loadFiles = () => { | |
initCollection(); | |
if (cnt === fontIconCollections.length) { | |
this.filesLoaded.next(this.css); | |
} else { | |
this.loadFile(TNSFontIconService.config[this._currentName]).then(() => { | |
cnt++; | |
loadFiles(); | |
}); | |
} | |
}; | |
loadFiles(); | |
} | |
private loadFile(path: string): Promise<any> { | |
if (TNSFontIconService.debug) { | |
console.log(`----------`); | |
console.log(`Loading collection '${this._currentName}' from file: ${path}`); | |
} | |
let cssFile = knownFolders.currentApp().getFile(path); | |
return new Promise((resolve, reject) => { | |
cssFile.readText().then((data) => { | |
this.mapCss(data); | |
resolve(); | |
}, (err) => { | |
reject(err); | |
}); | |
}); | |
} | |
private mapCss(data: any): void { | |
let sets = data.split('}'); | |
let cleanValue = (val) => { | |
let v = val.split('content:')[1].toLowerCase().replace(/\\e/, '\\ue').replace(/\\f/, '\\uf').trim().replace(/\"/g, '').replace(/;/g, ''); | |
return v; | |
}; | |
for (let set of sets) { | |
let pair = set.replace(/ /g, '').split(':before{'); | |
let keyGroups = pair[0]; | |
let keys = keyGroups.split(','); | |
if (pair[1]) { | |
let value = cleanValue(pair[1]); | |
for (let key of keys) { | |
key = key.trim().slice(1).split(':before')[0]; | |
this.css[this._currentName][key] = String.fromCharCode(parseInt(value.substring(2), 16)); | |
if (TNSFontIconService.debug) { | |
console.log(`${key}: ${value}`); | |
} | |
} | |
} | |
} | |
} | |
} | |
const PIPES: Array<any> = [ | |
TNSFontIconPipe, | |
]; | |
@NgModule({ | |
declarations: PIPES, | |
exports: PIPES | |
}) | |
export class TNSFontIconModule { | |
static forRoot(config?: any): ModuleWithProviders { | |
return { | |
ngModule: TNSFontIconModule, | |
providers: [ | |
TNSFontIconService | |
] | |
}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment