@celljs/widget 3.0.0

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 +1 -0
  3. package/cell.yml +3 -0
  4. package/lib/browser/annotation/index.d.ts +2 -0
  5. package/lib/browser/annotation/index.d.ts.map +1 -0
  6. package/lib/browser/annotation/index.js +18 -0
  7. package/lib/browser/annotation/index.js.map +1 -0
  8. package/lib/browser/annotation/widget.d.ts +10 -0
  9. package/lib/browser/annotation/widget.d.ts.map +1 -0
  10. package/lib/browser/annotation/widget.js +30 -0
  11. package/lib/browser/annotation/widget.js.map +1 -0
  12. package/lib/browser/index.d.ts +6 -0
  13. package/lib/browser/index.d.ts.map +1 -0
  14. package/lib/browser/index.js +22 -0
  15. package/lib/browser/index.js.map +1 -0
  16. package/lib/browser/keyboard/index.d.ts +2 -0
  17. package/lib/browser/keyboard/index.d.ts.map +1 -0
  18. package/lib/browser/keyboard/index.js +18 -0
  19. package/lib/browser/keyboard/index.js.map +1 -0
  20. package/lib/browser/keyboard/keys.d.ts +254 -0
  21. package/lib/browser/keyboard/keys.d.ts.map +1 -0
  22. package/lib/browser/keyboard/keys.js +620 -0
  23. package/lib/browser/keyboard/keys.js.map +1 -0
  24. package/lib/browser/locale/index.d.ts +3 -0
  25. package/lib/browser/locale/index.d.ts.map +1 -0
  26. package/lib/browser/locale/index.js +19 -0
  27. package/lib/browser/locale/index.js.map +1 -0
  28. package/lib/browser/locale/locale-manager.d.ts +14 -0
  29. package/lib/browser/locale/locale-manager.d.ts.map +1 -0
  30. package/lib/browser/locale/locale-manager.js +71 -0
  31. package/lib/browser/locale/locale-manager.js.map +1 -0
  32. package/lib/browser/locale/locale-protocol.d.ts +16 -0
  33. package/lib/browser/locale/locale-protocol.d.ts.map +1 -0
  34. package/lib/browser/locale/locale-protocol.js +6 -0
  35. package/lib/browser/locale/locale-protocol.js.map +1 -0
  36. package/lib/browser/module.d.ts +3 -0
  37. package/lib/browser/module.d.ts.map +1 -0
  38. package/lib/browser/module.js +5 -0
  39. package/lib/browser/module.js.map +1 -0
  40. package/lib/browser/theme/index.d.ts +3 -0
  41. package/lib/browser/theme/index.d.ts.map +1 -0
  42. package/lib/browser/theme/index.js +19 -0
  43. package/lib/browser/theme/index.js.map +1 -0
  44. package/lib/browser/theme/theme-manager.d.ts +14 -0
  45. package/lib/browser/theme/theme-manager.d.ts.map +1 -0
  46. package/lib/browser/theme/theme-manager.js +72 -0
  47. package/lib/browser/theme/theme-manager.js.map +1 -0
  48. package/lib/browser/theme/theme-protocol.d.ts +19 -0
  49. package/lib/browser/theme/theme-protocol.d.ts.map +1 -0
  50. package/lib/browser/theme/theme-protocol.js +7 -0
  51. package/lib/browser/theme/theme-protocol.js.map +1 -0
  52. package/lib/browser/widget/index.d.ts +5 -0
  53. package/lib/browser/widget/index.d.ts.map +1 -0
  54. package/lib/browser/widget/index.js +26 -0
  55. package/lib/browser/widget/index.js.map +1 -0
  56. package/lib/browser/widget/widget-factory.d.ts +10 -0
  57. package/lib/browser/widget/widget-factory.d.ts.map +1 -0
  58. package/lib/browser/widget/widget-factory.js +46 -0
  59. package/lib/browser/widget/widget-factory.js.map +1 -0
  60. package/lib/browser/widget/widget-manager.d.ts +15 -0
  61. package/lib/browser/widget/widget-manager.d.ts.map +1 -0
  62. package/lib/browser/widget/widget-manager.js +80 -0
  63. package/lib/browser/widget/widget-manager.js.map +1 -0
  64. package/lib/browser/widget/widget-protocol.d.ts +38 -0
  65. package/lib/browser/widget/widget-protocol.d.ts.map +1 -0
  66. package/lib/browser/widget/widget-protocol.js +12 -0
  67. package/lib/browser/widget/widget-protocol.js.map +1 -0
  68. package/lib/browser/widget/widget-util.d.ts +6 -0
  69. package/lib/browser/widget/widget-util.d.ts.map +1 -0
  70. package/lib/browser/widget/widget-util.js +28 -0
  71. package/lib/browser/widget/widget-util.js.map +1 -0
  72. package/lib/package.spec.d.ts +1 -0
  73. package/lib/package.spec.d.ts.map +1 -0
  74. package/lib/package.spec.js +4 -0
  75. package/lib/package.spec.js.map +1 -0
  76. package/package.json +42 -0
  77. package/src/browser/annotation/index.ts +1 -0
  78. package/src/browser/annotation/widget.ts +34 -0
  79. package/src/browser/index.ts +5 -0
  80. package/src/browser/keyboard/index.ts +1 -0
  81. package/src/browser/keyboard/keys.ts +678 -0
  82. package/src/browser/locale/index.ts +2 -0
  83. package/src/browser/locale/locale-manager.ts +54 -0
  84. package/src/browser/locale/locale-protocol.ts +18 -0
  85. package/src/browser/module.ts +3 -0
  86. package/src/browser/theme/index.ts +2 -0
  87. package/src/browser/theme/theme-manager.ts +53 -0
  88. package/src/browser/theme/theme-protocol.ts +22 -0
  89. package/src/browser/widget/index.ts +4 -0
  90. package/src/browser/widget/widget-factory.ts +36 -0
  91. package/src/browser/widget/widget-manager.ts +64 -0
  92. package/src/browser/widget/widget-protocol.ts +38 -0
  93. package/src/browser/widget/widget-util.ts +26 -0
  94. package/src/package.spec.ts +4 -0
