x4js 1.4.20 → 1.4.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.
package/src/button.ts CHANGED
@@ -31,6 +31,7 @@
31
31
  import { Component, CProps, CEventMap, HtmlString } from './component'
32
32
  import { EventCallback, EvClick, EvChange } from './x4events'
33
33
 
34
+ import { Action } from './action'
34
35
  import { Icon, IconID } from './icon'
35
36
  import { Label } from './label'
36
37
  import { Menu, MenuItem, MenuOrSep } from './menu'
@@ -57,8 +58,9 @@ interface ButtonProps<E extends ButtonEventMap = ButtonEventMap> extends CProps<
57
58
  align?: 'center' | 'left' | 'right'; // text alignment
58
59
  autoRepeat?: number; // time in ms or 0/undefined for none
59
60
  menu?: MenuOrSep[] | MenuCallBack;
60
-
61
61
  click?: EventCallback<EvClick>; // shortcut to events: { click: ... }
62
+
63
+ action?: Action;
62
64
  }
63
65
 
64
66
 
@@ -83,11 +85,26 @@ export class BaseButton<P extends ButtonProps = ButtonProps, E extends ButtonEve
83
85
 
84
86
  render(props: ButtonProps) {
85
87
 
86
- let icon = props.icon ? new Icon({ icon: props.icon, cls: 'left', ref: 'l_icon' }) : null;
87
- let label = new Label({ flex: 1, text: props.text ?? '', align: props.align, ref: 'label' });
88
- let ricon = props.rightIcon ? new Icon({ icon: props.rightIcon, cls: 'right', ref: 'r_icon' }) : null;
88
+ const action = props.action;
89
+
90
+ let icon = props.icon;
91
+ let text = props.text;
92
+
93
+ if( action ) {
94
+ if( !icon && action.props.icon ) {
95
+ icon = action.props.icon;
96
+ }
97
+
98
+ if( text===undefined && action.props.text ) {
99
+ text = action.props.text;
100
+ }
101
+ }
89
102
 
90
- this.setContent([icon, label, ricon]);
103
+ const ui_icon = icon ? new Icon({ icon, cls: 'left', ref: 'l_icon' }) : null;
104
+ const ui_label = new Label({ flex: 1, text: text ?? '', align: props.align, ref: 'label' });
105
+ const ui_ricon = props.rightIcon ? new Icon({ icon: props.rightIcon, cls: 'right', ref: 'r_icon' }) : null;
106
+
107
+ this.setContent([ui_icon, ui_label, ui_ricon]);
91
108
  this._setTabIndex(props.tabIndex);
92
109
  }
93
110
 
@@ -164,6 +181,9 @@ export class BaseButton<P extends ButtonProps = ButtonProps, E extends ButtonEve
164
181
  }
165
182
  else {
166
183
  this.emit('click', EvClick());
184
+ if( this.m_props.action ) {
185
+ this.m_props.action.fire( );
186
+ }
167
187
  }
168
188
  }
169
189
 
package/src/component.ts CHANGED
@@ -41,6 +41,7 @@ import { _tr } from './i18n';
41
41
  import { BasicEvent, EventCallback } from './x4events';
42
42
  import { BaseComponent, BaseComponentProps, BaseComponentEventMap } from './base_component';
43
43
  import { IDOMEvents, X4ElementEventMap } from './dom_events';
44
+ import { IconID } from 'x4js';
44
45
 
45
46
  export { HtmlString, isHtmlString, html } from './tools'
46
47
 
@@ -1143,15 +1144,6 @@ export class Component<P extends CProps<BaseComponentEventMap> = CProps<BaseComp
1143
1144
  }
1144
1145
  }
1145
1146
 
