cavalion-vcl 1.1.84 → 1.1.86

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
@@ -14,12 +14,12 @@
14
14
  * [Input](src/ui/:.js) < [Checkbox](src/ui/:.js) - [Combobox](src/ui/:.js) - [DatePicker](src/ui/:.js)
15
15
  * [Button](src/ui/:.js) < [PopupButton](src/ui/:.js)
16
16
  * [Select](src/ui/:.js)
17
- * [Container](src/ui/:.js)
17
+ * **[Container](src/ui/:.js)**
18
18
  * [Group](src/ui/:.js)
19
19
  * [CheckGroup](src/ui/:.js)
20
20
  * [Bar](src/ui/:.js)
21
21
  * [Tabs](src/ui/:.js) - [Tab](src/ui/:.js)
22
- * [Panel](src/ui/:.js)
22
+ * **[Panel](src/ui/:.js)**
23
23
  * [Popup](src/ui/:.js) - [Ace](src/ui/:.js) - [Console](src/ui/:.js)
24
24
  * ( [Form](src/ui/:.js) - [FormContainer](src/ui/:.js) ) _where does onActive/Deactive go?_
25
25
  * [List](src/ui/:.js) | [ListColumn](src/ui/:.js) - [ListBody](src/ui/:.js) - [ListFooter](src/ui/:.js) - [ListHeader](src/ui/:.js) - [ListRow](src/ui/:.js)
@@ -27,7 +27,9 @@
27
27
 
28
28
  # [prototypes](src/:/) `2022/04/17`
29
29
 
30
- > * [App](src/prototypes/:.js) - <= _#window is instantiated here (weirdly not in .desktop)_
30
+ >
31
+ * [cavalion-blocks](src/prototypes/:.js)
32
+ * [App](src/prototypes/:.js) - <= _#window is instantiated here (weirdly not in .desktop)_
31
33
  * [.console](src/prototypes/App:.js) << _hotkeys_ _probably deprecated_
32
34
  * [.desktop](src/prototypes/App:.js) << _#client [ui/forms/Portal<>]()_ _used at all?_
33
35
  * [.framework7](src/prototypes/App:.js) -[.scaffold](src/prototypes/App:.js)
package/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ ### `2025/04/03` - 1.1.86
2
+
3
+ * 20250403 fixes bug in sorting by column (List) improves selecting console nodes with keyboard
4
+ * 20250403 updates ^Escape handling to toggle console visibility updates glassy styles toasts out a message whenever the system clipboard is read or written
5
+ * 20250403 introduces Action.prototype.go() (alias for execute()) finetunes Component.prototype.getVar introduces Control.findByName(node) where node is a string (eg. ":focus")
6
+ * 20241119 develops support for searching through history updates Panel.prototype.setZoom to support setting transform-origin as well updates auto ListColumn header algoritm
7
+ * 20241119 updates Component.prototype.setVars to control whether to mixInR or mixIn fixes a bug in Control.prototype.updateChildren() updates glassy styles
8
+ * 20241111 updates glassy background to be more light sets ace.config for dynamic loading of themes and modes
9
+ * 20241108 adds prepend
10
+
11
+ ### `2024/11/08` - 1.1.85
12
+
13
+ * Service build in favor of cavalion-code
14
+
15
+ ### `2024/10/..` - 1.1.84
16
+
1
17
  ### `2024/10/24` - 1.1.83
2
18
 
3
19
  - 20241024 introduces Control.prototype.getNext/PreviousSibling introduces Ace.prototype.append
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cavalion-vcl",
3
- "version": "1.1.84",
3
+ "version": "1.1.86",
4
4
  "description": "Visual Component Library for vcl-comps",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/src/Action.js CHANGED
@@ -62,6 +62,10 @@ define(function (require) {
62
62
  }
63
63
  }
64
64
  },
65
+ go: function() {
66
+ Action.prototype.go = Action.prototype.execute;
67
+ return this.go.apply(this, arguments);
68
+ },
65
69
  execute: function (evt, sender) {
66
70
  return this.onexecute(evt, sender);
67
71
  },
