UNPKG

5.17 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const _ = require("lodash");
4const events_1 = require("./events");
5const childMappings = [];
6function Component(options) {
7 return (target) => {
8 const proto = target.prototype;
9 if (!(proto instanceof AbstractComponent)) {
10 throw new Error('The `Component` decorator can only be used with a subclass of `AbstractComponent`.');
11 }
12 if (options.childClass) {
13 if (!(proto instanceof ChildableComponent)) {
14 throw new Error('The `Component` decorator accepts the parameter `childClass` only when used with a subclass of `ChildableComponent`.');
15 }
16 childMappings.push({
17 host: proto,
18 child: options.childClass
19 });
20 }
21 const name = options.name;
22 if (name) {
23 proto.componentName = name;
24 }
25 const internal = !!options.internal;
26 if (name && !internal) {
27 for (const childMapping of childMappings) {
28 if (!(proto instanceof childMapping.child)) {
29 continue;
30 }
31 const host = childMapping.host;
32 host['_defaultComponents'] = host['_defaultComponents'] || {};
33 host['_defaultComponents'][name] = target;
34 break;
35 }
36 }
37 };
38}
39exports.Component = Component;
40function Option(options) {
41 return function (target, propertyKey) {
42 if (!(target instanceof AbstractComponent)) {
43 throw new Error('The `Option` decorator can only be used on properties within an `AbstractComponent` subclass.');
44 }
45 options.component = target['_componentName'];
46 target['_componentOptions'] = target['_componentOptions'] || [];
47 target['_componentOptions'].push(options);
48 Object.defineProperty(target, propertyKey, {
49 get: function () {
50 return this.application.options.getValue(options.name);
51 },
52 enumerable: true,
53 configurable: true
54 });
55 };
56}
57exports.Option = Option;
58class ComponentEvent extends events_1.Event {
59 constructor(name, owner, component) {
60 super(name);
61 this.owner = owner;
62 this.component = component;
63 }
64}
65ComponentEvent.ADDED = 'componentAdded';
66ComponentEvent.REMOVED = 'componentRemoved';
67exports.ComponentEvent = ComponentEvent;
68exports.DUMMY_APPLICATION_OWNER = Symbol();
69class AbstractComponent extends events_1.EventDispatcher {
70 constructor(owner) {
71 super();
72 this._componentOwner = owner;
73 this.initialize();
74 }
75 initialize() { }
76 bubble(name, ...args) {
77 super.trigger(name, ...args);
78 if (this.owner instanceof AbstractComponent && this._componentOwner !== exports.DUMMY_APPLICATION_OWNER) {
79 this.owner.bubble(name, ...args);
80 }
81 return this;
82 }
83 getOptionDeclarations() {
84 return (this._componentOptions || []).slice();
85 }
86 get application() {
87 return this._componentOwner === exports.DUMMY_APPLICATION_OWNER
88 ? this
89 : this._componentOwner.application;
90 }
91 get owner() {
92 return this._componentOwner === exports.DUMMY_APPLICATION_OWNER
93 ? this
94 : this._componentOwner;
95 }
96}
97exports.AbstractComponent = AbstractComponent;
98class ChildableComponent extends AbstractComponent {
99 constructor(owner) {
100 super(owner);
101 _.entries(this._defaultComponents || {}).forEach(([name, component]) => {
102 this.addComponent(name, component);
103 });
104 }
105 getComponent(name) {
106 return (this._componentChildren || {})[name];
107 }
108 getComponents() {
109 return _.values(this._componentChildren);
110 }
111 hasComponent(name) {
112 return !!(this._componentChildren || {})[name];
113 }
114 addComponent(name, componentClass) {
115 if (!this._componentChildren) {
116 this._componentChildren = {};
117 }
118 if (this._componentChildren[name]) {
119 return this._componentChildren[name];
120 }
121 else {
122 const component = typeof componentClass === 'function'
123 ? new componentClass(this)
124 : componentClass;
125 const event = new ComponentEvent(ComponentEvent.ADDED, this, component);
126 this.bubble(event);
127 this._componentChildren[name] = component;
128 return component;
129 }
130 }
131 removeComponent(name) {
132 const component = (this._componentChildren || {})[name];
133 if (component) {
134 delete this._componentChildren[name];
135 component.stopListening();
136 this.bubble(new ComponentEvent(ComponentEvent.REMOVED, this, component));
137 return component;
138 }
139 }
140 removeAllComponents() {
141 for (const component of _.values(this._componentChildren)) {
142 component.stopListening();
143 }
144 this._componentChildren = {};
145 }
146}
147exports.ChildableComponent = ChildableComponent;
148//# sourceMappingURL=component.js.map
\No newline at end of file