composite-monaco-diff 1.0.2

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.
Files changed (49) hide show
  1. package/LICENSE +338 -0
  2. package/dist/cjs/CenterAndHeightResizer.cjs +325 -0
  3. package/dist/cjs/CenterResizer.cjs +195 -0
  4. package/dist/cjs/Module.cjs +12 -0
  5. package/dist/cjs/MonacoDiffManager.cjs +306 -0
  6. package/dist/cjs/composite-monaco-diff.cjs +123 -0
  7. package/dist/cjs/manager/index.cjs +177 -0
  8. package/dist/cjs/react.cjs +64 -0
  9. package/dist/cjs/trimLeft.cjs +28 -0
  10. package/dist/cjs/urlchange/ChildSection.cjs +174 -0
  11. package/dist/cjs/urlchange/index.cjs +229 -0
  12. package/dist/cjs/urlchange/toolsURLSearchParams.cjs +111 -0
  13. package/dist/cjs/urlchange/urlchange.cjs +197 -0
  14. package/dist/cjs/web-component/from-js/index.cjs +160 -0
  15. package/dist/cjs/web-component/from-scripts/index.cjs +114 -0
  16. package/dist/esm/CenterAndHeightResizer.js +325 -0
  17. package/dist/esm/CenterResizer.js +195 -0
  18. package/dist/esm/Module.js +12 -0
  19. package/dist/esm/MonacoDiffManager.js +306 -0
  20. package/dist/esm/composite-monaco-diff.js +123 -0
  21. package/dist/esm/manager/index.js +177 -0
  22. package/dist/esm/react.js +64 -0
  23. package/dist/esm/trimLeft.js +28 -0
  24. package/dist/esm/urlchange/ChildSection.js +174 -0
  25. package/dist/esm/urlchange/index.js +229 -0
  26. package/dist/esm/urlchange/toolsURLSearchParams.js +111 -0
  27. package/dist/esm/urlchange/urlchange.js +197 -0
  28. package/dist/esm/web-component/from-js/index.js +160 -0
  29. package/dist/esm/web-component/from-scripts/index.js +114 -0
  30. package/dist/types/CenterAndHeightResizer.d.ts +27 -0
  31. package/dist/types/CenterResizer.d.ts +16 -0
  32. package/dist/types/Module.d.ts +11 -0
  33. package/dist/types/MonacoDiffManager.d.ts +62 -0
  34. package/dist/types/composite-monaco-diff.d.ts +48 -0
  35. package/dist/types/manager/index.d.ts +1 -0
  36. package/dist/types/react.d.ts +19 -0
  37. package/dist/types/trimLeft.d.ts +1 -0
  38. package/dist/types/urlchange/ChildSection.d.ts +41 -0
  39. package/dist/types/urlchange/index.d.ts +1 -0
  40. package/dist/types/urlchange/toolsURLSearchParams.d.ts +40 -0
  41. package/dist/types/urlchange/urlchange.d.ts +107 -0
  42. package/dist/types/web-component/from-js/index.d.ts +1 -0
  43. package/dist/types/web-component/from-scripts/index.d.ts +1 -0
  44. package/package.json +44 -0
  45. package/web-component/Module.js +413 -0
  46. package/web-component/MonacoDiffManager.js +306 -0
  47. package/web-component/composite-monaco-diff.js +123 -0
  48. package/web-component/react.js +64 -0
  49. package/web-component/trimLeft.js +28 -0
