lupine.web 1.0.14

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 (94) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3 -0
  3. package/jsx-runtime/index.js +14 -0
  4. package/jsx-runtime/package.json +16 -0
  5. package/jsx-runtime/src/index.d.ts +2 -0
  6. package/package.json +51 -0
  7. package/src/assets/themes/base-themes.ts +16 -0
  8. package/src/assets/themes/dark-themes.ts +85 -0
  9. package/src/assets/themes/index.ts +4 -0
  10. package/src/assets/themes/light-themes.ts +92 -0
  11. package/src/assets/themes/shared-themes.ts +50 -0
  12. package/src/components/button-push-animation.tsx +138 -0
  13. package/src/components/button.tsx +55 -0
  14. package/src/components/drag-refresh.tsx +110 -0
  15. package/src/components/editable-label.tsx +83 -0
  16. package/src/components/float-window.tsx +226 -0
  17. package/src/components/grid.tsx +18 -0
  18. package/src/components/html-var.tsx +41 -0
  19. package/src/components/index.ts +36 -0
  20. package/src/components/input-with-title.tsx +24 -0
  21. package/src/components/link-item.tsx +13 -0
  22. package/src/components/link-list.tsx +62 -0
  23. package/src/components/menu-bar.tsx +220 -0
  24. package/src/components/menu-item-props.tsx +10 -0
  25. package/src/components/menu-sidebar.tsx +289 -0
  26. package/src/components/message-box.tsx +44 -0
  27. package/src/components/meta-data.tsx +54 -0
  28. package/src/components/meta-description.tsx +19 -0
  29. package/src/components/meta-title.tsx +19 -0
  30. package/src/components/modal.tsx +29 -0
  31. package/src/components/notice-message.tsx +119 -0
  32. package/src/components/paging-link.tsx +100 -0
  33. package/src/components/panel.tsx +24 -0
  34. package/src/components/popup-menu.tsx +218 -0
  35. package/src/components/progress.tsx +91 -0
  36. package/src/components/redirect.tsx +19 -0
  37. package/src/components/resizable-splitter.tsx +129 -0
  38. package/src/components/select-with-title.tsx +37 -0
  39. package/src/components/spinner.tsx +100 -0
  40. package/src/components/svg.tsx +24 -0
  41. package/src/components/tabs.tsx +252 -0
  42. package/src/components/text-glow.tsx +36 -0
  43. package/src/components/text-wave.tsx +54 -0
  44. package/src/components/theme-selector.tsx +35 -0
  45. package/src/components/toggle-base.tsx +260 -0
  46. package/src/components/toggle-switch.tsx +156 -0
  47. package/src/core/bind-attributes.ts +58 -0
  48. package/src/core/bind-lang.ts +51 -0
  49. package/src/core/bind-links.ts +16 -0
  50. package/src/core/bind-ref.ts +33 -0
  51. package/src/core/bind-styles.ts +180 -0
  52. package/src/core/bind-theme.ts +51 -0
  53. package/src/core/camel-to-hyphens.ts +3 -0
  54. package/src/core/core.ts +179 -0
  55. package/src/core/index.ts +15 -0
  56. package/src/core/mount-components.ts +259 -0
  57. package/src/core/page-loaded-events.ts +16 -0
  58. package/src/core/page-router.ts +170 -0
  59. package/src/core/replace-innerhtml.ts +10 -0
  60. package/src/core/server-cookie.ts +22 -0
  61. package/src/core/web-version.ts +12 -0
  62. package/src/global.d.ts +66 -0
  63. package/src/index.ts +15 -0
  64. package/src/jsx.ts +1041 -0
  65. package/src/lib/date-utils.ts +317 -0
  66. package/src/lib/debug-watch.ts +31 -0
  67. package/src/lib/deep-merge.ts +37 -0
  68. package/src/lib/document-ready.ts +36 -0
  69. package/src/lib/dom/calculate-text-width.ts +13 -0
  70. package/src/lib/dom/cookie.ts +41 -0
  71. package/src/lib/dom/download-stream.ts +17 -0
  72. package/src/lib/dom/download.ts +12 -0
  73. package/src/lib/dom/index.ts +71 -0
  74. package/src/lib/dynamical-load.ts +138 -0
  75. package/src/lib/format-bytes.ts +11 -0
  76. package/src/lib/index.ts +17 -0
  77. package/src/lib/lite-dom.ts +227 -0
  78. package/src/lib/logger.ts +55 -0
  79. package/src/lib/message-hub.ts +105 -0
  80. package/src/lib/observable.ts +188 -0
  81. package/src/lib/promise-timeout.ts +1 -0
  82. package/src/lib/simple-storage.ts +40 -0
  83. package/src/lib/stop-propagation.ts +7 -0
  84. package/src/lib/unique-id.ts +39 -0
  85. package/src/lib/upload-file.ts +68 -0
  86. package/src/lib/web-env.ts +98 -0
  87. package/src/models/index.ts +2 -0
  88. package/src/models/simple-storage-props.ts +9 -0
  89. package/src/models/to-client-delivery-props.ts +8 -0
  90. package/src/types/css-styles.ts +814 -0
  91. package/src/types/css-types.ts +17 -0
  92. package/src/types/index.ts +6 -0
  93. package/src/types/media-query.ts +93 -0
  94. package/tsconfig.json +113 -0
