cavalion-js 1.0.79 → 1.0.80

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/.md CHANGED
@@ -22,17 +22,17 @@
22
22
  - [nameOf.js](src/js/:)
23
23
  - [mixIn.js](src/js/:) - [mixInRecursive.js](src/js/:)
24
24
  - [minify.js](src/js/:) - [beautify.js](src/js/:) - [serialize.js](src/js/:)
25
- - [util](src/:/) / [net](src/util/:/) / [HttpStatusCode.js](src/util/net/:) - [Url.js](src/util/net/:)
26
- - [Ajax.js](src/util/:) - [Command.js](src/util/:)
27
- - [Browser.js](src/util/:) - [CssSelectorParser.js](src/util/:)
28
- - [DocumentHook.js](src/util/:) - [Event.js](src/util/:) - [Fullscreen.js](src/util/:)
29
- - [HotkeyManager.js](src/util/:) - [HtmlElement.js](src/util/:)
30
- - [Hash.js](src/util/:)
31
- - [Keyboard.js](src/util/:)
32
- - [Rest.js](src/util/:)
33
- - [Stylesheet.js](src/util/:)
34
- - [Text.js](src/util/:)
35
- - [Xml.js](src/util/:)
25
+ - **[util](src/:/)** / [net](src/util/:/) / [HttpStatusCode.js](src/util/net/:) - [Url.js](src/util/net/:)
26
+ - [Ajax.js](src/util/:) - [Command.js](src/util/:)
27
+ - [Browser.js](src/util/:) - [CssSelectorParser.js](src/util/:)
28
+ - [DocumentHook.js](src/util/:) - [Event.js](src/util/:) - [Fullscreen.js](src/util/:)
29
+ - [HotkeyManager.js](src/util/:) - [HtmlElement.js](src/util/:)
30
+ - [Hash.js](src/util/:)
31
+ - [Keyboard.js](src/util/:)
32
+ - [Rest.js](src/util/:)
33
+ - [Stylesheet.js](src/util/:)
34
+ - [Text.js](src/util/:)
35
+ - [Xml.js](src/util/:)
36
36
 
37
37
  #
38
38
 
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ### 2024/10/25 - 1.0.80
2
+
3
+ * Adds Array.sortValues
4
+ * Adds Date.format (USE IT! ;-))
5
+ * Fixes/prepares js.nameOf() for some exotic use case with dropped files
6
+
7
+
1
8
  ### 2024/07/07 - 1.0.79
2
9
 
3
10
  * Removes `Array.prototype.last` and -`first`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cavalion-js",
3
- "version": "1.0.79",
3
+ "version": "1.0.80",
4
4
  "description": "Cavalion common JavaScript library",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/src/js/_js.js CHANGED
@@ -254,6 +254,7 @@ define(function(require) {
254
254
  }
255
255
  return obj;
256
256
  },