@@ -312,8 +316,7 @@ define(function (require) {
312
316
  /**
313
317
  * Sets the -hotkey-property.
314
318
  */
315
- value = value.replace(/Cmd\+/g, "Meta+").replace(/\+Cmd/, "+Meta");
316
-
319
+
317
320
  if (this._hotkey !== value) {
318
321
  this._hotkey = value;
319
322
 
@@ -324,11 +327,18 @@ define(function (require) {
324
327
  }
325
328
 
326
329
  var me = this;
327
- var arr = this._hotkey.split("|");
330
+ var arr;
331
+
332
+ if(typeof this._hotkey === "string") {
333
+ arr = this._hotkey.split("|");
334
+ } else if(this._hotkey instanceof Array) {
335
+ arr = this._hotkey;
336
+ }
328
337
 
329
338
  this._hotkeyListeners = [];
330
339
 
331
340
  arr.forEach(function(hotkey, type) {
341
+ hotkey = hotkey.replace(/Cmd\+/g, "Meta+").replace(/\+Cmd/, "+Meta");
332
342
  hotkey = String.trim(hotkey).split(":");
333
343
  type = hotkey.length === 1 ? "keydown" : hotkey.shift();
334
344
  hotkey = hotkey.shift();
@@ -478,6 +488,7 @@ define(function (require) {
478
488
  type: Type.BOOLEAN,
479
489
  set: Function
480
490
  },
491
+ "hotkeys": { set(value) { this.setHotkey(value); } }, // alias
481
492
  "hotkey": {
482
493
  type: Type.STRING,
483
494
  get: Function,
package/src/Component.js CHANGED
@@ -512,7 +512,7 @@ define(function (require) {
512
512
  if(arguments.length === 2) {
513
513
  return this.setVar("" + key, value);
514
514
  }
515
- if(arguments.length === 3) {
515
+ if(arguments.length >= 3) {
516
516
  return this.getVar.apply(this, arguments);
517
517
  }
518
518
  if(key instanceof Array) {
@@ -535,13 +535,12 @@ define(function (require) {
535
535
  }
536
536
  return this._vars;
537
537
  },
538
- setVars: function (value) {
538
+ setVars: function (value, mixInRecursive) {
539
539
  if(typeof value === "string") {
540
540
  value = js.str2obj(value);
541
541
  }
542
- if (this.isLoading()) {
543
- this._vars = mixInR(this._vars || {},
544
- value);
542
+ if (mixInRecursive || this.isLoading()) {
543
+ this._vars = mixInR(this._vars || {}, value);
545
544
  } else {
546
545
  this._vars = value;
547
546
  }
@@ -557,16 +556,18 @@ define(function (require) {
557
556
  hasVar: function (key) {
558
557
  return (this._vars && this._vars.hasOwnProperty(key)) || false;
559
558
  },
560
- getVar: function (namePath, fallback_to_owner, defaultValue) {
561
- if (this._vars !== null && arguments.length === 3) {
559
+ getVar: function (namePath, fallback_to_owner, defaultValue, callingComponent) {
560
+ if (this._vars !== null && arguments.length >= 3) {
562
561
  this._vars = this._vars || {};
563
562
  }
564
563
 
564
+ if(arguments.length < 4) callingComponent = this;
565
+
565
566
  var r = this._vars !== null ? js.get(namePath, this._vars) : undefined;
566
567
  if (r === undefined) {
567
568
  if(fallback_to_owner === true && this._owner !== null) {
568
- r = this._owner.getVar(namePath, true, defaultValue);
569
- } else if(arguments.length === 3) {
569
+ r = this._owner.getVar(namePath, true, defaultValue, callingComponent);
570
+ } else if(arguments.length >= 3) {
570
571
  if((r = defaultValue) !== undefined) {
571
572
  if(typeof defaultValue === "function") {
572
573
  r = defaultValue([this].concat(js.copy_args(arguments)));
package/src/Control.js CHANGED
@@ -1244,6 +1244,8 @@ define(function(require) {
1244
1244
  control.update();
1245
1245
  } else if(control._node !== null) {
1246
1246
  control._update();
1247
+ } else {
1248
+ control.getNode();
1247
1249
  }
1248
1250
  control.updateChildren(recursive, directly);
1249
1251
  }, this);
@@ -1949,6 +1951,11 @@ this._updateCalls = this._updateCalls || 0; this._updateCalls++;
1949
1951
  }, Object.create(root, { hashCode: { value: () => ";-)" } })),
1950
1952
 
1951
1953
  findByNode: function(node) {
1954
+ // as selector when string (usage findByNode(":focus"))
1955
+ if(typeof node === "string") {
1956
+ node = document.qs(node);
1957
+ }
1958
+
1952
1959
  while(node !== null && node[EventDispatcher.elementKey] === undefined) {
1953
1960
  node = node.parentNode || null; // IE
1954
1961
  }
package/src/Factory.js CHANGED
@@ -534,9 +534,7 @@ this._source = source;
534
534
  var sourceUri = Factory.makeTextUri(name);
535
535
 
536
536
  function instantiate(source, local) {
537
- var p = "";//local ? ".skip-fetch.local" : "";
538
- var factory = new Factory(parentRequire, name + p, sourceUri + p);
539
- // console.log("instantiate", name + p);
537
+ var factory = new Factory(parentRequire, name, sourceUri);
540
538
  factory.load(source, () => load(factory, source));
541
539
  }
542
540
 
@@ -7,57 +7,42 @@ const Control = require("vcl/Control");
7
7
 
8
8
  require("console/node/vcl/Component").initialize();
9
9
  override(require("vcl/Component").prototype, "print", function(inherited) {
10
- return function() {
11
- var console = this.down("vcl/ui/Console#console");
12
- if(console && !console.vars("skip-print")) {
13
- return console.print.apply(console, arguments);
14
- }
15
- return inherited.apply(this, arguments);
16
- };
17
- });
10
+ return function() {
11
+ var console = this.down("vcl/ui/Console#console");
12
+ if(console && !console.vars("skip-print")) {
13
+ return console.print.apply(console, arguments);
14
+ }
15
+ return inherited.apply(this, arguments);
16
+ };
17
+ });
18
18
 
19
19
  [(""), [
20
20
  ["vcl/Action", ("toggle-console"), {
21
- hotkey: `
22
- keyup:Ctrl+Escape|keydown:Ctrl+Escape|
23
- keyup:Ctrl+Shift+D|keydown:Ctrl+Shift+D|
24
- keyup:Alt+Shift+Z|keydown:Alt+Shift+Z|
25
- keyup:MetaCtrl+192`,
21
+ hotkey: "keyup:Ctrl+Escape|keydown_:Ctrl+Escape|keyup:Ctrl+Shift+D|keyup:MetaCtrl+192",
26
22
  onLoad() {
27
23
  // TODO #CVLN-20200822-2
28
- this.readStorage("visible", (visible) => eval(visible) && this.execute({}));
24
+ this.readStorage("visible", (visible) => JSON.parse(visible) && this.execute({}));
29
25
  },
30
26
  onExecute(evt) {
31
- var scope = this.scope();
32
- var focused;
33
-
34
- if (evt.type === "keydown") {
35
- focused = require("vcl/Control").focused;
36
- if (focused !== scope.console.getScope().console) {
37
- this.setVar("focused", focused);
38
- }
39
- } else {
40
- if (!scope.console.isVisible()) {
41
- scope.console.show();
42
- scope['align-enabled'].setState(true);
43
- } else {
44
- if(Control.focused === scope.console.getScope().console) {
45
- scope['align-enabled'].setState(false);
46
- scope.console.hide();
47
- focused = this.removeVar("focused");
48
- if (focused && focused !== scope.console) {
49
- this.setTimeout("focus", function() {
50
- // console.log("setFocus", focused);
51
- focused.setFocus();
52
- }, 250);
53
- }
54
- } else {
55
- scope.console.setFocus();
56
- }
57
- }
58
- }
27
+ var scope = this.scope(), console = scope.console.qs("#console");
28
+ var focused = Control.findByNode(document.qs(":focus"));
29
+ var visible = scope.console.getVisible();
59
30
 
60
- this.writeStorage("visible", scope.console.isVisible());
31
+ if(focused !== console) {
32
+ this.vars("focused", focused);
33
+ }
34
+
35
+ if(visible && focused !== console) {
36
+ console.setFocus();
37
+ } else if(!scope.console.toggle("visible")) {
38
+ if((focused = this.vars("focused"))) {
39
+ focused.setFocus();
40
+ }
41
+ }
42
+
43
+ visible = scope.console.isVisible();
44
+ scope['align-enabled'].setState(visible);
45
+ this.writeStorage("visible", visible);
61
46
 
62
47
  return this.inherited(arguments);
63
48
  }
@@ -125,6 +110,17 @@ keyup:MetaCtrl+192`,
125
110
  }
126
111
  }
127
112
  }],
113
+ ["vcl/Action", ("open-alphaview"), {
114
+ hotkey: "MetaCtrl+F3",
115
+ on() {
116
+ let c = Control.findByNode(document.qs(":focus"));
117
+ if(c && (c = c instanceof (req("vcl/ui/Console")) ? c : c.udr("vcl/ui/Console"))) {
118
+ H("devtools/Alphaview.csv", { console: c });
119
+ } else {
120
+ H("devtools/Alphaview.csv");
121
+ }
122
+ }
123
+ }],
128
124
 
129
125
  [["ui/forms/util/Console"], "console", {
130
126
  align: "bottom",
@@ -1,32 +1,22 @@
1
- "use vcl/CssRules, vcl/ui/Input";
1
+ "use vcl/CssRules, vcl/ui/Input, vcl/ui/Tabs, vcl/ui/ListRow";
2
2
 
3
3
  var CssRules = require("vcl/CssRules");
4
4
 
5
5
  var css = {
6
6
  '#close-x': {
7
- '': "transition: opacity 1s, background-color 1s; opacity: 0.1; position:absolute;top:0;right:0;color:silver;padding:4px 8px;font-size:14pt;z-index:999999999999;border-radius:15px;background-color:rgba(255,255,255,0.5);",
8
- '&:hover': "color:rgb(56,121,217);cursor:pointer;opacity: 1;"
7
+ '': "transition: opacity 1s; opacity: 0.1; position:absolute;top:0;right:0;color:silver;padding:4px 8px;font-size:14pt;z-index:999999999999; border: 1px solid transparent; border-radius:3px;",
8
+ '&:hover': "color:black;font-weight:bold;cursor:pointer;opacity: 1;backdrop-filter: blur(10px); background-color: rgba(255,255,255,0.5); border: 1px solid silver;",
9
+ '&:active': "background-color: rgba(56,127,217,0.025);"
9
10
  },
10
- 'font-family': "Lucida Grande, Arial, sans-serif",
11
- 'font-size': "9pt",
12
- '.{./Button}': {
13
- 'font-size': "9pt",
14
- 'font-family': "Lucida Grande, Arial, sans-serif",
15
- 'vertical-align': "top",
16
- '&.disabled': "color:gray;",
17
- '&:not(:active)': "margin-bottom:4px;",
18
- '&:active': "margin-bottom:0;margin-top:2px;border:2px solid rgb(57,121,217); padding-left:8px; padding-right:6px;"// background:-webkit-linear-gradient(top, rgb(255, 255, 255) 10%, rgb(227, 227, 227) 100%);"
19
- },
20
-
21
11
  ".with-shadow": "box-shadow:rgba(0, 0, 0, 0.4) 0px 1px 2px 0px;",
22
12
  ".with-text-shadow": "text-shadow: rgb(255 255 255) 0px 0px 12px, #00000094 0px 0px 5px;",
23
13
  ".transparent": "background-color:transparent;",
24
14
  ".glassy-overlay": {
25
15
  "": "pointer-events: none; color:rgba(5,5,5,0.95);",
26
- ".glassy": "background-color: rgba(155, 155, 155, 0.35); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);",
27
- ".loading": "background: rgba(155, 155, 155, 0.35) url(/shared/vcl/images/loading.gif) 50% 50% no-repeat;",
16
+ ".glassy": "background-color: rgba(215, 215, 215, 0.35); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);",
17
+ ".loading": "background: url(/shared/vcl/images/loading.gif) 50% 50% no-repeat;",
28
18
  ".rounded": "padding: 4px; border-radius: 5px;",
29
- ".animate-width-height": "transition: z-index 400ms, width 250ms ease-in, height 250ms ease-in, transform 450ms;",
19
+ ".animate-width-height": "transition: width 250ms ease-in, height 250ms ease-in;",
30
20
  ">.glassy:not(.no-margin)": "margin: 32px;",
31
21
  ">.glassy": {
32
22
  "": "pointer-events: auto;",
@@ -53,12 +43,12 @@ var css = {
53
43
  'border-radius': "5px",
54
44
  'z-index': "1999",
55
45
  // 'backdrop-filter': "blur(10px)",
56
- 'transition': "box-shadow 0.45s ease 0s, transform 0.45s ease 0s, left 0.45s ease 0s, right 0.45s ease 0s, top 0.45s ease 0s, bottom 0.45s ease 0s, width 0.45s ease 0s, height 0.45s ease 0s, border-width 0.45s ease 0s, transform-origin 0.45s ease 0s",
46
+ 'transition': "box-shadow 0.45s ease 0s, transform 0.45s ease 0s, left 0.45s ease 0s, right 0.45s ease 0s, top 0.45s ease 0s, bottom 0.45s ease 0s, width 0.45s ease 0s, height 0.45s ease 0s, border-width 0.45s ease 0s",
57
47
  },
58
48
  '&:hover': {
59
49
  'box-shadow': "0 0 10px 5px rgba(0,0,0,.2)",
60
50
  'cursor': "move",
61
- '.client': "border-color: rgba(56,127,217,0.025); background-color:rgba(155, 155, 155, 0.2);"
51
+ '.client': "border-color: rgba(56,127,217,0.025); background-color:rgba(215, 215, 215, 0.2);"
62
52
  },
63
53
  // '&.square': {
64
54
  // 'min-width': 175 + "px",
@@ -76,16 +66,6 @@ var css = {
76
66
  '&.glassy-overlay > .client.no-margin': "margin:0;",
77
67
  '&.right': "right: 40px; transform-origin: top right;",
78
68
  '&.left': "left: 40px; transform-origin: top left;",
79
-
80
- '&.parent-topleft': "transform-origin: 0% 0%;",
81
- '&.parent-topcenter': "transform-origin: 50% 0%;",
82
- '&.parent-topright': "transform-origin: 100% 0%;",
83
- '&.parent-middleleft': "transform-origin: 0% 50%;",
84
- '&.parent-middlecenter': "transform-origin: 50% 50%;",
85
- '&.parent-middleright': "transform-origin: 100% 50%;",
86
- '&.parent-bottomleft': "transform-origin: 0% 100%;",
87
- '&.parent-bottomcenter': "transform-origin: 50% 100%;",
88
- '&.parent-bottomright': "transform-origin: 100% 100%;",
89
69
 
90
70
  // "&.right": {
91
71
  // '': "right: 5%; transform-origin: top right;",
@@ -94,7 +74,18 @@ var css = {
94
74
  // "&.left": {
95
75
  // '': "left: 5%; transform-origin: top left;",
96
76
  // },
77
+
78
+ '#menubar': "border-bottom: none;",
97
79
 
80
+ '&.parent-topleft': "transform-origin: 0% 0%;",
81
+ '&.parent-topcenter': "transform-origin: 50% 0%;",
82
+ '&.parent-topright': "transform-origin: 100% 0%;",
83
+ '&.parent-middleleft': "transform-origin: 0% 50%;",
84
+ '&.parent-middlecenter': "transform-origin: 50% 50%;",
85
+ '&.parent-middleright': "transform-origin: 100% 50%;",
86
+ '&.parent-bottomleft': "transform-origin: 0% 100%;",
87
+ '&.parent-bottomcenter': "transform-origin: 50% 100%;",
88
+ '&.parent-bottomright': "transform-origin: 100% 100%;",
98
89
  '&.shrink-to-corner:not(:hover)': {
99
90
  'width': 175 + "px",
100
91
  'height': 175 + "px"
@@ -104,7 +95,7 @@ var css = {
104
95
  '.{List}': "border-radius:5px;",
105
96
  '.{ListHeader}': {
106
97
  '': "background-color:transparent;transition:background-color 1s ease 0s;",
107
- '&.scrolled': "background-color:rgba(255,255,255,0.75);",
98
+ '&.scrolled': "background-color:rgba(255,255,255,0.75);backdrop-filter:blur(10px);",
108
99
  '>div': "background-image:none;border:none;font-weight:bold;"
109
100
  },
110
101
  '.{Input}': {
@@ -136,11 +127,12 @@ var css = {
136
127
  'border': "7px solid rgba(0,0,0,0)",
137
128
  // 'overflow': "hidden",
138
129
  'height': "100%",
139
- 'transition': "border-color 0.45s ease 0s, background-color 0.45s ease 0s",
130
+ 'transition': "border-color 0.45s ease 0s, background-color 0.45s ease 0s, border-width: 0.45s ease 0s",
140
131
  '&:hover': {
132
+ 'border-width': "10px"
141
133
  }
142
134
  },
143
- '.seperator.seperator.seperator': "border-top: 1px solid rgba(155, 155, 155, 0.55);",
135
+ '.seperator.seperator.seperator': "border-top: 1px solid rgba(215, 215, 215, 0.55);",
144
136
 
145
137
  '&.phone': {
146
138
  '': "width: 389px; border-radius:20px; box-shadow: 0 0 20px 10px rgba(0,0,0,.2);",
@@ -151,24 +143,15 @@ var css = {
151
143
  }
152
144
  },
153
145
 
154
- '.glassy-overflow': "position: absolute; _pointer-events: none; background-color: rgba(205,95,65,0.1); z-index: 1998;",
155
-
156
- '.veldoffice\\/Tabs\\<Document\\> .\\#preview': "background-color: rgba(240, 240, 240, 0.75);"
146
+ '.glassy': {
147
+ '#bar': "background-color: rgba(240, 240, 240, 0.35);",
148
+ '.{Tabs}': "background-color: rgba(240, 240, 240, 0.35);",
149
+ '.{ListRow}:not(.selected).odd': "background-color: rgba(240, 240, 240, 0.55);"
150
+ }
157
151
  };
158
152
 
159
- [(""), {
160
- onLoad() {
161
- const w = this.qs("#window");
162
- w.set("css", js.mi(w.get("css") || {}, css));
163
- return this.inherited(arguments);
164
- }
165
- }, [
153
+ [(""), [
154
+
155
+ [("#window"), { css: css }]
166
156
 
167
- // ["#window", {
168
-
169
- // css: css
170
-
171
- // }]
172
-
173
-
174
157
  ]];
@@ -1,6 +1,7 @@
1
1
  "use vcl/ui/Popup, vcl/ui/List";
2
2
 
3
3
  ["vcl/Application", { }, [
4
+
4
5
  ["vcl/ui/Panel", ("window"), {
5
6
  align: "client", classes: "animated",
6
7
  onLoad() {
@@ -11,5 +12,11 @@
11
12
  },
12
13
  req("vcl/ui/Popup").prototype._parent = this;
13
14
  }
15
+ }],
16
+ ["vcl/Action", ("reload-app"), {
17
+ hotkey: "Shift+MetaCtrl+R|Cmd+Alt+R",
18
+ on(evt) { evt.preventDefault(); document.location.reload(); }
14
19
  }]
20
+
21
+
15
22
  ]];
@@ -1,4 +1,33 @@
1
+ "use util/Clipboard";
2
+
3
+ const Clipboard = req("util/Clipboard");
4
+
1
5
  ["", {
6
+ onLoad() {
7
+
8
+ // Override toast method to be more convenient (TODO refactor to vcl/Application)
9
+ this.toast = (c = "Content not provided", ms = 1500, opts = {}) => {
10
+ if(typeof c === "object") {
11
+ return this.constructor.prototype.toast.apply(this, [c]);
12
+ }
13
+ return this.constructor.prototype.toast.apply(this, [
14
+ js.mi({content: c, ms: ms, classes: "fade glassy"}, opts)
15
+ ]);
16
+ };
17
+
18
+ Clipboard.onPaste.addListener(e => {
19
+ this.print("onPaste", e);
20
+ this.toast(js.sf("Pasted %d bytes...", e.length ))});
21
+ Clipboard.onCopy.addListener(e => {
22
+ this.print("onCopy", e);
23
+ if(typeof e === "string" && e.length > 150) {
24
+ this.toast(js.sf("Copied %d bytes", e.length ));
25
+ } else {
26
+ this.toast(js.sf("Copied <b>%H<b>", e));
27
+ }});
28
+
29
+ return this.inherited(arguments);
30
+ },
2
31
  onToast: function(options) {
3
32
 
4
33
  /*-
@@ -67,5 +67,11 @@ var FormContainer = require("vcl/ui/FormContainer");
67
67
  ["vcl/ui/FormContainer", "client", {
68
68
  formUri: "./ui/forms/Portal<>"
69
69
  }]
70
- ]]
70
+ ]],
71
+
72
+ // [("vcl/Action"), "reload-app", {
73
+ // hotkey: "Shift+MetaCtrl+R|Cmd+Alt+R",
74
+ // on(evt) { evt.preventDefault(); document.location.reload(); }
75
+ // }]
76
+
71
77
  ]];
@@ -1,154 +1,32 @@
1
1
  "use js, vcl/ui/Node, vcl/ui/Input, vcl/ui/Tab, vcl/ui/Button";
2
2
 
3
+ const css = {
4
+ 'font-family': "Lucida Grande, Arial, sans-serif",
5
+ 'font-size': "9pt",
6
+ '.{Console}': {
7
+ '.node > .container': "padding-top: 2px;",
8
+ '.node': "padding-bottom: 2.4px;"
9
+ },
10
+ '.{Button}': {
11
+ 'font-size': "9pt",
12
+ 'font-family': "Lucida Grande, Arial, sans-serif",
13
+ 'vertical-align': "top",
14
+ '&.disabled': "color:gray;",
15
+ '&:not(:active)': "margin-bottom:4px;",
16
+ '&:active': "margin-bottom:0;margin-top:2px;border:2px solid rgb(57,121,217); padding-left:8px; padding-right:6px;"// background:-webkit-linear-gradient(top, rgb(255, 255, 255) 10%, rgb(227, 227, 227) 100%);"
17
+ }
18
+ };
19
+
3
20
  [["./App.console.toast.glassy<>"], {
4
- vars: { canunload: true }
21
+ vars: { canunload: false }
5
22
  }, [
6
23
 
7
- [("vcl/Action"), "reload-app", {
8
- hotkey: "Shift+MetaCtrl+R|Cmd+Alt+R",
9
- on() {
10
- document.location.reload();
11
- }
12
- }],
24
+ // [("vcl/Action"), "reload-app", {
25
+ // hotkey: "Shift+MetaCtrl+R|Cmd+Alt+R",
26
+ // on() {
27
+ // document.location.reload();
28
+ // }
29
+ // }],
13
30
 
14
- [("#window"), {
15
- css: {
16
- '#close-x': {
17
- '': "transition: opacity 1s; opacity: 0.1; position:absolute;top:0;right:0;color:silver;padding:4px 8px;font-size:14pt;z-index:999999999999;",
18
- '&:hover': "color:black;cursor:pointer;opacity: 1;"
19
- },
20
- 'font-family': "Lucida Grande, Arial, sans-serif",
21
- 'font-size': "9pt",
22
- '.{./Button}': {
23
- 'font-size': "9pt",
24
- 'font-family': "Lucida Grande, Arial, sans-serif",
25
- 'vertical-align': "top",
26
- '&.disabled': "color:gray;",
27
- '&:not(:active)': "margin-bottom:4px;",
28
- '&:active': "margin-bottom:0;margin-top:2px;border:2px solid rgb(57,121,217); padding-left:8px; padding-right:6px; background:-webkit-linear-gradient(top, rgb(255, 255, 255) 10%, rgb(227, 227, 227) 100%);"
29
- },
30
- ".with-shadow": "box-shadow:rgba(0, 0, 0, 0.4) 0px 1px 2px 0px;",
31
- ".with-text-shadow": "text-shadow: rgb(255 255 255) 0px 0px 12px, #00000094 0px 0px 5px;",
32
- ".transparent": "background-color:transparent;",
33
- ".glassy-overlay": {
34
- "": "pointer-events: none; color:rgba(5,5,5,0.95);",
35
- ".glassy": "background-color: rgba(155, 155, 155, 0.35); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);",
36
- ".loading": "background: rgba(155, 155, 155, 0.35) url(/shared/vcl/images/loading.gif) 50% 50% no-repeat;",
37
- ".rounded": "padding: 4px; border-radius: 5px;",
38
- ".animate-width-height": "transition: width 250ms ease-in, height 250ms ease-in;",
39
- ">.glassy:not(.no-margin)": "margin: 32px;",
40
- ">.glassy": {
41
- "": "pointer-events: auto;",
42
- // "&:hover": "backdrop-filter: blur(25px); -webkit-backdrop-filter: blur(25px);"
43
- },
44
- ">.{Element}": "pointer-events: auto;",
45
- ".{Node}": {
46
- "&.invisible-layer": "opacity: 0.4;",
47
- "&.seperator": "border-top:1px solid rgba(155,155,155,0.55);margin-top:2px;padding-top:2px;",
48
- ">.text>img": "width:20px;height:20px;"
49
- }
50
- },
51
- '.container-glassy': {
52
- /* TODO CSS definitions must (eventually) be moved to App.glassy */
53
- '': {
54
- // 'height': HEIGHT + "px",
55
- // 'width': WIDTH + "px",
56
- 'top': "5%",
57
- // 'height': "100%",
58
-
59
- 'min-width': "54px",
60
- 'min-height': "54px",
61
-
62
- 'border-radius': "5px",
63
- 'z-index': "1999",
64
- // 'backdrop-filter': "blur(10px)",
65
- 'transition': "box-shadow 0.45s ease 0s, transform 0.45s ease 0s, left 0.45s ease 0s, right 0.45s ease 0s, top 0.45s ease 0s, bottom 0.45s ease 0s, width 0.45s ease 0s, height 0.45s ease 0s, border-width 0.45s ease 0s",
66
- },
67
- '&:hover': {
68
- 'box-shadow': "0 0 10px 5px rgba(0,0,0,.2)",
69
- 'cursor': "move",
70
- '.client': "border-color: rgba(56,127,217,0.025); background-color:rgba(155, 155, 155, 0.2);"
71
- },
72
- // '&.square': {
73
- // 'min-width': 175 + "px",
74
- // 'min-height': 175 + "px"
75
- // },
76
- '&.dragging': {
77
- 'transition': "box-shadow 0.15s ease 0s" || "transform 75ms ease-out 0s, left 75ms ease-out 0s, right 75ms ease-out 0s, top 75ms ease-out 0s, bottom 75ms ease-out 0s, width 75ms ease-out 0s, height 75ms ease-out 0s, border-width 0.45s ease 0s",
78
-
79
- 'box-shadow': "0 0 20px 10px rgba(0,0,0,.2)",
80
- '.client': {
81
- 'border-color': "rgba(56,127,217,0.4)" || "rgba(255,215,0,0.75)"
82
- }
83
-
84
- },
85
- '&.glassy-overlay > .client.no-margin': "margin:0;",
86
- '&.right': "right: 40px; transform-origin: top right;",
87
- '&.left': "left: 40px; transform-origin: top left;",
88
-
89
- // "&.right": {
90
- // '': "right: 5%; transform-origin: top right;",
91
- // "&:not(:hover)": "margin-left:1px; transform: translate3d(75%, 0, 0);"
92
- // },
93
- // "&.left": {
94
- // '': "left: 5%; transform-origin: top left;",
95
- // },
96
-
97
- '&.shrink-to-corner:not(:hover)': {
98
- 'width': 175 + "px",
99
- 'height': 175 + "px"
100
- },
101
- '&:not(.no-transparent-effects)': {
102
- '*': "text-shadow: none;",
103
- '.{List}': "border-radius:5px;",
104
- '.{ListHeader}': {
105
- '': "background-color:transparent;transition:background-color 1s ease 0s;",
106
- '&.scrolled': "background-color:rgba(255,255,255,0.75);",
107
- '>div': "background-image:none;border:none;font-weight:bold;"
108
- },
109
- '.{Input}': {
110
- 'input': 'background-color: rgba(255,255,255,0.2);',
111
- // 'input:focus': 'background-color: rgba(255,255,255,0.9);'
112
- },
113
-
114
- // '.{ListHeader}': {
115
- // '': "background-color:transparent;transition:background-color 0.5s ease 0s;",
116
- // ':active': "background-color: gold;", //rgb(56, 121, 217);" }
117
- // '&.scrolled': "background-color:rgba(255,255,255,0.75);"
118
- // }
119
-
120
- },
121
-
122
- 'input': {
123
- // 'flex': "1 1 0%",
124
- // 'transition': "width 0.5s ease 0s",
125
- // 'width': "150px"
126
- 'padding': "5px",//"5px 24px",
127
- 'border-radius': "5px",
128
- 'border': "none",
129
- 'background': "rgba(255, 255, 255, 0.2)"
130
- },
131
-
132
- '.client': {
133
- 'position': "relative",
134
- 'border-radius': "5px",
135
- 'border': "7px solid rgba(0,0,0,0)",
136
- // 'overflow': "hidden",
137
- 'height': "100%",
138
- 'transition': "border-color 0.45s ease 0s, background-color 0.45s ease 0s",
139
- '&:hover': {
140
- }
141
- },
142
- '.seperator.seperator.seperator': "border-top: 1px solid rgba(155, 155, 155, 0.55);",
143
-
144
- '&.phone': {
145
- '': "width: 389px; border-radius:20px; box-shadow: 0 0 20px 10px rgba(0,0,0,.2);",
146
- ">.client": {
147
- '': "border-radius: 20px;",
148
- 'iframe': "border-radius: 20px;"
149
- }
150
- }
151
- }
152
- }
153
- }]
31
+ [("#window"), { css: css }]
154
32
  ]];
@@ -76,9 +76,9 @@ var Handlers = {
76
76
  return alert("app-js not set");
77
77
  }
78
78
 
79
- if(confirm("Make?")) {
80
- Handlers.make_app.apply(this, [evt]);
81
- }
79
+ // if(confirm("Make?")) {
80
+ // Handlers.make_app.apply(this, [evt]);
81
+ // }
82
82
 
83
83
  var text = this.ud("#extra-components").getValue();
84
84
  RM.get(uri).then(res => {
@@ -4,11 +4,18 @@
4
4
  ["vcl/ui/Panel", ("left"), { align: "left", width: 325 }, [
5
5
  ["vcl/ui/Panel", ("left_content"), { align: "top", autoSize: "height" }, [
6
6
  ["vcl/ui/Element", ("description"), {
7
- content: [
8
- // "A view form consists of a panel aligned to the left ",
9
- // "and one aligned client. The client panel usually shows a menubar ",
10
- // "aligned to the top."
11
- ].join("")
7
+ // onRender() {
8
+ // this.nextTick(() => {
9
+ // const left_content = this.ud("#left_content").getNode();
10
+ // // const has = left_content.hasAttribte
11
+ // if (left_content.scrollHeight > left_content.clientHeight) {
12
+ // left_content.setAttribute("data-overflow-y", "true");
13
+ // } else {
14
+ // left_content.removeAttribute("data-overflow-y");
15
+ // }
16
+ // });
17
+ // },
18
+ content: locale("App-description.default")
12
19
  }]
13
20
  ]]
14
21
  ]],
@@ -1,4 +1,4 @@
1
- "use devtools/Resources, devtools/Parser, vcl/Component, vcl/Control, vcl/Dragger, util/HotkeyManager, vcl/ui/Sizer, vcl/ui/FormContainer, devtools/cavalion-devtools, vcl/ui/Ace";
1
+ "use devtools/Resources, devtools/Parser, vcl/Component, vcl/Control, vcl/Dragger, util/HotkeyManager, vcl/ui/Sizer, vcl/ui/FormContainer, devtools/cavalion-devtools, vcl/ui/Ace, util/Clipboard, blocks/Blocks";
2
2
 
3
3
  const Component = require("vcl/Component");
4
4
  const Control = require("vcl/Control");
@@ -8,12 +8,18 @@ const Sizer = require("vcl/ui/Sizer");
8
8
  const Dragger = require("vcl/Dragger");
9
9
  const Resources = require("devtools/Resources");
10
10
  const Parser = require("devtools/Parser");
11
+ const Clipboard = require("util/Clipboard");
12
+ const B = require("blocks/Blocks");
11
13
 
12
14
  const HOTKEY_ALWAYS_ENABLED = {
13
15
  isHotkeyEnabled() {
14
- return this._owner.isEnabled();
16
+ if(this._owner.isEnabled()) {
17
+ return (Control.focused || this).up("devtools/Workspace<>") === null;
18
+ }
19
+ return false;
15
20
  }
16
21
  };
22
+
17
23
  const getAce = () => {
18
24
  return Control.focused instanceof Ace ?
19
25
  Control.focused :
@@ -22,26 +28,22 @@ const getAce = () => {
22
28
  .filter(ace => ace.isVisible())
23
29
  .pop();
24
30
  };
25
-
26
31
  const deselect = () => {
27
32
  window.getSelection && window.getSelection().removeAllRanges();
28
33
  document.selection && document.selection.empty();
29
34
  };
30
35
 
31
- window.H = (uri, vars) => B.i(["Hover<>", { vars: js.mi({ uri: uri }, vars)}]);
32
-
33
- let cc = function() { // HM-20241010-1-method-auto-require-in-first-call
34
- // const args = js.copy_args(arguments);
35
- return Promise.resolve(req("clipboard-copy")).then(cc_ => {
36
- cc = cc_;
37
-
38
- return cc.apply(window, arguments);
39
- });
40
- };
36
+ const H = (uri, vars) => B.i(["Hover<>", { vars: js.mi({ uri: uri }, vars)}]);
41
37
 
38
+ const cc = (text) => Clipboard.copy(text);
42
39
  const cl = console.log;
43
40
  const facts = (comp) => Component.getFactories(comp);
44
41
 
42
+ window.B = B; window.H = H;
43
+ window.facts = facts;
44
+ window.cc = cc;
45
+ window.cl = cl;
46
+
45
47
  [["ui/Form"], {
46
48
  activeControl: "console",
47
49
  align: "bottom",
@@ -343,7 +345,6 @@ const facts = (comp) => Component.getFactories(comp);
343
345
  }
344
346
  }],
345
347
 
346
-
347
348
  [["ui/controls/Toolbar"], "toolbar", {
348
349
  css: { cursor: "ns-resize" },
349
350
  draggable: true,
@@ -379,7 +380,6 @@ const facts = (comp) => Component.getFactories(comp);
379
380
  },
380
381
  onEvaluate(expr) {
381
382
  const cl = console.log;
382
- const cc = req("clipboard-copy");
383
383
  const pr = () => this.print.apply(this, arguments);
384
384
 
385
385
  const open = (uri, opts) => this.bubble(
package/src/ui/Ace.js CHANGED
@@ -53,7 +53,9 @@ function(require, Ace, ace, Panel, Type, Text) {
53
53
  const markDeletionInGutter = (editor, lineNumber) => {
54
54
  editor.session.addGutterDecoration(lineNumber, "line-deleted");
55
55
  };
56
-
56
+
57
+ ace.config.set("basePath", window.require.toUrl("ace").split("?")[0]);
58
+
57
59
  return (Ace = Ace(require, {
58
60
  inherits: Panel,
59
61
  prototype: {
@@ -71,7 +73,7 @@ function(require, Ace, ace, Panel, Type, Text) {
71
73
  _content: "<div></div>",
72
74
 
73
75
  _cursorPos: null,
74
-
76
+
75
77
  onnodecreated: function() {
76
78
  /**
77
79
  * @overrides ../Control.prototype.onnodecreated
@@ -82,8 +84,31 @@ function(require, Ace, ace, Panel, Type, Text) {
82
84
  this._editor.$blockScrolling = Infinity;
83
85
  this._editor.setOption("useSoftTabs", false);
84
86
  this._editor.on("change", (e) => this.dispatch("change", e));
85
-
87
+
86
88
  initCommands(this._editor);
89
+
90
+ if(this.hasOwnProperty("_value")) {
91
+ this._editor.setValue(this._value);
92
+ delete this._value;
93
+ }
94
+
95
+ if(this.hasOwnProperty("_mode")) {
96
+ this.setMode(this._mode);
97
+ }
98
+
99
+ // this.setTimeout(() => {
100
+
101
+ // const app = this.app();
102
+ // if(app && app.qsa("#ace").length > 5) {
103
+ // if(this.isVisible() === false) {
104
+ // this.print(this, "autoremove - isVisible: " + this.isVisible());
105
+ // this._value = this.getValue();
106
+ // this.destroyNode();
107
+ // delete this._editor;
108
+ // }
109
+ // }
110
+
111
+ // }, 200);
87
112
 
88
113
  return this.inherited(arguments);
89
114
  },
@@ -113,27 +138,42 @@ function(require, Ace, ace, Panel, Type, Text) {
113
138
  *
114
139
  * @returns
115
140
  */
141
+
142
+ // this.print(this, "getEditor: " + this._editor);
143
+
116
144
  this.nodeNeeded();
117
145
  return this._editor;
118
146
  },
119
147
  getValue: function() {
148
+ if(this.hasOwnProperty("_value")) return this._value;
149
+
120
150
  this.nodeNeeded();
121
151
  return this._editor.session.getValue();
122
152
  },
123
153
  setValue: function(value) {
124
- this.nodeNeeded();
125
154
  if(value instanceof Array && value.every(s => typeof s === "string")) {
126
155
  value = value.join("\n");
127
156
  }
128
- return this._editor.setValue(typeof value === "string" ? value : JSON.stringify(value));
157
+
158
+ value = typeof value === "string" ? value : JSON.stringify(value);
159
+
160
+ if(!this._node) {
161
+ return (this._value = value);
162
+ }
163
+
164
+ // this.nodeNeeded();
165
+ return this._editor.setValue(value);
129
166
  },
130
167
  getLines: function(seperator) {
131
168
  return this.getValue().split(seperator || "\n");
132
169
  },
133
170
  setMode: function (mode) {
134
- this.getEditor().session.setMode("ace/mode/" + mode);
171
+ if(!this._editor) {
172
+ return this._mode = mode;
173
+ }
174
+ this._editor.session.setMode("ace/mode/" + mode);
135
175
  },
136
-
176
+
137
177
  append: function(content) {
138
178
  const editor = this.getEditor();
139
179
  const session = editor.getSession(); // Get the current session
@@ -141,6 +181,12 @@ function(require, Ace, ace, Panel, Type, Text) {
141
181
 
142
182
  session.insert({ row: lastRow, column: 0 }, '\n' + content); // Insert content at the bottom
143
183
  },
184
+ prepend: function(content) {
185
+ const editor = this.getEditor();
186
+ const session = editor.getSession(); // Get the current session
187
+
188
+ session.insert({ row: 0, column: 0 }, '\n' + content); // Insert content at the bottom
189
+ },
144
190
 
145
191
  getSelection: function() {
146
192
  const editor = this.getEditor();
package/src/ui/Console.js CHANGED
@@ -1,6 +1,7 @@
1
1
  define(function(require) {
2
2
 
3
3
  var Class = require("js/Class");
4
+ var Browser = require("util/Browser");
4
5
  var Deferred = require("js/Deferred");
5
6
  var js = require("js");
6
7
  var Printer = require("console/Printer");
@@ -17,6 +18,17 @@ define(function(require) {
17
18
  };
18
19
 
19
20
  var MAX_HISTORY_LENGTH = 1024 * 50;
21
+
22
+ const initialize_Q = (root, value) => {
23
+ const v = value || root._nodes.input.value;
24
+ root._Q = root._history.filter((s, i, a) => (!i || a[i - 1] !== s) && (!v || s.startsWith(v)));
25
+ root._Q = root._Q.concat(root._history.filter(s => s.includes(v))).reverse().filter(Array.fn.unique).reverse();
26
+
27
+ if(root._Q.length === 0) {
28
+ root._Q = [v];//
29
+ }
30
+ root._Q.index = root._Q.length;
31
+ };
20
32
 
21
33
  var Console = {
22
34
  inherits: Panel,
@@ -155,30 +167,41 @@ define(function(require) {
155
167
 
156
168
  this._nodes.console = this.getChildNode(0);
157
169
  this._nodes.input = this.getChildNode(1, 0);
158
-
170
+
159
171
  this._printer = new Printer(this._nodes.console);
160
172
  },
161
- /*
162
173
  onmousedown: function(evt) {
163
- if(evt.target === this._node) {
164
- this.addClass("highlight-click");
165
- }
174
+ // if(evt.target === this._node) {
175
+ // this.addClass("highlight-click");
176
+ // }
166
177
  },
167
- onmouseup: function() {
168
- if(this.hasClass("highlight-click")) {
169
- this.removeClass("highlight-click");
170
- }
178
+ onmouseup: function(evt) {
179
+ // if(this.hasClass("highlight-click")) {
180
+ // this.removeClass("highlight-click");
181
+ // }
171
182
  },
172
- */
183
+
173
184
  onclick: function(evt) {
174
185
  /** @overrides ../../Control.prototype.onclick */
175
- this.setTimeout("focus", function() {
176
- //if(evt.target === this._node) {
177
- this.storeScroll();
178
- this._nodes.input.focus();
179
- this.restoreScroll();
180
- //}
181
- }.bind(this), 200);
186
+
187
+ if(this._ignoreClick) return console.log("blocked-click");
188
+
189
+ this.setTimeout("focus", () => requestAnimationFrame(() => {
190
+ this.storeScroll();
191
+
192
+ if(Browser.chrome) {
193
+ this._ignoreClick = true;
194
+ this._nodes.input.focus();
195
+ this._node.click(); // Force Chrome to acknowledge a user event
196
+ delete this._ignoreClick;
197
+ }
198
+ this._nodes.input.focus();
199
+
200
+ Browser.chrome && this.restoreScroll();
201
+ Browser.safari && this.nextTick(() => this.restoreScroll());
202
+
203
+ // Browser.chrome && this.nextTick(() => this._nodes.input.focus());
204
+ }), 100);
182
205
 
183
206
  var node = evt.target;
184
207
  if(evt.metactrlKey && HE.hasClass(node, "key")) {
@@ -220,9 +243,9 @@ define(function(require) {
220
243
  onkeypress: function(evt) {
221
244
  /** @overrides ../../Control.prototype.onkeydown */
222
245
  var r = this.inherited(arguments);
223
- if(r !== false) {
246
+ if(r !== false) { this.nextTick(() => { // let key be handled
247
+ const text = this._nodes.input.value;
224
248
  if(evt.keyCode === 13) {
225
- var text = this._nodes.input.value;
226
249
  if(text !== "") {
227
250
  var value;
228
251
 
@@ -236,14 +259,23 @@ define(function(require) {
236
259
  }
237
260
  this.print(text, value);
238
261
  }
262
+ } else if(text.startsWith("// ") && text.endsWith(" //")) {
263
+ if(!this._Q || this._Q.text !== text) {
264
+ initialize_Q(this, text.substring(0, text.length - 4));
265
+
266
+ this._Q.index--;
267
+ this._nodes.input.value = this._Q[this._Q.index];
268
+ this._Q.text = text;
269
+ }
270
+
239
271
  }
240
- }
272
+ });}
241
273
  //this.print("press", evt.keyCode);
242
274
  return r;
243
275
  },
244
276
  onkeydown: function(evt) {
245
277
  /** @overrides ../../Control.prototype.onkeyup */
246
- var r = this.inherited(arguments), clearQ = !!this._Q;
278
+ var r = this.inherited(arguments), clearQ = !!this._Q, nodes;
247
279
 
248
280
  if(evt.ctrlKey === true) {
249
281
  if(evt.altKey === true && evt.keyCode === 13) {
@@ -257,12 +289,12 @@ define(function(require) {
257
289
  if(evt.shiftKey === true) {
258
290
  console.log(sel);
259
291
  }
260
- this.print(sel);
261
- } else if(evt.keyCode === 76) {
292
+ this.print(js.sf("c$%d", Math.random() * 10), sel);
293
+ } else if(evt.keyCode === 76) { // control+L
262
294
  if(evt.shiftKey === true) {
263
295
 
264
296
  } else {
265
- var nodes = this._nodes.console.qsa(".selected.node").map(_ => {
297
+ nodes = this._nodes.console.qsa(".selected.node").map(_ => {
266
298
  _.parentNode.removeChild(_);
267
299
  return _;
268
300
  });
@@ -270,21 +302,40 @@ define(function(require) {
270
302
  evt.preventDefault();
271
303
  nodes.map(_ => this._nodes.console.appendChild(_));
272
304
  }
273
- } else if(evt.keyCode === 75) {
305
+ } else if(evt.keyCode === 75) { // control+K
274
306
  this._nodes.console.qsa(".selected.node").map(_ => HE.removeClass(_, "selected"));
307
+ } else if(evt.keyCode === 73) { // control+I {
308
+ nodes = this._nodes.console.qsa(".selected.node");
309
+ if(nodes.length >= 1) {
310
+ if(nodes[0].previousSibling) {
311
+ nodes[0].previousSibling.classList.add("selected");
312
+ nodes[0].previousSibling.scrollIntoView({ behavior: "auto", block: "center", inline: "nearest" });
313
+ if(evt.shiftKey !== true) {
314
+ nodes[0].classList.remove("selected");
315
+ }
316
+ }
317
+ } else {
318
+ nodes = this._nodes.console.qsa(":scope > .node").reverse()
319
+ nodes[0].classList.add("selected");
320
+ nodes[0].scrollIntoView({ behavior: "auto", block: "center", inline: "nearest" });
321
+ }
322
+ } else if(evt.keyCode === 74) { // control+J {
323
+ nodes = this._nodes.console.qsa(".selected.node").reverse();
324
+ if(nodes.length >= 1) {
325
+ if(nodes[0].nextSibling) {
326
+ nodes[0].nextSibling.classList.add("selected");
327
+ nodes[0].scrollIntoView({ behavior: "auto", block: "center", inline: "nearest" });
328
+ if(evt.shiftKey !== true) {
329
+ nodes[0].classList.remove("selected");
330
+ }
331
+ }
332
+ }
275
333
  }
276
334
  } else if(evt.keyCode === 38 || evt.keyCode === 40) {
277
335
  clearQ = false;
278
- if(!this._Q) {
279
- const v = this._nodes.input.value;
280
-
281
- this._Q = this._history.filter((s, i, a) => (!i || a[i - 1] !== s) && (!v || s.startsWith(v)));
282
- this._Q = this._Q.concat(this._history.filter(s => s.includes(v))).reverse().filter(Array.fn.unique).reverse();
283
336
 
284
- if(this._Q.length === 0) {
285
- this._Q = [v];
286
- }
287
- this._Q.index = this._Q.length;
337
+ if(!this._Q) {
338
+ initialize_Q(this);
288
339
  }
289
340
 
290
341
  if(evt.keyCode === 38) {
@@ -435,13 +486,13 @@ define(function(require) {
435
486
  },
436
487
  getValues: function(selected) {
437
488
  return this.getNode("console")
438
- .qsa(".node" + selected ? ".selected" : "")
489
+ .qsa((selected ? "" : ":scope > ") + " .node" + (selected ? ".selected" : ""))
439
490
  .map(n => n._line)
440
491
  .filter(Boolean).map(l => l._value);
441
492
  },
442
493
  getKeys: function(selected) {
443
494
  return this.getNode("console")
444
- .qsa(".node" + selected ? ".selected" : "")
495
+ .qsa((selected ? "" : ":scope > ") + " .node" + (selected ? ".selected" : ""))
445
496
  .map(n => n._line)
446
497
  .filter(Boolean).map(l => l._key);
447
498
  }
package/src/ui/List.js CHANGED
@@ -37,9 +37,9 @@ define(function(require) {
37
37
  constructor: function() {
38
38
  this._columns = [];
39
39
 
40
- this._header = new ListHeader();
41
- this._footer = new ListFooter();
42
- this._body = new ListBody();
40
+ this._header = new ListHeader(this);
41
+ this._footer = new ListFooter(this);
42
+ this._body = new ListBody(this);
43
43
 
44
44
  this._header.setParent(this);
45
45
  this._body.setParent(this);
@@ -715,10 +715,10 @@ workaroundColumnAlignment(this);
715
715
  if(column === null) {
716
716
  column = this.addColumn();
717
717
  column.setAttribute(attrs[i]);
718
- var s = attrs[i].split(":").pop().split(".");
718
+ var s = attrs[i]/*.split(":").pop()*/.split(".");
719
719
  if(s.length > 1) {
720
720
  if(shuffle) {
721
- s = [s.pop()].concat(s).join(".");
721
+ s = [s.pop()].concat(s.join(".")).join(" ");
722
722
  } else {
723
723
  s = s.join(".");
724
724
  }
@@ -914,15 +914,19 @@ workaroundColumnAlignment(this);
914
914
  var row1 = this._source._array.indexOf(i1);
915
915
  var row2 = this._source._array.indexOf(i2);
916
916
 
917
- if(sv) {
918
- i1 = this._source.getAttributeValue(column._attribute, row1, true);
919
- i2 = this._source.getAttributeValue(column._attribute, row2, true);
917
+ // if(sv) {
918
+ // i1 = this._source.getAttributeValue(column._attribute, row1, true);
919
+ // i2 = this._source.getAttributeValue(column._attribute, row2, true);
920
920
 
921
- return dir * sv(i1, i2);
922
- }
921
+ // return dir * sv(i1, i2);
922
+ // }
923
923
 
924
924
  i1 = this.valueByColumnAndRow(column, row1);
925
925
  i2 = this.valueByColumnAndRow(column, row2);
926
+
927
+ if(numeric === undefined) {
928
+ numeric = (!isNaN(parseFloat(i1)) || !isNaN(parseFloat(i2)));
929
+ }
926
930
 
927
931
  if(i1 === i2) return 0;
928
932
 
package/src/ui/Panel.js CHANGED
@@ -47,15 +47,9 @@ define(function (require) {
47
47
  inherits: Container,
48
48
  prototype: {
49
49
  "@css": {
50
- "position": "absolute",
51
- "overflow": "auto",
52
- "cursor": "default",
53
- "&:focus": {
54
- outline: "none"
55
- },
56
- "&.animated": {
57
- "transition": "transform 0.45s"
58
- }
50
+ '': "position: absolute; overflow: auto; cursor: default;",
51
+ '&:focus': "outline: none;",
52
+ '&.animated': "transition: transform 0.45s;"// transform-origin: 0 0;"
59
53
  },
60
54
 
61
55
  /** @overrides ../Control */
@@ -72,7 +66,8 @@ define(function (require) {
72
66
  _bottom: 0,
73
67
  _width: 0,
74
68
  _height: 0,
75
- _zoom: 1.0,
69
+ _zoom: 1.0,
70
+ _zoomOrigin: "0 0",
76
71
 
77
72
  _focusable: false,
78
73
 
@@ -368,10 +363,11 @@ define(function (require) {
368
363
  if(zoomed && parseFloat(this._zoom) !== 1) {
369
364
  style.transform = String.format("scale3d(%s, %s, 1)",
370
365
  this._zoom, this._zoom);
371
- style['transform-origin'] = "0 0";
366
+ style['transform-origin'] = this._zoomOrigin;
372
367
  } else {
373
368
  style.transform = "";
374
- style['transform-origin'] = "";
369
+ setTimeout(() => style['transform-origin'] = "", 450);
370
+ // something is not right here, 0 0 is already the default, right?
375
371
  }
376
372
  },
377
373
 
@@ -852,13 +848,23 @@ define(function (require) {
852
848
  }
853
849
  return this._zoom;
854
850
  },
855
- setZoom: function(f) {
856
- if(this._zoom !== f) {
851
+ setZoom: function(f, o) {
852
+ if(f instanceof Array) {
853
+ // support for zoom: [1.5, "50% 0"]
854
+ return this.setZoom(f[0], f[1]);
855
+ }
856
+
857
+ if(this._zoom !== f || this._zoomOrigin !== o) {
857
858
  if(!this.hasClass("animated")) {
858
859
  this.addClass("animated");
859
- return this.update(function() { this.setZoom(f); }.bind(this));
860
+ return this.update(function() { this.setZoom(f, o); }.bind(this));
860
861
  }
861
862
  this._zoom = f;
863
+ if(o === undefined) {
864
+ delete this._zoomOrigin;
865
+ } else {
866
+ this._zoomOrigin = o;
867
+ }
862
868
  this.nodeNeeded();
863
869
  this.renderZoom();
864
870
  this.setTimeout("align", 450);
package/src/ui/Tree.js CHANGED
@@ -117,7 +117,6 @@ define(function (require) {
117
117
  },
118
118
  "&.expandable:not(.expanding)": {
119
119
  ">.icon::before": {
120
- transform: "translate(0, -2px)",
121
120
  'line-height': "0",
122
121
  content: "'▸'" // http://www.alanwood.net/unicode/geometric_shapes.html
123
122
  }