All files / mframejs/attribute cssAttribute.ts

100% Statements 25/25
100% Branches 4/4
100% Functions 10/10
100% Lines 24/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 10329x   29x               29x           1x                 1x 1x   1x         11x       1x                     11x   11x     14x       11x   3x       11x             10x 10x 11x 11x       10x   7x         10x     1x                     1x        
import { customAttribute } from '../decorator/exported';
import { IAttribute, IListener, IBindingContext } from '../interface/exported';
import { BindingEngine } from '../binding/exported';
 
 
/**
 * css replaces style in elements
 *
 */
@customAttribute('css')
export class CssAttribute implements IAttribute {
    public $element: any;
    public $attribute: Attr;
    public $bindingContext: IBindingContext;
    private subscribeInternal: IListener;
    private value: string;
    private lastStyles: string[] = [];
 
 
    /**
     * created
     *
     */
    public created() {
 
        this.value = this.$attribute.value;
        this.$element.removeAttribute(this.$attribute.name);
 
        this.subscribeInternal = {
            name: 'cssAttribute:',
            value: this.value,
            call: (newValue: any, oldValue: any) => {
                if (oldValue !== newValue) {
                    this.splitAndInsert(newValue);
                }
            }
        };
        BindingEngine.subscribeClassProperty(this.$bindingContext, this.value, this.subscribeInternal);
    }
 
 
 
    /**
     * splits new value into array/maps it and sets it to style
     *
     */
    public splitAndInsert(value: string) {
        try {
            value = value === undefined || value === null ? '' : value;
 
            const x = value
                .split(';')
                .map((statement: any) => {
                    return statement.split(':');
                }).filter((value: any) => {
                    // needs to contains attribute and value, check array have 2
                    if (value.length === 2) {
                        return true;
                    } else {
                        return false;
                    }
                })
                .map((result: any) => {
                    return {
                        attribute: result[0],
                        value: result[1].replace(/ /g, '')
                    };
                });
 
 
            const newStyles: string[] = [];
            x.forEach((val) => {
                newStyles.push(val.attribute.trim());
                (<any>this.$element).style[val.attribute.trim()] = val.value.trim();
            });
 
            // remove if style isnt there anymore
            this.lastStyles.forEach((val) => {
                if (newStyles.indexOf(val) === -1) {
                    (<any>this.$element).style[val] = null;
                }
            });
 
            // save new styles so we know what to remove
            this.lastStyles = newStyles;
 
        } catch (e) {
            console.error('could not parse css values');
        }
    }
 
 
 
    /**
     * detached, remove binding
     *
     */
    public detached() {
        BindingEngine.unSubscribeClassProperty(this.$bindingContext, this.subscribeInternal);
    }
 
}