lupine.components 1.1.13 → 1.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.md +3 -3
  2. package/package.json +42 -42
  3. package/src/components/action-sheet.tsx +419 -419
  4. package/src/components/button-push-animation.tsx +147 -138
  5. package/src/components/button.tsx +55 -55
  6. package/src/components/desktop-footer.tsx +17 -17
  7. package/src/components/desktop-header.tsx +52 -52
  8. package/src/components/drag-refresh.tsx +129 -129
  9. package/src/components/editable-label.tsx +83 -83
  10. package/src/components/float-window.tsx +233 -233
  11. package/src/components/grid.tsx +18 -18
  12. package/src/components/html-load.tsx +41 -41
  13. package/src/components/html-var.tsx +81 -81
  14. package/src/components/index.ts +43 -44
  15. package/src/components/input-with-title.tsx +24 -24
  16. package/src/components/link-item.tsx +13 -13
  17. package/src/components/link-list.tsx +62 -62
  18. package/src/components/menu-bar.tsx +219 -219
  19. package/src/components/menu-item-props.tsx +13 -13
  20. package/src/components/menu-sidebar.tsx +325 -318
  21. package/src/components/message-box.tsx +44 -44
  22. package/src/components/meta-data.tsx +36 -36
  23. package/src/components/meta-description.tsx +12 -12
  24. package/src/components/mobile-components/icon-menu-item-props.ts +6 -6
  25. package/src/components/mobile-components/index.ts +8 -9
  26. package/src/components/mobile-components/mobile-footer-menu.tsx +95 -95
  27. package/src/components/mobile-components/mobile-header-component.tsx +101 -101
  28. package/src/components/mobile-components/mobile-header-title-icon.tsx +109 -101
  29. package/src/components/mobile-components/mobile-header-with-back.tsx +127 -117
  30. package/src/components/mobile-components/mobile-side-menu.tsx +154 -154
  31. package/src/components/mobile-components/mobile-top-sys-icon.tsx +18 -18
  32. package/src/components/mobile-components/mobile-top-sys-menu.tsx +62 -62
  33. package/src/components/modal.tsx +33 -33
  34. package/src/components/notice-message.tsx +118 -118
  35. package/src/components/page-title.tsx +6 -6
  36. package/src/components/paging-link.tsx +175 -175
  37. package/src/components/panel.tsx +21 -21
  38. package/src/components/popup-menu.tsx +289 -289
  39. package/src/components/progress.tsx +91 -91
  40. package/src/components/radio-label-component.tsx +36 -36
  41. package/src/components/redirect.tsx +19 -19
  42. package/src/components/resizable-splitter.tsx +128 -128
  43. package/src/components/select-angle-component.tsx +127 -127
  44. package/src/components/select-with-title.tsx +37 -37
  45. package/src/components/slide-tab-component.tsx +144 -149
  46. package/src/components/spinner.tsx +106 -100
  47. package/src/components/stars-component.tsx +66 -66
  48. package/src/components/svg.tsx +24 -24
  49. package/src/components/tabs.tsx +279 -279
  50. package/src/components/text-glow.tsx +37 -37
  51. package/src/components/text-scale.tsx +42 -42
  52. package/src/components/text-wave.tsx +55 -55
  53. package/src/components/theme-selector.tsx +28 -28
  54. package/src/components/toggle-base.tsx +285 -269
  55. package/src/components/toggle-switch.tsx +160 -160
  56. package/src/frames/index.ts +3 -3
  57. package/src/frames/responsive-frame.tsx +83 -83
  58. package/src/frames/slider-frame.tsx +111 -111
  59. package/src/frames/top-frame.tsx +30 -30
  60. package/src/index.ts +5 -5
  61. package/src/lib/back-action-helper.ts +54 -54
  62. package/src/lib/base62.ts +23 -23
  63. package/src/lib/blob-utils.ts +23 -23
  64. package/src/lib/calculate-text-width.ts +13 -13
  65. package/src/lib/date-utils.ts +317 -317
  66. package/src/lib/deep-merge.ts +37 -37
  67. package/src/lib/document-ready.ts +34 -34
  68. package/src/lib/dom-utils.ts +32 -32
  69. package/src/lib/download-file.ts +118 -118
  70. package/src/lib/download-link.ts +12 -12
  71. package/src/lib/download-stream.ts +19 -19
  72. package/src/lib/drag-util.ts +118 -118
  73. package/src/lib/dynamical-load.ts +134 -134
  74. package/src/lib/encode-html.ts +27 -27
  75. package/src/lib/find-parent-tag.ts +8 -8
  76. package/src/lib/format-bytes.ts +11 -11
  77. package/src/lib/index.ts +24 -24
  78. package/src/lib/lite-dom.ts +225 -225
  79. package/src/lib/message-hub.ts +103 -104
  80. package/src/lib/observable.ts +188 -188
  81. package/src/lib/path-utils.ts +42 -42
  82. package/src/lib/promise-timeout.ts +1 -1
  83. package/src/lib/simple-storage.ts +40 -40
  84. package/src/lib/stop-propagation.ts +7 -7
  85. package/src/lib/upload-file.ts +101 -101
  86. package/src/styles/base-themes.ts +17 -17
  87. package/src/styles/dark-themes.ts +99 -99
  88. package/src/styles/index.ts +5 -5
  89. package/src/styles/light-themes.ts +106 -106
  90. package/src/styles/media-query.ts +93 -93
  91. package/src/styles/shared-themes.ts +57 -57
  92. package/tsconfig.json +113 -113
