{"size": 6482, "ext": "js", "max_stars_repo_path": "PWAApp/scripts/Components/component.js", "max_stars_repo_name": "ArasLabs/pwa-with-cui-sample", "max_stars_repo_stars_event_min_datetime": "2020-03-30T19:25:12.000Z", "max_stars_repo_stars_event_max_datetime": "2020-03-30T19:25:12.000Z", "max_issues_repo_path": "PWAApp/scripts/Components/component.js", "max_issues_repo_name": "ArasLabs/pwa-with-cui-sample", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "PWAApp/scripts/Components/component.js", "max_forks_repo_name": "ArasLabs/pwa-with-cui-sample", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": 1, "max_issues_count": null, "max_forks_count": null, "avg_line_length": 37.4682080925, "max_line_length": 173, "alphanum_fraction": 0.519901265}
export default class Component {
    constructor(item, containerSelector, templateSelector){
        this.item = item;
        this.container = document.querySelector(containerSelector);
        this.template = document.querySelector(templateSelector);
    }

    render(replace) {
        const templateInstance = this.getComponent();
        if (replace) {
            this.clear();
        }

        this.container.appendChild(templateInstance);

        const tooltipEls = this.container.querySelectorAll('[data-tooltip]');
        M.Tooltip.init(tooltipEls);
    }

    clear() {
        this.container.innerHTML = '';
    }

    getComponent() {
        if('content' in document.createElement('template')) {
            const component = document.importNode(this.template.content, true);
            component.firstElementChild.setAttribute('data-id-binding', this.item.id);

            this._bindEvents(component);
            this._bindProperties(component);
            this._bindAttributes(component);
            this._bindClasses(component);

            return component;
        } else {
            console.error('Your browser does not support templates');
            return '';
        }
    }

    _bindEvents(templateInstance) {
        let elements = templateInstance.querySelectorAll('[data-event-handler]');

        for(let i = 0; i < elements.length; ++i) {
            let element = elements[i];
            const handler = element.dataset.eventHandler;
            const type = element.dataset.eventType;

            if(handler in this) {
                element.addEventListener(type, (e) => {
                                                element.disabled = true;
                                                element.classList.add("disabled");
                                                new Promise(resolve => { 
                                                    this[handler](resolve); 
                                                    }).then(() => {
                                                        element.disabled = false;
                                                        element.classList.remove("disabled");
                                                    }).catch(() => {
                                                        element.disabled = false;
                                                        element.classList.remove("disabled");
                                                    }
                                                );
                                        }
                );

                continue;
            }

            const templateDesc = this.template.cloneNode(false);
            console.error(`The handler with name - '${handler}' is not defined in contex for '${this.constructor.name}', template described as '${templateDesc.outerHTML}'`);
        }
    }

    _bindProperties(templateInstance) {
        var self = this;

        modelPropertyBinding(self.item, templateInstance);
        for(var propertyName in self.item) {
            const propertyNameLocal = propertyName;
            let elements = templateInstance.querySelectorAll(`[data-property-binding='${propertyNameLocal}']`);

            if(elements && elements.length > 0) {
                for(let element of elements) { 
                    bindProperty(self.item, propertyNameLocal, element);
                }
            }
        }
    }

    _bindAttributes(templateInstance) {
        let elements = templateInstance.querySelectorAll(`[data-attribute-binding]`);

        if(elements && elements.length > 0) {                
            for(let element of elements) {
                const propertyName = element.dataset.attributeBinding;
                const attributeName = element.dataset.attributeName;

                if(attributeName && propertyName && this.item.hasOwnProperty(propertyName) && this.item[propertyName]) {                    
                    element.setAttribute(attributeName, this.item[propertyName]);
                }
            }
        }
    }

    _bindClasses(templateInstance) {
        let elements = templateInstance.querySelectorAll(`[data-class-binding]`);

        if (elements && elements.length > 0) {
            for (let element of elements) {
                const propertyName = element.dataset.classBinding;
                const classModifier = element.dataset.classModifier || "";

                if (propertyName && this.item.hasOwnProperty(propertyName) && this.item[propertyName]) {
                    element.setAttribute("class", `${element.getAttribute("class")} ${this.item[propertyName]}${classModifier}`);
                }
            }
        }
    }
}

function modelPropertyBinding(item, componentTemplate) {
    let elements = componentTemplate.querySelectorAll('[data-model-property-binding*="."]');

    if(elements && elements.length > 0) {
        for(let element of elements) {
            const modelPropertyBinding = element.dataset.modelPropertyBinding;
            const navigationPropNames = modelPropertyBinding.split('.');
            let prop = item;
            for(let i = 0; i < navigationPropNames.length - 1; ++i) {
                const propName = navigationPropNames[i];
                if(prop && prop.hasOwnProperty(propName)) {
                    prop = prop[propName]
                } else {
                    console.error(`Property with name ${propName} from navigation modelPropertyBinding: ${modelPropertyBinding} was not found`);
                    return;
                }
            }

            bindProperty(prop, navigationPropNames[navigationPropNames.length - 1], element);
        }
    }
}

function bindProperty(item, propName, element) {
    const tootipAtr = 'data-tooltip';
    const value = item[propName] || '';

    if(element.hasAttribute(tootipAtr)) {
        element.setAttribute(tootipAtr, value);
        if(!value) {
            element.removeAttribute(tootipAtr);
        }
    }

    if ('value' in element) {
        if(element.type === 'checkbox') {
            element.checked = !!+value;
        } else {
            element.value = value;
        }
        element.onchange = () => {
            if(element.type === 'checkbox') {
                item[propName] = element.checked ? "1" : "0";
                return;
            }

            item[propName] = element.value; 
        }
        return;
    }

    element.textContent = value;
}