@jxsuite/studio 2.4.0 → 2.4.1
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/dist/chunks/{content-source-jrvn5vwy.js → content-source-cn9te96r.js} +8 -8
- package/dist/chunks/{convert-to-repeater-109dwcj7.js → convert-to-repeater-65gjgdst.js} +7 -7
- package/dist/chunks/{extension-sections-2zjyty05.js → extension-sections-mdgmqrry.js} +11 -11
- package/dist/chunks/{files-jdbtammm.js → files-dsh5g8j4.js} +12 -12
- package/dist/chunks/{format-host-kq6963gs.js → format-host-m9h45a79.js} +2 -2
- package/dist/chunks/{git-panel-2stf3ahg.js → git-panel-rfs8pqjj.js} +7 -7
- package/dist/chunks/{layers-panel-a8wjsdjj.js → layers-panel-6cj5nf6a.js} +10 -10
- package/dist/chunks/{publish-panel-2we6smjv.js → publish-panel-b0xh7b4y.js} +5 -5
- package/dist/chunks/{quick-search-hmpwdgys.js → quick-search-a83fhnsh.js} +13 -13
- package/dist/chunks/{right-panel-hn3y3j0j.js → right-panel-hrw5kdh5.js} +9 -9
- package/dist/chunks/{studio-102jzb8r.js → studio-0svvdm0a.js} +4 -4
- package/dist/chunks/{studio-8x4399kc.js → studio-1d6bm7eg.js} +7 -7
- package/dist/chunks/{studio-6gcrk1bq.js → studio-40fm3hyr.js} +2 -2
- package/dist/chunks/{studio-0evba9z5.js → studio-4m39t01b.js} +5 -5
- package/dist/chunks/{studio-53dn6e6t.js → studio-675v08qj.js} +2 -2
- package/dist/chunks/{studio-kwavhmdr.js → studio-91sdrn9x.js} +2 -2
- package/dist/chunks/{studio-qd4k0h80.js → studio-9sxn0eaa.js} +4 -4
- package/dist/chunks/{studio-eqyybj2e.js → studio-d1f2rqxh.js} +4 -4
- package/dist/chunks/{studio-yz06mkfj.js → studio-gfzyxa0m.js} +5 -5
- package/dist/chunks/{studio-wxthr2x1.js → studio-gqpbrrj5.js} +8 -8
- package/dist/chunks/{studio-yk7037sg.js → studio-h6553a8h.js} +56 -17
- package/dist/chunks/{studio-1dgqagzz.js → studio-jand3kjg.js} +10 -10
- package/dist/chunks/{studio-ddgrc5hs.js → studio-kfq9ed73.js} +3 -3
- package/dist/chunks/{studio-ng5gbxkj.js → studio-n9k15qdg.js} +8 -8
- package/dist/chunks/{studio-377bbhtz.js → studio-qb6vy1z1.js} +8 -8
- package/dist/chunks/{studio-tqr02xaa.js → studio-qymkxbcq.js} +3 -3
- package/dist/chunks/{studio-ky68mp85.js → studio-rkr6pm84.js} +3 -3
- package/dist/chunks/{studio-rdsvb808.js → studio-rz861p2b.js} +5 -5
- package/dist/chunks/{studio-q07vj7p9.js → studio-tdt7b6qb.js} +6 -6
- package/dist/iframe-entry.js +67 -7
- package/dist/studio.js +31 -31
- package/package.json +4 -4
- package/src/canvas/editable-actions.ts +37 -1
- package/src/canvas/iframe-editable-root.ts +27 -0
- package/src/canvas/iframe-host.ts +118 -7
- package/src/canvas/iframe-inline-edit.ts +64 -2
- package/src/canvas/iframe-protocol.ts +7 -0
- package/src/canvas/iframe-render.ts +38 -1
- package/src/editor/inline-edit-apply.ts +10 -4
- package/src/editor/inline-edit.ts +62 -4
package/dist/iframe-entry.js
CHANGED
|
@@ -3480,6 +3480,16 @@ function getPath2(obj, path) {
|
|
|
3480
3480
|
return readPath(obj, path);
|
|
3481
3481
|
}
|
|
3482
3482
|
var _privatePropWarned = new Set;
|
|
3483
|
+
function instanceSupplies(el, key) {
|
|
3484
|
+
if (Object.hasOwn(el, key)) {
|
|
3485
|
+
return true;
|
|
3486
|
+
}
|
|
3487
|
+
if (el.hasAttribute(key)) {
|
|
3488
|
+
return true;
|
|
3489
|
+
}
|
|
3490
|
+
const kebab = key.replaceAll(/[A-Z]/gu, (c) => `-${c.toLowerCase()}`);
|
|
3491
|
+
return kebab !== key && el.hasAttribute(kebab);
|
|
3492
|
+
}
|
|
3483
3493
|
function refusePrivateProp(key, where) {
|
|
3484
3494
|
if (!isPrivateStateKey(key)) {
|
|
3485
3495
|
return false;
|
|
@@ -3630,7 +3640,7 @@ async function defineElement(source, baseUrl) {
|
|
|
3630
3640
|
if (isPrivateStateKey(key)) {
|
|
3631
3641
|
continue;
|
|
3632
3642
|
}
|
|
3633
|
-
if (key in this && this[key] !== undefined) {
|
|
3643
|
+
if (key in this && this[key] !== undefined && instanceSupplies(this, key)) {
|
|
3634
3644
|
state[key] = this[key];
|
|
3635
3645
|
}
|
|
3636
3646
|
}
|
|
@@ -4199,6 +4209,8 @@ function injectHead(doc) {
|
|
|
4199
4209
|
}
|
|
4200
4210
|
}
|
|
4201
4211
|
function makeStamper(ctx) {
|
|
4212
|
+
const islands = [];
|
|
4213
|
+
const insideIsland = (path) => islands.some((island) => path.length > island.length && island.every((seg, i) => path[i] === seg));
|
|
4202
4214
|
return (created, path, def2) => {
|
|
4203
4215
|
if (!(created instanceof HTMLElement)) {
|
|
4204
4216
|
return;
|
|
@@ -4207,8 +4219,10 @@ function makeStamper(ctx) {
|
|
|
4207
4219
|
if (isDefinitionRoot) {
|
|
4208
4220
|
created.dataset.jxDefinitionRoot = "";
|
|
4209
4221
|
}
|
|
4210
|
-
|
|
4222
|
+
const isIsland = !isDefinitionRoot && created.tagName.includes("-") && isEditableMode(ctx.canvasMode);
|
|
4223
|
+
if (isIsland) {
|
|
4211
4224
|
created.contentEditable = "false";
|
|
4225
|
+
islands.push(path);
|
|
4212
4226
|
}
|
|
4213
4227
|
const classified = classifyRenderNode(path, def2, ctx);
|
|
4214
4228
|
if (classified.kind === "layout") {
|
|
@@ -4225,6 +4239,9 @@ function makeStamper(ctx) {
|
|
|
4225
4239
|
return;
|
|
4226
4240
|
}
|
|
4227
4241
|
created.dataset.jxPath = serializeJxPath(classified.path);
|
|
4242
|
+
if (!isIsland && isEditableMode(ctx.canvasMode) && insideIsland(path)) {
|
|
4243
|
+
created.contentEditable = "true";
|
|
4244
|
+
}
|
|
4228
4245
|
};
|
|
4229
4246
|
}
|
|
4230
4247
|
function installCanvasImageRetry(root, maxAttempts = 3) {
|
|
@@ -5188,6 +5205,7 @@ var insertFn = null;
|
|
|
5188
5205
|
var endFn = null;
|
|
5189
5206
|
var _plainMode = false;
|
|
5190
5207
|
var _plainOriginal = "";
|
|
5208
|
+
var _plainPosted = false;
|
|
5191
5209
|
var editableVerdicts = null;
|
|
5192
5210
|
function setEditableVerdicts(verdicts) {
|
|
5193
5211
|
editableVerdicts = verdicts;
|
|
@@ -5207,6 +5225,7 @@ function startEditing(el, path, callbacks, opts) {
|
|
|
5207
5225
|
endFn = callbacks.onEnd;
|
|
5208
5226
|
_plainMode = opts?.plainText === true;
|
|
5209
5227
|
_plainOriginal = _plainMode ? el.textContent ?? "" : "";
|
|
5228
|
+
_plainPosted = false;
|
|
5210
5229
|
el.dataset.jxActiveBlock = "";
|
|
5211
5230
|
if (_plainMode) {
|
|
5212
5231
|
try {
|
|
@@ -5240,6 +5259,7 @@ function stopEditing(silent = false) {
|
|
|
5240
5259
|
insertFn = null;
|
|
5241
5260
|
_plainMode = false;
|
|
5242
5261
|
_plainOriginal = "";
|
|
5262
|
+
_plainPosted = false;
|
|
5243
5263
|
if (silent) {
|
|
5244
5264
|
endFn = null;
|
|
5245
5265
|
} else if (endFn) {
|
|
@@ -5251,6 +5271,9 @@ function stopEditing(silent = false) {
|
|
|
5251
5271
|
function commitActiveBlock() {
|
|
5252
5272
|
commitChanges(true);
|
|
5253
5273
|
}
|
|
5274
|
+
function isPlainSession() {
|
|
5275
|
+
return _plainMode && activeEl !== null;
|
|
5276
|
+
}
|
|
5254
5277
|
function isEditing() {
|
|
5255
5278
|
return activeEl !== null;
|
|
5256
5279
|
}
|
|
@@ -5336,6 +5359,7 @@ function releaseWithoutCommit() {
|
|
|
5336
5359
|
insertFn = null;
|
|
5337
5360
|
_plainMode = false;
|
|
5338
5361
|
_plainOriginal = "";
|
|
5362
|
+
_plainPosted = false;
|
|
5339
5363
|
if (endFn) {
|
|
5340
5364
|
const fn = endFn;
|
|
5341
5365
|
endFn = null;
|
|
@@ -5347,8 +5371,14 @@ function commitChanges(inPlace) {
|
|
|
5347
5371
|
return;
|
|
5348
5372
|
}
|
|
5349
5373
|
if (_plainMode) {
|
|
5350
|
-
|
|
5351
|
-
`, " ")
|
|
5374
|
+
const text = (activeEl.textContent ?? "").replaceAll(`
|
|
5375
|
+
`, " ");
|
|
5376
|
+
if (text === _plainOriginal.replaceAll(`
|
|
5377
|
+
`, " ") && !_plainPosted) {
|
|
5378
|
+
return;
|
|
5379
|
+
}
|
|
5380
|
+
_plainPosted = true;
|
|
5381
|
+
commitFn(activePath, null, text, inPlace);
|
|
5352
5382
|
return;
|
|
5353
5383
|
}
|
|
5354
5384
|
normalizeInlineContent(activeEl);
|
|
@@ -5471,6 +5501,9 @@ function openSlashMenu(opts) {
|
|
|
5471
5501
|
if (!activeEl || !insertFn || !activePath) {
|
|
5472
5502
|
return;
|
|
5473
5503
|
}
|
|
5504
|
+
if (_plainMode) {
|
|
5505
|
+
return;
|
|
5506
|
+
}
|
|
5474
5507
|
const sel = window.getSelection();
|
|
5475
5508
|
if (!sel || !sel.rangeCount) {
|
|
5476
5509
|
return;
|
|
@@ -5986,6 +6019,7 @@ var INSERT_TEXT = new Set([
|
|
|
5986
6019
|
"insertTranspose"
|
|
5987
6020
|
]);
|
|
5988
6021
|
var NATIVE_FORMAT_PREFIX = "format";
|
|
6022
|
+
var PROP_STRUCTURAL = new Set(["insertParagraph", "insertLineBreak"]);
|
|
5989
6023
|
function classifyBeforeInput(ctx) {
|
|
5990
6024
|
const { inputType, from, to } = ctx;
|
|
5991
6025
|
if (inputType === "insertCompositionText" || inputType === "insertFromComposition") {
|
|
@@ -6000,6 +6034,9 @@ function classifyBeforeInput(ctx) {
|
|
|
6000
6034
|
if (inputType === "insertFromDrop" || inputType === "deleteByDrag") {
|
|
6001
6035
|
return { kind: "reject" };
|
|
6002
6036
|
}
|
|
6037
|
+
if (ctx.inPropHost) {
|
|
6038
|
+
return PROP_STRUCTURAL.has(inputType) ? { kind: "reject" } : { kind: "native" };
|
|
6039
|
+
}
|
|
6003
6040
|
if (!from || !to) {
|
|
6004
6041
|
return { kind: "reject" };
|
|
6005
6042
|
}
|
|
@@ -6107,6 +6144,11 @@ function startEditableRoot(container, deps) {
|
|
|
6107
6144
|
composing = false;
|
|
6108
6145
|
scheduleCommitTick();
|
|
6109
6146
|
};
|
|
6147
|
+
const forget = () => {
|
|
6148
|
+
cancelCommitTick();
|
|
6149
|
+
activeEl2 = null;
|
|
6150
|
+
activeKey = null;
|
|
6151
|
+
};
|
|
6110
6152
|
const deactivate = () => {
|
|
6111
6153
|
if (!activeEl2) {
|
|
6112
6154
|
return;
|
|
@@ -6181,6 +6223,7 @@ function startEditableRoot(container, deps) {
|
|
|
6181
6223
|
atBlockStart: resolved ? isAtBlockStart(resolved.from) : false,
|
|
6182
6224
|
data: e.data ?? "",
|
|
6183
6225
|
from: resolved?.from ?? null,
|
|
6226
|
+
inPropHost: activeEl2 !== null && activeKey === null,
|
|
6184
6227
|
inputType: e.inputType,
|
|
6185
6228
|
to: resolved?.to ?? null
|
|
6186
6229
|
});
|
|
@@ -6251,6 +6294,7 @@ function startEditableRoot(container, deps) {
|
|
|
6251
6294
|
doc.addEventListener("pointerdown", onPointerDownCapture, true);
|
|
6252
6295
|
return {
|
|
6253
6296
|
capture: () => captureDocSelection(container, deps.isEditableBlock),
|
|
6297
|
+
forget,
|
|
6254
6298
|
isComposing: () => composing,
|
|
6255
6299
|
flush: () => {
|
|
6256
6300
|
if (composing) {
|
|
@@ -6746,14 +6790,18 @@ function startIframeInlineEdit(channel, container, opts) {
|
|
|
6746
6790
|
return true;
|
|
6747
6791
|
}
|
|
6748
6792
|
const node = getNodeAtPath(shadowDoc, hostPath);
|
|
6793
|
+
const attrs = node?.attributes;
|
|
6794
|
+
if (attrs?.[`props.${prop}`] !== undefined || attrs?.[prop] !== undefined) {
|
|
6795
|
+
return false;
|
|
6796
|
+
}
|
|
6749
6797
|
const raw = node?.$props?.[prop];
|
|
6750
6798
|
if (raw == null) {
|
|
6751
6799
|
return true;
|
|
6752
6800
|
}
|
|
6753
|
-
if (typeof raw
|
|
6801
|
+
if (typeof raw !== "string") {
|
|
6754
6802
|
return false;
|
|
6755
6803
|
}
|
|
6756
|
-
return !
|
|
6804
|
+
return !raw.includes("${");
|
|
6757
6805
|
};
|
|
6758
6806
|
const enterPropEditAt = (el, hostPath, prop) => {
|
|
6759
6807
|
channel.post({ kind: "editStart", path: hostPath, prop });
|
|
@@ -6768,6 +6816,7 @@ function startIframeInlineEdit(channel, container, opts) {
|
|
|
6768
6816
|
onEnd: () => {
|
|
6769
6817
|
clearHighlight();
|
|
6770
6818
|
lastNonEmptyRange = null;
|
|
6819
|
+
root.forget();
|
|
6771
6820
|
channel.post({ kind: "editEnd" });
|
|
6772
6821
|
},
|
|
6773
6822
|
onInsert: () => {},
|
|
@@ -6779,6 +6828,9 @@ function startIframeInlineEdit(channel, container, opts) {
|
|
|
6779
6828
|
if (!el) {
|
|
6780
6829
|
return;
|
|
6781
6830
|
}
|
|
6831
|
+
if (isPlainSession()) {
|
|
6832
|
+
return;
|
|
6833
|
+
}
|
|
6782
6834
|
if (lastNonEmptyRange && lastNonEmptyRange.startContainer.isConnected && el.contains(lastNonEmptyRange.commonAncestorContainer)) {
|
|
6783
6835
|
const sel = window.getSelection();
|
|
6784
6836
|
el.focus();
|
|
@@ -6893,6 +6945,14 @@ function startIframeInlineEdit(channel, container, opts) {
|
|
|
6893
6945
|
if (!editingAllowed()) {
|
|
6894
6946
|
return;
|
|
6895
6947
|
}
|
|
6948
|
+
if (msg.prop !== undefined) {
|
|
6949
|
+
const instance = elementForPath2(container, msg.path);
|
|
6950
|
+
const marker = instance?.querySelector(`[data-jx-bound-prop="${CSS.escape(msg.prop)}"]`);
|
|
6951
|
+
if (marker) {
|
|
6952
|
+
activateProp(marker);
|
|
6953
|
+
}
|
|
6954
|
+
return;
|
|
6955
|
+
}
|
|
6896
6956
|
const el = elementForPath2(container, msg.path);
|
|
6897
6957
|
if (el && isEditableBlock(el)) {
|
|
6898
6958
|
root.placeCaret({ offset: msg.offset ?? 0, path: msg.path });
|
|
@@ -8170,5 +8230,5 @@ export {
|
|
|
8170
8230
|
startCanvasIframe
|
|
8171
8231
|
};
|
|
8172
8232
|
|
|
8173
|
-
//# debugId=
|
|
8233
|
+
//# debugId=8BEF1FC0BD88A0F164756E2164756E21
|
|
8174
8234
|
//# sourceMappingURL=iframe-entry.js.map
|
package/dist/studio.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
seedPublishConnected
|
|
3
|
-
} from "./chunks/studio-
|
|
3
|
+
} from "./chunks/studio-qymkxbcq.js";
|
|
4
4
|
import"./chunks/studio-wdt9y92a.js";
|
|
5
5
|
import {
|
|
6
6
|
ElementResolutionController,
|
|
@@ -67,7 +67,7 @@ import {
|
|
|
67
67
|
registerStyleCommands,
|
|
68
68
|
render as render3,
|
|
69
69
|
setInspectorTab
|
|
70
|
-
} from "./chunks/studio-
|
|
70
|
+
} from "./chunks/studio-1d6bm7eg.js";
|
|
71
71
|
import {
|
|
72
72
|
CommandUnavailableError,
|
|
73
73
|
chordFromEvent,
|
|
@@ -99,7 +99,7 @@ import {
|
|
|
99
99
|
showSlashMenu,
|
|
100
100
|
showSlashMenuAtRect,
|
|
101
101
|
suppressBlockActionBar
|
|
102
|
-
} from "./chunks/studio-
|
|
102
|
+
} from "./chunks/studio-qb6vy1z1.js";
|
|
103
103
|
import {
|
|
104
104
|
addableContexts,
|
|
105
105
|
defaultCommands,
|
|
@@ -111,7 +111,7 @@ import {
|
|
|
111
111
|
tokenLabel,
|
|
112
112
|
transposeStylebookStyle,
|
|
113
113
|
writeTokenOverride
|
|
114
|
-
} from "./chunks/studio-
|
|
114
|
+
} from "./chunks/studio-gfzyxa0m.js";
|
|
115
115
|
import {
|
|
116
116
|
DERIVE_PRESETS,
|
|
117
117
|
JxColorPopover,
|
|
@@ -144,7 +144,7 @@ import {
|
|
|
144
144
|
spNumberField,
|
|
145
145
|
spTextArea,
|
|
146
146
|
spTextField
|
|
147
|
-
} from "./chunks/studio-
|
|
147
|
+
} from "./chunks/studio-n9k15qdg.js";
|
|
148
148
|
import {
|
|
149
149
|
LitElement,
|
|
150
150
|
css
|
|
@@ -160,7 +160,7 @@ import {
|
|
|
160
160
|
import {
|
|
161
161
|
initQuickSearch,
|
|
162
162
|
openQuickSearch
|
|
163
|
-
} from "./chunks/studio-
|
|
163
|
+
} from "./chunks/studio-9sxn0eaa.js";
|
|
164
164
|
import {
|
|
165
165
|
addRecentProject,
|
|
166
166
|
clearRecentProjects,
|
|
@@ -187,10 +187,10 @@ import {
|
|
|
187
187
|
removeRecentProject,
|
|
188
188
|
renderFilesTemplate,
|
|
189
189
|
seedEntry
|
|
190
|
-
} from "./chunks/studio-
|
|
190
|
+
} from "./chunks/studio-jand3kjg.js";
|
|
191
191
|
import {
|
|
192
192
|
computeWindow
|
|
193
|
-
} from "./chunks/studio-
|
|
193
|
+
} from "./chunks/studio-91sdrn9x.js";
|
|
194
194
|
import {
|
|
195
195
|
autoSyncProjectOnOpen,
|
|
196
196
|
cleanupGitPanel,
|
|
@@ -211,13 +211,13 @@ import {
|
|
|
211
211
|
registerSourceControlCommands,
|
|
212
212
|
renderGitPanel,
|
|
213
213
|
stripRange
|
|
214
|
-
} from "./chunks/studio-
|
|
214
|
+
} from "./chunks/studio-tdt7b6qb.js";
|
|
215
215
|
import {
|
|
216
216
|
createPanelScheduler
|
|
217
217
|
} from "./chunks/studio-8jpzqk5s.js";
|
|
218
218
|
import {
|
|
219
219
|
selectContributedEntry
|
|
220
|
-
} from "./chunks/studio-
|
|
220
|
+
} from "./chunks/studio-rz861p2b.js";
|
|
221
221
|
import {
|
|
222
222
|
notifySettingsDocument,
|
|
223
223
|
onSettingsDocumentChanged,
|
|
@@ -238,7 +238,7 @@ import {
|
|
|
238
238
|
renderForm,
|
|
239
239
|
renderProvenanceChip,
|
|
240
240
|
resolveContextPointer
|
|
241
|
-
} from "./chunks/studio-
|
|
241
|
+
} from "./chunks/studio-rkr6pm84.js";
|
|
242
242
|
import {
|
|
243
243
|
validateDoc,
|
|
244
244
|
validateProjectConfig
|
|
@@ -263,7 +263,7 @@ import {
|
|
|
263
263
|
registerGridCommands,
|
|
264
264
|
scanLibrary,
|
|
265
265
|
uploadDirForCategory
|
|
266
|
-
} from "./chunks/studio-
|
|
266
|
+
} from "./chunks/studio-4m39t01b.js";
|
|
267
267
|
import {
|
|
268
268
|
live
|
|
269
269
|
} from "./chunks/studio-c31yb4t6.js";
|
|
@@ -307,7 +307,7 @@ import {
|
|
|
307
307
|
setIncludeDrafts,
|
|
308
308
|
startFsSync,
|
|
309
309
|
writesForTurn
|
|
310
|
-
} from "./chunks/studio-
|
|
310
|
+
} from "./chunks/studio-gqpbrrj5.js";
|
|
311
311
|
import"./chunks/studio-2w11grav.js";
|
|
312
312
|
import"./chunks/studio-bw5dz6km.js";
|
|
313
313
|
import {
|
|
@@ -316,18 +316,18 @@ import {
|
|
|
316
316
|
isImage,
|
|
317
317
|
setMediaChangedHandler,
|
|
318
318
|
uploadAssets
|
|
319
|
-
} from "./chunks/studio-
|
|
319
|
+
} from "./chunks/studio-0svvdm0a.js";
|
|
320
320
|
import {
|
|
321
321
|
beginActivity,
|
|
322
322
|
registerActivityPanel,
|
|
323
323
|
showProgressModal
|
|
324
|
-
} from "./chunks/studio-
|
|
324
|
+
} from "./chunks/studio-d1f2rqxh.js";
|
|
325
325
|
import {
|
|
326
326
|
currentDeploy,
|
|
327
327
|
latestDeployment,
|
|
328
328
|
noteDeployment,
|
|
329
329
|
platformSupportsPublish
|
|
330
|
-
} from "./chunks/studio-
|
|
330
|
+
} from "./chunks/studio-675v08qj.js";
|
|
331
331
|
import {
|
|
332
332
|
CATEGORIES,
|
|
333
333
|
SPAN_FULL_RENDER,
|
|
@@ -439,7 +439,7 @@ import {
|
|
|
439
439
|
timeSpan,
|
|
440
440
|
timeSpanAsync,
|
|
441
441
|
updateActivePanelHeaders
|
|
442
|
-
} from "./chunks/studio-
|
|
442
|
+
} from "./chunks/studio-h6553a8h.js";
|
|
443
443
|
import {
|
|
444
444
|
BOTTOM_TAB_IDS,
|
|
445
445
|
BUFFER_COMMIT,
|
|
@@ -606,7 +606,7 @@ import {
|
|
|
606
606
|
updateSiteConfig,
|
|
607
607
|
view,
|
|
608
608
|
workspace
|
|
609
|
-
} from "./chunks/studio-
|
|
609
|
+
} from "./chunks/studio-kfq9ed73.js";
|
|
610
610
|
import {
|
|
611
611
|
classMap,
|
|
612
612
|
ifDefined,
|
|
@@ -669,7 +669,7 @@ import {
|
|
|
669
669
|
mountStillWanted,
|
|
670
670
|
refreshExtensionUi,
|
|
671
671
|
refreshFormats
|
|
672
|
-
} from "./chunks/studio-
|
|
672
|
+
} from "./chunks/studio-40fm3hyr.js";
|
|
673
673
|
import {
|
|
674
674
|
getPlatform,
|
|
675
675
|
hasPlatform,
|
|
@@ -16807,7 +16807,7 @@ function entryIdsFor(collection) {
|
|
|
16807
16807
|
if (known) {
|
|
16808
16808
|
return known;
|
|
16809
16809
|
}
|
|
16810
|
-
const pending = import("./chunks/content-source-
|
|
16810
|
+
const pending = import("./chunks/content-source-cn9te96r.js").then((m) => m.listCollectionEntryIds(collection));
|
|
16811
16811
|
entryIdCache.set(collection, pending);
|
|
16812
16812
|
return pending;
|
|
16813
16813
|
}
|
|
@@ -17068,7 +17068,7 @@ function renderEntryMode(surface, tab) {
|
|
|
17068
17068
|
});
|
|
17069
17069
|
}
|
|
17070
17070
|
async function openEntryEditor(path) {
|
|
17071
|
-
const { openFileInTab: openFileInTab2 } = await import("./chunks/files-
|
|
17071
|
+
const { openFileInTab: openFileInTab2 } = await import("./chunks/files-dsh5g8j4.js");
|
|
17072
17072
|
await openFileInTab2(path);
|
|
17073
17073
|
for (const [id, tab] of workspace.tabs.entries()) {
|
|
17074
17074
|
if (tab.documentPath !== path) {
|
|
@@ -17129,7 +17129,7 @@ async function createEntry(collectionName) {
|
|
|
17129
17129
|
});
|
|
17130
17130
|
return null;
|
|
17131
17131
|
}
|
|
17132
|
-
const { createFileIn: createFileIn2 } = await import("./chunks/files-
|
|
17132
|
+
const { createFileIn: createFileIn2 } = await import("./chunks/files-dsh5g8j4.js");
|
|
17133
17133
|
const created = await createFileIn2({
|
|
17134
17134
|
content,
|
|
17135
17135
|
dir: collection.dir,
|
|
@@ -22349,7 +22349,7 @@ function groupProblems(records = problems) {
|
|
|
22349
22349
|
return groups;
|
|
22350
22350
|
}
|
|
22351
22351
|
function openProblemPath(path) {
|
|
22352
|
-
import("./chunks/files-
|
|
22352
|
+
import("./chunks/files-dsh5g8j4.js").then((m) => m.openFileInTab(path));
|
|
22353
22353
|
}
|
|
22354
22354
|
function actionTpl(record) {
|
|
22355
22355
|
const id = record.action;
|
|
@@ -58591,9 +58591,9 @@ function renderDefsEditor(container) {
|
|
|
58591
58591
|
|
|
58592
58592
|
// src/version.ts
|
|
58593
58593
|
var APP_NAME = "Jx Studio";
|
|
58594
|
-
var VERSION = "2.4.
|
|
58595
|
-
var BUILD_DATE = "2026-08-
|
|
58596
|
-
var GIT_COMMIT = "
|
|
58594
|
+
var VERSION = "2.4.1";
|
|
58595
|
+
var BUILD_DATE = "2026-08-24T11:52:26.010Z";
|
|
58596
|
+
var GIT_COMMIT = "eb4fe5d";
|
|
58597
58597
|
var LINKS = {
|
|
58598
58598
|
github: "https://github.com/jxsuite/jx",
|
|
58599
58599
|
docs: "https://github.com/jxsuite/jx#readme",
|
|
@@ -59670,7 +59670,7 @@ async function openProjectSettings(section) {
|
|
|
59670
59670
|
showSettingsDocument();
|
|
59671
59671
|
notifySettingsDocument();
|
|
59672
59672
|
try {
|
|
59673
|
-
const { syncExtensionSettingsSections } = await import("./chunks/extension-sections-
|
|
59673
|
+
const { syncExtensionSettingsSections } = await import("./chunks/extension-sections-mdgmqrry.js");
|
|
59674
59674
|
await syncExtensionSettingsSections();
|
|
59675
59675
|
} catch (error) {
|
|
59676
59676
|
notify.warn(`Could not load extension settings sections — ${errorMessage(error)}`, {
|
|
@@ -60294,7 +60294,7 @@ function publishCommands() {
|
|
|
60294
60294
|
name: "set_up_publishing"
|
|
60295
60295
|
},
|
|
60296
60296
|
run: async () => {
|
|
60297
|
-
const { openPublishPanel } = await import("./chunks/publish-panel-
|
|
60297
|
+
const { openPublishPanel } = await import("./chunks/publish-panel-b0xh7b4y.js");
|
|
60298
60298
|
openPublishPanel();
|
|
60299
60299
|
},
|
|
60300
60300
|
title: "Set Up Publishing"
|
|
@@ -61016,7 +61016,7 @@ function i18nCommands() {
|
|
|
61016
61016
|
});
|
|
61017
61017
|
return;
|
|
61018
61018
|
}
|
|
61019
|
-
const { openFileInTab: openFileInTab2 } = await import("./chunks/files-
|
|
61019
|
+
const { openFileInTab: openFileInTab2 } = await import("./chunks/files-dsh5g8j4.js");
|
|
61020
61020
|
await openFileInTab2(path);
|
|
61021
61021
|
},
|
|
61022
61022
|
title: "Open Translation"
|
|
@@ -61063,7 +61063,7 @@ function i18nCommands() {
|
|
|
61063
61063
|
return;
|
|
61064
61064
|
}
|
|
61065
61065
|
const cut = path.lastIndexOf("/");
|
|
61066
|
-
const { createFileIn: createFileIn2, openFileInTab: openFileInTab2 } = await import("./chunks/files-
|
|
61066
|
+
const { createFileIn: createFileIn2, openFileInTab: openFileInTab2 } = await import("./chunks/files-dsh5g8j4.js");
|
|
61067
61067
|
const created = await createFileIn2({
|
|
61068
61068
|
content,
|
|
61069
61069
|
dir: cut === -1 ? "." : path.slice(0, cut),
|
|
@@ -61876,5 +61876,5 @@ export {
|
|
|
61876
61876
|
hasUnsavedTabs
|
|
61877
61877
|
};
|
|
61878
61878
|
|
|
61879
|
-
//# debugId=
|
|
61879
|
+
//# debugId=C20E21297FE0976064756E2164756E21
|
|
61880
61880
|
//# sourceMappingURL=studio.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jxsuite/studio",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.1",
|
|
4
4
|
"description": "Jx Studio — visual builder for Jx documents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -59,11 +59,11 @@
|
|
|
59
59
|
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^2.1.0",
|
|
60
60
|
"@jxsuite/ai": "^0.36.2",
|
|
61
61
|
"@jxsuite/collab": "^0.8.1",
|
|
62
|
-
"@jxsuite/create": "^1.3.
|
|
63
|
-
"@jxsuite/formulas": "^0.0.
|
|
62
|
+
"@jxsuite/create": "^1.3.5",
|
|
63
|
+
"@jxsuite/formulas": "^0.0.11",
|
|
64
64
|
"@jxsuite/markup": "^0.4.5",
|
|
65
65
|
"@jxsuite/protocol": "^1.2.0",
|
|
66
|
-
"@jxsuite/runtime": "^2.0.
|
|
66
|
+
"@jxsuite/runtime": "^2.0.4",
|
|
67
67
|
"@jxsuite/schema": "^1.8.0",
|
|
68
68
|
"@spectrum-web-components/accordion": "^1.12.2",
|
|
69
69
|
"@spectrum-web-components/action-bar": "1.12.2",
|
|
@@ -49,6 +49,15 @@ export interface BeforeInputContext {
|
|
|
49
49
|
atBlockEnd: boolean;
|
|
50
50
|
/** The event's `data` (inserted text), empty for deletions. */
|
|
51
51
|
data: string;
|
|
52
|
+
/**
|
|
53
|
+
* The caret is in a PROP-BOUND nested host — text inside a component instance that is an
|
|
54
|
+
* invertible prop binding (studio.md §8.2.5), not a block of the page document.
|
|
55
|
+
*
|
|
56
|
+
* Such a host has no `data-jx-path` of its own, so `from`/`to` are always null for it. Without
|
|
57
|
+
* this flag the null-position rule below rejected every keystroke: the caret appeared, and
|
|
58
|
+
* nothing typed into a component slot ever landed.
|
|
59
|
+
*/
|
|
60
|
+
inPropHost: boolean;
|
|
52
61
|
}
|
|
53
62
|
|
|
54
63
|
/**
|
|
@@ -91,6 +100,20 @@ const INSERT_TEXT = new Set([
|
|
|
91
100
|
*/
|
|
92
101
|
const NATIVE_FORMAT_PREFIX = "format";
|
|
93
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Intents refused inside a prop-bound host, because a prop value is ONE PLAIN STRING.
|
|
105
|
+
*
|
|
106
|
+
* `docs/studio/editing/writing.md` puts it as "paragraph splits are off": there is no second block
|
|
107
|
+
* for Enter to make, and a `<br>` would serialise into a value that is supposed to be a single
|
|
108
|
+
* line. Everything else — insert, delete, paste, cut, IME — is ordinary text editing on a
|
|
109
|
+
* `plaintext-only` host and runs natively.
|
|
110
|
+
*
|
|
111
|
+
* These are refused rather than re-expressed: Enter FINISHES the edit (handled as a keystroke by
|
|
112
|
+
* the editing engine, not as an input event), so the chokepoint's only job is to stop the browser
|
|
113
|
+
* inserting the newline first.
|
|
114
|
+
*/
|
|
115
|
+
const PROP_STRUCTURAL = new Set(["insertParagraph", "insertLineBreak"]);
|
|
116
|
+
|
|
94
117
|
/**
|
|
95
118
|
* Classify one `beforeinput`.
|
|
96
119
|
*
|
|
@@ -124,7 +147,20 @@ export function classifyBeforeInput(ctx: BeforeInputContext): EditAction {
|
|
|
124
147
|
return { kind: "reject" };
|
|
125
148
|
}
|
|
126
149
|
|
|
127
|
-
|
|
150
|
+
/*
|
|
151
|
+
* 2. A prop-bound host is editable text with NO document path — it is written back as a prop
|
|
152
|
+
* value by its own commit (`editCommitProp`), not as a block. It must be judged before the
|
|
153
|
+
* null-position rule below, which would otherwise reject it for having no path: that is exactly
|
|
154
|
+
* what made a component slot show a caret and swallow every keystroke.
|
|
155
|
+
*
|
|
156
|
+
* Nothing here is structural, so nothing is re-expressed; the browser edits the text and the
|
|
157
|
+
* session commits the string.
|
|
158
|
+
*/
|
|
159
|
+
if (ctx.inPropHost) {
|
|
160
|
+
return PROP_STRUCTURAL.has(inputType) ? { kind: "reject" } : { kind: "native" };
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// 3. No resolvable position means the caret is in canvas chrome or a `contenteditable="false"`
|
|
128
164
|
// Island — there is no document node to write to.
|
|
129
165
|
if (!from || !to) {
|
|
130
166
|
return { kind: "reject" };
|
|
@@ -134,6 +134,12 @@ export function restoreDocSelection(container: HTMLElement, range: DocRange): bo
|
|
|
134
134
|
export interface EditableRootHandle {
|
|
135
135
|
/** Tear the host down. */
|
|
136
136
|
stop: () => void;
|
|
137
|
+
/**
|
|
138
|
+
* Forget the active element without committing or notifying — for when the EDITING ENGINE has
|
|
139
|
+
* already ended the session itself (Enter / Escape in a prop host) and only this module's
|
|
140
|
+
* bookkeeping is left pointing at it.
|
|
141
|
+
*/
|
|
142
|
+
forget: () => void;
|
|
137
143
|
/**
|
|
138
144
|
* Re-derive the active block from the live selection. Call after moving the selection
|
|
139
145
|
* programmatically — `selectionchange` is dispatched as a task, so a caller that needs the
|
|
@@ -242,6 +248,23 @@ export function startEditableRoot(
|
|
|
242
248
|
scheduleCommitTick();
|
|
243
249
|
};
|
|
244
250
|
|
|
251
|
+
/**
|
|
252
|
+
* Drop the active element WITHOUT telling the engine — the engine is what asked.
|
|
253
|
+
*
|
|
254
|
+
* `deactivate()` exists for the caret leaving, and calls `onDeactivate` to commit on the way out.
|
|
255
|
+
* When the ENGINE ends a session itself (Enter or Escape in a prop host), that has already
|
|
256
|
+
* happened, and calling back into it would re-enter a teardown that is mid-flight. What was
|
|
257
|
+
* missing was the other half: nothing cleared `activeEl`/`activeKey`, so the host kept pointing
|
|
258
|
+
* at a dead session — `onPointerDownCapture`'s `el !== activeEl` guard was then false and the
|
|
259
|
+
* next click on the same text did nothing at all, and `inPropHost` stayed true with no session
|
|
260
|
+
* behind it.
|
|
261
|
+
*/
|
|
262
|
+
const forget = () => {
|
|
263
|
+
cancelCommitTick();
|
|
264
|
+
activeEl = null;
|
|
265
|
+
activeKey = null;
|
|
266
|
+
};
|
|
267
|
+
|
|
245
268
|
/** Release whatever is active, if anything. */
|
|
246
269
|
const deactivate = () => {
|
|
247
270
|
if (!activeEl) {
|
|
@@ -358,6 +381,9 @@ export function startEditableRoot(
|
|
|
358
381
|
atBlockStart: resolved ? isAtBlockStart(resolved.from) : false,
|
|
359
382
|
data: e.data ?? "",
|
|
360
383
|
from: resolved?.from ?? null,
|
|
384
|
+
/* An adopted element with no path IS the prop-bound host — `onPointerDownCapture` sets
|
|
385
|
+
exactly that pair, and `syncActiveBlock` preserves it while the caret stays inside. */
|
|
386
|
+
inPropHost: activeEl !== null && activeKey === null,
|
|
361
387
|
inputType: e.inputType,
|
|
362
388
|
to: resolved?.to ?? null,
|
|
363
389
|
});
|
|
@@ -456,6 +482,7 @@ export function startEditableRoot(
|
|
|
456
482
|
|
|
457
483
|
return {
|
|
458
484
|
capture: () => captureDocSelection(container, deps.isEditableBlock),
|
|
485
|
+
forget,
|
|
459
486
|
/** Whether an IME composition is in flight — callers must not rewrite the DOM under it. */
|
|
460
487
|
isComposing: () => composing,
|
|
461
488
|
flush: () => {
|