x4js 1.5.23 → 1.5.24

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.
@@ -174,6 +174,7 @@ interface CInternalProps {
174
174
  dom_events: any;
175
175
  classes: IMap<boolean>;
176
176
  uid: number;
177
+ created: boolean;
177
178
  inrender: boolean;
178
179
  }
179
180
 
@@ -891,6 +892,18 @@ export class Component<P extends CProps<CEventMap> = CProps<CEventMap>, E extend
891
892
 
892
893
  // notify descendants that we have been created (dom exists)
893
894
 
895
+ const notify = ( c: Component ) => {
896
+
897
+ if( !c.m_iprops.created ) {
898
+ if (c.dom && c.m_iprops.dom_events && c.m_iprops.dom_events.create) {
899
+ c.dom.dispatchEvent(new Event('create'));
900
+ }
901
+
902
+ c.componentCreated();
903
+ c.m_iprops.created = true;
904
+ }
905
+ }
906
+
894
907
  for (let mutation of mutations) {
895
908
 
896
909
  if (mutation.type == 'childList') {
@@ -902,24 +915,16 @@ export class Component<P extends CProps<CEventMap> = CProps<CEventMap>, E extend
902
915
 
903
916
  if (el) {
904
917
  el.enumChilds((c: Component) => {
905
-
906
- if (c.dom && c.m_iprops.dom_events && c.m_iprops.dom_events.create) {
907
- c.dom.dispatchEvent(new Event('create'));
908
- }
909
-
910
- c.componentCreated();
911
-
918
+ notify( c );
912
919
  }, true);
913
920
 
914
- if (el.m_iprops.dom_events && el.m_iprops.dom_events.create) {
915
- el.dom.dispatchEvent(new Event('create'));
916
- }
917
-
918
- el.componentCreated();
921
+ notify( el );
919
922
  }
920
923
  }
921
924
  }
922
925
  }
926
+
927
+
923
928
  }
924
929
 
925
930
  public dispose() {
@@ -953,6 +958,7 @@ export class Component<P extends CProps<CEventMap> = CProps<CEventMap>, E extend
953
958
  }
954
959
 
955
960
  this.componentDisposed();
961
+ this.m_iprops.created = false;
956
962
  // todo: pb on update this.removeAllListeners( null );
957
963
  }
958
964
 
@@ -39,7 +39,6 @@ export type FieldType = 'string' | 'int' | 'float' | 'date' | 'bool' | 'array' |
39
39
  export type DataIndex = Uint32Array;
40
40
 
41
41
  interface EvDataChange extends BasicEvent {
42
-
43
42
  type: string;
44
43
  id: any;
45
44
  }
@@ -49,6 +48,8 @@ function EvDataChange( type: 'create' | 'update' | 'delete' | 'data' | 'change',
49
48
  }
50
49
 
51
50
 
