@isopodlabs/vscode_utils 0.1.1 → 0.2.0

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.
@@ -0,0 +1,42 @@
1
+ export declare const vscode: {
2
+ postMessage: (message: any) => void;
3
+ getState: () => any;
4
+ setState: (state: any) => void;
5
+ };
6
+ export declare function createElement<K extends keyof HTMLElementTagNameMap>(tag: K, options: Record<string, unknown>): HTMLElement;
7
+ export declare function getFirstText(element: Element): string | undefined;
8
+ export declare class Pool<T extends Element> {
9
+ private make;
10
+ private pool;
11
+ constructor(make: () => T);
12
+ get(): T;
13
+ discard(item: T): void;
14
+ discardElement(item: T): void;
15
+ }
16
+ export declare class Splitter {
17
+ private readonly splitter;
18
+ constructor(splitter: HTMLElement, notify: (split: number) => void);
19
+ set(x: number): void;
20
+ }
21
+ interface Container {
22
+ clientOffset: number;
23
+ clientPixels: number;
24
+ clientSize: number;
25
+ scrollOffset: number;
26
+ scrollSize: number;
27
+ }
28
+ export declare class ScrollBar {
29
+ horizontal: boolean;
30
+ container: any;
31
+ thumb: HTMLElement;
32
+ thumbSize: number;
33
+ constructor(parent: HTMLElement, container: Container | HTMLElement, horizontal: boolean);
34
+ update(): void;
35
+ setScroll(scroll: number): void;
36
+ setThumbSize(size: number): void;
37
+ setThumb(scroll: number): void;
38
+ setThumbPixel(pos: number): void;
39
+ }
40
+ export declare function template(template: HTMLElement, parent: HTMLElement, values: Record<string, string>[]): void;
41
+ export declare function generateSelector(e: Node | null): string;
42
+ export {};
@@ -0,0 +1,288 @@
1
+ "use strict";
2
+ /// <reference lib="dom" />
3
+ /// <reference lib="dom.iterable" />
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.ScrollBar = exports.Splitter = exports.Pool = exports.vscode = void 0;
6
+ exports.createElement = createElement;
7
+ exports.getFirstText = getFirstText;
8
+ exports.template = template;
9
+ exports.generateSelector = generateSelector;
10
+ console.log("Hello from shared.ts!");
11
+ exports.vscode = acquireVsCodeApi();
12
+ //fix up icons in attributes
13
+ document.querySelectorAll('[icon]').forEach(element => {
14
+ const value = element.getAttribute('icon');
15
+ if (value && value.includes('/')) {
16
+ element.removeAttribute('icon');
17
+ element.classList.add('icon');
18
+ element.style.setProperty('--icon', `url(${value})`);
19
+ }
20
+ const col = element.getAttribute('color');
21
+ if (col) {
22
+ element.removeAttribute('color');
23
+ element.style.setProperty('--icon-color', col);
24
+ }
25
+ });
26
+ document.querySelectorAll('.select').forEach(item => {
27
+ item.addEventListener('click', event => {
28
+ if (event.target === item) {
29
+ exports.vscode.postMessage({
30
+ command: 'select',
31
+ selector: generateSelector(item),
32
+ text: item.textContent,
33
+ ...item.dataset
34
+ });
35
+ event.stopPropagation();
36
+ }
37
+ });
38
+ });
39
+ function createElement(tag, options) {
40
+ const e = document.createElement(tag);
41
+ if (options) {
42
+ for (const [k, v] of Object.entries(options))
43
+ e[k] = v;
44
+ }
45
+ return e;
46
+ }
47
+ function getFirstText(element) {
48
+ // eslint-disable-next-line @typescript-eslint/prefer-for-of
49
+ for (let i = 0; i < element.childNodes.length; i++) {
50
+ const node = element.childNodes[i];
51
+ if (isText(node)) {
52
+ const text = node.textContent?.trim();
53
+ if (text)
54
+ return text;
55
+ }
56
+ }
57
+ }
58
+ class Pool {
59
+ make;
60
+ pool = [];
61
+ constructor(make) {
62
+ this.make = make;
63
+ }
64
+ get() {
65
+ if (this.pool.length === 0)
66
+ this.pool.push(this.make());
67
+ return this.pool.length === 1
68
+ ? this.pool[0].cloneNode(true)
69
+ : this.pool.pop();
70
+ }
71
+ discard(item) {
72
+ this.pool.push(item);
73
+ }
74
+ discardElement(item) {
75
+ this.discard(item);
76
+ item.remove();
77
+ }
78
+ }
79
+ exports.Pool = Pool;
80
+ //-------------------------------------
81
+ // splitter
82
+ //-------------------------------------
83
+ class Splitter {
84
+ splitter;
85
+ constructor(splitter, notify) {
86
+ this.splitter = splitter;
87
+ splitter.addEventListener('pointerdown', (e) => {
88
+ e.preventDefault();
89
+ splitter.setPointerCapture(e.pointerId);
90
+ const left = splitter.previousSibling;
91
+ const style = getComputedStyle(left);
92
+ let split = left.clientWidth - parseFloat(style.paddingLeft) - parseFloat(style.paddingRight);
93
+ const offset = split - e.clientX;
94
+ const min = parseFloat(style.minWidth);
95
+ const max = Math.min(parseFloat(style.maxWidth), splitter.parentElement?.clientWidth ?? 0 - 300);
96
+ left.style.width = `${split}px`;
97
+ left.style.flex = 'none';
98
+ function resizePanels(e) {
99
+ split = Math.min(Math.max(e.clientX + offset, min), max);
100
+ left.style.width = `${split}px`;
101
+ }
102
+ function stopResizing(e) {
103
+ notify(split);
104
+ //state.split = split;
105
+ //vscode.setState(state);
106
+ splitter.releasePointerCapture(e.pointerId);
107
+ document.removeEventListener('pointermove', resizePanels);
108
+ document.removeEventListener('pointerup', stopResizing);
109
+ }
110
+ document.addEventListener('pointermove', resizePanels);
111
+ document.addEventListener('pointerup', stopResizing);
112
+ });
113
+ }
114
+ set(x) {
115
+ const left = this.splitter.previousSibling;
116
+ left.style.width = `${x}px`;
117
+ left.style.flex = 'none';
118
+ }
119
+ }
120
+ exports.Splitter = Splitter;
121
+ function VScrollContainer(container, offset = 0) {
122
+ return {
123
+ clientOffset: Math.max(container.clientTop, 0) + offset,
124
+ get clientPixels() { return container.clientHeight - offset; },
125
+ get clientSize() { return container.clientHeight - offset; },
126
+ get scrollOffset() { return container.scrollTop; },
127
+ get scrollSize() { return container.scrollHeight; },
128
+ set scrollOffset(x) { container.scrollTop = x; },
129
+ };
130
+ }
131
+ function HScrollContainer(container, offset = 0) {
132
+ return {
133
+ clientOffset: Math.max(container.clientLeft, 0) + offset,
134
+ get clientPixels() { return container.clientWidth - offset; },
135
+ get clientSize() { return container.clientWidth - offset; },
136
+ get scrollOffset() { return container.scrollLeft; },
137
+ get scrollSize() { return container.scrollWidth; },
138
+ set scrollOffset(x) { container.scrollLeft = x; },
139
+ };
140
+ }
141
+ class ScrollBar {
142
+ horizontal;
143
+ container;
144
+ thumb;
145
+ thumbSize = 0;
146
+ constructor(parent, container, horizontal) {
147
+ this.horizontal = horizontal;
148
+ const thumb = this.thumb = createElement('div', { className: horizontal ? 'hscrollbar' : 'vscrollbar' });
149
+ parent.appendChild(thumb);
150
+ this.container = container instanceof HTMLElement
151
+ ? horizontal ? HScrollContainer(container) : VScrollContainer(container)
152
+ : container;
153
+ this.update();
154
+ thumb.addEventListener("lostpointercapture", (e) => thumb.dispatchEvent(new MouseEvent('mouseup', e)));
155
+ thumb.addEventListener('pointerdown', event => {
156
+ console.log('down');
157
+ const pointerOffset = horizontal ? thumb.offsetLeft - event.clientX : thumb.offsetTop - event.clientY;
158
+ thumb.classList.add('active');
159
+ const onPointerMove = (event) => {
160
+ this.setThumbPixel(pointerOffset + (horizontal ? event.clientX : event.clientY));
161
+ };
162
+ const onPointerUp = () => {
163
+ console.log('up');
164
+ thumb.classList.remove('active');
165
+ window.removeEventListener('pointermove', onPointerMove);
166
+ window.removeEventListener('pointerup', onPointerUp);
167
+ };
168
+ if (thumb.setPointerCapture)
169
+ thumb.setPointerCapture(event.pointerId);
170
+ window.addEventListener('pointermove', onPointerMove);
171
+ window.addEventListener('pointerup', onPointerUp);
172
+ });
173
+ }
174
+ update() {
175
+ this.setThumb(this.container.scrollOffset);
176
+ }
177
+ setScroll(scroll) {
178
+ this.container.scrollOffset = scroll;
179
+ this.setThumb(scroll);
180
+ }
181
+ setThumbSize(size) {
182
+ if (size != this.thumbSize) {
183
+ this.thumbSize = size;
184
+ if (this.horizontal)
185
+ this.thumb.style.width = `${size}px`;
186
+ else
187
+ this.thumb.style.height = `${size}px`;
188
+ }
189
+ }
190
+ setThumb(scroll) {
191
+ const clientPixels = this.container.clientPixels;
192
+ const clientSize = this.container.clientSize;
193
+ const scrollSize = this.container.scrollSize;
194
+ const clientOffset = this.container.clientOffset;
195
+ let thumbPos, thumbSize;
196
+ if (clientSize >= scrollSize) {
197
+ this.thumb.classList.add('invisible');
198
+ thumbSize = scrollSize;
199
+ thumbPos = clientOffset;
200
+ }
201
+ else {
202
+ this.thumb.classList.remove('invisible');
203
+ thumbSize = Math.max(clientPixels * clientSize / scrollSize, 20);
204
+ thumbPos = clientOffset + scroll * (clientPixels - thumbSize) / (scrollSize - clientSize);
205
+ }
206
+ this.setThumbSize(thumbSize);
207
+ if (this.horizontal)
208
+ this.thumb.style.left = `${thumbPos}px`;
209
+ else
210
+ this.thumb.style.top = `${thumbPos}px`;
211
+ }
212
+ setThumbPixel(pos) {
213
+ const clientPixels = this.container.clientPixels;
214
+ const clientSize = this.container.clientSize;
215
+ const scrollSize = this.container.scrollSize;
216
+ const clientOffset = this.container.clientOffset;
217
+ const thumbPos = Math.min(Math.max(pos, clientOffset), clientOffset + clientPixels - this.thumbSize);
218
+ const scroll = (thumbPos - clientOffset) * (scrollSize - clientSize) / (clientPixels - this.thumbSize);
219
+ this.container.scrollOffset = scroll;
220
+ if (this.horizontal) {
221
+ this.thumb.style.left = `${thumbPos}px`;
222
+ }
223
+ else {
224
+ this.thumb.style.top = `${thumbPos}px`;
225
+ }
226
+ }
227
+ }
228
+ exports.ScrollBar = ScrollBar;
229
+ let resizeTimeout;
230
+ window.addEventListener('resize', () => {
231
+ document.documentElement.classList.add('resizing');
232
+ clearTimeout(resizeTimeout);
233
+ resizeTimeout = window.setTimeout(() => document.documentElement.classList.remove('resizing'), 500);
234
+ });
235
+ //-------------------------------------
236
+ // template
237
+ //-------------------------------------
238
+ function replace(text, re, process) {
239
+ let i = 0;
240
+ let result = '';
241
+ for (let m; (m = re.exec(text)); i = re.lastIndex)
242
+ result += text.substring(i, m.index) + process(m);
243
+ return result + text.substring(i);
244
+ }
245
+ function isElement(n) { return n.nodeType === window.Node.ELEMENT_NODE; }
246
+ function isText(n) { return n.nodeType === window.Node.TEXT_NODE; }
247
+ function replace_in_element(e, re, process) {
248
+ if (e.id)
249
+ e.id = replace(e.id, re, process);
250
+ const name = e.attributes.getNamedItem('name');
251
+ if (name)
252
+ name.value = replace(name.value, re, process);
253
+ const childNodes = e.childNodes;
254
+ for (const node of childNodes) {
255
+ if (isText(node) && node.textContent)
256
+ node.textContent = replace(node.textContent, re, process);
257
+ else if (isElement(node))
258
+ replace_in_element(node, re, process);
259
+ }
260
+ }
261
+ function template(template, parent, values) {
262
+ const newnodes = values.map(i => {
263
+ const child = template.cloneNode(true);
264
+ child.hidden = false;
265
+ replace_in_element(child, /\$\((.*)\)/g, m => i[m[1]]);
266
+ return child;
267
+ });
268
+ // const parent = after.parentNode;
269
+ // const before = after.nextSibling;
270
+ const before = null;
271
+ for (const i of newnodes)
272
+ parent.insertBefore(i, before);
273
+ }
274
+ function generateSelector(e) {
275
+ const path = [];
276
+ while (e && isElement(e)) {
277
+ let index = 1;
278
+ for (let s = e; (s = s.previousElementSibling);) {
279
+ if (s.tagName === e.tagName)
280
+ index++;
281
+ }
282
+ //const selector = e.tagName.toLowerCase() + (index > 1 ? `:nth-of-type(${index})` : '');
283
+ const selector = `${e.tagName.toLowerCase()}:nth-of-type(${index})`;
284
+ path.unshift(selector);
285
+ e = e.parentNode;
286
+ }
287
+ return path.join(' > ');
288
+ }
@@ -0,0 +1,12 @@
1
+ export declare class Tree {
2
+ root: HTMLElement;
3
+ constructor(root: HTMLElement, notify: (caret: Element, down: boolean) => void);
4
+ open(element: Element): void;
5
+ close(element: Element): void;
6
+ close_all(): void;
7
+ all_open(): string[];
8
+ reveal(element: Element): void;
9
+ lastStuck(): HTMLElement | undefined;
10
+ }
11
+ export declare function lastStuck(tree?: HTMLElement): HTMLElement | undefined;
12
+ export declare function updateStuck(): void;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ /// <reference lib="dom" />
3
+ /// <reference lib="dom.iterable" />
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.Tree = void 0;
6
+ exports.lastStuck = lastStuck;
7
+ exports.updateStuck = updateStuck;
8
+ const shared_1 = require("./shared");
9
+ class Tree {
10
+ root;
11
+ constructor(root, notify) {
12
+ this.root = root;
13
+ this.root = root;
14
+ root.querySelectorAll('.caret').forEach(caret => {
15
+ caret.addEventListener('click', event => {
16
+ if (event.target === caret) {
17
+ caret.classList.toggle('caret-down');
18
+ notify(caret, caret.classList.contains('caret-down'));
19
+ event.stopPropagation();
20
+ }
21
+ });
22
+ });
23
+ }
24
+ open(element) {
25
+ element?.classList.add('caret-down');
26
+ }
27
+ close(element) {
28
+ element?.classList.remove('caret-down');
29
+ }
30
+ close_all() {
31
+ this.root.querySelectorAll('.caret-down').forEach(e => e.classList.remove('caret-down'));
32
+ }
33
+ all_open() {
34
+ return Array.from(this.root.querySelectorAll('.caret-down'), element => (0, shared_1.generateSelector)(element));
35
+ }
36
+ reveal(element) {
37
+ if (element) {
38
+ for (let parent = element.parentNode; parent; parent = parent.parentNode) {
39
+ const p = parent;
40
+ if (p.classList?.contains('caret'))
41
+ p.classList.add('caret-down');
42
+ }
43
+ element.scrollIntoView({ behavior: 'smooth', block: 'center' });
44
+ }
45
+ }
46
+ lastStuck() {
47
+ return lastStuck(this.root);
48
+ }
49
+ }
50
+ exports.Tree = Tree;
51
+ function lastStuck(tree) {
52
+ let last_stuck;
53
+ if (tree) {
54
+ const x = tree.clientWidth - 20;
55
+ let y = 5;
56
+ for (;;) {
57
+ const e = document.elementFromPoint(x, y);
58
+ if (!e || getComputedStyle(e).getPropertyValue('position') != 'sticky')
59
+ break;
60
+ const bottom = e.getBoundingClientRect().bottom;
61
+ const next = e.nextElementSibling;
62
+ if (next?.getBoundingClientRect().top >= bottom)
63
+ break;
64
+ last_stuck = e;
65
+ y = bottom + 5;
66
+ }
67
+ }
68
+ return last_stuck;
69
+ }
70
+ let prev_stuck;
71
+ function updateStuck() {
72
+ const last_stuck = lastStuck(document.querySelector('.tree'));
73
+ if (last_stuck !== prev_stuck) {
74
+ if (prev_stuck)
75
+ prev_stuck.classList.remove('stuck');
76
+ if (last_stuck)
77
+ last_stuck.classList.add('stuck');
78
+ prev_stuck = last_stuck;
79
+ }
80
+ }
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@isopodlabs/vscode_utils",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "vscode utilities",
5
5
  "exports": {
6
6
  "./fs": "./dist/fs.js",
7
7
  "./debug": "./dist/debug.js",
8
8
  "./icon-theme": "./dist/icon-theme.js",
9
- "./jsx-runtime": "./dist/jsx-runtime.js"
9
+ "./jsx-runtime": "./dist/jsx-runtime.js",
10
+ "./webview": "./dist/webview/shared.js"
10
11
  },
11
12
  "files": [
12
13
  "dist",
@@ -14,7 +15,7 @@
14
15
  "README.md"
15
16
  ],
16
17
  "scripts": {
17
- "build": "tsc",
18
+ "compile": "tsc",
18
19
  "test": "echo \"No tests specified\" && exit 0"
19
20
  },
20
21
  "keywords": [