bobjoll 1.0.3

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 (95) hide show
  1. package/README.md +35 -0
  2. package/package.json +25 -0
  3. package/scss/layout/_footer.scss +10 -0
  4. package/scss/layout/_header.scss +10 -0
  5. package/scss/modules/_fonts.scss +26 -0
  6. package/scss/modules/_reset.scss +219 -0
  7. package/scss/modules/bourbon/addons/_clearfix.scss +25 -0
  8. package/scss/modules/bourbon/addons/_ellipsis.scss +30 -0
  9. package/scss/modules/bourbon/addons/_position.scss +48 -0
  10. package/scss/modules/bourbon/addons/_prefixer.scss +66 -0
  11. package/scss/modules/bourbon/addons/_size.scss +51 -0
  12. package/scss/modules/bourbon/addons/_timing-functions.scss +34 -0
  13. package/scss/modules/bourbon/addons/_triangle.scss +63 -0
  14. package/scss/modules/bourbon/css3/_calc.scss +4 -0
  15. package/scss/modules/bourbon/css3/_flex-box.scss +287 -0
  16. package/scss/modules/bourbon/css3/_keyframes.scss +36 -0
  17. package/scss/modules/bourbon/css3/_linear-gradient.scss +38 -0
  18. package/scss/modules/bourbon/css3/_placeholder.scss +8 -0
  19. package/scss/modules/bourbon/css3/_selection.scss +42 -0
  20. package/scss/modules/bourbon/css3/_transition.scss +71 -0
  21. package/scss/modules/mixins/_component.scss +9 -0
  22. package/scss/modules/mixins/_grid.scss +75 -0
  23. package/scss/modules/mixins/_helpers.scss +224 -0
  24. package/scss/modules/variables/_colors.scss +447 -0
  25. package/scss/modules/variables/_general.scss +235 -0
  26. package/scss/partials/_accordion-v1-0.scss +165 -0
  27. package/scss/partials/_autocomplete-v1-0.scss +55 -0
  28. package/scss/partials/_general-v1-0.scss +51 -0
  29. package/scss/partials/_grid-v1-0.scss +109 -0
  30. package/scss/partials/_helper-v1-0.scss +299 -0
  31. package/scss/partials/_icon-v2-0.scss +323 -0
  32. package/scss/partials/_list-v1-0.scss +100 -0
  33. package/scss/partials/_modal-v1-0.scss +159 -0
  34. package/scss/partials/_notification-v1-1.scss +297 -0
  35. package/scss/partials/_progress-bar-v1.0.scss +25 -0
  36. package/scss/partials/_range-v1.0.scss +75 -0
  37. package/scss/partials/_tooltipFixed-v1.0.scss +128 -0
  38. package/scss/partials/_typography-v1-0.scss +201 -0
  39. package/scss/partials/animations/_fade.scss +23 -0
  40. package/scss/partials/animations/_rotate.scss +11 -0
  41. package/scss/partials/animations/_scale.scss +23 -0
  42. package/scss/partials/animations/_slide.scss +31 -0
  43. package/scss/partials/button-v4-0/_component.scss +304 -0
  44. package/scss/partials/form/_checkbox-and-radio-v1-0.scss +187 -0
  45. package/scss/partials/form/_dropdowns-v1-0.scss +323 -0
  46. package/scss/partials/form/_general-v1-0.scss +166 -0
  47. package/scss/partials/form/_group-v1-0.scss +157 -0
  48. package/scss/partials/form/_password-v1-0.scss +28 -0
  49. package/scss/partials/form/_switch-v1-0.scss +128 -0
  50. package/scss/partials/form/_upload-v1-0.scss +91 -0
  51. package/ts/library/common.ts +30 -0
  52. package/ts/library/cookie.ts +47 -0
  53. package/ts/library/delegate.ts +122 -0
  54. package/ts/library/dom.ts +124 -0
  55. package/ts/library/event.ts +138 -0
  56. package/ts/library/extend.js +32 -0
  57. package/ts/library/gr/dom.q.ts +12 -0
  58. package/ts/library/gr/social/dependency/twitter_pu.js +66 -0
  59. package/ts/library/gr/social/facebook.ts +154 -0
  60. package/ts/library/gr/social/google.ts +127 -0
  61. package/ts/library/gr/social/index.ts +35 -0
  62. package/ts/library/gr/social/twitter.ts +65 -0
  63. package/ts/library/helpers.ts +9 -0
  64. package/ts/library/number-abbreviate.js +57 -0
  65. package/ts/library/settings.ts +7 -0
  66. package/ts/library/storage.ts +131 -0
  67. package/ts/library/svg4everybody.legacy.js +122 -0
  68. package/ts/partials/accordion-v1.0.ts +104 -0
  69. package/ts/partials/accordionTabs-v1.0.ts +27 -0
  70. package/ts/partials/alert-v1.0.ts +51 -0
  71. package/ts/partials/copy-v1.0.ts +17 -0
  72. package/ts/partials/countdown-v1.0.ts +119 -0
  73. package/ts/partials/dropdown-v1.0.ts +247 -0
  74. package/ts/partials/hbs-v1.0.ts +9 -0
  75. package/ts/partials/modal-v1.0.ts +213 -0
  76. package/ts/partials/notifications-v1.1.ts +376 -0
  77. package/ts/partials/notify-v1.0.ts +746 -0
  78. package/ts/partials/password-v1.0.ts +19 -0
  79. package/ts/partials/popover-v1.0.ts +125 -0
  80. package/ts/partials/progress-bar-v1.0.ts +29 -0
  81. package/ts/partials/scroll-v1.0.ts +169 -0
  82. package/ts/partials/scrollable-v1.0.ts +90 -0
  83. package/ts/partials/tabs-v1.0.ts +79 -0
  84. package/ts/partials/tags-v1.0.ts +21 -0
  85. package/ts/partials/trigger-v2.0.ts +155 -0
  86. package/ts/partials/upload-v1.0.ts +17 -0
  87. package/ts/views/hbs/alert-v1.0/element.html.hbs +35 -0
  88. package/ts/views/hbs/countdown-v1.0/countdown-inner.hbs +39 -0
  89. package/ts/views/hbs/countdown-v1.0/countdown.hbs +4 -0
  90. package/ts/views/hbs/dropdown-v1.0/element.html.hbs +70 -0
  91. package/ts/views/hbs/helpers.js +58 -0
  92. package/ts/views/hbs/modal-v1.0/element.html.hbs +17 -0
  93. package/ts/views/hbs/notification-v1.1/element-disable.html.hbs +26 -0
  94. package/ts/views/hbs/notification-v1.1/element.html.hbs +43 -0
  95. package/ts/views/hbs/notification-v1.1/wrapper.html.hbs +4 -0
