structured-fw 0.9.4 → 0.9.7

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.
package/README.md CHANGED
@@ -644,7 +644,7 @@ Methods:
644
644
  - `find(componentName: string, recursive: boolean = true): ClientComponent | null` - find a child component
645
645
  - `findParent(componentName: string): ClientComponent | null` - find the first parent with given name
646
646
  - `query(componentName: string, recursive: boolean = true): Array<ClientComponent>` - return all components with given name found within this component, if `recursive = false`, only direct children are considered
647
- - `bind(element: HTMLElement, eventName: string | Array<string>, callback: (e: Event) => void): void` - adds event listener(s) to given element. This is preferred over addEventListener because when the component is redrawn/removed, the event listeners added using bind method are automatically removed
647
+ - `bind<T extends LooseObject | undefined = undefined>(element: HTMLElement, eventName: string | Array<string>, callback: (e: Event, data: T) => void): void` - adds event listener(s) to given element. This is preferred over addEventListener because when the component is redrawn/removed, the event listeners added using bind method are automatically restored/removed. Callback receives event as the first argument. Any "data-" prefixed attributes found on `element` are parsed into an object and provided as second argument to callback (you can specify data using attr helper if you want to pass in something other than a string). The method is generic, allowing you to specify expected data type
648
648
  - `ref<T>(refName: string): T` - get a HTMLElement or ClientComponent that has attribute `ref="[refName]"`
649
649
  - `arrayRef<T>(refName: string): Array<T>` - get an array of HTMLElement or ClientComponent that have attribute `array:ref="[refName]"`
650
650
  - `add(appendTo: HTMLElement, componentName: string, data?: LooseObject): Promise<ClientComponent | null>` - add `componentName` component to `appendTo` element, optionally passing `data` to the component when it's being rendered. Returns a promise that resolves with added ClientComponent or null if something went wrong
@@ -159,10 +159,12 @@ export type InitializerFunctionContext = {
159
159
  isRedraw: boolean;
160
160
  };
161
161
  export type StoreChangeCallback = (key: string, value: any, oldValue: any, componentId: string) => void;