51
+
52
+
52
53
  /**
53
54
  * fields definition
54
55
  * field with index=0 is record id
@@ -553,55 +554,55 @@ interface DataEventMap extends BaseComponentEventMap {
553
554
  change?: EvChange;
554
555
  }
555
556
 
557
+ type DataSolver = ( data: any ) => Record[];
558
+
556
559
  export interface DataProxyProps extends BaseComponentProps<DataEventMap> {
557
- type: 'local' | 'immediate' | 'ajax';
558
- path?: string;
559
- params?: any;
560
+ url: string;
561
+ params?: string[];
562
+ solver?: DataSolver;
560
563
  }
561
564
 
562
565
  export class DataProxy extends BaseComponent<DataProxyProps,DataEventMap> {
563
-
566
+
564
567
  constructor( props: DataProxyProps ) {
565
568
  super( props );
566
569
  }
567
570
 
568
- load( ) {
571
+ load( url?: string ) {
572
+ if( url ) {
573
+ this.m_props.url = url;
574
+ }
575
+
569
576
  this._refresh( );
570
577
  }
571
578
 
572
- save( data ) {
573
- if( this.m_props.type=='local' ) {
574
- console.assert( false ); // not imp
575
- /*
576
- const fs = require('fs');
577
- fs.writeFileSync( this.m_path, data );
578
- */
579
- }
580
- }
581
-
582
579
  private _refresh( delay: number = 0 ) {
583
580
 
584
- if( this.m_props.type=='local' ) {
585
- console.assert( false ); // not imp
586
- /*
587
- const fs = require('fs');
588
- fs.readFile( this.m_path, ( _, bdata ) => {;
589
- let data = JSON.parse(bdata);
590
- this.emit( 'dataready', data );
591
- } );
592
- */
581
+ const load = async ( ) => {
582
+
583
+ let url = this.m_props.url;
584
+ if( this.m_props.params ) {
585
+ url += '?' + this.m_props.params.join( '&' );
586
+ }
587
+
588
+ const r = await fetch( url );
589
+ if( r.ok ) {
590
+ const raw = await r.json( );
591
+
592
+ let json = raw;
593
+ if( this.m_props.solver ) {
594
+ json = this.m_props.solver( json );
595
+ }
596
+
597
+ this.emit( 'change', EvChange(json,raw) );
598
+ }
599
+ }
600
+
601
+ if( delay ) {
602
+ setTimeout( load, delay );
593
603
  }
594
604
  else {
595
- setTimeout( ( ) => {
596
- ajaxRequest( {
597
- url: this.m_props.path,
598
- method: 'GET',
599
- params: this.m_props.params,
600
- success: ( data ) => {
601
- this.emit( 'change', EvChange(data) );
602
- }
603
- });
604
- }, delay );
605
+ load( );
605
606
  }
606
607
  }
607
608
  }
@@ -650,7 +651,13 @@ export class DataStore extends EventSource<DataStoreEventMap> {
650
651
  this.setRawData( props.data );
651
652
  }
652
653
  else if( props.url ) {
653
- this.load( props.url );
654
+ this.m_proxy = new DataProxy( {
655
+ url: props.url,
656
+ solver: props.solver,
657
+ events: { change: (ev) => { this.setData( ev.value ); } }
658
+ });
659
+
660
+ this.m_proxy.load( );
654
661
  }
655
662
  }
656
663
 
