ContentLine.ts 2.17 KB
Newer Older
Mark Stenglein's avatar
Mark Stenglein committed
1
import { isIamaToken, 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";
Mark Stenglein's avatar
Mark Stenglein committed
5 6 7 8 9 10 11 12 13 14

/**
 * 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
15 16 17
 *
 * @author Mark Stenglein <mark@stengle.in>
 * @since 0.1.0
Mark Stenglein's avatar
Mark Stenglein committed
18
 */
19
export default class ContentLine implements ICalElement {
Mark Stenglein's avatar
Mark Stenglein committed
20
    private _name: string;
21
    private _params: Parameter[];
Mark Stenglein's avatar
Mark Stenglein committed
22 23
    private _value: string;

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

    /* Getters */

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

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

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

    /* Setters */

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

    set value(newValue: string) {
        if (isAlpha(newValue)) {
            this._value = newValue;
        }
    }
60 61 62

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

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

80
        this.params.forEach((param) => {
81
            outputLine += ";";
82 83 84
            outputLine += param;
        });

Mark Stenglein's avatar
Mark Stenglein committed
85
        outputLine += ":" + this.value + CRLF;
86 87 88

        return ContentLine.fold(outputLine);
    }
89
}