UNPKG

@veams/component

Version:

Component Class for Components in Veams for static page apps

395 lines 13.7 kB
'use strict'; var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); /** * Represents a component constructor which supports * options merging, * binding and unbinding of events and subscriptions with template strings, * rendering of templates * and a destroy behaviour. * * @module @veams/component * @author Sebastian Fitzner */ /** * Imports */ var base_1 = require("@veams/base"); var get_string_value_1 = require("./helpers/get-string-value"); var template_engine_1 = require("./helpers/template-engine"); var event_handler_1 = require("./helpers/event-handler"); var DEFAULT_LIFECYCLES = { create: true, willMount: true, didMount: true, render: false }; /** * Custom Functions */ function buildEvtId(evtKeyArr, fnName) { return evtKeyArr.join('_') + '_' + fnName; } /** * Hidden variables */ // Custom event handler element which will be used in `events()` and `subscribe` var eventElement = null; var Component = /** @class */ (function (_super) { __extends(Component, _super); /** * Constructor * * to save standard elements like el and options and * execute initialize as default method. * * @param {Object} obj [{}] - Object which contains el, options from the DOM and namespace. * @param {Object} options [{}] - Object which contains options of the extended class. */ function Component(obj, options) { if (options === void 0) { options = {}; } var _this = _super.call(this, obj, options) || this; _this.context = obj.context || window['Veams']; _this.__eventElement = event_handler_1.default(_this.el); if (!_this.context) { console.info('@veams/component :: There is no context defined! When you want to use @veams/plugin-vent or any other singleton shared by your Veams instance provide the Veams object as context!'); } _this.initialize(obj, options); return _this; } Object.defineProperty(Component.prototype, "events", { get: function () { return this._events; }, // ---------------------------------------------------------- // GETTER & SETTERS // ---------------------------------------------------------- /** * Get and set events object */ set: function (obj) { this._events = obj; }, enumerable: true, configurable: true }); Object.defineProperty(Component.prototype, "subscribe", { get: function () { return this._subscribe; }, /** * Get and set subscribe object */ set: function (obj) { this._subscribe = obj; }, enumerable: true, configurable: true }); Component.prototype.addSubscriber = function (obj) { if (!this.__subscribers) { this.__subscribers = {}; } this.__subscribers[obj.id] = { delegate: obj.delegate, type: obj.type, event: obj.event, handler: obj.handler }; }; Object.defineProperty(Component.prototype, "_subscribers", { get: function () { return this.__subscribers; }, enumerable: true, configurable: true }); // ---------------------------------------------------------- // STANDARD METHODS // ---------------------------------------------------------- Component.prototype.initialize = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } }; /** * Private method to create all necessary elements and bindings. * * @private */ Component.prototype.create = function () { this.preRender(); this.registerEvents(this.events, false); this.registerEvents(this.subscribe, true); this.bindEvents(); }; /** * Bind local and global events * * @public */ Component.prototype.bindEvents = function () { }; /** * Unbind events * * @public */ Component.prototype.unbindEvents = function () { }; /** * Pre-Render templates * which can be used to render content into it * * @public */ Component.prototype.preRender = function () { return this; }; /** * Render your module * * @public */ Component.prototype.render = function () { return this; }; /** * Destroy component by unbinding events and * removing element from DOM */ Component.prototype.destroy = function () { this.unregisterEvents(); this.unbindEvents(); this.el.remove(); }; /** * Render template with data * * @param {String} tplName - Template name which gets returned as rendered element. * @param {Object} data - Data which gets handled by the template. */ Component.prototype.renderTemplate = function (tplName, data) { if (!this.context.templater) { console.error("\n\t\t\t\t@veams/component :: It seems that you haven't added the @veams/plugin-templater. In order to work with 'renderTemplate()' you need to add it!\n\t\t\t"); } else { return this.context.templater.render(tplName, data); } }; // ---------------------------------------------------------- // MOUNT PROCESS METHODS // Mount process methods will be handled by the VeamsModules plugin // ---------------------------------------------------------- /** * This method will be executed after initialise */ Component.prototype.willMount = function () { }; ; /** * This method will be executed before unregistering events */ Component.prototype.willUnmount = function () { }; ; /** * This method will be executed after render */ Component.prototype.didMount = function () { }; ; /** * This method will be executed after unregistering events */ Component.prototype.didUnmount = function () { }; ; // ---------------------------------------------------------- // EVENTS METHODS // ---------------------------------------------------------- /** * Register multiple events which are saved in an object. * * @param {Object} evts - Events object which contains an object with events as key and functions as value. * @param {Boolean} global - Flag to switch between global and local events. * * @private */ Component.prototype.registerEvents = function (evts, global) { var _this = this; if (global === void 0) { global = false; } if (evts) { Object.keys(evts).forEach(function (key) { _this.registerEvent(key, evts[key], global); }); } }; /** * Register an event by using a simple template engine and * a key/value pair. * * @param {String} evtKey - Event key which contains event and additionally a delegated element. * @param {String} fn - Function defined as string which will be bound to this. * @param {Boolean} global - Flag if global or local event . * * @public * * @example * this.registerEvent('click .btn', 'render'); * this.registerEvent('click {{this.options.btn}}', 'render'); * this.registerEvent('{{App.EVENTS.custom.event', 'render'); * this.registerEvent('{{App.EVENTS.resize', 'render', true); */ Component.prototype.registerEvent = function (evtKey, fn, global) { if (global === void 0) { global = false; } if (typeof evtKey !== 'string') { console.error('@veams/component :: Your event is not a string!'); return; } if (typeof fn !== 'string') { console.error('@veams/component :: Your event handler function is not a string!'); return; } var evtKeyArr = evtKey.split(' '); var arrlen = evtKeyArr.length; var evtType = get_string_value_1.default.apply(this, [template_engine_1.default(evtKeyArr[0]), this.context]); var bindFn = this[fn].bind(this); var id = buildEvtId(evtKeyArr, fn); if (arrlen > 2) { throw new Error('@veams/component :: It seems like you have more than two strings in your events object!'); } // Bind on this.el if (arrlen === 1 && !global) { this.__eventElement.on(evtType, bindFn); this.addSubscriber({ type: 'event', id: id, event: evtType, handler: bindFn }); } else if (arrlen === 1 && global) { if (!this.context && !this.context.Vent) { console.warn('@veams/component :: There is no context or the Vent object is missing. Subscribing to global events will not work without it!'); return; } this.context.Vent.subscribe(evtType, bindFn); this.addSubscriber({ type: 'globalEvent', id: id, event: evtType, handler: bindFn }); } else { var delegate = get_string_value_1.default.apply(this, [template_engine_1.default(evtKeyArr[1])]); this.__eventElement.on(evtType, delegate, bindFn); this.addSubscriber({ type: 'delegatedEvent', delegate: delegate, id: id, event: evtType, handler: bindFn }); } }; /** * Delete all registered events. */ Component.prototype.unregisterEvents = function () { for (var key in this._subscribers) { if (this._subscribers.hasOwnProperty(key)) { var obj = this._subscribers[key]; if (obj.type === 'globalEvent') { if (!this.context && !this.context.Vent) { console.warn('@veams/component :: There is no context or the Vent object is missing. Subscribing to global events will not work without it!'); return; } this.context.Vent.unsubscribe(obj.event, obj.handler); } else if (obj.type === 'delegatedEvent') { this.__eventElement.off(obj.event, obj.delegate, obj.handler); } else { this.__eventElement.off(obj.event, obj.handler); } } } }; /** * Unregister an event by using the saved subscribers and * a key/value pair. * * @param {String} evtKey - Event key which contains event and additionally a delegated element. * @param {String} fn - Function defined as string which will be unbound to this. * * @public * * @example * this.unregisterEvent('click .btn', 'render'); * this.unregisterEvent('click {{this.options.btn}}', 'render'); * this.unregisterEvent('{{App.EVENTS.custom.event', 'render'); * this.unregisterEvent('{{App.EVENTS.resize', 'render'); */ Component.prototype.unregisterEvent = function (evtKey, fn) { var evtKeyArr = evtKey.split(' '); var id = buildEvtId(evtKeyArr, fn); if (this._subscribers[id]) { var obj = this._subscribers[id]; if (obj.type === 'globalEvent') { if (!this.context && !this.context.Vent) { console.warn('@veams/component :: There is no context or the Vent object is missing. Subscribing to global events will not work without it!'); return; } this.context.Vent.unsubscribe(obj.event, obj.handler); } else if (obj.type === 'delegatedEvent') { this.__eventElement.off(obj.event, obj.delegate, obj.handler); } else { this.__eventElement.off(obj.event, obj.handler); } } }; return Component; }(base_1.default)); function autocreate(lifecycles) { var mergedLifeCycles = __assign({}, DEFAULT_LIFECYCLES, lifecycles); return function creatInstance(instance) { if (mergedLifeCycles.create) { instance.create(); } if (mergedLifeCycles.willMount) { instance.willMount(); } if (mergedLifeCycles.didMount) { instance.didMount(); } if (mergedLifeCycles.render) { instance.render(); } return instance; }; } exports.autocreate = autocreate; exports.default = Component; //# sourceMappingURL=index.js.map