@@ -0,0 +1,128 @@
1
+ @if $form-v1-0 {
2
+ $switch-padding: 2px;
3
+ $switch-shadow: 0 $base-border-width 0 0 color('gray', 'state');
4
+
5
+ .switch {
6
+ @extend %row-flexbox;
7
+ @extend .row--vertical-center;
8
+
9
+ background-color: color('input', 'background');
10
+
11
+ cursor: pointer;
12
+
13
+ &:hover {
14
+ .switch__indicator::after {
15
+ background-color: color('secondary', 'background');
16
+ }
17
+ }
18
+
19
+ .switch__indicator ~ .switch__link,
20
+ .switch__link ~ .switch__indicator {
21
+ margin: 0 0 0 $small-spacing;
22
+ }
23
+
24
+ input[type="checkbox"],
25
+ input[type="radio"] {
26
+ display: none;
27
+
28
+ &:checked ~ .switch__indicator {
29
+ background-color: color('green', 'state');
30
+
31
+ &::before {
32
+ @include transform(scale(0));
33
+ }
34
+
35
+ &::after {
36
+ background-color: color('input', 'background');
37
+
38
+ box-shadow: 0 0 0 $base-border-width color('border', 'general', 0);
39
+ }
40
+ }
41
+
42
+ &:checked ~ .switch__link {
43
+ color: color('text', 'general');
44
+ }
45
+ }
46
+
47
+ @include element('indicator') {
48
+
49
+ position: relative;
50
+
51
+ display: block;
52
+
53
+ background: color('switch', 'background');
54
+
55
+ &::before {
56
+ @include position(absolute, $switch-padding null null $switch-padding);
57
+ @include transform(scale(1));
58
+ @include transition(all $base-duration $base-timing);
59
+
60
+ // background-color: color('input', 'background');
61
+
62
+ z-index: 1;
63
+
64
+ content: '';
65
+ }
66
+
67
+ &::after {
68
+ @include position(absolute, 0 null null 0);
69
+ @include transition(all $base-duration $base-timing);
70
+
71
+ margin: $switch-padding;
72
+
73
+ background-color: color('body', 'background');
74
+
75
+ box-shadow: $switch-shadow;
76
+
77
+ z-index: 2;
78
+
79
+ content: '';
80
+ }
81
+ }
82
+
83
+ // Sizes
84
+ @each $size in $sizes {
85
+ @include modifier($size) {
86
+ $spacing: map-get($input-ui-sizes, $size) / 2;
87
+ $switch-width: map-get($input-ui-sizes, $size) + $spacing;
88
+ $switch-height: map-get($input-ui-sizes, $size);
89
+ $switch-spacing: ((map-get($input-sizes, $size) - map-get($input-ui-sizes, $size)) / 2);
90
+ $switch-font-size: map-get($font-sizes, $size);
91
+
92
+ .switch__indicator {
93
+ width: $switch-width;
94
+ height: $switch-height;
95
+
96
+ border-radius: $switch-height;
97
+
98
+ line-height: $switch-height;
99
+
100
+ &::before {
101
+ width: $switch-width - ($switch-padding * 2);
102
+ height: $switch-height - ($switch-padding * 2);
103
+
104
+ border-radius: $switch-height - ($switch-padding * 2);
105
+ }
106
+
107
+ &::after {
108
+ width: $switch-height - ($switch-padding * 2);
109
+ height: $switch-height - ($switch-padding * 2);
110
+
111
+ border-radius: $switch-height - ($switch-padding * 2);
112
+ }
113
+ }
114
+
115
+ .switch__link {
116
+ font-size: $switch-font-size;
117
+ }
118
+
119
+ input[type="checkbox"],
120
+ input[type="radio"] {
121
+ &:checked ~ .switch__indicator::after {
122
+ left: ($switch-width - $switch-height);
123
+ }
124
+ }
125
+ }
126
+ }
127
+ }
128
+ }
@@ -0,0 +1,91 @@
1
+ @if $form-v1-0 {
2
+ .upload {
3
+ overflow: hidden;
4
+
5
+ height: $base-input-height;
6
+
7
+ margin: 0 0 $small-spacing;
8
+
9
+ border-radius: $base-border-radius;
10
+
11
+ line-height: $base-input-height - ($base-border-width * 2);
12
+
13
+ @include element('files') {
14
+ display: table-cell;
15
+
16
+ padding: 0 $base-spacing;
17
+
18
+ border: $base-border;
19
+ border-color: color('border', 'general', 1, 10);
20
+ border-right: none;
21
+
22
+ width: 100%;
23
+ }
24
+
25
+ @include element('link') {
26
+ @include transition(all $base-duration $base-timing);
27
+
28
+ position: relative;
29
+
30
+ display: table-cell;
31
+
32
+ padding: 0 $base-spacing;
33
+
34
+ background-color: color('button', 'general');
35
+
36
+ color: color('text-inverted', 'general');
37
+ white-space: nowrap;
38
+
39
+ &:hover {
40
+ background-color: color('button', 'general', 1, 10);
41
+
42
+ box-shadow: inset 0 ($base-border-width * -1) ($base-border-width) color('shadow', 'general', .35);
43
+
44
+ color: pick-visible-color(
45
+ color('button', 'general', 1, 10),
46
+ color('text', 'general'),
47
+ color('text-inverted', 'general')
48
+ );
49
+ }
50
+
51
+ @include modifier('icon') {
52
+ padding: 0 $base-spacing 0 ($base-spacing + $small-icon-width + $small-spacing);
53
+
54
+ svg {
55
+ @include position(absolute, 50% null null $base-spacing);
56
+ @include transform(translateY(-50%));
57
+
58
+ fill: color('icon-inverted', 'general');
59
+ }
60
+ }
61
+ }
62
+
63
+ @include modifier('sm') {
64
+ height: $small-input-height;
65
+
66
+ line-height: $small-input-height - ($base-border-width * 2);
67
+ }
68
+
69
+ @include modifier('large') {
70
+ height: $large-input-height;
71
+
72
+ line-height: $large-input-height - ($base-border-width * 2);
73
+ }
74
+
75
+ @include modifier('inline') {
76
+ display: inline-block;
77
+ }
78
+
79
+ input[type="file"] {
80
+ display: none;
81
+ }
82
+
83
+ label {
84
+ display: table;
85
+
86
+ width: 100%;
87
+
88
+ cursor: pointer;
89
+ }
90
+ }
91
+ } // End if
@@ -0,0 +1,30 @@
1
+ interface Element {
2
+ parent(selector: string): Element | undefined;
3
+ parents(selector: string): Element[];
4
+ }
5
+
6
+ Element.prototype.parent = function (this: Element, selector: string) {
7
+ return this.parents(selector)[0];
8
+ };
9
+
10
+ Element.prototype.parents = function (
11
+ this: Element,
12
+ selector: string
13
+ ): Element[] {
14
+ var elements: Element[] = [];
15
+ var elem: Element | null = this;
16
+
17
+ if (elem && elem.parentElement) {
18
+ while ((elem = elem.parentElement) !== null) {
19
+ if (elem.nodeType !== Node.ELEMENT_NODE) {
20
+ continue;
21
+ }
22
+
23
+ if (selector && elem.matches(selector)) {
24
+ elements.push(elem);
25
+ }
26
+ }
27
+ }
28
+
29
+ return elements;
30
+ };
@@ -0,0 +1,47 @@
1
+ export class Cookie {
2
+ public static setItem(name: string, value: string, options?: CookieOptions) {
3
+ let cookieSettings: CookieSettings = {
4
+ expires: new Date(new Date().getTime() + (24 * 60 * 60 * 1000 * 365)),
5
+ path: '/',
6
+ ...options
7
+ };
8
+ let cookieString = `${name}=${value};path=${cookieSettings.path}`;
9
+
10
+ if (cookieSettings.domain) {
11
+ cookieString += `;domain=${cookieSettings.domain}`;
12
+ }
13
+
14
+ cookieString += `;expires=${cookieSettings.expires.toUTCString()}`;
15
+
16
+ document.cookie = cookieString;
17
+ }
18
+
19
+ public static getItem(name: string) {
20
+ let c = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
21
+ return c ? c[2] : null;
22
+ }
23
+
24
+ public static removeItem(name: string) {
25
+ Cookie.setItem(name, '', {
26
+ expires: new Date(),
27
+ });
28
+ }
29
+
30
+ public static isEnabled() {
31
+ document.cookie = "testcookie";
32
+ var cookieEnabled = (document.cookie.indexOf("testcookie") != -1) ? true : false;
33
+ return cookieEnabled || false;
34
+ }
35
+ }
36
+
37
+ interface CookieOptions {
38
+ expires?: Date;
39
+ path?: string;
40
+ domain?: string;
41
+ }
42
+
43
+ interface CookieSettings {
44
+ expires: Date;
45
+ path: string;
46
+ domain?: string;
47
+ }
@@ -0,0 +1,122 @@
1
+ class DelegateListeners {
2
+ private static listeners: {
3
+ [name: string]: {
4
+ eventType: Event['type'];
5
+ eventHandler: Function;
6
+ elementScopeHandler: EventListener;
7
+ }[];
8
+ } = {};
9
+
10
+ public static set(selector: string, eventType: Event['type'], eventHandler: Function, elementScopeHandler: EventListener) {
11
+ if (!DelegateListeners.listeners[selector]) {
12
+ DelegateListeners.listeners[selector] = [];
13
+ }
14
+
15
+ if (this.unique(DelegateListeners.listeners[selector], eventType, eventHandler)) {
16
+ let listener = {
17
+ eventType: eventType,
18
+ eventHandler: eventHandler,
19
+ elementScopeHandler: elementScopeHandler,
20
+ };
21
+
22
+ DelegateListeners.listeners[selector].push(listener);
23
+
24
+ return listener;
25
+ } else {
26
+ return this.get(selector, eventType, eventHandler);
27
+ }
28
+ }
29
+
30
+ public static get(selector: string, eventType: Event['type'], eventHandler: Function) {
31
+ if (DelegateListeners.listeners[selector]) {
32
+ try {
33
+ return DelegateListeners.listeners[selector].filter((listener) => {
34
+ return eventHandler === listener.eventHandler && eventType === listener.eventType;
35
+ })[0];
36
+ } catch (err) { };
37
+ }
38
+
39
+ return null;
40
+ }
41
+
42
+ public static delete(selector: string, eventType: Event['type'], eventHandler: Function) {
43
+ let deleteListenersID: number[] = [];
44
+
45
+ if (DelegateListeners.listeners[selector]) {
46
+ DelegateListeners.listeners[selector].forEach((listener, index: number) => {
47
+ if (eventType === listener.eventType && eventHandler === listener.eventHandler) {
48
+ deleteListenersID.unshift(index);
49
+ }
50
+ });
51
+
52
+ deleteListenersID.forEach((id) => {
53
+ DelegateListeners.listeners[selector].splice(id, 1);
54
+ });
55
+
56
+ if (0 === DelegateListeners.listeners[selector].length) {
57
+ delete DelegateListeners.listeners[selector];
58
+ }
59
+ }
60
+ }
61
+
62
+ private static unique(listeners: {
63
+ eventType: Event['type'];
64
+ eventHandler: Function;
65
+ elementScopeHandler: EventListener;
66
+ }[], eventType: Event['type'], eventHandler: Function): boolean {
67
+ try {
68
+ let existing = listeners.filter((listener) => {
69
+ return eventHandler === listener.eventHandler && eventType === listener.eventType;
70
+ });
71
+
72
+ if (0 === existing.length) {
73
+ return true;
74
+ } else {
75
+ return false;
76
+ }
77
+ } catch (err) {
78
+ return false;
79
+ }
80
+ }
81
+ }
82
+
83
+ export function q(selector: string, parent: HTMLElement | Document = document): HTMLElement | null {
84
+ const x = parent.querySelector(selector);
85
+
86
+ return x ? x as HTMLElement : x;
87
+ }
88
+
89
+ export function qq(selector: string, parent: HTMLElement | Document = document): HTMLElement[] {
90
+ return Array.prototype.slice.call(parent.querySelectorAll(selector), 0);
91
+ }
92
+
93
+ export function delegate(selector: string, eventType: Event['type'], eventHandler: Function, elementScope: HTMLElement | Document = document) {
94
+ let listener = DelegateListeners.set(selector, eventType, eventHandler, function (event: any) {
95
+ try {
96
+ let target = event.target;
97
+
98
+ while (target && target !== elementScope) {
99
+ if (target.matches(selector)) {
100
+ eventHandler.call(target, [event]);
101
+ break;
102
+ }
103
+
104
+ target = (<Element>target.parentNode);
105
+ }
106
+ } catch (err) { }
107
+ });
108
+
109
+ if (listener) {
110
+ elementScope.addEventListener(eventType, listener.elementScopeHandler);
111
+ }
112
+ }
113
+
114
+ export function delegateRemove(selector: string, eventType: Event['type'], eventHandler: Function, elementScope: HTMLElement | Document = document) {
115
+ let listener = DelegateListeners.get(selector, eventType, eventHandler);
116
+
117
+ if (listener) {
118
+ elementScope.removeEventListener(eventType, listener.elementScopeHandler);
119
+
120
+ DelegateListeners.delete(selector, eventType, eventHandler);
121
+ }
122
+ }
@@ -0,0 +1,124 @@
1
+ class DelegateListeners {
2
+ private static listeners: {
3
+ [name: string]: {
4
+ eventType: Event['type'];
5
+ eventHandler: Function;
6
+ elementScopeHandler: EventListener;
7
+ }[];
8
+ } = {};
9
+
10
+ public static set(selector: string, eventType: Event['type'], eventHandler: Function, elementScopeHandler: EventListener) {
11
+ if (!DelegateListeners.listeners[selector]) {
12
+ DelegateListeners.listeners[selector] = [];
13
+ }
14
+
15
+ if (this.unique(DelegateListeners.listeners[selector], eventType, eventHandler)) {
16
+ let listener = {
17
+ eventType: eventType,
18
+ eventHandler: eventHandler,
19
+ elementScopeHandler: elementScopeHandler,
20
+ };
21
+
22
+ DelegateListeners.listeners[selector].push(listener);
23
+
24
+ return listener;
25
+ } else {
26
+ return this.get(selector, eventType, eventHandler);
27
+ }
28
+ }
29
+
30
+ public static get(selector: string, eventType: Event['type'], eventHandler: Function) {
31
+ if (DelegateListeners.listeners[selector]) {
32
+ try {
33
+ return DelegateListeners.listeners[selector].filter((listener) => {
34
+ return eventHandler === listener.eventHandler && eventType === listener.eventType;
35
+ })[0];
36
+ } catch (err) { };
37
+ }
38
+
39
+ return null;
40
+ }
41
+
42
+ public static delete(selector: string, eventType: Event['type'], eventHandler: Function) {
43
+ let deleteListenersID: number[] = [];
44
+
45
+ if (DelegateListeners.listeners[selector]) {
46
+ DelegateListeners.listeners[selector].forEach((listener, index: number) => {
47
+ if (eventType === listener.eventType && eventHandler === listener.eventHandler) {
48
+ deleteListenersID.unshift(index);
49
+ }
50
+ });
51
+
52
+ deleteListenersID.forEach((id) => {
53
+ DelegateListeners.listeners[selector].splice(id, 1);
54
+ });
55
+
56
+ if (0 === DelegateListeners.listeners[selector].length) {
57
+ delete DelegateListeners.listeners[selector];
58
+ }
59
+ }
60
+ }
61
+
62
+ private static unique(listeners: {
63
+ eventType: Event['type'];
64
+ eventHandler: Function;
65
+ elementScopeHandler: EventListener;
66
+ }[], eventType: Event['type'], eventHandler: Function): boolean {
67
+ try {
68
+ let existing = listeners.filter((listener) => {
69
+ return eventHandler === listener.eventHandler && eventType === listener.eventType;
70
+ });
71
+
72
+ if (0 === existing.length) {
73
+ return true;
74
+ } else {
75
+ return false;
76
+ }
77
+ } catch (err) {
78
+ return false;
79
+ }
80
+ }
81
+ }
82
+
83
+ export const ww = (window as any);
84
+
85
+ export function delegate(selector: string, eventType: Event['type'], eventHandler: Function, elementScope: HTMLElement | Document = document) {
86
+ let listener = DelegateListeners.set(selector, eventType, eventHandler, function (event: any) {
87
+ try {
88
+ let target = event.target;
89
+
90
+ while (target && target !== elementScope) {
91
+ if (target.matches(selector)) {
92
+ eventHandler.call(target, event);
93
+ break;
94
+ }
95
+
96
+ target = (<Element>target.parentNode);
97
+ }
98
+ } catch (err) { }
99
+ });
100
+
101
+ if (listener) {
102
+ elementScope.addEventListener(eventType, listener.elementScopeHandler);
103
+ }
104
+ }
105
+
106
+ export function delegateRemove(selector: string, eventType: Event['type'], eventHandler: Function, elementScope: HTMLElement | Document = document) {
107
+ let listener = DelegateListeners.get(selector, eventType, eventHandler);
108
+
109
+ if (listener) {
110
+ elementScope.removeEventListener(eventType, listener.elementScopeHandler);
111
+
112
+ DelegateListeners.delete(selector, eventType, eventHandler);
113
+ }
114
+ }
115
+
116
+ export function q(selector: string, parent: HTMLElement | Document = document): HTMLElement | null {
117
+ const x = parent.querySelector(selector);
118
+
119
+ return x ? x as HTMLElement : x;
120
+ }
121
+
122
+ export function qq(selector: string, parent: HTMLElement | Document = document): HTMLElement[] {
123
+ return Array.prototype.slice.call(parent.querySelectorAll(selector), 0);
124
+ }
@@ -0,0 +1,138 @@
1
+ 'use strict';
2
+
3
+ export abstract class KEventTarget {
4
+ private eventListeners: { [type: string]: ((ev: KEvent) => any)[] };
5
+
6
+ constructor() {
7
+ this.eventListeners = {};
8
+ }
9
+
10
+ public addEventListener(type: string, listener: (ev: KEvent) => any, useCapture: boolean = true) {
11
+ const listeners = this.getListeners(type, useCapture);
12
+ listeners.push(listener);
13
+ }
14
+
15
+ public removeEventListener(type: string, listener: (ev: KEvent) => any, useCapture: boolean = true) {
16
+ const listeners = this.getListeners(type, useCapture);
17
+ const i = listeners.indexOf(listener);
18
+ if (i !== -1) {
19
+ listeners.splice(i, 1);
20
+ }
21
+ }
22
+
23
+ public dispatchEvent(evt: KEvent): boolean {
24
+ const ancestors: KEventTarget[] = [this];
25
+ let parent = this.getParent();
26
+
27
+ while (parent != null) {
28
+ ancestors.push(parent);
29
+ parent = parent.getParent();
30
+ }
31
+
32
+ evt._target = this;
33
+ ancestors.reverse();
34
+ for (const target of ancestors) {
35
+ target.fireEvent(evt, true);
36
+ if (evt.stopPropagationFlag) {
37
+ return true;
38
+ }
39
+ }
40
+
41
+ ancestors.reverse();
42
+ for (const target of ancestors) {
43
+ target.fireEvent(evt, false);
44
+ if (evt.stopPropagationFlag) {
45
+ return true;
46
+ }
47
+ }
48
+
49
+ return true;
50
+ }
51
+
52
+ private fireEvent(evt: KEvent, capture: boolean): void {
53
+ const listeners = this.getListeners(evt.type, capture);
54
+ evt._currentTarget = this;
55
+
56
+ for (const l of listeners) {
57
+ l.call(this, evt);
58
+ if (evt.stopImmediatePropagationFlag) {
59
+ break;
60
+ }
61
+ }
62
+ }
63
+
64
+ private getListeners(type: string, capture: boolean) {
65
+ const key = type + (capture ? 'c' : 'b');
66
+ let listeners = this.eventListeners[key];
67
+ if (!listeners) {
68
+ listeners = this.eventListeners[key] = [];
69
+ }
70
+ return listeners;
71
+ }
72
+
73
+ private getParent(): KEventTarget | null {
74
+ return null;
75
+ }
76
+ }
77
+
78
+ class KDummyEventTarget extends KEventTarget {
79
+ }
80
+
81
+ export class KEvent {
82
+ public type: string;
83
+ public _target: KEventTarget;
84
+ public _currentTarget: KEventTarget;
85
+ public stopPropagationFlag: boolean;
86
+ public stopImmediatePropagationFlag: boolean;
87
+ public extra: { [key: string]: any };
88
+
89
+ constructor(public wrappedEvent?: Event) {
90
+ if (wrappedEvent) {
91
+ this.type = wrappedEvent.type;
92
+ } else {
93
+ this.type = 'unknown';
94
+ }
95
+ this._target = this._currentTarget = new KDummyEventTarget();
96
+ this.extra = {};
97
+ this.stopPropagationFlag = false;
98
+ this.stopImmediatePropagationFlag = false;
99
+ }
100
+
101
+ // tslint:disable-next-line:function-name
102
+ public static fromType(type: string, extra?: { [key: string]: any }): KEvent {
103
+ const ev = new KEvent();
104
+ ev.type = type;
105
+ if (extra) {
106
+ ev.setExtra(extra);
107
+ }
108
+ return ev;
109
+ }
110
+
111
+ public get target() {
112
+ return this._target;
113
+ }
114
+
115
+ public get currentTarget() {
116
+ return this._currentTarget;
117
+ }
118
+
119
+ public setExtra(e: { [key: string]: any }): this {
120
+ this.extra = e;
121
+ return this;
122
+ }
123
+
124
+ public stopPropagation() {
125
+ this.stopPropagationFlag = true;
126
+ if (this.wrappedEvent) {
127
+ this.wrappedEvent.stopPropagation();
128
+ }
129
+ }
130
+
131
+ public stopImmediatePropagation() {
132
+ this.stopPropagationFlag = true;
133
+ this.stopImmediatePropagationFlag = true;
134
+ if (this.wrappedEvent) {
135
+ this.wrappedEvent.stopImmediatePropagation();
136
+ }
137
+ }
138
+ }