##// END OF EJS Templates
implemented @on("event-name") decorator for event handlers
cin -
r73:fdde09e66c00 v1.2.0 default
parent child
Show More
@@ -10,11 +10,10
10 10 "license": "BSD-2-Clause",
11 11 "devDependencies": {
12 12 "@implab/core-amd": "^1.4.0",
13 "@implab/dojo-typings": "/home/sergey/projects/implabjs-dojo-typings/dojo-typings/build/npm/package/implab-dojo-typings-v1.0.0-rc4.tgz",
13 "@implab/dojo-typings": "1.0.0",
14 14 "@types/chai": "4.1.3",
15 15 "@types/requirejs": "2.1.31",
16 16 "@types/yaml": "1.2.0",
17 "chai": "4.2.0",
18 17 "dojo": "1.16.0",
19 18 "eslint": "6.8.0",
20 19 "requirejs": "2.3.6",
@@ -63,11 +62,10
63 62 "dev": true
64 63 },
65 64 "node_modules/@implab/dojo-typings": {
66 "version": "v1.0.0-rc4",
67 "resolved": "file:../../implabjs-dojo-typings/dojo-typings/build/npm/package/implab-dojo-typings-v1.0.0-rc4.tgz",
68 "integrity": "sha512-whWA/3shw3j4WFdmh5ml9BYZMj4KFruv1YXtz29W0LXMNpmj5nyyM8FJYYCdtvWJEGvnEUcUCQ0zsZ+Gh5ah9Q==",
69 "dev": true,
70 "license": "MIT"
65 "version": "1.0.0",
66 "resolved": "https://registry.npmjs.org/@implab/dojo-typings/-/dojo-typings-1.0.0.tgz",
67 "integrity": "sha512-B2kvlKJgvyIQAl/k1pVyNmtp4ADvBDCs4Lw/qfBC+Sz/ft4c7EuRXmN/+2dhWrd6A5SMjEgex5oeq6Ja2ntrig==",
68 "dev": true
71 69 },
72 70 "node_modules/@types/chai": {
73 71 "version": "4.1.3",
@@ -159,15 +157,6
159 157 "sprintf-js": "~1.0.2"
160 158 }
161 159 },
162 "node_modules/assertion-error": {
163 "version": "1.1.0",
164 "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
165 "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
166 "dev": true,
167 "engines": {
168 "node": "*"
169 }
170 },
171 160 "node_modules/astral-regex": {
172 161 "version": "1.0.0",
173 162 "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
@@ -211,23 +200,6
211 200 "node": ">=6"
212 201 }
213 202 },
214 "node_modules/chai": {
215 "version": "4.2.0",
216 "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz",
217 "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==",
218 "dev": true,
219 "dependencies": {
220 "assertion-error": "^1.1.0",
221 "check-error": "^1.0.2",
222 "deep-eql": "^3.0.1",
223 "get-func-name": "^2.0.0",
224 "pathval": "^1.1.0",
225 "type-detect": "^4.0.5"
226 },
227 "engines": {
228 "node": ">=4"
229 }
230 },
231 203 "node_modules/chalk": {
232 204 "version": "2.4.2",
233 205 "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -248,15 +220,6
248 220 "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
249 221 "dev": true
250 222 },
251 "node_modules/check-error": {
252 "version": "1.0.2",
253 "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
254 "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
255 "dev": true,
256 "engines": {
257 "node": "*"
258 }
259 },
260 223 "node_modules/cli-cursor": {
261 224 "version": "3.1.0",
262 225 "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
@@ -336,18 +299,6
336 299 "ms": "^2.1.1"
337 300 }
338 301 },
339 "node_modules/deep-eql": {
340 "version": "3.0.1",
341 "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
342 "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
343 "dev": true,
344 "dependencies": {
345 "type-detect": "^4.0.0"
346 },
347 "engines": {
348 "node": ">=0.12"
349 }
350 },
351 302 "node_modules/deep-is": {
352 303 "version": "0.1.3",
353 304 "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
@@ -638,15 +589,6
638 589 "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
639 590 "dev": true
640 591 },
641 "node_modules/get-func-name": {
642 "version": "2.0.0",
643 "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
644 "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
645 "dev": true,
646 "engines": {
647 "node": "*"
648 }
649 },
650 592 "node_modules/glob": {
651 593 "version": "7.1.6",
652 594 "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
@@ -1018,15 +960,6
1018 960 "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
1019 961 "dev": true
1020 962 },
1021 "node_modules/pathval": {
1022 "version": "1.1.0",
1023 "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
1024 "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
1025 "dev": true,
1026 "engines": {
1027 "node": "*"
1028 }
1029 },
1030 963 "node_modules/prelude-ls": {
1031 964 "version": "1.1.2",
1032 965 "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
@@ -1425,15 +1358,6
1425 1358 "node": ">= 0.8.0"
1426 1359 }
1427 1360 },
1428 "node_modules/type-detect": {
1429 "version": "4.0.8",
1430 "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
1431 "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
1432 "dev": true,
1433 "engines": {
1434 "node": ">=4"
1435 }
1436 },
1437 1361 "node_modules/type-fest": {
1438 1362 "version": "0.8.1",
1439 1363 "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
@@ -1560,8 +1484,9
1560 1484 "dev": true
1561 1485 },
1562 1486 "@implab/dojo-typings": {
1563 "version": "file:/home/sergey/projects/implabjs-dojo-typings/dojo-typings/build/npm/package/implab-dojo-typings-v1.0.0-rc4.tgz",
1564 "integrity": "sha512-whWA/3shw3j4WFdmh5ml9BYZMj4KFruv1YXtz29W0LXMNpmj5nyyM8FJYYCdtvWJEGvnEUcUCQ0zsZ+Gh5ah9Q==",
1487 "version": "1.0.0",
1488 "resolved": "https://registry.npmjs.org/@implab/dojo-typings/-/dojo-typings-1.0.0.tgz",
1489 "integrity": "sha512-B2kvlKJgvyIQAl/k1pVyNmtp4ADvBDCs4Lw/qfBC+Sz/ft4c7EuRXmN/+2dhWrd6A5SMjEgex5oeq6Ja2ntrig==",
1565 1490 "dev": true
1566 1491 },
1567 1492 "@types/chai": {
@@ -1639,12 +1564,6
1639 1564 "sprintf-js": "~1.0.2"
1640 1565 }
1641 1566 },
1642 "assertion-error": {
1643 "version": "1.1.0",
1644 "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
1645 "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
1646 "dev": true
1647 },
1648 1567 "astral-regex": {
1649 1568 "version": "1.0.0",
1650 1569 "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
@@ -1679,20 +1598,6
1679 1598 "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
1680 1599 "dev": true
1681 1600 },
1682 "chai": {
1683 "version": "4.2.0",
1684 "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz",
1685 "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==",
1686 "dev": true,
1687 "requires": {
1688 "assertion-error": "^1.1.0",
1689 "check-error": "^1.0.2",
1690 "deep-eql": "^3.0.1",
1691 "get-func-name": "^2.0.0",
1692 "pathval": "^1.1.0",
1693 "type-detect": "^4.0.5"
1694 }
1695 },
1696 1601 "chalk": {
1697 1602 "version": "2.4.2",
1698 1603 "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -1710,12 +1615,6
1710 1615 "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
1711 1616 "dev": true
1712 1617 },
1713 "check-error": {
1714 "version": "1.0.2",
1715 "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
1716 "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
1717 "dev": true
1718 },
1719 1618 "cli-cursor": {
1720 1619 "version": "3.1.0",
1721 1620 "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
@@ -1788,15 +1687,6
1788 1687 "ms": "^2.1.1"
1789 1688 }
1790 1689 },
1791 "deep-eql": {
1792 "version": "3.0.1",
1793 "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
1794 "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
1795 "dev": true,
1796 "requires": {
1797 "type-detect": "^4.0.0"
1798 }
1799 },
1800 1690 "deep-is": {
1801 1691 "version": "0.1.3",
1802 1692 "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
@@ -2029,12 +1919,6
2029 1919 "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
2030 1920 "dev": true
2031 1921 },
2032 "get-func-name": {
2033 "version": "2.0.0",
2034 "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
2035 "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
2036 "dev": true
2037 },
2038 1922 "glob": {
2039 1923 "version": "7.1.6",
2040 1924 "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
@@ -2339,12 +2223,6
2339 2223 "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
2340 2224 "dev": true
2341 2225 },
2342 "pathval": {
2343 "version": "1.1.0",
2344 "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
2345 "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
2346 "dev": true
2347 },
2348 2226 "prelude-ls": {
2349 2227 "version": "1.1.2",
2350 2228 "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
@@ -2662,12 +2540,6
2662 2540 "prelude-ls": "~1.1.2"
2663 2541 }
2664 2542 },
2665 "type-detect": {
2666 "version": "4.0.8",
2667 "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
2668 "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
2669 "dev": true
2670 },
2671 2543 "type-fest": {
2672 2544 "version": "0.8.1",
2673 2545 "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
@@ -17,6 +17,9 export interface EventArgs {
17 17 export interface DjxWidgetBase<Attrs = {}, Events extends { [name in keyof Events]: Event } = {}> extends
18 18 _WidgetBase<Events> {
19 19
20 /** This property is declared only for type inference to work, it is never assigned
21 * and should not be used.
22 */
20 23 readonly _eventMap: Events & GlobalEventHandlersEventMap;
21 24 }
22 25
@@ -27,9 +30,12 type _super = {
27 30 @djclass
28 31 export abstract class DjxWidgetBase<Attrs = {}, Events = {}> extends djbase<_super, _AttachMixin>(_WidgetBase, _AttachMixin) {
29 32
33 /** The list of pairs of event and method names. When the widget is created all methods from
34 * this list will be connected to corresponding events.
35 */
30 36 _eventHandlers: Array<{
31 eventName: keyof Events,
32 handlerMethod: string;
37 eventName: string,
38 handlerMethod: keyof any;
33 39 }> = [];
34 40
35 41 buildRendering() {
@@ -41,6 +47,9 export abstract class DjxWidgetBase<Attr
41 47 const src = this.srcNodeRef;
42 48 const dest = this.containerNode;
43 49
50 // the donNode is constructed now we need to connect event handlers
51 this._connectEventHandlers();
52
44 53 if (src && dest) {
45 54 while (src.firstChild)
46 55 dest.appendChild(src.firstChild);
@@ -51,8 +60,9 export abstract class DjxWidgetBase<Attr
51 60
52 61 private _connectEventHandlers() {
53 62 this._eventHandlers.forEach(({eventName, handlerMethod}) => {
54 if (typeof this[handlerMethod as keyof this] === "function")
55 this.on(eventName, this[handlerMethod] as Function);
63 const handler = this[handlerMethod as keyof this];
64 if (typeof handler === "function")
65 this.on(eventName, handler);
56 66 });
57 67 }
58 68
@@ -204,19 +204,24 export function watch<T extends Stateful
204 204 return rendition;
205 205 }
206 206
207 export type WidgetEvents<W> = W extends DjxWidgetBase<any, infer EM> ? EM : never;
208
209 export type HandlerType<W, E extends keyof any> = W extends {
210 on(eventName: E, handler: infer H): any;
211 } ? H : never;
212
213 export const on = <E extends keyof any>(eventName: E) =>
207 /** Decorates the method which will be registered as the handle for the specified event.
208 * This decorator can be applied to DjxWidgetBase subclass methods.
209 *
210 * ```
211 * @on("click")
212 * _onClick(eventObj: MouseEvent) {
213 * // ...
214 * }
215 * ```
216 */
217 export const on = <E extends string>(eventName: E) =>
214 218 <K extends keyof T,
215 T extends DjxWidgetBase
219 T extends DjxWidgetBase<any, { [p in E]: EV }>,
220 EV extends Event
216 221 >(
217 222 target: T,
218 223 key: K,
219 descriptor: PropertyDescriptor
224 descriptor: TypedPropertyDescriptor<(eventObj: EV) => void> | TypedPropertyDescriptor<() => void>
220 225 ): any => {
221 target.
226 target._eventHandlers.push({ eventName, handlerMethod: key });
222 227 };
@@ -1,5 +1,4
1 1 /// <reference path="./css.d.ts"/>
2 /// <reference path="./dijit.d.ts"/>
3 2
4 3 declare namespace JSX {
5 4
@@ -2,7 +2,7 import { djbase, djclass, bind, prototyp
2 2
3 3 import { DjxWidgetBase } from "../tsx/DjxWidgetBase";
4 4 import { createElement } from "../tsx";
5 import { HandlerType, on, WidgetEvents } from "../tsx/traits";
5 import { on } from "../tsx/traits";
6 6
7 7 interface MyWidgetAttrs {
8 8 title: string;
@@ -61,13 +61,11 export class MyWidget extends djbase(Djx
61 61 }
62 62
63 63 @on("count-inc")
64 _onCounterInc(evt: Event & { detail: number; }) {
64 _onCounterInc(evt: Event & { detail: number; x?: number; }) {
65 }
66
67 @on("click")
68 _onClick() {
65 69
66 70 }
67 }
68
69 declare const w: MyWidget;
70 w.on("click", () => {});
71
72 declare const ev: WidgetEvents<MyWidget>;
73 ev["count-inc"];
71 } No newline at end of file
@@ -14,5 +14,4
14 14
15 15 rootProject.name = 'implabjs-djx'
16 16
17 include 'djx'
18 include 'playground' No newline at end of file
17 include 'djx' No newline at end of file
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now