ContentLine.ts 2.22 KB
Newer Older
1
import { isAlpha } from "./util";
2
import { ICalElement } from "./ICalElement";
Mark Stenglein's avatar
Mark Stenglein committed
3
import Parameter from "./Parameter";
4
const CRLF: string = "/r/n";
5 6 7
function isIamaToken(input: string): boolean {
    return true;
}
Mark Stenglein's avatar
Mark Stenglein committed
8 9 10 11 12 13 14 15 16 17

/**
 * Implementation of a Content Line from RFC 5545
 *
 * Chapter 3.1 defines the content line. This implementation will use it as an
 * abstract class which can be extended later by the specific content types.
 *
 * This class defines all of the general features specified by the chapter,
 * while leaving the specific features required by individual component objects
 * unfilled.
Mark Stenglein's avatar
Mark Stenglein committed
18 19 20
 *
 * @author Mark Stenglein <mark@stengle.in>
 * @since 0.1.0
Mark Stenglein's avatar
Mark Stenglein committed
21
 */
22
export default class ContentLine implements ICalElement {
Mark Stenglein's avatar
Mark Stenglein committed
23
    private _name: string;
24
    private _params: Parameter[];
Mark Stenglein's avatar
Mark Stenglein committed
25 26
    private _value: string;

Mark Stenglein's avatar
Mark Stenglein committed
27
    constructor(inName: string, inParams: Parameter[], inValue: string) {
Mark Stenglein's avatar
Mark Stenglein committed
28
        this.name = inName;
29
        this._params = inParams;
Mark Stenglein's avatar
Mark Stenglein committed
30 31 32 33 34 35 36 37 38
        this.value = inValue;
    }

    /* Getters */

    get name(): string {
        return this._name;
    }

Mark Stenglein's avatar
Mark Stenglein committed
39
    get params(): Parameter[] {
40
        return this._params;
Mark Stenglein's avatar
Mark Stenglein committed
41 42 43 44 45 46 47 48 49
    }

    get value(): string {
        return this._value;
    }

    /* Setters */

    set name(newName: string) {
Mark Stenglein's avatar
Mark Stenglein committed
50
        if (isIamaToken(newName)) {
Mark Stenglein's avatar
Mark Stenglein committed
51 52 53
            this._name = newName;
        }
        else {
54
            throw new TypeError("'name' must be alphabetic!");
Mark Stenglein's avatar
Mark Stenglein committed
55 56 57 58 59 60 61 62
        }
    }

    set value(newValue: string) {
        if (isAlpha(newValue)) {
            this._value = newValue;
        }
    }
63 64 65

    /**
     * Folds lines into 74 octet sections
Mark Stenglein's avatar
Mark Stenglein committed
66
     *
67
     * @author Sebastian Pekarek <mail@sebbo.net>
Mark Stenglein's avatar
Mark Stenglein committed
68
     *
69 70 71
     * TODO: Make sure that this handles multi-octed UTF-8 segments properly.
     */
    static fold(line: string): string {
Mark Stenglein's avatar
Mark Stenglein committed
72
        return line.match(/(.{1,74})/g).join(CRLF + " ");
73 74 75 76
    }

    /**
     * Generates a folded content line to use to create the final file.
Mark Stenglein's avatar
Mark Stenglein committed
77
     *
78 79 80 81 82
     * @author Mark Stenglein <mark@stengle.in>
     */
    public generate(): string {
        let outputLine = this.name;

83
        this.params.forEach((param) => {
84
            outputLine += ";";
85 86 87
            outputLine += param;
        });

Mark Stenglein's avatar
Mark Stenglein committed
88
        outputLine += ":" + this.value + CRLF;
89 90 91

        return ContentLine.fold(outputLine);
    }
92
}