UNPKG

web-atoms-core

Version:
500 lines • 20.7 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; (function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "../App", "../core/AtomBridge", "../core/PropertyBinding", "../core/PropertyMap", "../core/types", "../di/Inject", "./AtomDisposableList", "./Bind", "./XNode"], factory); } })(function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var App_1 = require("../App"); var AtomBridge_1 = require("../core/AtomBridge"); var PropertyBinding_1 = require("../core/PropertyBinding"); var PropertyMap_1 = require("../core/PropertyMap"); // tslint:disable-next-line:import-spacing var types_1 = require("../core/types"); var Inject_1 = require("../di/Inject"); var AtomDisposableList_1 = require("./AtomDisposableList"); var Bind_1 = require("./Bind"); var XNode_1 = require("./XNode"); var AtomComponent = /** @class */ (function () { function AtomComponent(app, element) { if (element === void 0) { element = null; } this.app = app; this.mInvalidated = 0; this.mPendingPromises = {}; this.mData = undefined; this.mViewModel = undefined; this.mLocalViewModel = undefined; this.disposables = new AtomDisposableList_1.AtomDisposableList(); this.bindings = []; this.eventHandlers = []; this.element = element; AtomBridge_1.AtomBridge.instance.attachControl(this.element, this); var a = this.beginEdit(); this.preCreate(); this.create(); app.callLater(function () { return a.dispose(); }); } Object.defineProperty(AtomComponent.prototype, "data", { get: function () { if (this.mData !== undefined) { return this.mData; } var parent = this.parent; if (parent) { return parent.data; } return undefined; }, set: function (v) { this.mData = v; AtomBridge_1.AtomBridge.refreshInherited(this, "data"); }, enumerable: true, configurable: true }); Object.defineProperty(AtomComponent.prototype, "viewModel", { get: function () { if (this.mViewModel !== undefined) { return this.mViewModel; } var parent = this.parent; if (parent) { return parent.viewModel; } return undefined; }, set: function (v) { var old = this.mViewModel; if (old && old.dispose) { old.dispose(); } this.mViewModel = v; AtomBridge_1.AtomBridge.refreshInherited(this, "viewModel"); }, enumerable: true, configurable: true }); Object.defineProperty(AtomComponent.prototype, "localViewModel", { get: function () { if (this.mLocalViewModel !== undefined) { return this.mLocalViewModel; } var parent = this.parent; if (parent) { return parent.localViewModel; } return undefined; }, set: function (v) { var old = this.mLocalViewModel; if (old && old.dispose) { old.dispose(); } this.mLocalViewModel = v; AtomBridge_1.AtomBridge.refreshInherited(this, "localViewModel"); }, enumerable: true, configurable: true }); Object.defineProperty(AtomComponent.prototype, "vsProps", { /** Do not ever use, only available as intellisense feature for * vs code editor. */ get: function () { return undefined; }, enumerable: true, configurable: true }); AtomComponent.prototype.bind = function (element, name, path, twoWays, valueFunc, source) { var _this = this; // remove existing binding if any var binding = this.bindings.find(function (x) { return x.name === name && (element ? x.element === element : true); }); if (binding) { binding.dispose(); types_1.ArrayHelper.remove(this.bindings, function (x) { return x === binding; }); } binding = new PropertyBinding_1.PropertyBinding(this, element, name, path, twoWays, valueFunc, source); this.bindings.push(binding); return { dispose: function () { binding.dispose(); types_1.ArrayHelper.remove(_this.bindings, function (x) { return x === binding; }); } }; }; /** * Remove all bindings associated with given element and optional name * @param element T * @param name string */ AtomComponent.prototype.unbind = function (element, name) { var toDelete = this.bindings.filter(function (x) { return x.element === element && (!name || (x.name === name)); }); var _loop_1 = function (iterator) { iterator.dispose(); types_1.ArrayHelper.remove(this_1.bindings, function (x) { return x === iterator; }); }; var this_1 = this; for (var _i = 0, toDelete_1 = toDelete; _i < toDelete_1.length; _i++) { var iterator = toDelete_1[_i]; _loop_1(iterator); } }; AtomComponent.prototype.bindEvent = function (element, name, method, key) { var _this = this; if (!element) { return; } if (!method) { return; } var be = { element: element, name: name, handler: method }; if (key) { be.key = key; } be.disposable = AtomBridge_1.AtomBridge.instance.addEventHandler(element, name, method, false); this.eventHandlers.push(be); return { dispose: function () { be.disposable.dispose(); types_1.ArrayHelper.remove(_this.eventHandlers, function (e) { return e.disposable === be.disposable; }); } }; }; AtomComponent.prototype.unbindEvent = function (element, name, method, key) { var _this = this; var deleted = []; var _loop_2 = function (be) { if (element && be.element !== element) { return { value: void 0 }; } if (key && be.key !== key) { return { value: void 0 }; } if (name && be.name !== name) { return { value: void 0 }; } if (method && be.handler !== method) { return { value: void 0 }; } be.disposable.dispose(); be.handler = null; be.element = null; be.name = null; be.key = null; deleted.push(function () { return _this.eventHandlers.remove(be); }); }; for (var _i = 0, _a = this.eventHandlers; _i < _a.length; _i++) { var be = _a[_i]; var state_1 = _loop_2(be); if (typeof state_1 === "object") return state_1.value; } for (var _b = 0, deleted_1 = deleted; _b < deleted_1.length; _b++) { var iterator = deleted_1[_b]; iterator(); } }; AtomComponent.prototype.hasProperty = function (name) { if (this[name] !== undefined) { return true; } var map = PropertyMap_1.PropertyMap.from(this); return map.map[name]; }; /** * Use this method if you want to set attribute on HTMLElement immediately but * defer atom control property * @param element HTMLElement * @param name string * @param value any */ AtomComponent.prototype.setPrimitiveValue = function (element, name, value) { var _this = this; var p = value; if (p && p.then && p.catch) { this.mPendingPromises[name] = p; p.then(function (r) { if (_this.mPendingPromises[name] !== p) { return; } _this.mPendingPromises[name] = null; _this.setPrimitiveValue(element, name, r); }).catch(function (e) { if (_this.mPendingPromises[name] !== p) { return; } _this.mPendingPromises[name] = null; // tslint:disable-next-line:no-console console.error(e); }); return; } if (/^(viewModel|localViewModel)$/.test(name)) { this[name] = value; return; } if ((!element || element === this.element) && this.hasProperty(name)) { this.runAfterInit(function () { _this[name] = value; }); } else { this.setElementValue(element, name, value); } }; AtomComponent.prototype.setLocalValue = function (element, name, value) { var _this = this; // if value is a promise var p = value; if (p && p.then && p.catch) { this.mPendingPromises[name] = p; p.then(function (r) { if (_this.mPendingPromises[name] !== p) { return; } _this.mPendingPromises[name] = null; _this.setLocalValue(element, name, r); }).catch(function (e) { if (_this.mPendingPromises[name] !== p) { return; } _this.mPendingPromises[name] = null; // tslint:disable-next-line:no-console console.error(e); }); return; } if ((!element || element === this.element) && this.hasProperty(name)) { this[name] = value; } else { this.setElementValue(element, name, value); } }; AtomComponent.prototype.dispose = function (e) { if (this.mInvalidated) { clearTimeout(this.mInvalidated); this.mInvalidated = 0; } AtomBridge_1.AtomBridge.instance.visitDescendents(e || this.element, function (ex, ac) { if (ac) { ac.dispose(); return false; } return true; }); if (!e) { this.unbindEvent(null, null, null); for (var _i = 0, _a = this.bindings; _i < _a.length; _i++) { var binding = _a[_i]; binding.dispose(); } this.bindings.length = 0; this.bindings = null; AtomBridge_1.AtomBridge.instance.dispose(this.element); this.element = null; var lvm = this.mLocalViewModel; if (lvm && lvm.dispose) { lvm.dispose(); this.mLocalViewModel = null; } var vm = this.mViewModel; if (vm && vm.dispose) { vm.dispose(); this.mViewModel = null; } this.disposables.dispose(); this.pendingInits = null; } }; // tslint:disable-next-line:no-empty AtomComponent.prototype.onPropertyChanged = function (name) { }; AtomComponent.prototype.beginEdit = function () { var _this = this; this.pendingInits = []; var a = this.pendingInits; return { dispose: function () { if (_this.pendingInits == null) { // case where current control is disposed... return; } _this.pendingInits = null; if (a) { for (var _i = 0, a_1 = a; _i < a_1.length; _i++) { var iterator = a_1[_i]; iterator(); } } _this.invalidate(); } }; }; AtomComponent.prototype.invalidate = function () { var _this = this; if (this.mInvalidated) { clearTimeout(this.mInvalidated); } this.mInvalidated = setTimeout(function () { _this.mInvalidated = 0; _this.app.callLater(function () { _this.onUpdateUI(); }); }, 5); }; AtomComponent.prototype.onUpdateUI = function () { // for implementors.. }; AtomComponent.prototype.runAfterInit = function (f) { if (this.pendingInits) { this.pendingInits.push(f); } else { f(); } }; AtomComponent.prototype.registerDisposable = function (d) { return this.disposables.add(d); }; AtomComponent.prototype.render = function (node, e, creator) { creator = creator || this; var bridge = AtomBridge_1.AtomBridge.instance; var app = this.app; var renderFirst = AtomBridge_1.AtomBridge.platform === "xf"; e = e || this.element; var attr = node.attributes; if (attr) { for (var key in attr) { if (attr.hasOwnProperty(key)) { var item = attr[key]; if (item instanceof Bind_1.default) { item.setupFunction(key, item, this, e, creator); } else if (item instanceof XNode_1.default) { // this is template.. if (item.isTemplate) { this.setLocalValue(e, key, AtomBridge_1.AtomBridge.toTemplate(app, item, creator)); } else { var child = AtomBridge_1.AtomBridge.createNode(item, app); this.setLocalValue(e, key, child.element); } } else { this.setLocalValue(e, key, item); } } } } for (var _i = 0, _a = node.children; _i < _a.length; _i++) { var iterator = _a[_i]; if (typeof iterator === "string") { e.appendChild(document.createTextNode(iterator)); continue; } if (iterator.isTemplate) { if (iterator.isProperty) { this.setLocalValue(e, iterator.name, AtomBridge_1.AtomBridge.toTemplate(app, iterator.children[0], creator)); } else { e.appendChild(AtomBridge_1.AtomBridge.toTemplate(app, iterator, creator)); } continue; } if (iterator.isProperty) { for (var _b = 0, _c = iterator.children; _b < _c.length; _b++) { var child = _c[_b]; var pc = AtomBridge_1.AtomBridge.createNode(child, app); (pc.control || this).render(child, pc.element, creator); // in Xamarin.Forms certain properties are required to be // set in advance, so we append the element after setting // all children properties bridge.append(e, iterator.name, pc.element); } continue; } var t = iterator.attributes && iterator.attributes.template; if (t) { this.setLocalValue(e, t, AtomBridge_1.AtomBridge.toTemplate(app, iterator, creator)); continue; } var c = AtomBridge_1.AtomBridge.createNode(iterator, app); if (renderFirst) { (c.control || this).render(iterator, c.element, creator); } if (this.element === e) { this.append(c.control || c.element); } else { e.appendChild(c.element); } if (!renderFirst) { (c.control || this).render(iterator, c.element, creator); } } }; // tslint:disable-next-line:no-empty AtomComponent.prototype.create = function () { }; // tslint:disable-next-line:no-empty AtomComponent.prototype.preCreate = function () { }; AtomComponent.prototype.setElementValue = function (element, name, value) { AtomBridge_1.AtomBridge.instance.setValue(element, name, value); }; AtomComponent.prototype.resolve = function (c, selfName) { var result = this.app.resolve(c, true); if (selfName) { if (typeof selfName === "function") { // this is required as parent is not available // in items control so binding becomes difficult this.runAfterInit(function () { var v = selfName(); if (v) { for (var key in v) { if (v.hasOwnProperty(key)) { var element = v[key]; result[key] = element; } } } }); } else { result[selfName] = this; } } return result; }; AtomComponent.isControl = true; AtomComponent = __decorate([ __param(0, Inject_1.Inject), __metadata("design:paramtypes", [App_1.App, Object]) ], AtomComponent); return AtomComponent; }()); exports.AtomComponent = AtomComponent; }); //# sourceMappingURL=AtomComponent.js.map