@@ -659,27 +666,8 @@ export class DataStore extends EventSource<DataStoreEventMap> {
659
666
  * @param records
660
667
  */
661
668
 
662
- load( url: string ) {
663
-
664
- //todo: that
665
- if( url.substr(0,7)==='file://' ) {
666
- this.m_proxy = new DataProxy( {
667
- type: 'local',
668
- path: url.substr( 7 ),
669
- events: { change: (ev) => { this.setData( ev.value ); } }
670
- });
671
-
672
- this.m_proxy.load( );
673
- }
674
- else {
675
- this.m_proxy = new DataProxy( {
676
- type: 'ajax',
677
- path: url,
678
- events: { change: (ev) => { this.setData( ev.value ); } }
679
- });
680
-
681
- this.m_proxy.load( );
682
- }
669
+ load( url?: string ) {
670
+ this.m_proxy.load( url );
683
671
  }
684
672
 
685
673
  reload( ) {
@@ -34,7 +34,12 @@ import { Point } from './tools';
34
34
 
35
35
  const x_drag_cb = Symbol( 'x-drag-cb' );
36
36
 
37
- type DropCallback = ( command: 'enter' | 'leave' | 'drag' | 'drop', el: Component, point: Point ) => void;
37
+ interface DropInfo {
38
+ pt: Point;
39
+ data: DataTransfer;
40
+ }
41
+
42
+ type DropCallback = ( command: 'enter' | 'leave' | 'drag' | 'drop', el: Component, infos: DropInfo ) => void;
38
43
  type FilterCallback = ( el: Component ) => boolean;
39
44
 
40
45
  /**
@@ -91,10 +96,10 @@ class DragManager {
91
96
  *
92
97
  */
93
98
 
94
- registerDropTarget(el: Component, cb: DropCallback, filterCB: FilterCallback ) {
99
+ registerDropTarget(el: Component, cb: DropCallback, filterCB?: FilterCallback ) {
95
100
 
96
101
  const dragEnter = (ev: DragEvent) => {
97
- if( !filterCB(this.dragSource) ) {
102
+ if( filterCB && !filterCB(this.dragSource) ) {
98
103
  console.log( 'reject ', el );
99
104
  ev.dataTransfer.dropEffect = 'none';
100
105
  return;
@@ -108,7 +113,7 @@ class DragManager {
108
113
  const dragOver = (ev: DragEvent) => {
109
114
  //console.log( "dragover", ev.target );
110
115
 
111
- if( !filterCB(this.dragSource) ) {
116
+ if( filterCB && !filterCB(this.dragSource) ) {
112
117
  console.log( 'reject ', el );
113
118
  ev.dataTransfer.dropEffect = 'none';
114
119
  return;
@@ -122,7 +127,12 @@ class DragManager {
122
127
  }
123
128
 
124
129
  if( this.dropTarget ) {
125
- cb( 'drag', this.dragSource, {x:ev.pageX,y:ev.pageY} );
130
+ const infos = {
131
+ pt: new Point( ev.pageX, ev.pageY ),
132
+ data: ev.dataTransfer,
133
+ }
134
+
135
+ cb( 'drag', this.dragSource, infos );
126
136
  }
127
137
 
128
138
  ev.dataTransfer.dropEffect = 'copy';
@@ -135,10 +145,17 @@ class DragManager {
135
145
  };
136
146
 
137
147
  const drop = (ev: DragEvent) => {
138
- cb('drop', this.dragSource, {x:ev.pageX,y:ev.pageY} );
148
+ const infos = {
149
+ pt: new Point( ev.pageX, ev.pageY ),
150
+ data: ev.dataTransfer,
151
+ }
152
+
153
+ cb('drop', this.dragSource, infos );
139
154
 
140
155
  this.dropTarget = null;
141
156
  el.removeClass('drop-over');
157
+
158
+ ev.preventDefault();
142
159
  }
143
160
 
144
161
  el.setDomEvent('dragenter', dragEnter);
package/lib/src/layout.ts CHANGED
@@ -153,7 +153,8 @@ interface CellData {
153
153
  width?: number;
154
154
  height?: number;
155
155
  cls?: string;
156
- item: ComponentContent;
156
+ item?: ComponentContent;
157
+ data?: any;
157
158
  }
158
159
 
159
160
  export class TableLayout extends Container<TableLayoutProps> {
@@ -204,6 +205,17 @@ export class TableLayout extends Container<TableLayoutProps> {
204
205
  this._setCell(row, col, cell, true);
205
206
  }
206
207
 
208
+ setCellData(row: number, col: number, data: any ) {
209
+ let cell = this._getCell(row, col);
210
+ cell.data = data;
211
+ this._setCell(row, col, cell, true);
212
+ }
213
+
214
+ getCellData(row: number, col: number ) {
215
+ let cell = this._getCell(row, col, false);
216
+ return cell?.data;
217
+ }
218
+
207
219
  merge(row: number, col: number, rowCount: number, colCount: number) {
208
220
  let cell = this._getCell(row, col);
209
221
  cell.rowSpan = rowCount;
package/lib/src/router.ts CHANGED
@@ -93,18 +93,46 @@ function parseRoute(str: string | RegExp, loose = false): Segment {
93
93
  interface RouterEventMap extends EventMap {
94
94
  error: EvError;
95
95
  }
96
-
96
+
97
+
98
+ /**
99
+ * micro router
100
+ *
101
+ * ```
102
+ * const router = new Router( );
103
+ *
104
+ * router.get( "/detail/:id", ( params: any ) => {
105
+ * this._showDetail( detail );
106
+ * } );
107
+ *
108
+ * router.get( "/:id", ( params: any ) => {
109
+ * if( params.id==0 )
110
+ * router.navigate( '/home' );
111
+ * }
112
+ * });
113
+ *
114
+ * router.on( "error", ( ) => {
115
+ * router.navigate( '/home' );
116
+ * })
117
+ *
118
+ * router.init( );
119
+ * ```
120
+ */
121
+
122
+
97
123
  export class Router extends EventSource< RouterEventMap > {
98
124
 
99
- private routes: Route[];
125
+ private m_routes: Route[];
126
+ private m_useHash: boolean;
100
127
 
101
- constructor() {
128
+ constructor( useHash = true ) {
102
129
  super( );
103
130
 
104
- this.routes = [];
131
+ this.m_routes = [];
132
+ this.m_useHash = useHash;
105
133
 
106
134
  window.addEventListener('popstate', (event) => {
107
- const url = x4document.location.pathname;
135
+ const url = this._getLocation( );
108
136
  const found = this._find(url);
109
137
 
110
138
  found.handlers.forEach(h => {
@@ -115,11 +143,15 @@ export class Router extends EventSource< RouterEventMap > {
115
143
 
116
144
  get(uri: string | RegExp, handler: RouteHandler ) {
117
145
  let { keys, pattern } = parseRoute(uri);
118
- this.routes.push({ keys, pattern, handler });
146
+ this.m_routes.push({ keys, pattern, handler });
119
147
  }
120
148
 
121
149
  init() {
122
- this.navigate( window.location.pathname );
150
+ this.navigate( this._getLocation() );
151
+ }
152
+
153
+ private _getLocation( ) {
154
+ return this.m_useHash ? '/'+x4document.location.hash.substring(1) : x4document.location.pathname;
123
155
  }
124
156
 
125
157
  navigate( uri: string, notify = true ) {
@@ -133,7 +165,16 @@ export class Router extends EventSource< RouterEventMap > {
133
165
  return;
134
166
  }
135
167
 
136
- window.history.pushState({}, '', uri )
168
+ if( this.m_useHash ) {
169
+ while( uri.startsWith('/') ) {
170
+ uri = uri.substring( 1 );
171
+ }
172
+
173
+ window.history.pushState({}, '', '#'+uri );
174
+ }
175
+ else {
176
+ window.history.pushState({}, '', uri );
177
+ }
137
178
 
138
179
  if( notify ) {
139
180
  found.handlers.forEach( h => {
@@ -148,7 +189,7 @@ export class Router extends EventSource< RouterEventMap > {
148
189
  let params = {};
149
190
  let handlers = [];
150
191
 
151
- for (const tmp of this.routes ) {
192
+ for (const tmp of this.m_routes ) {
152
193
  if (!tmp.keys ) {
153
194
  matches = tmp.pattern.exec(url);
154
195
  if (!matches) {
@@ -27,4 +27,4 @@
27
27
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
28
  **/
29
29
 
30
- export const x4js_version = "1.5.23";
30
+ export const x4js_version = "1.5.24";
@@ -208,15 +208,15 @@ export declare class AutoRecord extends Record {
208
208
  interface DataEventMap extends BaseComponentEventMap {
209
209
  change?: EvChange;
210
210
  }
211
+ type DataSolver = (data: any) => Record[];
211
212
  export interface DataProxyProps extends BaseComponentProps<DataEventMap> {
212
- type: 'local' | 'immediate' | 'ajax';
213
- path?: string;
214
- params?: any;
213
+ url: string;
214
+ params?: string[];
215
+ solver?: DataSolver;
215
216
  }
216
217
  export declare class DataProxy extends BaseComponent<DataProxyProps, DataEventMap> {
217
218
  constructor(props: DataProxyProps);
218
- load(): void;
219
- save(data: any): void;
219
+ load(url?: string): void;
220
220
  private _refresh;
221
221
  }
222
222
  /**
@@ -244,7 +244,7 @@ export declare class DataStore extends EventSource<DataStoreEventMap> {
244
244
  *
245
245
  * @param records
246
246
  */
247
- load(url: string): void;
247
+ load(url?: string): void;
248
248
  reload(): void;
249
249
  /**
250
250
  * convert raw objects to real records from model
@@ -28,7 +28,11 @@
28
28
  **/
29
29
  import { Component } from './component';
30
30
  import { Point } from './tools';
31
- type DropCallback = (command: 'enter' | 'leave' | 'drag' | 'drop', el: Component, point: Point) => void;
31
+ interface DropInfo {
32
+ pt: Point;
33
+ data: DataTransfer;
34
+ }
35
+ type DropCallback = (command: 'enter' | 'leave' | 'drag' | 'drop', el: Component, infos: DropInfo) => void;
32
36
  type FilterCallback = (el: Component) => boolean;
33
37
  /**
34
38
  *
@@ -46,7 +50,7 @@ declare class DragManager {
46
50
  /**
47
51
  *
48
52
  */
49
- registerDropTarget(el: Component, cb: DropCallback, filterCB: FilterCallback): void;
53
+ registerDropTarget(el: Component, cb: DropCallback, filterCB?: FilterCallback): void;
50
54
  _startCheck(): void;
51
55
  _check(): void;
52
56
  }
@@ -63,6 +63,8 @@ export declare class TableLayout extends Container<TableLayoutProps> {
63
63
  private _getCell;
64
64
  private _setCell;
65
65
  setCell(row: number, col: number, item: ComponentContent): void;
66
+ setCellData(row: number, col: number, data: any): void;
67
+ getCellData(row: number, col: number): any;
66
68
  merge(row: number, col: number, rowCount: number, colCount: number): void;
67
69
  setCellWidth(row: number, col: number, width?: number): void;
68
70
  setCellHeight(row: number, col: number, height?: number): void;
@@ -31,11 +31,36 @@ type RouteHandler = (params: any, path: string) => void;
31
31
  interface RouterEventMap extends EventMap {
32
32
  error: EvError;
33
33
  }
34
+ /**
35
+ * micro router
36
+ *
37
+ * ```
38
+ * const router = new Router( );
39
+ *
40
+ * router.get( "/detail/:id", ( params: any ) => {
41
+ * this._showDetail( detail );
42
+ * } );
43
+ *
44
+ * router.get( "/:id", ( params: any ) => {
45
+ * if( params.id==0 )
46
+ * router.navigate( '/home' );
47
+ * }
48
+ * });
49
+ *
50
+ * router.on( "error", ( ) => {
51
+ * router.navigate( '/home' );
52
+ * })
53
+ *
54
+ * router.init( );
55
+ * ```
56
+ */
34
57
  export declare class Router extends EventSource<RouterEventMap> {
35
- private routes;
36
- constructor();
58
+ private m_routes;
59
+ private m_useHash;
60
+ constructor(useHash?: boolean);
37
61
  get(uri: string | RegExp, handler: RouteHandler): void;
38
62
  init(): void;
63
+ private _getLocation;
39
64
  navigate(uri: string, notify?: boolean): void;
40
65
  private _find;
41
66
  }
@@ -26,4 +26,4 @@
26
26
  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27
27
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
28
  **/
29
- export declare const x4js_version = "1.5.23";
29
+ export declare const x4js_version = "1.5.24";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "x4js",
3
- "version": "1.5.23",
3
+ "version": "1.5.24",
4
4
  "description": "X4js core files",
5
5
  "main": "lib/cjs/index.js",
6
6
  "types": "lib/types/index.d.ts",