1146
- public mapPropEvents<N extends keyof E>(props: P, ...elements: N[] ) {
1147
- elements.forEach( name => {
1148
- const n = name as string;
1149
- if (props[n]) {
1150
- this._on(n, props[n]);
1151
- }
1152
- })
1153
- }
1154
-
1155
1147
  /**
1156
1148
  *
1157
1149
  * @param name
@@ -2333,4 +2325,6 @@ export class Container<P extends ContainerProps = ContainerProps, E extends Cont
2333
2325
  }
2334
2326
  }
2335
2327
 
2336
- export type ComponentConstructor<T> = new (props: CProps) => T;
2328
+ export type ComponentConstructor<T> = new (props: CProps) => T;
2329
+
2330
+
package/src/icon.ts CHANGED
@@ -100,10 +100,15 @@ class Loader extends EventSource<LoadingEventMap> {
100
100
  const r = await fetch( url );
101
101
  if( r.ok ) {
102
102
  const svg = await r.text();
103
- this.svgs.set( url, svg );
104
-
105
- //console.log( 'signal=', url );
106
- this.signal( 'loaded', EvLoaded(url,svg) );
103
+ // check response, must be svg
104
+ if( !svg.startsWith("<svg") ) {
105
+ console.error( "svg loading error: ", svg );
106
+ this.signal( 'loaded', EvLoaded(url,"") );
107
+ }
108
+ else {
109
+ this.svgs.set( url, svg );
110
+ this.signal( 'loaded', EvLoaded(url,svg) );
111
+ }
107
112
  }
108
113
  }
109
114
  }
package/src/menu.ts CHANGED
@@ -32,6 +32,8 @@ import { x4document } from './x4dom'
32
32
  import { CEventMap, Component, CProps } from './component'
33
33
  import { EvClick, EventCallback } from './x4events'
34
34
 
35
+ import { Action } from './action'
36
+
35
37
  import { Popup, PopupProps } from './popup'
36
38
  import { Icon, IconID } from './icon'
37
39
  import { Label } from './label'
@@ -244,8 +246,9 @@ export interface MenuItemProps extends CProps {
244
246
  items?: MenuOrSep[];
245
247
  checked?: boolean;
246
248
  cls?: string;
247
-
248
249
  click?: EventCallback<EvClick>; // shortcut to events: { click ... }
250
+
251
+ action?: Action;
249
252
  }
250
253
 
251
254
 
@@ -254,12 +257,21 @@ export class MenuItem extends Component<MenuItemProps, MenuItemEventMap> {
254
257
 
255
258
  private m_menu: Menu;
256
259
  private m_isOpen: boolean;
260
+ private m_action: Action;
257
261
 
262
+ constructor( action: Action );
258
263
  constructor( text: string, click: EventCallback<EvClick> );
259
264
  constructor( props: MenuItemProps);
260
265
  constructor( a, b? ) {
261
266
 
262
- if( isString(a) ) {
267
+ if( a instanceof Action ) {
268
+ super( {
269
+ click: ( ) => { a.fire(); }
270
+ });
271
+
272
+ this.m_action = a;
273
+ }
274
+ else if( isString(a) ) {
263
275
  super( {
264
276
  text: a,
265
277
  click: b
@@ -288,6 +300,16 @@ export class MenuItem extends Component<MenuItemProps, MenuItemEventMap> {
288
300
  icon = props.checked ? 'cls(far fa-check)' : 0; //todo: use stylesheet
289
301
  }
290
302
 
303
+ if( this.m_action ) {
304
+ if( !icon ) {
305
+ icon = this.m_action.props.icon;
306
+ }
307
+
308
+ if( text===undefined ) {
309
+ text = this.m_action.props.text;
310
+ }
311
+ }
312
+
291
313
  let popIco = null;
292
314
  if (this.isPopup) {
293
315
  this.addClass('@popup-menu-item');
package/src/settings.ts CHANGED
@@ -27,8 +27,6 @@
27
27
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
28
  **/
29
29
 