@@ -1,225 +1,225 @@
1
- // Lite Dom Utils
2
- /*
3
- Don't judge whether this.node is valid, so it throws error when this.node is not found or undefined
4
- */
5
- export class LiteDom {
6
- private node: Element;
7
-
8
- static queryOne(selector?: string | Element | LiteDom, docRoot?: Element): LiteDom | null {
9
- if (!selector) {
10
- return null;
11
- }
12
- if (selector instanceof LiteDom) {
13
- return selector;
14
- }
15
- if (selector instanceof Element) {
16
- return new LiteDom(selector);
17
- }
18
- const el = (docRoot || document).querySelector(selector) as Element;
19
- return el ? new LiteDom(el) : null;
20
- }
21
-
22
- static queryAll(selector?: string | Element | LiteDom, docRoot?: Element): LiteDom[] {
23
- if (!selector) {
24
- return [];
25
- }
26
- if (selector instanceof LiteDom) {
27
- return [selector];
28
- }
29
- if (selector instanceof Element) {
30
- return [new LiteDom(selector)];
31
- }
32
- const el = (docRoot || document).querySelectorAll(selector);
33
- const ret = [];
34
- for (let i in el) {
35
- ret.push(new LiteDom(el[i] as Element));
36
- }
37
- return ret;
38
- }
39
-
40
- static createElement(html: string, docRoot?: Document): LiteDom {
41
- const dom = (docRoot || document).createElement(html);
42
- const domLib = new LiteDom(dom);
43
- return domLib;
44
- }
45
-
46
- constructor(selector?: string | Element | LiteDom, docRoot?: Element) {
47
- if (selector instanceof LiteDom) {
48
- this.node = selector.node;
49
- } else if (selector instanceof Element) {
50
- this.node = selector;
51
- } else {
52
- const el = selector && ((docRoot || document).querySelector(selector) as Element);
53
- if (el) {
54
- this.node = el;
55
- } else {
56
- throw new TypeError('Element is not defined for a new LibDom');
57
- }
58
- }
59
- }
60
-
61
- getElement(): Element {
62
- return this.node;
63
- }
64
-
65
- // query children and set value or innerHTML
66
- $(selector: string, value?: string | number | boolean | null): LiteDom | null {
67
- const dom = LiteDom.queryOne(selector, this.node);
68
- if (dom && typeof value !== 'undefined') {
69
- if ('checked' in dom.node) {
70
- dom.node.checked = !!value;
71
- } else if ('value' in dom.node) {
72
- dom.node.value = value;
73
- } else if ('innerHTML' in dom.node) {
74
- dom.node.innerHTML = '' + value;
75
- }
76
- }
77
- return dom;
78
- }
79
-
80
- // query children
81
- query(selector: string): LiteDom | null {
82
- return LiteDom.queryOne(selector, this.node);
83
- }
84
-
85
- // query children
86
- queryAll(selector: string): LiteDom[] {
87
- return LiteDom.queryAll(selector, this.node);
88
- }
89
-
90
- on(eventName: string, eventHandler: (this: Element, ev: any) => any) {
91
- this.node.addEventListener(eventName, eventHandler, false);
92
- return this;
93
- }
94
-
95
- off(eventName: string, eventHandler: (this: Element, ev: any) => any) {
96
- this.node.removeEventListener(eventName, eventHandler, false);
97
- return this;
98
- }
99
-
100
- fire(event: Event) {
101
- this.node.dispatchEvent(event);
102
- return this;
103
- }
104
-
105
- isCheckbox(): boolean {
106
- return this.tagName === 'INPUT' && (this.node as any).type === 'checkbox';
107
- }
108
- isRadio(): boolean {
109
- return this.tagName === 'INPUT' && (this.node as any).type === 'radio';
110
- }
111
-
112
- val(value?: string): string | LiteDom {
113
- if (typeof value === 'undefined') {
114
- return (<any>this.node).value;
115
- }
116
- 'value' in this.node && (this.node.value = value);
117
- return this;
118
- }
119
-
120
- checked(value?: boolean) {
121
- if (typeof value === 'undefined') {
122
- return (<any>this.node).checked;
123
- }
124
- 'checked' in this.node && (this.node.checked = !!value);
125
- return this;
126
- }
127
-
128
- selectedIndex(value?: number) {
129
- if (typeof value === 'undefined') {
130
- return (<any>this.node).selectedIndex;
131
- }
132
- 'selectedIndex' in this.node && (this.node.selectedIndex = value);
133
- return this;
134
- }
135
-
136
- html(value?: string): string | LiteDom {
137
- if (typeof value === 'undefined') {
138
- return this.node.innerHTML;
139
- }
140
- 'innerHTML' in this.node && (this.node.innerHTML = value);
141
- return this;
142
- }
143
-
144
- /*
145
- element.style.backgroundColor = 'blue' // works
146
- element.style['backgroundColor'] = 'blue' // works
147
- element.style['background-color'] = 'blue' // does not work
148
-
149
- element.style.setProperty('background-color','blue') // works
150
- element.style.setProperty('backgroundColor','blue') // does not work
151
- */
152
- css(propertyName: string, value?: string): string | false | LiteDom {
153
- if (typeof value === 'undefined') {
154
- return this.node instanceof HTMLElement && this.node.style.getPropertyValue(propertyName);
155
- }
156
- if (this.node instanceof HTMLElement) {
157
- if (value === null) {
158
- this.node.style.removeProperty(propertyName);
159
- } else {
160
- this.node.style.setProperty(propertyName, value);
161
- }
162
- }
163
- return this;
164
- }
165
-
166
- attribute(attributeName: string, value?: string): string | null | LiteDom {
167
- if (typeof value === 'undefined') {
168
- return this.node.getAttribute(attributeName);
169
- }
170
- if (value === null) {
171
- this.node.removeAttribute(attributeName);
172
- } else {
173
- this.node.setAttribute(attributeName, value);
174
- }
175
- return this;
176
- }
177
-
178
- class(addClass?: string | string[], removeClass?: string | string[]): string | LiteDom {
179
- if (!addClass && !removeClass) {
180
- return (<any>this.node).className;
181
- }
182
- const classList = this.node.classList;
183
- if (addClass) {
184
- addClass instanceof Array ? classList.add(...addClass) : classList.add(addClass);
185
- }
186
- if (removeClass) {
187
- removeClass instanceof Array ? classList.remove(...removeClass) : classList.remove(removeClass);
188
- }
189
- return this;
190
- }
191
-
192
- appendChild(child: Element | LiteDom) {
193
- const dom = child instanceof LiteDom ? child.getElement() : child;
194
- dom && this.node.appendChild(dom);
195
- return this;
196
- }
197
-
198
- removeChild(child: Element | LiteDom) {
199
- const dom = child instanceof LiteDom ? child.getElement() : child;
200
- dom && this.node.removeChild(dom);
201
- return this;
202
- }
203
-
204
- removeSelf() {
205
- // this.node.parentElement!.removeChild(this.node);
206
- this.node.remove();
207
- return this;
208
- }
209
-
210
- get children(): LiteDom[] {
211
- if (!this.node.children) {
212
- return [];
213
- }
214
- const ret = [];
215
- for (let i = 0; i < this.node.children.length; i++) {
216
- ret.push(new LiteDom(this.node.children[i]));
217
- }
218
- return ret;
219
- }
220
-
221
- // originally returns the HTML-uppercased qualified name.
222
- get tagName(): string {
223
- return this.node.tagName.toUpperCase();
224
- }
225
- }
1
+ // Lite Dom Utils
2
+ /*
3
+ Don't judge whether this.node is valid, so it throws error when this.node is not found or undefined
4
+ */
5
+ export class LiteDom {
6
+ private node: Element;
7
+
8
+ static queryOne(selector?: string | Element | LiteDom, docRoot?: Element): LiteDom | null {
9
+ if (!selector) {
10
+ return null;
11
+ }
12
+ if (selector instanceof LiteDom) {
13
+ return selector;
14
+ }
15
+ if (selector instanceof Element) {
16
+ return new LiteDom(selector);
17
+ }
18
+ const el = (docRoot || document).querySelector(selector) as Element;
19
+ return el ? new LiteDom(el) : null;
20
+ }
21
+
22
+ static queryAll(selector?: string | Element | LiteDom, docRoot?: Element): LiteDom[] {
23
+ if (!selector) {
24
+ return [];
25
+ }
26
+ if (selector instanceof LiteDom) {
27
+ return [selector];
28
+ }
29
+ if (selector instanceof Element) {
30
+ return [new LiteDom(selector)];
31
+ }
32
+ const el = (docRoot || document).querySelectorAll(selector);
33
+ const ret = [];
34
+ for (let i in el) {
35
+ ret.push(new LiteDom(el[i] as Element));
36
+ }
37
+ return ret;
38
+ }
39
+
40
+ static createElement(html: string, docRoot?: Document): LiteDom {
41
+ const dom = (docRoot || document).createElement(html);
42
+ const domLib = new LiteDom(dom);
43
+ return domLib;
44
+ }
45
+
46
+ constructor(selector?: string | Element | LiteDom, docRoot?: Element) {
47
+ if (selector instanceof LiteDom) {
48
+ this.node = selector.node;
49
+ } else if (selector instanceof Element) {
50
+ this.node = selector;
51
+ } else {
52
+ const el = selector && ((docRoot || document).querySelector(selector) as Element);
53
+ if (el) {
54
+ this.node = el;
55
+ } else {
56
+ throw new TypeError('Element is not defined for a new LibDom');
57
+ }
58
+ }
59
+ }
60
+
61
+ getElement(): Element {
62
+ return this.node;
63
+ }
64
+
65
+ // query children and set value or innerHTML
66
+ $(selector: string, value?: string | number | boolean | null): LiteDom | null {
67
+ const dom = LiteDom.queryOne(selector, this.node);
68
+ if (dom && typeof value !== 'undefined') {
69
+ if ('checked' in dom.node) {
70
+ dom.node.checked = !!value;
71
+ } else if ('value' in dom.node) {
72
+ dom.node.value = value;
73
+ } else if ('innerHTML' in dom.node) {
74
+ dom.node.innerHTML = '' + value;
75
+ }
76
+ }
77
+ return dom;
78
+ }
79
+
80
+ // query children
81
+ query(selector: string): LiteDom | null {
82
+ return LiteDom.queryOne(selector, this.node);
83
+ }
84
+
85
+ // query children
86
+ queryAll(selector: string): LiteDom[] {
87
+ return LiteDom.queryAll(selector, this.node);
88
+ }
89
+
90
+ on(eventName: string, eventHandler: (this: Element, ev: any) => any) {
91
+ this.node.addEventListener(eventName, eventHandler, false);
92
+ return this;
93
+ }
94
+
95
+ off(eventName: string, eventHandler: (this: Element, ev: any) => any) {
96
+ this.node.removeEventListener(eventName, eventHandler, false);
97
+ return this;
98
+ }
99
+
100
+ fire(event: Event) {
101
+ this.node.dispatchEvent(event);
102
+ return this;
103
+ }
104
+
105
+ isCheckbox(): boolean {
106
+ return this.tagName === 'INPUT' && (this.node as any).type === 'checkbox';
107
+ }
108
+ isRadio(): boolean {
109
+ return this.tagName === 'INPUT' && (this.node as any).type === 'radio';
110
+ }
111
+
112
+ val(value?: string): string | LiteDom {
113
+ if (typeof value === 'undefined') {
114
+ return (<any>this.node).value;
115
+ }
116
+ 'value' in this.node && (this.node.value = value);
117
+ return this;
118
+ }
119
+
120
+ checked(value?: boolean) {
121
+ if (typeof value === 'undefined') {
122
+ return (<any>this.node).checked;
123
+ }
124
+ 'checked' in this.node && (this.node.checked = !!value);
125
+ return this;
126
+ }
127
+
128
+ selectedIndex(value?: number) {
129
+ if (typeof value === 'undefined') {
130
+ return (<any>this.node).selectedIndex;
131
+ }
132
+ 'selectedIndex' in this.node && (this.node.selectedIndex = value);
133
+ return this;
134
+ }
135
+
136
+ html(value?: string): string | LiteDom {
137
+ if (typeof value === 'undefined') {
138
+ return this.node.innerHTML;
139
+ }
140
+ 'innerHTML' in this.node && (this.node.innerHTML = value);
141
+ return this;
142
+ }
143
+
144
+ /*
145
+ element.style.backgroundColor = 'blue' // works
146
+ element.style['backgroundColor'] = 'blue' // works
147
+ element.style['background-color'] = 'blue' // does not work
148
+
149
+ element.style.setProperty('background-color','blue') // works
150
+ element.style.setProperty('backgroundColor','blue') // does not work
151
+ */
152
+ css(propertyName: string, value?: string): string | false | LiteDom {
153
+ if (typeof value === 'undefined') {
154
+ return this.node instanceof HTMLElement && this.node.style.getPropertyValue(propertyName);
155
+ }
156
+ if (this.node instanceof HTMLElement) {
157
+ if (value === null) {
158
+ this.node.style.removeProperty(propertyName);
159
+ } else {
160
+ this.node.style.setProperty(propertyName, value);
161
+ }
162
+ }
163
+ return this;
164
+ }
165
+
166
+ attribute(attributeName: string, value?: string): string | null | LiteDom {
167
+ if (typeof value === 'undefined') {
168
+ return this.node.getAttribute(attributeName);
169
+ }
170
+ if (value === null) {
171
+ this.node.removeAttribute(attributeName);
172
+ } else {
173
+ this.node.setAttribute(attributeName, value);
174
+ }
175
+ return this;
176
+ }
177
+
178
+ class(addClass?: string | string[], removeClass?: string | string[]): string | LiteDom {
179
+ if (!addClass && !removeClass) {
180
+ return (<any>this.node).className;
181
+ }
182
+ const classList = this.node.classList;
183
+ if (addClass) {
184
+ addClass instanceof Array ? classList.add(...addClass) : classList.add(addClass);
185
+ }
186
+ if (removeClass) {
187
+ removeClass instanceof Array ? classList.remove(...removeClass) : classList.remove(removeClass);
188
+ }
189
+ return this;
190
+ }
191
+
192
+ appendChild(child: Element | LiteDom) {
193
+ const dom = child instanceof LiteDom ? child.getElement() : child;
194
+ dom && this.node.appendChild(dom);
195
+ return this;
196
+ }
197
+
198
+ removeChild(child: Element | LiteDom) {
199
+ const dom = child instanceof LiteDom ? child.getElement() : child;
200
+ dom && this.node.removeChild(dom);
201
+ return this;
202
+ }
203
+
204
+ removeSelf() {
205
+ // this.node.parentElement!.removeChild(this.node);
206
+ this.node.remove();
207
+ return this;
208
+ }
209
+
210
+ get children(): LiteDom[] {
211
+ if (!this.node.children) {
212
+ return [];
213
+ }
214
+ const ret = [];
215
+ for (let i = 0; i < this.node.children.length; i++) {
216
+ ret.push(new LiteDom(this.node.children[i]));
217
+ }
218
+ return ret;
219
+ }
220
+
221
+ // originally returns the HTML-uppercased qualified name.
222
+ get tagName(): string {
223
+ return this.node.tagName.toUpperCase();
224
+ }
225
+ }
@@ -1,104 +1,103 @@
1
- export class MessageHubData<T> {
2
- constructor(public actionId: string, public message: string, public extraData?: T) {}
3
- }
4
- export class MessageHub {
5
- private subscriptions: { [key: string]: { [key: string]: Function } } = {};
6
- private subscriptionValues: { [key: string]: any } = {};
7
- private lastId = 0;
8
- constructor(public passLastMsgWhenSubscribe = false) {}
9
-
10
- // * for listening to all events
11
- public subscribe(targetType: string, fn: Function, recessiveLassMsg = true) {
12
- const id = this.lastId++;
13
- if (!this.subscriptions[targetType]) {
14
- this.subscriptions[targetType] = {};
15
- }
16
- this.subscriptions[targetType][id] = fn;
17
- if (recessiveLassMsg && this.passLastMsgWhenSubscribe && this.subscriptionValues[targetType]) {
18
- this.notify(fn, this.subscriptionValues[targetType]);
19
- }
20
-
21
- return () => {
22
- delete this.subscriptions[targetType][id];
23
- var needDestroy = true;
24
- for (var key in this.subscriptions[targetType]) {
25
- needDestroy = false;
26
- break;
27
- }
28
- if (needDestroy) {
29
- delete this.subscriptions[targetType];
30
- }
31
- };
32
- }
33
-
34
- public send(targetType: string, arg: any) {
35
- if (targetType === '*') {
36
- for (var groupKey in this.subscriptions) {
37
- for (var key in this.subscriptions[groupKey]) {
38
- this.notify(this.subscriptions[groupKey][key], arg);
39
- }
40
- }
41
- return;
42
- }
43
-
44
- if (this.passLastMsgWhenSubscribe) {
45
- this.subscriptionValues[targetType] = arg;
46
- }
47
-
48
- if (this.subscriptions[targetType]) {
49
- for (var key in this.subscriptions[targetType]) {
50
- this.notify(this.subscriptions[targetType][key], arg);
51
- }
52
- }
53
- if (this.subscriptions['*']) {
54
- for (var key in this.subscriptions['*']) {
55
- this.notify(this.subscriptions['*'][key], arg);
56
- }
57
- }
58
- }
59
-
60
- public hasListener(targetType: string): boolean {
61
- if (targetType === '*') {
62
- // if has any subscriptions
63
- for (var groupKey in this.subscriptions) {
64
- return true;
65
- }
66
- } else {
67
- // if has any subscriptions of eventType
68
- for (var groupKey in this.subscriptions[targetType]) {
69
- return true;
70
- }
71
- }
72
- return false;
73
- }
74
-
75
- private notify(fn: Function, arg: any) {
76
- setTimeout(() => {
77
- fn(arg);
78
- }, 0);
79
- }
80
- }
81
-
82
-
83
- // /*[TEST-START]*/
84
- // function TEST_sample() {
85
- // var mHub = new MessageHub(true);
86
- // var unsubscribeA = mHub.subscribe('test', (msg: string) => {
87
- // console.log('MessageHub test', msg);
88
- // });
89
- // var unsubscribeB = mHub.subscribe('*', (msg: string) => {
90
- // console.log('MessageHub *', msg);
91
- // });
92
- // console.log(mHub.hasListener('test'));
93
-
94
- // mHub.send('test', new MessageHubData('aa', 'bb'));
95
- // mHub.send('*', new MessageHubData('aa*', 'bb*'));
96
-
97
- // unsubscribeA();
98
- // mHub.send('test', new MessageHubData('aa', 'bb'));
99
- // unsubscribeB();
100
- // mHub.send('*', new MessageHubData<string>('aa to * 2', 'bb', 'extra message'));
101
- // console.log(mHub.hasListener('test'));
102
- // }
103
- // // TEST_sample();
104
- // /*[TEST-END]*/
1
+ export class MessageHubData<T> {
2
+ constructor(public actionId: string, public message: string, public extraData?: T) {}
3
+ }
4
+ export class MessageHub {
5
+ private subscriptions: { [key: string]: { [key: string]: Function } } = {};
6
+ private subscriptionValues: { [key: string]: any } = {};
7
+ private lastId = 0;
8
+ constructor(public passLastMsgWhenSubscribe = false) {}
9
+
10
+ // * for listening to all events
11
+ public subscribe(targetType: string, fn: Function, recessiveLassMsg = true) {
12
+ const id = this.lastId++;
13
+ if (!this.subscriptions[targetType]) {
14
+ this.subscriptions[targetType] = {};
15
+ }
16
+ this.subscriptions[targetType][id] = fn;
17
+ if (recessiveLassMsg && this.passLastMsgWhenSubscribe && this.subscriptionValues[targetType]) {
18
+ this.notify(fn, this.subscriptionValues[targetType]);
19
+ }
20
+
21
+ return () => {
22
+ delete this.subscriptions[targetType][id];
23
+ var needDestroy = true;
24
+ for (var key in this.subscriptions[targetType]) {
25
+ needDestroy = false;
26
+ break;
27
+ }
28
+ if (needDestroy) {
29
+ delete this.subscriptions[targetType];
30
+ }
31
+ };
32
+ }
33
+
34
+ public send(targetType: string, arg: any) {
35
+ if (targetType === '*') {
36
+ for (var groupKey in this.subscriptions) {
37
+ for (var key in this.subscriptions[groupKey]) {
38
+ this.notify(this.subscriptions[groupKey][key], arg);
39
+ }
40
+ }
41
+ return;
42
+ }
43
+
44
+ if (this.passLastMsgWhenSubscribe) {
45
+ this.subscriptionValues[targetType] = arg;
46
+ }
47
+
48
+ if (this.subscriptions[targetType]) {
49
+ for (var key in this.subscriptions[targetType]) {
50
+ this.notify(this.subscriptions[targetType][key], arg);
51
+ }
52
+ }
53
+ if (this.subscriptions['*']) {
54
+ for (var key in this.subscriptions['*']) {
55
+ this.notify(this.subscriptions['*'][key], arg);
56
+ }
57
+ }
58
+ }
59
+
60
+ public hasListener(targetType: string): boolean {
61
+ if (targetType === '*') {
62
+ // if has any subscriptions
63
+ for (var groupKey in this.subscriptions) {
64
+ return true;
65
+ }
66
+ } else {
67
+ // if has any subscriptions of eventType
68
+ for (var groupKey in this.subscriptions[targetType]) {
69
+ return true;
70
+ }
71
+ }
72
+ return false;
73
+ }
74
+
75
+ private notify(fn: Function, arg: any) {
76
+ setTimeout(() => {
77
+ fn(arg);
78
+ }, 0);
79
+ }
80
+ }
81
+
82
+ // /*[TEST-START]*/
83
+ // function TEST_sample() {
84
+ // var mHub = new MessageHub(true);
85
+ // var unsubscribeA = mHub.subscribe('test', (msg: string) => {
86
+ // console.log('MessageHub test', msg);
87
+ // });
88
+ // var unsubscribeB = mHub.subscribe('*', (msg: string) => {
89
+ // console.log('MessageHub *', msg);
90
+ // });
91
+ // console.log(mHub.hasListener('test'));
92
+
93
+ // mHub.send('test', new MessageHubData('aa', 'bb'));
94
+ // mHub.send('*', new MessageHubData('aa*', 'bb*'));
95
+
96
+ // unsubscribeA();
97
+ // mHub.send('test', new MessageHubData('aa', 'bb'));
98
+ // unsubscribeB();
99
+ // mHub.send('*', new MessageHubData<string>('aa to * 2', 'bb', 'extra message'));
100
+ // console.log(mHub.hasListener('test'));
101
+ // }
102
+ // // TEST_sample();
103
+ // /*[TEST-END]*/