162
- export type ClientComponentBoundEvent = {
162
+ export type ClientComponentEventCallback<T> = T extends undefined ? (e: Event) => void : (e: Event, data: T) => void;
163
+ export type ClientComponentBoundEvent<T extends LooseObject | undefined = undefined> = {
163
164
  element: HTMLElement;
164
165
  event: keyof HTMLElementEventMap;
165
166
  callback: (e: Event) => void;
167
+ callbackOriginal: ClientComponentEventCallback<T>;
166
168
  };
167
169
  export type ClientComponentTransition = {
168
170
  fade: false | number;
@@ -1,4 +1,4 @@
1
- import { LooseObject } from '../Types.js';
1
+ import { ClientComponentEventCallback, LooseObject } from '../Types.js';
2
2
  import { DataStoreView } from './DataStoreView.js';
3
3
  import { DataStore } from './DataStore.js';
4
4
  import { Net } from './Net.js';
@@ -29,6 +29,7 @@ export declare class ClientComponent extends EventEmitter {
29
29
  private init;
30
30
  private runInitializer;
31
31
  private initData;
32
+ private attributeData;
32
33
  pathData(): Array<{
33
34
  [key: string]: string;
34
35
  }>;
@@ -55,7 +56,7 @@ export declare class ClientComponent extends EventEmitter {
55
56
  private transitionAttributes;
56
57
  private transitionAxis;
57
58
  private destroy;
58
- bind(element: HTMLElement, event: keyof HTMLElementEventMap | Array<keyof HTMLElementEventMap>, callback: (e: Event) => void): void;
59
- unbind(element: HTMLElement, event: keyof HTMLElementEventMap | Array<keyof HTMLElementEventMap>, callback: (e: Event) => void): void;
59
+ bind<T extends LooseObject | undefined = undefined>(element: HTMLElement, event: keyof HTMLElementEventMap | Array<keyof HTMLElementEventMap>, callback: ClientComponentEventCallback<T>): void;
60
+ unbind<T extends LooseObject | undefined = undefined>(element: HTMLElement, event: keyof HTMLElementEventMap | Array<keyof HTMLElementEventMap>, callback: ClientComponentEventCallback<T>): void;
60
61
  private unbindAll;
61
62
  }
@@ -90,19 +90,26 @@ export class ClientComponent extends EventEmitter {
90
90
  this.initializerExecuted = true;
91
91
  }
92
92
  initData() {
93
- for (let i = 0; i < this.domNode.attributes.length; i++) {
94
- if (/^((number|string|boolean|object|any):)?data-[^\s]+/.test(this.domNode.attributes[i].name)) {
95
- const value = this.domNode.attributes[i].value;
93
+ objectEach(this.attributeData(this.domNode), (key, val) => {
94
+ this.setData(key, val, false);
95
+ });
96
+ }
97
+ attributeData(node) {
98
+ const data = {};
99
+ for (let i = 0; i < node.attributes.length; i++) {
100
+ if (/^((number|string|boolean|object|any):)?data-[^\s]+/.test(node.attributes[i].name)) {
101
+ const value = node.attributes[i].value;
96
102
  const attrData = attributeValueFromString(value);
97
103
  if (typeof attrData === 'object') {
98
- this.setData(attrData.key, attrData.value, false);
104
+ data[attrData.key] = attrData.value;
99
105
  }
100
106
  else {
101
- const key = toCamelCase(this.domNode.attributes[i].name.substring(5));
102
- this.setData(key, attrData, false);
107
+ const key = toCamelCase(node.attributes[i].name.substring(5));
108
+ data[key] = attrData;
103
109
  }
104
110
  }
105
111
  }
112
+ return data;
106
113
  }
107
114
  pathData() {
108
115
  let current = this;
@@ -721,12 +728,16 @@ export class ClientComponent extends EventEmitter {
721
728
  return;
722
729
  }
723
730
  if (element instanceof HTMLElement) {
731
+ const callbackWrapper = (e) => {
732
+ callback.apply(this, [e, this.attributeData(element)]);
733
+ };
724
734
  this.bound.push({
725
735
  element,
726
736
  event,
727
- callback
737
+ callback: callbackWrapper,
738
+ callbackOriginal: callback
728
739
  });
729
- element.addEventListener(event, callback);
740
+ element.addEventListener(event, callbackWrapper);
730
741
  }
731
742
  }
732
743
  unbind(element, event, callback) {
@@ -737,7 +748,7 @@ export class ClientComponent extends EventEmitter {
737
748
  return;
738
749
  }
739
750
  const boundIndex = this.bound.findIndex((bound) => {
740
- return bound.event === event && bound.element === element && callback === callback;
751
+ return bound.event === event && bound.element === element && bound.callbackOriginal === callback;
741
752
  });
742
753
  if (boundIndex > -1) {
743
754
  const bound = this.bound[boundIndex];
@@ -18,6 +18,7 @@ export declare class Application {
18
18
  readonly components: Components;
19
19
  readonly handlebars: Handlebars;
20
20
  readonly exportedRequestContextData: Array<keyof RequestContextData>;
21
+ data: LooseObject;
21
22
  constructor(config: StructuredConfig);
22
23
  init(): Promise<void>;
23
24
  private start;
@@ -18,6 +18,7 @@ export class Application {
18
18
  this.eventEmitter = new EventEmitter();
19
19
  this.handlebars = new Handlebars();
20
20
  this.exportedRequestContextData = [];
21
+ this.data = {};
21
22
  this.config = config;
22
23
  this.cookies = new Cookies();
23
24
  this.session = new Session(this);
package/index.ts CHANGED
@@ -1,30 +1,4 @@
1
1
  import { Application } from "structured-fw/Application";
2
2
  import { config } from './Config.js';
3
- import { Layout } from "./system/server/Layout.js";
4
3
 
5
- const app = new Application(config);
6
-
7
- app.registerPlugin(async (app) => {
8
-
9
- }, {
10
- poop: 123
11
- });
12
-
13
- // app.on('afterComponentsLoaded', (components) => {
14
- // components.componentNames.forEach((componentName) => {
15
- // console.log(componentName)
16
- // console.log(components.getByName(componentName));
17
- // });
18
- // })
19
-
20
- // app.on('componentCreated', (component) => {
21
- // console.log(component.document.id);
22
- // })
23
-
24
- app.on('documentCreated', (document) => {
25
- document.on('componentCreated', (component) => {
26
- document.head.add(`<script>console.log('${component.name}')</script>`);
27
- });
28
- });
29
-
30
- export const layout: Layout = new Layout(app, 'layout');
4
+ new Application(config);
package/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "license": "MIT",
15
15
  "type": "module",
16
16
  "main": "build/index",
17
- "version": "0.9.4",
17
+ "version": "0.9.7",
18
18
  "scripts": {
19
19
  "develop": "tsc --watch",
20
20
  "startDev": "cd build && nodemon --watch '../app/**/*' --watch '../build/**/*' -e js,html,css index.js",