@@ -0,0 +1,260 @@
1
+ import { CssProps, RefProps, VNode } from 'lupine.js';
2
+
3
+ export const PlayButtonSize = {
4
+ Small: { w: 50, h: 50 },
5
+ Medium: { w: 70, h: 70 },
6
+ Large: { w: 90, h: 90 },
7
+ };
8
+ export type PlayButtonSizeProps = {
9
+ w: number;
10
+ h: number;
11
+ };
12
+ export type PlayButtonProps = {
13
+ size: PlayButtonSizeProps;
14
+ disabled?: boolean;
15
+ checked?: boolean;
16
+ onClick?: (checked: boolean) => void;
17
+ hook?: ToggleBaseHookProps;
18
+ };
19
+ export const PlayButton = (props: PlayButtonProps) => {
20
+ const css: CssProps = {
21
+ width: `100%`,
22
+ height: `100%`,
23
+ borderRadius: '50%',
24
+ backgroundColor: '#3b29cc',
25
+ display: 'flex',
26
+ alignItems: 'center',
27
+ justifyContent: 'center',
28
+ '.play-icon': {
29
+ width: '50%',
30
+ height: '50%',
31
+ transition: 'all 0.2s ease-in-out',
32
+ backgroundColor: '#fff',
33
+ cursor: 'pointer',
34
+ },
35
+ '&.toggle-off .play-icon': {
36
+ clipPath: 'polygon(20% 0, 20% 100%, 90% 50%, 90% 50%, 90% 50%, 90% 50%, 90% 50%, 90% 50%, 90% 50%)',
37
+ translate: '6% 0',
38
+ },
39
+ '&.toggle-on .play-icon': {
40
+ clipPath: 'polygon(0 0, 0 100%, 33.33% 100%, 33.33% 0, 66.66% 0, 100% 0, 100% 100%, 66.66% 100%, 66.66% 0)',
41
+ translate: '0 0',
42
+ },
43
+ '&.disabled': {
44
+ cursor: 'not-allowed',
45
+ backgroundColor: '#5d578b',
46
+ },
47
+ };
48
+ return (
49
+ <ToggleBase {...props}>
50
+ <ToggleWaveFrame>
51
+ <div
52
+ css={css}
53
+ class={`toggle-button-component toggle-placeholder ${props.checked ? 'toggle-on' : 'toggle-off'}${
54
+ props.disabled ? ' disabled' : ''
55
+ }`}
56
+ >
57
+ <div class='play-icon'></div>
58
+ </div>
59
+ </ToggleWaveFrame>
60
+ </ToggleBase>
61
+ );
62
+ };
63
+
64
+ export type ToggleButtonProps = {
65
+ size: ToggleBaseSizeProps;
66
+ onText: string;
67
+ offText: string;
68
+ disabled?: boolean;
69
+ checked?: boolean;
70
+ onClick?: (checked: boolean) => void;
71
+ hook?: ToggleBaseHookProps;
72
+ };
73
+ export const ToggleButton = (props: ToggleButtonProps) => {
74
+ const css: CssProps = {
75
+ // width: `${props.size + 5}px`,
76
+ // height: `${props.size + 5}px`,
77
+ '&.disabled': {
78
+ cursor: 'not-allowed',
79
+ },
80
+ '&.toggle-on .on, &.toggle-off .off': {
81
+ display: 'block',
82
+ },
83
+ '&.toggle-on .off, &.toggle-off .on': {
84
+ display: 'none',
85
+ },
86
+ };
87
+ return (
88
+ <ToggleBase {...props}>
89
+ <div
90
+ css={css}
91
+ class={`toggle-button-component toggle-placeholder ${props.checked ? 'toggle-on' : 'toggle-off'}${
92
+ props.disabled ? ' disabled' : ''
93
+ }`}
94
+ >
95
+ <div class='on'>{props.onText}</div>
96
+ <div class='off'>{props.offText}</div>
97
+ </div>
98
+ </ToggleBase>
99
+ );
100
+ };
101
+
102
+ export type ToggleWaveFrameProps = {
103
+ children: VNode<any>;
104
+ };
105
+ export const ToggleWaveFrame = (props: ToggleWaveFrameProps) => {
106
+ const css: CssProps = {
107
+ width: `100%`,
108
+ height: `100%`,
109
+ '@keyframes pulse-border': {
110
+ '0%': {
111
+ transform: 'scale(0.6)',
112
+ opacity: 1,
113
+ },
114
+ '100%': {
115
+ transform: 'scale(1)',
116
+ opacity: 0,
117
+ },
118
+ },
119
+ '.toggle-waves': {
120
+ position: 'absolute',
121
+ width: `100%`,
122
+ height: `100%`,
123
+ top: '-0',
124
+ left: '0',
125
+ borderRadius: '50%',
126
+ backgroundColor: '#eb205580',
127
+ opacity: 0,
128
+ zIndex: -1,
129
+ animation: 'pulse-border 3s ease-in-out infinite',
130
+ },
131
+ '.toggle-waves-1': {
132
+ '-webkit-animation-delay': '0s',
133
+ 'animation-delay': '0s',
134
+ },
135
+
136
+ '.toggle-waves-2': {
137
+ '-webkit-animation-delay': '1s',
138
+ 'animation-delay': '1s',
139
+ },
140
+
141
+ '.toggle-waves-3': {
142
+ '-webkit-animation-delay': '2s',
143
+ 'animation-delay': '2s',
144
+ },
145
+ '.toggle-waves-box': {
146
+ width: `100%`,
147
+ height: `100%`,
148
+ padding: `18%`,
149
+ },
150
+ '&.disabled .toggle-waves': {
151
+ backgroundColor: '#5d578b',
152
+ },
153
+ };
154
+ return (
155
+ <div css={css} class='toggle-waves-box toggle-placeholder'>
156
+ <div class='toggle-waves toggle-waves-1'></div>
157
+ <div class='toggle-waves toggle-waves-2'></div>
158
+ <div class='toggle-waves toggle-waves-3'></div>
159
+ <div class='toggle-waves-box'>{props.children}</div>
160
+ </div>
161
+ );
162
+ };
163
+
164
+ export const ToggleBaseSize = {
165
+ Small: { w: 30, h: 30 },
166
+ Medium: { w: 50, h: 50 },
167
+ Large: { w: 70, h: 70 },
168
+ };
169
+ export type ToggleBaseSizeProps = {
170
+ w: number | string;
171
+ h: number | string;
172
+ };
173
+ export type ToggleBaseHookProps = {
174
+ setChecked?: (checked: boolean) => void;
175
+ getChecked?: () => boolean;
176
+ setEnabled?: (enabled: boolean) => void;
177
+ getEnabled?: () => boolean;
178
+ };
179
+ export type ToggleBaseProps = {
180
+ size: ToggleBaseSizeProps;
181
+ disabled?: boolean;
182
+ checked?: boolean;
183
+ onClick?: (checked: boolean) => void;
184
+ hook?: ToggleBaseHookProps;
185
+ children: VNode<any>;
186
+ };
187
+ export const ToggleBase = (props: ToggleBaseProps) => {
188
+ const applyToggle = (checked: boolean, disabled: boolean) => {
189
+ const childDom = ref.$all('.toggle-base-container .toggle-placeholder');
190
+ childDom.forEach((dom: HTMLElement) => {
191
+ dom.classList.toggle('toggle-on', checked);
192
+ dom.classList.toggle('toggle-off', !checked);
193
+ dom.classList.toggle('disabled', disabled);
194
+ });
195
+ };
196
+ let disabled = props.disabled || false;
197
+ const ref: RefProps = {
198
+ onLoad: async (el: Element) => {
199
+ applyToggle(props.checked || false, disabled);
200
+ },
201
+ };
202
+ const onClick = (e: MouseEvent) => {
203
+ if (disabled) {
204
+ return;
205
+ }
206
+
207
+ const checked = (e.target as HTMLInputElement).checked;
208
+ applyToggle(checked, disabled);
209
+ if (props.onClick) {
210
+ props.onClick(checked);
211
+ }
212
+ };
213
+ if (props.hook) {
214
+ props.hook.setChecked = (checked: boolean) => {
215
+ (ref.$('input.toggle-base-checkbox') as HTMLInputElement).checked = checked;
216
+ applyToggle(checked, disabled);
217
+ };
218
+ props.hook.getChecked = () => {
219
+ return (ref.$('input.toggle-base-checkbox') as HTMLInputElement).checked;
220
+ };
221
+ props.hook.setEnabled = (enabled: boolean) => {
222
+ disabled = !enabled;
223
+ const dom = ref.$('input.toggle-base-checkbox') as HTMLInputElement;
224
+ dom.disabled = disabled;
225
+ applyToggle(dom.checked, disabled);
226
+ };
227
+ props.hook.getEnabled = () => {
228
+ return !disabled;
229
+ };
230
+ }
231
+
232
+ const css: CssProps = {
233
+ width: `${typeof props.size.w === 'number' ? props.size.w + 'px' : props.size.w}`,
234
+ height: `${typeof props.size.h === 'number' ? props.size.h + 'px' : props.size.h}`,
235
+ '.toggle-base-box, .toggle-base-container': {
236
+ position: 'relative',
237
+ width: `100%`,
238
+ height: `100%`,
239
+ },
240
+ '.toggle-base-checkbox': {
241
+ opacity: 0,
242
+ position: 'absolute',
243
+ pointerEvents: 'none',
244
+ },
245
+ };
246
+ return (
247
+ <div ref={ref} css={css} class='toggle-base-component'>
248
+ <label class='toggle-base-box'>
249
+ <div class='toggle-base-container'>{props.children}</div>
250
+ <input
251
+ type='checkbox'
252
+ class='toggle-base-checkbox'
253
+ checked={props.checked || false}
254
+ disabled={disabled}
255
+ onClick={onClick}
256
+ />
257
+ </label>
258
+ </div>
259
+ );
260
+ };
@@ -0,0 +1,156 @@
1
+ import { bindGlobalStyles, CssProps } from 'lupine.js';
2
+ import { ToggleBase, ToggleBaseHookProps } from './toggle-base';
3
+
4
+ export enum ToggleSwitchSize {
5
+ SmallSmall = 'smallsmall',
6
+ Small = 'small',
7
+ Medium = 'medium',
8
+ Large = 'large',
9
+ }
10
+ export type ToggleSwitchProps = {
11
+ size: ToggleSwitchSize;
12
+ text?: { on: string; off: string };
13
+ textWidth?: string;
14
+ disabled?: boolean;
15
+ checked?: boolean;
16
+ onClick?: (checked: boolean) => void;
17
+ hook?: ToggleBaseHookProps;
18
+ };
19
+ export const ToggleSwitch = (props: ToggleSwitchProps) => {
20
+ const sizeH =
21
+ props.size === ToggleSwitchSize.SmallSmall
22
+ ? 16
23
+ : props.size === ToggleSwitchSize.Small
24
+ ? 22
25
+ : props.size === ToggleSwitchSize.Large
26
+ ? 42
27
+ : 34;
28
+ const cssSize =
29
+ props.size === ToggleSwitchSize.SmallSmall
30
+ ? 'smallsmall'
31
+ : props.size === ToggleSwitchSize.Small
32
+ ? 'small'
33
+ : props.size === ToggleSwitchSize.Large
34
+ ? 'large'
35
+ : '';
36
+
37
+ const css: CssProps = {
38
+ width: `100%`,
39
+ height: `100%`,
40
+ display: 'flex',
41
+ alignItems: 'center',
42
+ justifyContent: 'center',
43
+ '& .ts-slider': {
44
+ position: 'relative',
45
+ cursor: 'pointer',
46
+ backgroundColor: 'var(--toggle-background-color, #c7c7c7)',
47
+ transition: '.4s',
48
+ borderRadius: '34px',
49
+ height: '100%',
50
+ display: 'flex',
51
+ padding: '0 27px 0 37px',
52
+ alignItems: 'center',
53
+ },
54
+ '&.smallsmall .ts-slider': {
55
+ padding: '0 8px 0 22px',
56
+ fontSize: '0.65rem',
57
+ },
58
+ '&.small .ts-slider': {
59
+ padding: '0 17px 0 27px',
60
+ fontSize: '0.85rem',
61
+ },
62
+ '&.large .ts-slider': {
63
+ padding: '0 37px 0 57px',
64
+ },
65
+
66
+ '& .ts-slider .ts-circle': {
67
+ position: 'absolute',
68
+ content: '',
69
+ height: '26px',
70
+ width: '26px',
71
+ left: '4px',
72
+ bottom: '4px',
73
+ backgroundColor: 'var(--toggle-ball-color, #fff)',
74
+ transition: '.4s',
75
+ borderRadius: '50%',
76
+ },
77
+ '&.smallsmall .ts-slider .ts-circle': {
78
+ height: '12px',
79
+ width: '12px',
80
+ left: '2px',
81
+ bottom: '2px',
82
+ },
83
+ '&.small .ts-slider .ts-circle': {
84
+ height: '18px',
85
+ width: '18px',
86
+ left: '3px',
87
+ bottom: '2px',
88
+ },
89
+ '&.large .ts-slider .ts-circle': {
90
+ height: '38px',
91
+ width: '38px',
92
+ left: '4px',
93
+ bottom: '2px',
94
+ },
95
+
96
+ '& .ts-on-text, & .ts-off-text': {
97
+ display: 'none',
98
+ width: props.textWidth,
99
+ },
100
+ '&.toggle-on .ts-on-text': {
101
+ display: 'block',
102
+ },
103
+ '&.toggle-off .ts-off-text': {
104
+ display: 'block',
105
+ },
106
+
107
+ '&.toggle-on .ts-slider': {
108
+ backgroundColor: 'var(--primary-accent-color, #0a74c9)',
109
+ padding: '0 47px 0 17px',
110
+ },
111
+ '&.smallsmall.toggle-on .ts-slider': {
112
+ padding: '0 18px 0 12px',
113
+ },
114
+ '&.small.toggle-on .ts-slider': {
115
+ padding: '0 27px 0 17px',
116
+ },
117
+ '&.large.toggle-on .ts-slider': {
118
+ padding: '0 72px 0 22px',
119
+ },
120
+
121
+ '&.toggle-on .ts-slider .ts-circle': {
122
+ left: 'unset',
123
+ right: '3px',
124
+ },
125
+ '&.disabled .ts-slider': {
126
+ cursor: 'not-allowed',
127
+ opacity: 'var(--primary-disabled-opacity)',
128
+ },
129
+ };
130
+
131
+ // this is a sample to add variables for a theme
132
+ const cssTheme: CssProps = {
133
+ '[data-theme="dark" i]': {
134
+ '--toggle-ball-color': '#000000',
135
+ '--toggle-background-color': '#262626',
136
+ },
137
+ };
138
+
139
+ bindGlobalStyles('toggle-switch-theme', '', cssTheme);
140
+ return (
141
+ <ToggleBase {...props} size={{ w: 'auto', h: sizeH }}>
142
+ <div
143
+ css={css}
144
+ class={`toggle-switch-component toggle-placeholder ${props.checked ? 'toggle-on' : 'toggle-off'}${
145
+ props.disabled ? ' disabled' : ''
146
+ } ${cssSize}`}
147
+ >
148
+ <span class='ts-slider'>
149
+ <span class='ts-on-text'>{props.text?.on}</span>
150
+ <span class='ts-circle'></span>
151
+ <span class='ts-off-text'>{props.text?.off}</span>
152
+ </span>
153
+ </div>
154
+ </ToggleBase>
155
+ );
156
+ };
@@ -0,0 +1,58 @@
1
+ import { bindRef } from './bind-ref';
2
+
3
+ export const bindAttributesChildren = (topEl: Element, children: any) => {
4
+ for (let i = 0; i < children.length; i++) {
5
+ const item = children[i];
6
+ if (item && item.type && item.props) {
7
+ bindAttributes(topEl, item.type, item.props);
8
+ } else if (item && Array.isArray(item)) {
9
+ bindAttributesChildren(topEl, item);
10
+ } else if (
11
+ typeof item !== 'undefined' &&
12
+ item !== null &&
13
+ typeof item !== 'string' &&
14
+ typeof item !== 'number' &&
15
+ typeof item !== 'boolean'
16
+ ) {
17
+ console.warn(`Unexpected children:`, item);
18
+ }
19
+ }
20
+ };
21
+
22
+ export const bindAttributes = (topEl: Element, type: any, props: any) => {
23
+ const newProps = (props._result && props._result.props) || props;
24
+ if (newProps._id) {
25
+ const el = topEl.querySelector(`[${newProps._id}]`);
26
+ if (el) {
27
+ for (let i in newProps) {
28
+ if (i === 'ref') {
29
+ bindRef(type, newProps, el);
30
+ // } else if (i === "css") {
31
+ // mountStyles(`[${newProps._id}]`, `[${newProps._id}]`, newProps[i]);
32
+ } else if (i[0] === 'o' && i[1] === 'n') {
33
+ let name = i;
34
+ if (name.toLowerCase() in el) name = name.toLowerCase().slice(2);
35
+ else name = name.slice(2);
36
+ // console.log('===bind event', name, el);
37
+ el.addEventListener(name, newProps[i]);
38
+ }
39
+ }
40
+ }
41
+ }
42
+
43
+ if (newProps.children && Array.isArray(newProps.children)) {
44
+ bindAttributesChildren(topEl, newProps.children);
45
+ } else if (newProps._result && newProps._result.type !== 'Fragment' && newProps._result.props) {
46
+ bindAttributes(topEl, newProps._result.type, newProps._result.props);
47
+ } else if (newProps.children && newProps.children.type && newProps.children.props) {
48
+ bindAttributes(topEl, newProps.children.type, newProps.children.props);
49
+ } else if (
50
+ !newProps.children ||
51
+ typeof newProps.children === 'string' ||
52
+ typeof newProps.children === 'number' ||
53
+ typeof newProps.children === 'boolean'
54
+ ) {
55
+ } else {
56
+ console.warn(`Unexpected children:`, newProps.children, type, props);
57
+ }
58
+ };
@@ -0,0 +1,51 @@
1
+ import { DomUtils } from '../lib';
2
+ import { getEitherCookie } from './server-cookie';
3
+
4
+ // The FE only loads one language for the consideration of the size
5
+
6
+ export const defaultLangName = 'en';
7
+ export const langCookieName = 'lang';
8
+ export const updateLangEventName = 'updateLang';
9
+ const _langCfg: any = { defaultLang: defaultLangName, langs: {} };
10
+ export type OneLangProps = { [key: string]: string };
11
+ export const bindLang = (defaultLang: string, langs: OneLangProps) => {
12
+ _langCfg.defaultLang = defaultLang;
13
+ _langCfg.langs = langs;
14
+
15
+ // set to cookie
16
+ getCurrentLang();
17
+ };
18
+
19
+ export const getCurrentLang = () => {
20
+ let langName = getEitherCookie(langCookieName) as string;
21
+ if (!langName || !_langCfg.langs[langName]) {
22
+ langName = _langCfg.defaultLang;
23
+ if (typeof window !== 'undefined') {
24
+ DomUtils.setCookie(langCookieName, _langCfg.defaultLang);
25
+ }
26
+ }
27
+ return { langName, langs: _langCfg.langs };
28
+ };
29
+
30
+ // the FE needs to reload the page when the language is changed
31
+ export const updateLang = (langName: string) => {
32
+ // Lang is only updated in Browser
33
+ _langCfg.defaultLang = langName;
34
+ if (typeof window === 'undefined') {
35
+ return;
36
+ }
37
+
38
+ DomUtils.setCookie(langCookieName, langName);
39
+ // document.documentElement.setAttribute(langAttributeName, langName);
40
+
41
+ // // update lang for all iframe
42
+ // const allIframe = document.querySelectorAll('iframe');
43
+ // for (let i = 0; i < allIframe.length; i++) {
44
+ // if (allIframe[i].contentWindow && allIframe[i].contentWindow!.top === window) {
45
+ // allIframe[i].contentWindow!.document.documentElement.setAttribute(langAttributeName, langName);
46
+ // }
47
+ // }
48
+
49
+ const event = new CustomEvent(updateLangEventName, { detail: langName });
50
+ window.dispatchEvent(event);
51
+ };
@@ -0,0 +1,16 @@
1
+ import { initializePage } from './core';
2
+
3
+ export function bindLinks(el: Element | Document) {
4
+ const links = el.getElementsByTagName('a');
5
+ for (var i = 0, l = links.length; i < l; i++) {
6
+ let href = new URL(links[i].href, document.baseURI).href;
7
+ if (links[i].target !== '_blank' && href.startsWith(document.location.origin)) {
8
+ href = href.substring(document.location.origin.length);
9
+ // console.log(`====${href}, javascript:init('${document.links[i].href}')`);
10
+ links[i].onclick = () => {
11
+ initializePage(href);
12
+ return false;
13
+ };
14
+ }
15
+ }
16
+ }
@@ -0,0 +1,33 @@
1
+ // import { mountSelfComponents, renderComponent } from "./mount-components";
2
+
3
+ export const bindRef = (type: any, newProps: any, el: Element) => {
4
+ // console.log('========', newProps, el);
5
+ const id = newProps._id;
6
+ // newProps["ref"].id = id; // this is set at bindAttributes
7
+ newProps['ref'].current = el;
8
+ if (newProps['ref'].onLoad) {
9
+ // setTimeout(() => newProps['ref'].onLoad(el), 0);
10
+ const defer = Promise.prototype.then.bind(Promise.resolve());
11
+ defer(() => newProps['ref'].onLoad(el));
12
+ }
13
+ if (newProps['ref'].onUnload) {
14
+ (el as any)._lj = (el as any)._lj || {};
15
+ (el as any)._lj.onUnload = async () => {
16
+ await newProps['ref'].onUnload(el);
17
+ };
18
+ }
19
+
20
+ /**
21
+ * ref.$('selector')
22
+ * @param selector
23
+ * @returns Element
24
+ */
25
+ newProps['ref'].$ = (selector: string) => {
26
+ return el.querySelector(`[${id}] ` + selector);
27
+ // const dom = LiteDom.queryOne(el);
28
+ // return dom && dom.$(selector, value);
29
+ };
30
+ newProps['ref'].$all = (selector: string) => {
31
+ return el.querySelectorAll(`[${id}] ` + selector);
32
+ };
33
+ };