@@ -0,0 +1,325 @@
1
+ /**
2
+ * Resizable center panel with optional left gutter and bottom height handle.
3
+ *
4
+ * Import this module to register the element (`customElements.define` at file bottom).
5
+ * Before calling instance APIs from other modules, wait for registration:
6
+ *
7
+ * await customElements.whenDefined(CenterAndHeightResizer.tagName);
8
+ *
9
+ * Before mounting layout-sensitive UI (e.g. Monaco) in slotted content, prefer:
10
+ *
11
+ * await CenterAndHeightResizer.whenHostReady(container);
12
+ *
13
+ * @example HTML
14
+ * ```html
15
+ * <center-and-height-resizer left="50px" center="350px" height="200px" style="padding: 12px" data-test="idfortest">
16
+ * <div>Content</div>
17
+ * </center-and-height-resizer>
18
+ * ```
19
+ *
20
+ * @example JS
21
+ * ```js
22
+ * import { CenterAndHeightResizer } from "./CenterAndHeightResizer.js";
23
+ *
24
+ * await customElements.whenDefined(CenterAndHeightResizer.tagName);
25
+ *
26
+ * const resizer = document.querySelector(CenterAndHeightResizer.tagName);
27
+ * resizer.addEventListener("onLeft", (e) => console.log(e.detail.width));
28
+ * resizer.addEventListener("onCenter", (e) => console.log(e.detail.width));
29
+ * resizer.addEventListener("onHeight", (e) => console.log(e.detail.height));
30
+ * ```
31
+ */
32
+ const SKIP_ATTRIBUTES = ["id", "class", "left", "center", "height", "style"];
33
+ export class CenterAndHeightResizer extends HTMLElement {
34
+ static tagName = "center-and-height-resizer";
35
+ leftDiv;
36
+ rightDiv;
37
+ centerDiv;
38
+ resizerLeft;
39
+ resizerRight;
40
+ resizerBottom;
41
+ _isReady = false;
42
+ _readyPromise;
43
+ _resolveReady;
44
+ constructor() {
45
+ super();
46
+ this._readyPromise = new Promise((resolve) => {
47
+ this._resolveReady = resolve;
48
+ });
49
+ this.attachShadow({ mode: "open" });
50
+ this.shadowRoot.innerHTML = `
51
+ <style>
52
+ :host {
53
+ display: block;
54
+ width: 100%;
55
+ padding: 0 !important;
56
+ }
57
+ .flex {
58
+ display: flex;
59
+ width: 100%;
60
+ align-items: stretch;
61
+ }
62
+ .center-column {
63
+ display: flex;
64
+ flex-direction: column;
65
+ min-width: 0;
66
+ }
67
+ .center-div {
68
+ flex-grow: 1;
69
+ min-width: 0;
70
+ box-sizing: border-box;
71
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12), 0 0 1px rgba(0, 0, 0, 0.1);
72
+ background: #fff;
73
+ border-radius: 6px;
74
+ overflow: auto;
75
+ min-height: 50px;
76
+ border: 1px solid #eaeaea;
77
+ }
78
+ .side-div {
79
+ flex-shrink: 0;
80
+ box-sizing: border-box;
81
+ }
82
+ #right-div {
83
+ flex-grow: 1;
84
+ }
85
+ .resizer {
86
+ flex-shrink: 0;
87
+ transition: background 0.2s;
88
+ user-select: none;
89
+ position: relative;
90
+ }
91
+ .resizer.horizontal {
92
+ width: 8px;
93
+ cursor: col-resize;
94
+ }
95
+ .resizer.vertical {
96
+ height: 8px;
97
+ cursor: row-resize;
98
+ width: 100%;
99
+ }
100
+ .resizer:hover,
101
+ .resizer.active {
102
+ background: rgba(26, 115, 232, 0.12);
103
+ }
104
+ .resizer::after {
105
+ content: "";
106
+ position: absolute;
107
+ background: #ccc;
108
+ transition: background 0.2s;
109
+ }
110
+ .resizer.horizontal::after {
111
+ left: 50%;
112
+ top: 0;
113
+ bottom: 0;
114
+ width: 14px;
115
+ transform: translateX(-50%);
116
+ }
117
+ .resizer.vertical::after {
118
+ top: 50%;
119
+ left: 0;
120
+ right: 0;
121
+ height: 14px;
122
+ transform: translateY(-50%);
123
+ }
124
+ .resizer:hover::after,
125
+ .resizer.active::after {
126
+ background: #1a73e8;
127
+ }
128
+
129
+ #resizer-left {
130
+ margin-right: 5px;
131
+ }
132
+ #resizer-right {
133
+ margin-left: 5px;
134
+ }
135
+ #resizer-bottom {
136
+ margin-top: 5px;
137
+ }
138
+ </style>
139
+ <div class="flex">
140
+ <div class="side-div" id="left-div"></div>
141
+ <div class="resizer horizontal" id="resizer-left"></div>
142
+ <div class="center-column">
143
+ <div class="center-div" id="center-div">
144
+ <slot></slot>
145
+ </div>
146
+ <div class="resizer vertical" id="resizer-bottom"></div>
147
+ </div>
148
+ <div class="resizer horizontal" id="resizer-right"></div>
149
+ <div class="side-div" id="right-div"></div>
150
+ </div>
151
+ `;
152
+ }
153
+ static get observedAttributes() {
154
+ return SKIP_ATTRIBUTES.filter((attr) => !["id", "class"].includes(attr));
155
+ }
156
+ attributeChangedCallback(name, oldValue, newValue) {
157
+ if (oldValue === newValue)
158
+ return;
159
+ if (!this.leftDiv)
160
+ return; // Not connected yet
161
+ switch (name) {
162
+ case "left":
163
+ this.leftDiv.style.width = newValue;
164
+ break;
165
+ case "center":
166
+ this.centerDiv.style.width = newValue;
167
+ break;
168
+ case "height":
169
+ this.centerDiv.style.height = newValue;
170
+ break;
171
+ case "style":
172
+ this.centerDiv.style.cssText = newValue;
173
+ this._applyInternalStylesToCenterDiv();
174
+ break;
175
+ }
176
+ }
177
+ connectedCallback() {
178
+ this.leftDiv = this.shadowRoot.getElementById("left-div");
179
+ this.rightDiv = this.shadowRoot.getElementById("right-div");
180
+ this.centerDiv = this.shadowRoot.getElementById("center-div");
181
+ this.resizerLeft = this.shadowRoot.getElementById("resizer-left");
182
+ this.resizerRight = this.shadowRoot.getElementById("resizer-right");
183
+ this.resizerBottom = this.shadowRoot.getElementById("resizer-bottom");
184
+ const attrLeft = this.getAttribute("left");
185
+ const attrCenter = this.getAttribute("center");
186
+ const attrHeight = this.getAttribute("height");
187
+ if (attrLeft) {
188
+ this.leftDiv.style.width = attrLeft;
189
+ }
190
+ if (attrCenter) {
191
+ this.centerDiv.style.width = attrCenter;
192
+ }
193
+ if (attrHeight) {
194
+ this.centerDiv.style.height = attrHeight;
195
+ }
196
+ this.setupResizer(this.resizerLeft, this.leftDiv, "left", false);
197
+ this.setupResizer(this.resizerRight, this.centerDiv, "center", false);
198
+ this.setupHeightResizer(this.resizerBottom, this.centerDiv);
199
+ this._initForwarding();
200
+ this._isReady = true;
201
+ this._resolveReady();
202
+ }
203
+ /** Resolves after the first `connectedCallback` (attributes applied to the layout panel). */
204
+ whenReady() {
205
+ return this._isReady ? Promise.resolve() : this._readyPromise;
206
+ }
207
+ static whenLayoutReady(el, maxFrames = 120) {
208
+ return new Promise((resolve, reject) => {
209
+ let frames = 0;
210
+ const tick = () => {
211
+ const { width, height } = el.getBoundingClientRect();
212
+ if (width > 0 && height > 0) {
213
+ resolve();
214
+ return;
215
+ }
216
+ if (++frames >= maxFrames) {
217
+ reject(new Error("Layout root did not obtain non-zero dimensions"));
218
+ return;
219
+ }
220
+ requestAnimationFrame(tick);
221
+ };
222
+ tick();
223
+ });
224
+ }
225
+ /** Wait for custom element upgrade, `connectedCallback`, and a non-zero layout panel. */
226
+ static async whenHostReady(container) {
227
+ await customElements.whenDefined(CenterAndHeightResizer.tagName);
228
+ const resizer = container.closest(CenterAndHeightResizer.tagName);
229
+ if (resizer) {
230
+ await resizer.whenReady();
231
+ }
232
+ const layoutRoot = resizer?.getContentRoot() ?? container;
233
+ await CenterAndHeightResizer.whenLayoutReady(layoutRoot);
234
+ return layoutRoot;
235
+ }
236
+ _applyInternalStylesToCenterDiv() {
237
+ const center = this.getAttribute("center");
238
+ if (center)
239
+ this.centerDiv.style.width = center;
240
+ const height = this.getAttribute("height");
241
+ if (height)
242
+ this.centerDiv.style.height = height;
243
+ }
244
+ _initForwarding() {
245
+ const observer = new MutationObserver((mutations) => {
246
+ let syncNeeded = false;
247
+ for (const mutation of mutations) {
248
+ if (mutation.type === "attributes") {
249
+ if (!SKIP_ATTRIBUTES.includes(mutation.attributeName)) {
250
+ syncNeeded = true;
251
+ break;
252
+ }
253
+ }
254
+ }
255
+ if (syncNeeded)
256
+ this._syncAttributes();
257
+ });
258
+ observer.observe(this, { attributes: true });
259
+ this._syncAttributes();
260
+ }
261
+ _syncAttributes() {
262
+ for (const attr of Array.from(this.attributes)) {
263
+ if (SKIP_ATTRIBUTES.includes(attr.name))
264
+ continue;
265
+ this.centerDiv.setAttribute(attr.name, attr.value);
266
+ }
267
+ if (this.hasAttribute("style")) {
268
+ this.centerDiv.style.cssText = this.getAttribute("style") || "";
269
+ this._applyInternalStylesToCenterDiv();
270
+ }
271
+ }
272
+ getContentRoot() {
273
+ return this.centerDiv || this.shadowRoot.getElementById("center-div");
274
+ }
275
+ setupResizer(handle, target, attrName, invert) {
276
+ handle.addEventListener("mousedown", (e) => {
277
+ e.preventDefault();
278
+ handle.classList.add("active");
279
+ const startX = e.clientX;
280
+ const startWidth = target.offsetWidth;
281
+ const onMouseMove = (moveEvent) => {
282
+ let diff = moveEvent.clientX - startX;
283
+ if (invert)
284
+ diff = -diff;
285
+ let newWidth = startWidth + diff;
286
+ newWidth = Math.max(0, newWidth);
287
+ target.style.width = newWidth + "px";
288
+ this.setAttribute(attrName, newWidth + "px");
289
+ const eventName = attrName === "left" ? "onLeft" : "onCenter";
290
+ this.dispatchEvent(new CustomEvent(eventName, { detail: { width: newWidth } }));
291
+ };
292
+ const onMouseUp = () => {
293
+ handle.classList.remove("active");
294
+ document.removeEventListener("mousemove", onMouseMove);
295
+ document.removeEventListener("mouseup", onMouseUp);
296
+ };
297
+ document.addEventListener("mousemove", onMouseMove);
298
+ document.addEventListener("mouseup", onMouseUp);
299
+ });
300
+ }
301
+ setupHeightResizer(handle, target) {
302
+ handle.addEventListener("mousedown", (e) => {
303
+ e.preventDefault();
304
+ handle.classList.add("active");
305
+ const startY = e.clientY;
306
+ const startHeight = target.offsetHeight;
307
+ const onMouseMove = (moveEvent) => {
308
+ const diff = moveEvent.clientY - startY;
309
+ let newHeight = startHeight + diff;
310
+ newHeight = Math.max(0, newHeight);
311
+ target.style.height = newHeight + "px";
312
+ this.setAttribute("height", newHeight + "px");
313
+ this.dispatchEvent(new CustomEvent("onHeight", { detail: { height: newHeight } }));
314
+ };
315
+ const onMouseUp = () => {
316
+ handle.classList.remove("active");
317
+ document.removeEventListener("mousemove", onMouseMove);
318
+ document.removeEventListener("mouseup", onMouseUp);
319
+ };
320
+ document.addEventListener("mousemove", onMouseMove);
321
+ document.addEventListener("mouseup", onMouseUp);
322
+ });
323
+ }
324
+ }
325
+ customElements.define(CenterAndHeightResizer.tagName, CenterAndHeightResizer);
@@ -0,0 +1,195 @@
1
+ /**
2
+ * <center-resizer
3
+ * left="50px"
4
+ * center="350px"
5
+ * style="padding: 12px;"
6
+ * data-test="idfortest"
7
+ * >
8
+ * <div>Content</div>
9
+ * </center-resizer>
10
+ *
11
+ * const resizer = document.querySelector('center-resizer');
12
+ * resizer.addEventListener('onLeft', e => console.log(e.detail.width));
13
+ * resizer.addEventListener('onCenter', e => console.log(e.detail.width));
14
+ */
15
+ const SKIP_ATTRIBUTES = ["id", "class", "left", "center", "style"];
16
+ export class CenterResizer extends HTMLElement {
17
+ leftDiv;
18
+ centerDiv;
19
+ rightDiv;
20
+ resizerLeft;
21
+ resizerRight;
22
+ constructor() {
23
+ super();
24
+ this.attachShadow({ mode: "open" });
25
+ this.shadowRoot.innerHTML = `
26
+ <style>
27
+ :host {
28
+ display: block;
29
+ width: 100%;
30
+ padding: 0 !important;
31
+ }
32
+ .flex {
33
+ display: flex;
34
+ width: 100%;
35
+ align-items: stretch;
36
+ }
37
+ .center-div {
38
+ flex-shrink: 0;
39
+ min-width: 0;
40
+ padding-left: 15px;
41
+ padding-right: 15px;
42
+ box-sizing: border-box;
43
+ }
44
+ .side-div {
45
+ flex-shrink: 0;
46
+ box-sizing: border-box;
47
+ }
48
+ #right-div {
49
+ flex-grow: 1;
50
+ }
51
+ .resizer {
52
+ width: 8px;
53
+ cursor: col-resize;
54
+ flex-shrink: 0;
55
+ transition: background 0.2s;
56
+ user-select: none;
57
+ margin: 0 -4px;
58
+ position: relative;
59
+ }
60
+ .resizer:hover,
61
+ .resizer.active {
62
+ background: rgba(26, 115, 232, 0.2);
63
+ }
64
+ .resizer::after {
65
+ content: "";
66
+ position: absolute;
67
+ left: 50%;
68
+ top: 0;
69
+ bottom: 0;
70
+ width: 2px;
71
+ background: #ccc;
72
+ transform: translateX(-50%);
73
+ }
74
+ .resizer:hover::after,
75
+ .resizer.active::after {
76
+ background: #1a73e8;
77
+ }
78
+ </style>
79
+ <div class="flex">
80
+ <div class="side-div" id="left-div"></div>
81
+ <div class="resizer" id="resizer-left"></div>
82
+ <div class="center-div" id="center-div">
83
+ <slot></slot>
84
+ </div>
85
+ <div class="resizer" id="resizer-right"></div>
86
+ <div class="side-div" id="right-div"></div>
87
+ </div>
88
+ `;
89
+ }
90
+ static get observedAttributes() {
91
+ return SKIP_ATTRIBUTES.filter((attr) => !["id", "class"].includes(attr));
92
+ }
93
+ attributeChangedCallback(name, oldValue, newValue) {
94
+ if (oldValue === newValue)
95
+ return;
96
+ if (!this.centerDiv)
97
+ return;
98
+ switch (name) {
99
+ case "left":
100
+ this.leftDiv.style.width = newValue;
101
+ break;
102
+ case "center":
103
+ this.centerDiv.style.width = newValue;
104
+ break;
105
+ case "style":
106
+ this.centerDiv.style.cssText = newValue;
107
+ this._applyInternalStylesToCenterDiv();
108
+ break;
109
+ }
110
+ }
111
+ connectedCallback() {
112
+ this.leftDiv = this.shadowRoot.getElementById("left-div");
113
+ this.centerDiv = this.shadowRoot.getElementById("center-div");
114
+ this.rightDiv = this.shadowRoot.getElementById("right-div");
115
+ this.resizerLeft = this.shadowRoot.getElementById("resizer-left");
116
+ this.resizerRight = this.shadowRoot.getElementById("resizer-right");
117
+ const attrLeft = this.getAttribute("left");
118
+ const attrCenter = this.getAttribute("center");
119
+ if (attrLeft) {
120
+ this.leftDiv.style.width = attrLeft;
121
+ }
122
+ if (attrCenter) {
123
+ this.centerDiv.style.width = attrCenter;
124
+ }
125
+ this.setupResizer(this.resizerLeft, this.leftDiv, "left");
126
+ this.setupResizer(this.resizerRight, this.centerDiv, "center");
127
+ this._initForwarding();
128
+ }
129
+ _applyInternalStylesToCenterDiv() {
130
+ const center = this.getAttribute("center");
131
+ if (center)
132
+ this.centerDiv.style.width = center;
133
+ }
134
+ _initForwarding() {
135
+ const observer = new MutationObserver((mutations) => {
136
+ let syncNeeded = false;
137
+ for (const mutation of mutations) {
138
+ if (mutation.type === "attributes") {
139
+ if (!SKIP_ATTRIBUTES.includes(mutation.attributeName)) {
140
+ syncNeeded = true;
141
+ break;
142
+ }
143
+ }
144
+ }
145
+ if (syncNeeded)
146
+ this._syncAttributes();
147
+ });
148
+ observer.observe(this, { attributes: true });
149
+ this._syncAttributes();
150
+ }
151
+ _syncAttributes() {
152
+ for (const attr of Array.from(this.attributes)) {
153
+ if (SKIP_ATTRIBUTES.includes(attr.name))
154
+ continue;
155
+ this.centerDiv.setAttribute(attr.name, attr.value);
156
+ }
157
+ if (this.hasAttribute("style")) {
158
+ this.centerDiv.style.cssText = this.getAttribute("style") || "";
159
+ this._applyInternalStylesToCenterDiv();
160
+ }
161
+ }
162
+ getContentRoot() {
163
+ return this.centerDiv || this.shadowRoot.getElementById("center-div");
164
+ }
165
+ setupResizer(handle, target, attributeName) {
166
+ handle.addEventListener("mousedown", (e) => {
167
+ e.preventDefault();
168
+ handle.classList.add("active");
169
+ const startX = e.clientX;
170
+ const startWidth = target.offsetWidth;
171
+ const onMouseMove = (moveEvent) => {
172
+ let diff = moveEvent.clientX - startX;
173
+ let newWidth = startWidth + diff;
174
+ newWidth = Math.max(0, newWidth);
175
+ target.style.width = newWidth + "px";
176
+ if (attributeName === "center") {
177
+ this.setAttribute("center", newWidth + "px");
178
+ this.dispatchEvent(new CustomEvent("onCenter", { detail: { width: newWidth } }));
179
+ }
180
+ else {
181
+ this.setAttribute("left", newWidth + "px");
182
+ this.dispatchEvent(new CustomEvent("onLeft", { detail: { width: newWidth } }));
183
+ }
184
+ };
185
+ const onMouseUp = () => {
186
+ handle.classList.remove("active");
187
+ document.removeEventListener("mousemove", onMouseMove);
188
+ document.removeEventListener("mouseup", onMouseUp);
189
+ };
190
+ document.addEventListener("mousemove", onMouseMove);
191
+ document.addEventListener("mouseup", onMouseUp);
192
+ });
193
+ }
194
+ }
195
+ customElements.define("center-resizer", CenterResizer);
@@ -0,0 +1,12 @@
1
+ /** @es.ts
2
+ {
3
+ mode: "bundle",
4
+ extension: ".js",
5
+ options: {
6
+ }
7
+ }
8
+ @es.ts */
9
+ export * from "./composite-monaco-diff.js";
10
+ export * from "./MonacoDiffManager.js";
11
+ // export * from "./react.js"
12
+ export * from "./trimLeft.js";