30
- import { host } from './hosts/host';
31
-
32
30
  export class Settings {
33
31
 
34
32
  private m_data: any;
@@ -52,7 +50,7 @@ export class Settings {
52
50
 
53
51
  private _save( ) {
54
52
  let data = JSON.stringify(this.m_data);
55
- host.writeLocalStorage( this.m_name, data );
53
+ localStorage.setItem( this.m_name, data );
56
54
  }
57
55
 
58
56
  private _load( ) {
@@ -62,7 +60,7 @@ export class Settings {
62
60
 
63
61
  this.m_data = {};
64
62
 
65
- let data = host.readLocalStorage( this.m_name );
63
+ let data = localStorage.getItem( this.m_name );
66
64
  if( data!==null ) {
67
65
  data = JSON.parse( data );
68
66
  if( data ) {
package/tsconfig.json CHANGED
@@ -13,8 +13,6 @@
13
13
  "./src/*",
14
14
  ],
15
15
  "exclude": [
16
- "src/hosts/nwjs_types.ts",
17
- "src/hosts/nwjs.ts",
18
16
  "src/texthiliter.ts",
19
17
  "src/smartedit.ts"
20
18
  ],
@@ -1,164 +0,0 @@
1
- /**
2
- * @file host/electron.ts
3
- * @author Etienne Cochard
4
- * @license
5
- * Copyright (c) 2019-2021 R-libre ingenierie
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 3 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
18
- **/
19
-
20
- import { x4document } from '../dom-gen'
21
- import { FileStat, PathType, PartType, Host } from './host'
22
-
23
- export * from './host';
24
-
25
- declare const require;
26
- declare const host_require;
27
-
28
- if( !globalThis.host_require ) {
29
- globalThis.host_require = require;
30
- }
31
-
32
- export const fs = host_require( 'fs' );
33
- export const process = host_require( 'process' );
34
- export const electron = host_require( 'electron' );
35
- export const path = host_require( 'path' );
36
-
37
- //import * as path from 'node:path';
38
-
39
- export class ElectronHost extends Host {
40
-
41
- makePath( ...els: string[] ) {
42
- return path.join( ...els );
43
- }
44
-
45
- readBinary( path: string ): Promise<Uint8Array> {
46
- return new Promise( ( resolve, reject ) => {
47
- fs.readFile( path, ( err, buff ) => {
48
- if( err ) { reject( err ); }
49
- else { resolve( buff ); }
50
- } );
51
- } );
52
- }
53
-
54
- writeBinary( path: string, data: Uint8Array ): Promise<boolean> {
55
- return new Promise( ( resolve, reject ) => {
56
- fs.writeFile( path, data, ( err ) => {
57
- if( err ) { reject(err); }
58
- else { resolve( true ); }
59
- } );
60
- } );
61
- }
62
-
63
- readUtf8( path: string ): Promise<string> {
64
- return new Promise( ( resolve, reject ) => {
65
- fs.readFile( path, { encoding: 'utf8' }, ( err, buff ) => {
66
- if( err ) { reject( err ); }
67
- else { resolve( buff.toString() ); }
68
- } );
69
- } );
70
- }
71
-
72
- writeUtf8( path: string, data: string ): Promise<boolean> {
73
- return new Promise( ( resolve, reject ) => {
74
- fs.writeFile( path, data, {encoding: 'utf8'}, ( err ) => {
75
- if( err ) { reject(err); }
76
- else { resolve( true ); }
77
- } );
78
- } );
79
- }
80
-
81
- compress( data: Uint8Array ): Promise<Uint8Array> {
82
- return new Promise( (resolve, reject ) => {
83
- let zlib = this.require('zlib');
84
- zlib.gzip( data, ( err, Uint8Array ) => {
85
- if( err ) { reject( err); }
86
- else { resolve( Uint8Array); }
87
- } );
88
- } );
89
- }
90
-
91
- decompress( data: Uint8Array ): Promise<Uint8Array> {
92
- return new Promise( (resolve, reject ) => {
93
- let zlib = this.require('zlib');
94
- zlib.gunzip( data, ( err, Uint8Array ) => {
95
- if( err ) { reject( err); }
96
- else { resolve( Uint8Array); }
97
- } );
98
- } );
99
- }
100
-
101
- readLocalStorage( name: string ): string {
102
- return localStorage.getItem( name );
103
- }
104
-
105
- writeLocalStorage( name: string, data: string ): void {
106
- localStorage.setItem( name, data );
107
- }
108
-
109
- stat( name: string ): FileStat {
110
- let stat = fs.statSync( name );
111
- if( !stat ) {
112
- return null;
113
- }
114
-
115
- return {
116
- atime: stat.atimeMs,
117
- isDir: stat.isDirectory()
118
- }
119
- }
120
-
121
- readDir( path: string ): Promise<string[]> {
122
- return new Promise( ( resolve, reject ) => {
123
- fs.readdir( path, ( err, files ) => {
124
- if( err ) { reject(err); }
125
- else { resolve(files); }
126
- });
127
- });
128
- }
129
-
130
- require( name: string ): any {
131
- return host_require( name );
132
- }
133
-
134
- cwd( ): string {
135
- return process.cwd( );
136
- }
137
-
138
- get ipc( ) {
139
- return electron.ipcRenderer;
140
- }
141
-
142
- getPath( type: PathType ) : string {
143
- return this.ipc.sendSync( 'getPath', type );
144
- }
145
-
146
- getPathPart( pth: string, type: PartType ) : string {
147
-
148
- let els = path.parse( pth );
149
- switch ( type ) {
150
- case 'dirname': return els.dir;
151
- case 'basename': return els.base;
152
- case 'filename': return els.name;
153
- case 'extname': return els.ext;
154
- }
155
-
156
- return '';
157
- }
158
-
159
- createCanvas = ( ) => {
160
- return x4document.createElement('canvas');
161
- }
162
- }
163
-
164
- new ElectronHost( );
package/src/hosts/host.ts DELETED
@@ -1,100 +0,0 @@
1
- /**
2
- * @file host.ts
3
- * @author Etienne Cochard
4
- * @license
5
- * Copyright (c) 2019-2021 R-libre ingenierie
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 3 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
18
- **/
19
-
20
- export interface FileStat {
21
- atime: number;
22
- isDir: boolean;
23
- }
24
-
25
- export type PathType = 'home' | 'appData' | 'userData' | 'cache' | 'temp' | 'exe' | 'desktop' | 'documents' | 'downloads' | 'music'
26
- | 'pictures'| 'videos' | 'recent' | 'logs' | 'crashDumps';
27
-
28
- export type PartType = 'filename' | 'extname' | 'basename' | 'dirname';
29
-
30
- export abstract class Host {
31
-
32
- constructor( ) {
33
- host = this;
34
- }
35
-
36
- makePath( ...els: string[] ) {
37
- return els.join( '/' );
38
- }
39
-
40
- readBinary( path: string ): Promise<Uint8Array> {
41
- return Promise.reject( 'not imp' );
42
- }
43
-
44
- writeBinary( path: string, data: Uint8Array ): Promise<boolean> {
45
- return Promise.reject( 'not imp' );
46
- }
47
-
48
- readUtf8( path: string ): Promise<string> {
49
- return Promise.reject( 'not imp' );
50
- }
51
-
52
- writeUtf8( path: string, data: string ): Promise<boolean> {
53
- return Promise.reject( 'not imp' );
54
- }
55
-
56
- compress( data: Uint8Array ): Promise<Uint8Array> {
57
- return Promise.reject( 'not imp' );
58
- }
59
-
60
- decompress( data: Uint8Array ): Promise<Uint8Array> {
61
- return Promise.reject( 'not imp' );
62
- }
63
-
64
- readLocalStorage( name: string ): string {
65
- return localStorage.getItem( name );
66
- }
67
-
68
- writeLocalStorage( name: string, data: string ): void {
69
- localStorage.setItem( name, data );
70
- }
71
-
72
- stat( name: string ): FileStat {
73
- throw 'not imp';
74
- }
75
-
76
- readDir( path: string ): Promise<string[]> {
77
- throw 'not imp';
78
- }
79
-
80
- require( name: string ): any {
81
- throw 'not imp';
82
- }
83
-
84
- cwd( ): string {
85
- throw 'not imp';
86
- }
87
-
88
- getPath( type: PathType ) : string {
89
- throw 'not imp';
90
- }
91
-
92
- getPathPart( path: string, type: PartType ) : string {
93
- throw 'not imp';
94
- }
95
-
96
- abstract createCanvas( );
97
- }
98
-
99
-
100
- export let host: Host = null;
package/src/hosts/nwjs.ts DELETED
@@ -1,141 +0,0 @@
1
- /**
2
- * @file host/nwjs.ts
3
- * @author Etienne Cochard
4
- * @license
5
- * Copyright (c) 2019-2021 R-libre ingenierie
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 3 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
18
- **/
19
-
20
- import { FileStat, PathType, Host } from './host'
21
-
22
- export * from './host';
23
-
24
- // to deal with amd modules (that are not comletely compatible with nodejs)
25
- // globalThis.node_require must be set to require BEFORE polyfill code of amd module.
26
- // ie. globalThis.node_require = require;
27
-
28
- declare const host_require;
29
- if( !globalThis.host_require ) {
30
- globalThis.host_require = require;
31
- }
32
-
33
- const fs = host_require( 'fs' );
34
- const process = host_require( 'process' );
35
- const path = host_require( 'path' );
36
-
37
-
38
-
39
- export class NWJSHost implements Host {
40
-
41
- makePath( ...els: string[] ) {
42
- return path.join( ...els );
43
- }
44
-
45
- readBinary( path: string ): Promise<Uint8Array> {
46
- return new Promise( ( resolve, reject ) => {
47
- fs.readFile( path, ( err, buff ) => {
48
- if( err ) { reject( err ); }
49
- else { resolve( buff ); }
50
- } );
51
- } );
52
- }
53
-
54
- writeBinary( path: string, data: Uint8Array ): Promise<boolean> {
55
- return new Promise( ( resolve, reject ) => {
56
- fs.writeFile( path, data, ( err ) => {
57
- if( err ) { reject(err); }
58
- else { resolve( true ); }
59
- } );
60
- } );
61
- }
62
-
63
- readUtf8( path: string ): Promise<string> {
64
- return new Promise( ( resolve, reject ) => {
65
- fs.readFile( path, { encoding: 'utf8' }, ( err, buff ) => {
66
- if( err ) { reject( err ); }
67
- else { resolve( buff.toString() ); }
68
- } );
69
- } );
70
- }
71
-
72
- writeUtf8( path: string, data: string ): Promise<boolean> {
73
- return new Promise( ( resolve, reject ) => {
74
- fs.writeFile( path, data, {encoding: 'utf8'}, ( err ) => {
75
- if( err ) { reject(err); }
76
- else { resolve( true ); }
77
- } );
78
- } );
79
- }
80
-
81
- compress( data: Uint8Array ): Promise<Uint8Array> {
82
- return new Promise( (resolve, reject ) => {
83
- let zlib = host_require('zlib');
84
- zlib.gzip( data, ( err, Uint8Array ) => {
85
- if( err ) { reject( err); }
86
- else { resolve( Uint8Array); }
87
- } );
88
- } );
89
- }
90
-
91
- decompress( data: Uint8Array ): Promise<Uint8Array> {
92
- return new Promise( (resolve, reject ) => {
93
- let zlib = host_require('zlib');
94
- zlib.gunzip( data, ( err, Uint8Array ) => {
95
- if( err ) { reject( err); }
96
- else { resolve( Uint8Array); }
97
- } );
98
- } );
99
- }
100
-
101
- readLocalStorage( name: string ): string {
102
- return localStorage.getItem( name );
103
- }
104
-
105
- writeLocalStorage( name: string, data: string ): void {
106
- localStorage.setItem( name, data );
107
- }
108
-
109
- stat( name: string ): FileStat {
110
- let stat = fs.statSync( name );
111
- if( !stat ) {
112
- return null;
113
- }
114
-
115
- return {
116
- atime: stat.atimeMs
117
- }
118
- }
119
-
120
- readDir( path: string ): Promise<string[]> {
121
- return new Promise( ( resolve, reject ) => {
122
- fs.readdir( path, ( err, files ) => {
123
- if( err ) { reject(err); }
124
- else { resolve(files); }
125
- });
126
- });
127
- }
128
-
129
- require( name: string ): any {
130
- // your amd module must define window.node_require = require;
131
- return host_require( name );
132
- }
133
-
134
- cwd( ): string {
135
- return process.cwd( );
136
- }
137
-
138
- getPath( type: PathType ) : string {
139
- throw 'not imp';
140
- }
141
- }