@@ -0,0 +1,54 @@
1
+ import { LocaleManager, Locale } from './locale-protocol';
2
+ import { Component, Value, Autowired, Optional, Prioritizeable, PostConstruct } from '@celljs/core';
3
+ import { BehaviorSubject } from 'rxjs';
4
+
5
+ @Component(LocaleManager)
6
+ export class LocaleManagerImpl implements LocaleManager {
7
+
8
+ protected readonly langStorageKey = 'cell:lang';
9
+
10
+ @Value('cell.locales')
11
+ protected readonly localesForConfig: { [lang: string]: Locale };
12
+
13
+ @Autowired(Locale) @Optional()
14
+ protected readonly locales: Locale[];
15
+
16
+ protected prioritized: Locale[];
17
+
18
+ currentSubject = new BehaviorSubject<Locale | undefined>(undefined);
19
+
20
+ @PostConstruct()
21
+ init() {
22
+ (async () => {
23
+ const locales = await this.get();
24
+ const lang = localStorage.getItem(this.langStorageKey) || navigator.language;
25
+ if (locales.length) {
26
+ this.currentSubject.next(locales.find(l => l.lang === lang) || locales[0]);
27
+ }
28
+
29
+ this.currentSubject.subscribe(locale => {
30
+ if (locale) {
31
+ localStorage.setItem(this.langStorageKey, locale.lang);
32
+ } else {
33
+ localStorage.removeItem(this.langStorageKey);
34
+ }
35
+ });
36
+ })();
37
+ }
38
+
39
+ async get(): Promise<Locale[]> {
40
+ if (!this.prioritized) {
41
+ const config = this.localesForConfig || {};
42
+ const parsedLacalesForConfig = Object.keys(config).map(lang => {
43
+ const locale = { ...config[lang] };
44
+ locale.lang = lang;
45
+ locale.priority = locale.priority || 500;
46
+ return locale;
47
+ });
48
+
49
+ this.prioritized = Prioritizeable.prioritizeAllSync([ ...parsedLacalesForConfig, ...this.locales ]).map(p => p.value);
50
+ }
51
+ return this.prioritized;
52
+ }
53
+
54
+ }
@@ -0,0 +1,18 @@
1
+ import { BehaviorSubject } from 'rxjs';
2
+
3
+ export const Locale = Symbol('Locale');
4
+ export const LocaleManager = Symbol('LocaleManager');
5
+
6
+ export interface Locale {
7
+ lang: string;
8
+ priority: number;
9
+ label?: string;
10
+ messages: { [key: string]: string };
11
+ }
12
+
13
+ export interface LocaleManager {
14
+
15
+ currentSubject: BehaviorSubject<Locale | undefined>;
16
+
17
+ get(): Promise<Locale[]>;
18
+ }
@@ -0,0 +1,3 @@
1
+ import { autoBind } from '@celljs/core';
2
+
3
+ export default autoBind();
@@ -0,0 +1,2 @@
1
+ export * from './theme-protocol';
2
+ export * from './theme-manager';
@@ -0,0 +1,53 @@
1
+ import { Theme, ThemeManager, DEFAULT_THEME } from './theme-protocol';
2
+ import { Component, Value, Autowired, Optional, Prioritizeable, PostConstruct } from '@celljs/core';
3
+ import { BehaviorSubject } from 'rxjs';
4
+
5
+ @Component(ThemeManager)
6
+ export class ThemeManagerImpl<T> implements ThemeManager<T> {
7
+
8
+ protected readonly themeStorageKey = 'cell:theme';
9
+
10
+ @Value('cell.themes')
11
+ protected readonly themesForConfig: { [id: string]: Theme<T> };
12
+
13
+ @Autowired(Theme) @Optional()
14
+ protected readonly themes: Theme<T>[];
15
+
16
+ protected prioritized: Theme<T>[];
17
+
18
+ currentSubject = new BehaviorSubject<Theme<T> | undefined>(undefined);
19
+
20
+ @PostConstruct()
21
+ init() {
22
+ const themeStr = localStorage.getItem(this.themeStorageKey);
23
+ if (themeStr) {
24
+ this.currentSubject.next(JSON.parse(themeStr));
25
+ } else {
26
+ if (this.themesForConfig) {
27
+ this.currentSubject.next(this.themesForConfig[DEFAULT_THEME]);
28
+ }
29
+ }
30
+ this.currentSubject.subscribe(theme => {
31
+ if (theme) {
32
+ localStorage.setItem(this.themeStorageKey, JSON.stringify(theme));
33
+ } else {
34
+ localStorage.removeItem(this.themeStorageKey);
35
+ }
36
+ });
37
+ }
38
+
39
+ async get(): Promise<Theme<T>[]> {
40
+ if (!this.prioritized) {
41
+ const parsedThemesForConfig = Object.keys(this.themesForConfig || {}).map(id => {
42
+ const theme = { ...this.themesForConfig[id] };
43
+ theme.id = id;
44
+ theme.priority = theme.priority || 500;
45
+ return theme;
46
+ });
47
+
48
+ this.prioritized = Prioritizeable.prioritizeAllSync([ ...parsedThemesForConfig, ...this.themes ]).map(p => p.value);
49
+ }
50
+ return this.prioritized;
51
+ }
52
+
53
+ }
@@ -0,0 +1,22 @@
1
+ import { BehaviorSubject } from 'rxjs';
2
+
3
+ export const Theme = Symbol('Theme');
4
+ export const ThemeManager = Symbol('ThemeManager');
5
+
6
+ export const DEFAULT_THEME = 'default';
7
+
8
+ export interface Theme<T> {
9
+ id: string
10
+ label: string;
11
+ color: string;
12
+ priority: number;
13
+ props: T;
14
+ metadata: { [key: string]: any }
15
+ }
16
+
17
+ export interface ThemeManager<T> {
18
+
19
+ currentSubject: BehaviorSubject<Theme<T> | undefined>;
20
+
21
+ get(): Promise<Theme<T>[]>;
22
+ }
@@ -0,0 +1,4 @@
1
+ export { WidgetFactory, WidgetModel, WidgetManager, WidgetType } from './widget-protocol';
2
+ export * from './widget-manager';
3
+ export * from './widget-factory';
4
+ export * from './widget-util';
@@ -0,0 +1,36 @@
1
+ import { WidgetModel, WidgetFactory, Widget } from './widget-protocol';
2
+ import { WidgetUtil } from './widget-util';
3
+ import { Autowired, ExpressionHandler, Injectable } from '@celljs/core';
4
+
5
+ @Injectable()
6
+ export abstract class AbstractWidgetFactory<T> implements WidgetFactory<T> {
7
+
8
+ @Autowired(ExpressionHandler)
9
+ protected readonly expressionHandler: ExpressionHandler;
10
+
11
+ priority: number = 500;
12
+
13
+ async create(widgetModel: WidgetModel): Promise<Widget<T>> {
14
+ const { children = [] } = widgetModel;
15
+
16
+ return {
17
+ id: widgetModel.id,
18
+ visible: widgetModel.visible,
19
+ area: widgetModel.area,
20
+ priority: widgetModel.priority,
21
+ render: async () => {
22
+ if (widgetModel.props) {
23
+ this.expressionHandler.handle(widgetModel.props);
24
+ }
25
+ return this.doRender(widgetModel, await Promise.all(children.map(c => WidgetUtil.create<T>(c))));
26
+ }
27
+ };
28
+ }
29
+
30
+ async support(widgetModel: WidgetModel): Promise<boolean> {
31
+ return this.constructor.name.startsWith(widgetModel.type);
32
+ }
33
+
34
+ protected abstract doRender(widgetModel: WidgetModel, children: Widget<T>[]): Promise<T>;
35
+
36
+ }
@@ -0,0 +1,64 @@
1
+ import { Component, Autowired, Prioritizeable, Value, Optional } from '@celljs/core';
2
+ import { WidgetManager, WidgetModel, Widget } from './widget-protocol';
3
+ import { WidgetUtil } from './widget-util';
4
+
5
+ @Component(WidgetManager)
6
+ export class WidgetManagerImpl<T> implements WidgetManager<T> {
7
+
8
+ protected prioritized: Map<string, Widget<T>[]>;
9
+
10
+ constructor(
11
+ @Autowired(Widget) @Optional() protected readonly widgets: Widget<T>[],
12
+ @Autowired(WidgetModel) @Optional() protected readonly widgetModels: WidgetModel[],
13
+ @Value('cell.widget.widgets') protected readonly widgetModelsForConfig: { [id: string]: WidgetModel }
14
+ ) {}
15
+
16
+ async render(area: string): Promise<T[]> {
17
+ const widgets = await this.get(area);
18
+ return Promise.all(widgets.map(w => w.render()));
19
+ }
20
+
21
+ async get(area: string): Promise<Widget<T>[]> {
22
+ if (!this.prioritized) {
23
+ const result = new Map<string, Widget<T>[]>();
24
+ const config = { ...this.widgetModelsForConfig };
25
+ this.widgets.forEach(w => {
26
+ const c = config[w.id];
27
+ if (config) {
28
+ w.area = c.area;
29
+ w.priority = c.priority === undefined ? w.priority : c.priority;
30
+ w.visible = c.visible === undefined ? w.visible : c.visible;
31
+ delete config[w.id];
32
+ }
33
+ });
34
+ const parsedWdigets = await Promise.all(this.widgetModels.map(w => {
35
+ const c = config[w.id];
36
+ delete config[w.id];
37
+ return WidgetUtil.create<T>({ ...w, ...c});
38
+ }));
39
+ const parsedWidgetsForConfig = await Promise.all((Object.keys(config).map(id => {
40
+ const widgetModel = { ...config[id] };
41
+ widgetModel.id = id;
42
+ widgetModel.priority = widgetModel.priority || 500;
43
+ widgetModel.visible = widgetModel.visible === false ? false : true;
44
+ return WidgetUtil.create<T>(widgetModel);
45
+ })));
46
+
47
+ for (const widget of [ ...this.widgets, ...parsedWdigets, ...parsedWidgetsForConfig ]) {
48
+ if (!result.has(widget.area!)) {
49
+ result.set(widget.area!, []);
50
+ }
51
+ if (widget.visible) {
52
+ result.get(widget!.area!)!.push(widget);
53
+ }
54
+ }
55
+
56
+ for (const [ a, ws ] of result.entries()) {
57
+ result.set(a, Prioritizeable.prioritizeAllSync(ws).map(c => c.value));
58
+ }
59
+ this.prioritized = result;
60
+ }
61
+ return this.prioritized.get(area) || [];
62
+ }
63
+
64
+ }
@@ -0,0 +1,38 @@
1
+ export const Widget = Symbol('Widget');
2
+ export const WidgetModel = Symbol('WidgetModel');
3
+ export const WidgetFactory = Symbol('WidgetFactory');
4
+ export const WidgetManager = Symbol('WidgetManager');
5
+
6
+ export enum WidgetType {
7
+ Decorator = 'Decorator'
8
+ }
9
+
10
+ export interface Widget<T> {
11
+ id: string;
12
+ priority: number;
13
+ area?: string;
14
+ visible: boolean;
15
+ render(): Promise<T>;
16
+ }
17
+
18
+ export interface WidgetModel {
19
+ id: string;
20
+ type: string;
21
+ priority: number;
22
+ visible: boolean;
23
+ area?: string;
24
+ props?: { [key: string]: any };
25
+ matedata?: { [key: string]: any };
26
+ children?: WidgetModel[]
27
+ }
28
+
29
+ export interface WidgetFactory<T> {
30
+ priority: number;
31
+ create(widgetModel: WidgetModel): Promise<Widget<T>>;
32
+ support(widgetModel: WidgetModel): Promise<boolean>;
33
+ }
34
+
35
+ export interface WidgetManager<T> {
36
+ get(area: string): Promise<Widget<T>[]>;
37
+ render(area: string): Promise<T[]>;
38
+ }
@@ -0,0 +1,26 @@
1
+ import { ContainerUtil, Prioritizeable } from '@celljs/core';
2
+ import { WidgetModel, WidgetFactory, Widget } from './widget-protocol';
3
+
4
+ let widgetFactories: WidgetFactory<any>[];
5
+
6
+ export namespace WidgetUtil {
7
+ export async function create<T>(widgetModel: WidgetModel): Promise<Widget<T>> {
8
+ if (!widgetFactories) {
9
+ widgetFactories = Prioritizeable.prioritizeAllSync(ContainerUtil.getAll<WidgetFactory<T>>(WidgetFactory)).map(p => p.value);
10
+ }
11
+
12
+ for (const factory of widgetFactories) {
13
+ if (await factory.support(widgetModel)) {
14
+ const widget = await factory.create(widgetModel);
15
+ return widget;
16
+ }
17
+ }
18
+ throw new Error(`WidgetModel {id: ${widgetModel.id}, type: ${widgetModel.type}} there is no matching widget factory.`);
19
+ }
20
+
21
+ export async function render<T>(widgetModel: WidgetModel): Promise<T> {
22
+ const widget = await WidgetUtil.create<T>(widgetModel);
23
+ return widget.render();
24
+ }
25
+
26
+ }
@@ -0,0 +1,4 @@
1
+ describe('widget package', () => {
2
+
3
+ it('support code coverage statistics', () => {});
4
+ });