all files / src/ descriptor.ts

92.31% Statements 24/26
50% Branches 2/4
100% Functions 4/4
92% Lines 23/25
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57                                                                    
import { ScrollSettings } from './scroll-settings';
 
interface ExpressionDescriptor {
    index: string;
    collection: string;
    trackBy: string;
}
 
export class Descriptor {
    public Settings: ScrollSettings;
    public CollectionExpression: string;
    public IndexExpression: string;
    public TrackByExpression: string;
    public Scope: ng.IScope;
 
    private constructor() { }
 
    static createFrom(scope: ng.IScope, attr: ng.IAttributes): Descriptor {
        const settings = ScrollSettings.createFrom(attr);
        const expressionDesc = Descriptor.parseExpression(attr.infiniteScroller);
 
        const descriptor = new Descriptor();
        descriptor.CollectionExpression = expressionDesc.collection;
        descriptor.IndexExpression = expressionDesc.index;
        descriptor.TrackByExpression = expressionDesc.trackBy;
        descriptor.Scope = scope;
        descriptor.Settings = settings;
 
        return descriptor;
    }
 
    private static parseExpression(expression: string): ExpressionDescriptor {
        // parser logic mostly copied from ngRepeater https://github.com/angular/angular.js/blob/master/src/ng/directive/ngRepeat.js
        let match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
 
        Iif (!match) {
            throw Error(`Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '${expression}'.`);
        }
 
        const lhs = match[1];
        const rhs = match[2];
        const trackByExp = match[3];
 
        match = lhs.match(/^(?:(\s*[$\w]+))$/);
 
        Iif (!match) {
            throw Error(`'_item_' in '_item_ in _collection_' should be an identifier but got '${lhs}'.`);
        }
 
        return {
            collection: rhs,
            index: match[1],
            trackBy: trackByExp,
        };
    }
}