UNPKG

capivarajs

Version:

Um framework para criação de componentes.

331 lines (311 loc) 10.2 kB
import { Constants } from '../constants'; import { Scope } from '../scope/scope'; import { Component } from './component'; import { ComponentInstance } from './component.instance'; export class CapivaraInstance { /** * @name capivara.components * @description Armazena os componentes criados */ public scopes; public components; public $watchers; public version; public LAST_SCOPE_ID = 0; public core; public DOMMutation; constructor() { this.DOMMutation = window['MutationObserver'] || window['WebKitMutationObserver'] || window['MozMutationObserver']; this.version = '3.10.1'; this.components = {}; this.scopes = []; this.$watchers = []; if (!Element.prototype.hasOwnProperty('getAttributeStartingWith')) { Object.defineProperty(Element.prototype, 'getAttributeStartingWith', { value: function hasAttributeStartingWith(attr) { return Array.from(this.attributes).filter((attributeNode: any) => { return attributeNode.nodeName.indexOf(attr) === 0; }); }, configurable: true, }); } if (!Element.prototype.hasOwnProperty('hasAttributeStartingWith')) { Object.defineProperty(Element.prototype, 'hasAttributeStartingWith', { value: function hasAttributeStartingWith(attr) { return this.getAttributeStartingWith(attr).length > 0; }, configurable: true, }); } if (document.readyState === 'complete' || (document.readyState !== 'loading' && !document.documentElement['doScroll']) ) { setTimeout(() => { this.createListeners(); this.createComponents(); }); } else { document.addEventListener("DOMContentLoaded", (event) => { this.createListeners(); this.createComponents(); }); } } public createComponents() { Object.keys(this.components).forEach((componentName) => { const elms: any = document.querySelectorAll(componentName) || []; Array.from(elms).forEach((elm) => { this.constroyIfComponent(elm); }); }); } public hasRepeat(elm) { return elm && elm.classList && elm.classList.contains('binding-repeat'); } public constroyIfComponent(addedNode, forceCreated?) { const component = this.components[addedNode.nodeName]; if (component && (forceCreated || !addedNode.created)) { addedNode.created = true; component.createNewInstance(addedNode).create(); } if (addedNode.children && (forceCreated || !this.hasRepeat(addedNode))) { (Array.from(addedNode.children) || []).forEach((child) => { this.constroyIfComponent(child, forceCreated); }); } } public destroyIfComponent(removedNode) { removedNode.created = false; if (removedNode['$instance'] && !removedNode['$instance'].destroyed) { removedNode['$instance'].destroy(); } if (removedNode.children) { (Array.from(removedNode.children) || []).forEach((child) => this.destroyIfComponent(child)); } } public onMutation(mutations) { (mutations || []).forEach((mutation) => { if (mutation.type === 'childList') { ((mutation && mutation.addedNodes && mutation.addedNodes.forEach) ? mutation.addedNodes : []).forEach((addedNode) => { this.constroyIfComponent(addedNode); }); ((mutation && mutation.removedNodes && mutation.removedNodes.forEach) ? mutation.removedNodes : []).forEach((removedNode) => { this.destroyIfComponent(removedNode); }); } }); } public createListeners() { if (this.DOMMutation) { const observer = new this.DOMMutation((mutations) => this.onMutation(mutations)); observer.observe(document.body, { attributes: false, childList: true, subtree: true, characterData: false, }); } } /** * @name capivara.component * @description Registra um novo componente capivara */ public component(componentName, config) { if (window["capivara"].components[componentName]) { console.error("A registered component with this name already exists."); return; } window["capivara"].components[componentName.toUpperCase()] = new Component(componentName, config); } /** * @name capivara.componentBuilder * @description Faz a inicialização de um componente. */ public componentBuilder(hashName) { return new Promise((resp) => { let elms = window["capivara"].isElement(hashName) ? [hashName] : Array.from(document.querySelectorAll("[\\#" + hashName + "]")); if (elms.length === 0) { console.error("CapivaraJS did not find its component with the hash " + hashName); } let instance; const findElementAndCreateInstance = () => { elms = window["capivara"].isElement(hashName) ? [hashName] : Array.from(document.querySelectorAll("[\\#" + hashName + "]")); (elms || []).forEach((elm) => { const component = window["capivara"].components[elm.nodeName]; if (!component) { console.error("We did not find a registered entry under the name: " + elm.nodeName); return; } if (!instance) { instance = elm['$instance']; } }); return instance; }; setTimeout(() => { const componentInstance = findElementAndCreateInstance(); resp(componentInstance); }); }); } /** * @name capivara.controller * @description Cria um novo controller para fazer manipulação de um determinado elemento. */ public controller(elm, callback) { new ComponentInstance(elm, { controller: callback }).create(); } /** * @name capivara,isArray * @description Verifica se um valor é um Array. */ public isArray(value) { return Array.isArray(value) || value instanceof Array; } /** * @name capivara,isObject * @description Verifica se um valor é um Objeto. */ public isObject(value) { return value !== null && typeof value === "object"; } public isObjectConstructor(obj) { if (!obj) { return false; } return obj.__proto__.constructor.name === 'Object'; } /** * @name capivara,isDate * @description Verifica se um valor é uma Data. */ public isDate(value) { return toString.call(value) === "[object Date]"; } /** * @name capivara,isElement * @description Verifica se um valor é um NodeElement. */ public isElement(value) { return !!(value && (value.nodeName // We are a direct element. || (value.prop && value.attr && value.find))); } /** * @name capivara,isFunction * @description Verifica se um valor é uma função. */ public isFunction(value) { return typeof value === "function"; } /** * @name capivara,isNumber * @description Verifica se um valor é um número. */ public isNumber(value) { return typeof value === "number"; } /** * @name capivara,isString * @description Verifica se um valor é uma string. */ public isString(value) { return typeof value === "string"; } /** * @name capivara,merge * @description Faz a junção de objetos em um único objeto. */ public merge(...args) { return (Object.assign as any)(...args); } /** * @name capivara,copy * @description Faz a copia de um objeto para que seja criada a referência. */ public copy(value) { return Object.assign(value); } /** * @name capivara,replaceAll * @description Faz a devida alteração em todas as ocorrências */ public replaceAll(str, needle, replacement) { return str.split(needle).join(replacement); } /** * @name capivara.constants * @description Modifica o nome das diretivas que são criadas pelo capivara. */ public constants(obj) { Object.keys(obj).forEach((key) => { if (Constants[key]) { Constants[key] = obj[key]; } }); } public $on(evtName, callback) { window["capivara"].$watchers.push({ evtName, callback }); } public $emit(evtName, ...args) { window["capivara"] .$watchers .filter((watcher) => watcher.evtName === evtName) .forEach((watcher) => { watcher.callback(...args); }); } public simpleCompare(a, b) { return a === b || (a !== a && b !== b); } public isRegExp(value) { return toString.call(value) === '[object RegExp]'; } public isDefined(value) { return typeof value !== 'undefined'; } public isWindow(value) { return value && value.window === value; } public isScope(value) { return value instanceof Scope; } public equals(o1, o2) { if (o1 === o2) { return true; } if (o1 === null || o2 === null) { return false; } if (o1 !== o1 && o2 !== o2) { return true; } /* tslint:disable */ let t1 = typeof o1, t2 = typeof o2, length, key, keySet; if (t1 === t2 && t1 === 'object') { if (this.isArray(o1)) { if (!this.isArray(o2)) { return false }; if ((length = o1.length) === o2.length) { for (key = 0; key < length; key++) { if (!this.equals(o1[key], o2[key])) return false; } return true; } } else if (this.isDate(o1)) { if (!this.isDate(o2)) return false; return this.simpleCompare(o1.getTime(), o2.getTime()); } else if (this.isRegExp(o1)) { if (!this.isRegExp(o2)) return false; return o1.toString() === o2.toString(); } else { if (this.isScope(o1) || this.isScope(o2) || this.isWindow(o1) || this.isWindow(o2) || this.isArray(o2) || this.isDate(o2) || this.isRegExp(o2)) return false; keySet = Object.create(null); for (key in o1) { if (key.charAt(0) === '$' || this.isFunction(o1[key])) continue; if (!this.equals(o1[key], o2[key])) return false; keySet[key] = true; } for (key in o2) { if (!(key in keySet) && key.charAt(0) !== '$' && this.isDefined(o2[key]) && !this.isFunction(o2[key])) return false; } return true; } } return false; } }