257
+
257
258
  clone: function(obj) {
258
259
  /**
259
260
  *
@@ -116,6 +116,53 @@ define(function(require) {
116
116
  // sort()
117
117
  };
118
118
 
119
+ const stringify = (obj) => (
120
+ Object.entries(obj).map(e => js.sf("%s=%n", e[0],
121
+ js.nameOf(e[1], "compare"))).join(";"));
122
+
123
+ Array.sortValues = function generalizedSort(a, b) {
124
+ if(Array.onSortValues) return Array.onSortValues(a, b);
125
+
126
+ // Define type priority order for consistent sorting
127
+ const typeOrder = {
128
+ 'undefined': 0,
129
+ 'null': 1,
130
+ 'boolean': 2,
131
+ 'number': 3,
132
+ 'string': 4,
133
+ 'object': 5,
134
+ 'function': 6,
135
+ 'symbol': 7,
136
+ };
137
+
138
+ // Convert null to a string "null" for consistent sorting
139
+ const typeA = a === null ? 'null' : typeof a;
140
+ const typeB = b === null ? 'null' : typeof b;
141
+
142
+ // Compare types according to priority order
143
+ if (typeOrder[typeA] !== typeOrder[typeB]) {
144
+ return typeOrder[typeA] - typeOrder[typeB];
145
+ }
146
+
147
+ // Handle cases by type
148
+ switch (typeA) {
149
+ case 'boolean':
150
+ case 'number':
151
+ return a - b;
152
+ case 'string':
153
+ return a.localeCompare(b);
154
+ case 'null':
155
+ case 'undefined':
156
+ return 0; // Treat null and undefined as equal
157
+ case 'object':
158
+ if (a === null && b === null) return 0;
159
+
160
+ return stringify(a).localeCompare(stringify(b));
161
+ default:
162
+ }
163
+ return 0;
164
+ };
165
+
119
166
  if (typeof String.prototype.startsWith !== 'function') {
120
167
  String.prototype.startsWith = function(s) {
121
168
  return this.indexOf(s) === 0;
@@ -423,5 +470,17 @@ define(function(require) {
423
470
  return Math.ceil((((dt - new Date(dt.getFullYear(), 0, 1))
424
471
  / 8.64e7) + 1) / 7);
425
472
  };
473
+ Date.format = function (dt, fmt) {
474
+ if(!(dt instanceof Date)) {
475
+ dt = new Date(dt);
476
+ }
477
+ if(fmt === "YYYY/MM/DD hh:mm") {
478
+ return js.sf("%d/%02d/%02d %02d:%02d",
479
+ dt.getFullYear(), dt.getMonth() + 1, dt.getDate(),
480
+ dt.getHours(), dt.getMinutes()
481
+ );
482
+ }
483
+ return dt.toISOString();
484
+ };
426
485
 
427
486
  });
package/src/js/nameOf.js CHANGED
@@ -1,7 +1,11 @@
1
1
  define(function() {
2
2
 
3
3
  String.of = function(obj) { // TODO require("String.of")
4
+ try {
4
5
  return nameOf(obj);
6
+ } catch(e) {
7
+ debugger;
8
+ }
5
9
  };
6
10
 
7
11
  var methods = (nameOf.methods = [
@@ -34,6 +38,8 @@ define(function() {
34
38
  function nameOf(obj, hint, test) {
35
39
  if(obj === undefined || obj === null) return String(obj);
36
40
 
41
+ if(!obj.constructor) return "<Native?>";//obj;
42
+
37
43
  for(var i = methods.before.length - 1, r; i >= 0; --i) {
38
44
  if((r = methods.before[i].apply(this, arguments)) !== undefined) {
39
45
  return test ? ["before", i, methods.before[i]] : r;
@@ -1,8 +1,5 @@
1
- /**
2
- * Keyboard.js
3
- */
4
1
  define(function () {
5
-
2
+
6
3
  var specialKeys = {
7
4
  8: 'KEY_BACKSPACE',
8
5
  9: 'KEY_TAB',
@@ -65,9 +62,57 @@ define(function () {
65
62
  222: 'KEY_APOSTROPHE'
66
63
  // undefined: 'KEY_UNKNOWN'
67
64
  };
68
-
65
+ var listeners = {};
66
+
67
+ function init() {
68
+ if(init.HKM) return;
69
+
70
+ init.HKM = req("util/HotkeyManager").getInstance();
71
+ init.HKM.register("*", { callback(evt) {
72
+ (listeners[evt.key] || []).forEach(li => li(evt));
73
+ } });
74
+ }
75
+ function getListeners(name) {
76
+ init();
77
+
78
+ if(!listeners[name]) {
79
+ listeners[name] = [];
80
+ }
81
+ return listeners[name];
82
+ }
83
+
69
84
  return {
70
- // keys: specialKeys,
85
+ keys: specialKeys,
86
+ listeners: listeners,
87
+
88
+ on(name, listener) {
89
+ if(name.includes(":")) {
90
+ const li = listener;
91
+
92
+ const types = name.split(":");
93
+ name = types.pop();
94
+
95
+ listener = (evt) => {
96
+ if(types.includes(evt.type)) {
97
+ return li(evt);
98
+ }
99
+ };
100
+ }
101
+
102
+ const listeners = getListeners(name);
103
+ listeners.push(listener);
104
+ return listener;
105
+ },
106
+ once(name, listener) {
107
+ this.on(name, listener);
108
+ this.on(name, () => this.un(name, listener));
109
+ return listener;
110
+ },
111
+ un(name, listener) {
112
+ const listeners = getListeners(name);
113
+ listeners.splice(listeners.indexOf(listener), 1);
114
+ return listener;
115
+ },
71
116
 
72
117
  getKeyNames: function () {
73
118
  var r;