@ohhwells/bridge 0.1.53-next.145 → 0.1.54-next.146
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/index.cjs +98 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +98 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -155,7 +155,8 @@ function parseAiSectionsState(raw) {
|
|
|
155
155
|
label: typeof entry.label === "string" ? entry.label : "Generated section",
|
|
156
156
|
media: entry.media && typeof entry.media === "object" ? entry.media : {}
|
|
157
157
|
}));
|
|
158
|
-
|
|
158
|
+
const removed = Array.isArray(parsed.removed) ? parsed.removed.filter((id) => typeof id === "string" && id.length > 0) : [];
|
|
159
|
+
return { v: 1, sections, ...removed.length ? { removed } : {} };
|
|
159
160
|
} catch {
|
|
160
161
|
return EMPTY_AI_SECTIONS;
|
|
161
162
|
}
|
|
@@ -164,17 +165,30 @@ function serializeAiSectionsState(state) {
|
|
|
164
165
|
return JSON.stringify(state);
|
|
165
166
|
}
|
|
166
167
|
function applyTreeToState(state, payload) {
|
|
168
|
+
const insertBefore = payload.mode === "insert" && payload.position === "before";
|
|
167
169
|
const entry = {
|
|
168
170
|
id: payload.id,
|
|
169
171
|
label: payload.label ?? "Generated section",
|
|
170
|
-
afterSection: payload.mode === "insert" ? payload.targetSectionId ?? null : null,
|
|
172
|
+
afterSection: payload.mode === "insert" && !insertBefore ? payload.targetSectionId ?? null : null,
|
|
173
|
+
...insertBefore && payload.targetSectionId ? { beforeSection: payload.targetSectionId } : {},
|
|
171
174
|
...payload.mode === "replace" && payload.targetSectionId ? { replaces: payload.targetSectionId } : {},
|
|
172
175
|
tree: payload.tree,
|
|
173
176
|
media: payload.media ?? {},
|
|
174
177
|
...payload.brand && typeof payload.brand === "object" ? { brand: payload.brand } : {}
|
|
175
178
|
};
|
|
176
179
|
const others = state.sections.filter((existing) => existing.id !== entry.id);
|
|
177
|
-
return { v: 1, sections: [...others, entry] };
|
|
180
|
+
return { ...state, v: 1, sections: [...others, entry] };
|
|
181
|
+
}
|
|
182
|
+
function removeFromState(state, id) {
|
|
183
|
+
return { ...state, v: 1, sections: state.sections.filter((entry) => entry.id !== id) };
|
|
184
|
+
}
|
|
185
|
+
function deleteSectionFromState(state, sectionId) {
|
|
186
|
+
if (state.sections.some((entry) => entry.id === sectionId)) {
|
|
187
|
+
return removeFromState(state, sectionId);
|
|
188
|
+
}
|
|
189
|
+
const removed = state.removed ?? [];
|
|
190
|
+
if (removed.includes(sectionId)) return state;
|
|
191
|
+
return { ...state, v: 1, sections: state.sections, removed: [...removed, sectionId] };
|
|
178
192
|
}
|
|
179
193
|
|
|
180
194
|
// src/ui/ai-tree/aiSectionsManager.tsx
|
|
@@ -425,7 +439,7 @@ function PersonEl({
|
|
|
425
439
|
)
|
|
426
440
|
}
|
|
427
441
|
),
|
|
428
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
|
|
442
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: { flex: 1, minWidth: 0 }, children: [
|
|
429
443
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
430
444
|
"span",
|
|
431
445
|
{
|
|
@@ -499,7 +513,14 @@ function PricingCard({ node, ctx, path }) {
|
|
|
499
513
|
features && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
500
514
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { style: { border: "none", borderTop: `1px solid ${dark}`, opacity: 0.2, margin: 0, width: "100%" } }),
|
|
501
515
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: AI_TREE_TOKENS.spacing4 }, children: [
|
|
502
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
516
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
517
|
+
"div",
|
|
518
|
+
{
|
|
519
|
+
...textAttrs(ctx, `${path}.featuresLabel`),
|
|
520
|
+
style: { ...typeStyle({ size: 24, line: 1.3, weight: 700 }, ctx.brand.fonts.body), color: dark },
|
|
521
|
+
children: str(slots.featuresLabel) || "Includes:"
|
|
522
|
+
}
|
|
523
|
+
),
|
|
503
524
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: FEATURE_LINE_CSS }),
|
|
504
525
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
505
526
|
"div",
|
|
@@ -1203,6 +1224,7 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
|
|
|
1203
1224
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
1204
1225
|
var CONTAINER_ATTR = "data-ohw-ai-generated";
|
|
1205
1226
|
var REPLACED_ATTR = "data-ohw-ai-replaced-by";
|
|
1227
|
+
var REMOVED_ATTR = "data-ohw-ai-removed";
|
|
1206
1228
|
function deriveTemplateBrand() {
|
|
1207
1229
|
if (typeof document === "undefined") return null;
|
|
1208
1230
|
const cs = getComputedStyle(document.documentElement);
|
|
@@ -1231,6 +1253,14 @@ function findTemplateSection(id) {
|
|
|
1231
1253
|
}
|
|
1232
1254
|
return null;
|
|
1233
1255
|
}
|
|
1256
|
+
function findPlacementAnchor(id, exclude) {
|
|
1257
|
+
for (const el of document.querySelectorAll(`[data-ohw-section="${CSS.escape(id)}"]`)) {
|
|
1258
|
+
if (el === exclude) continue;
|
|
1259
|
+
if (el.parentElement?.closest("[data-ohw-section]")) continue;
|
|
1260
|
+
return el;
|
|
1261
|
+
}
|
|
1262
|
+
return null;
|
|
1263
|
+
}
|
|
1234
1264
|
function placeContainer(container, entry) {
|
|
1235
1265
|
if (entry.replaces) {
|
|
1236
1266
|
const original = findTemplateSection(entry.replaces);
|
|
@@ -1239,8 +1269,15 @@ function placeContainer(container, entry) {
|
|
|
1239
1269
|
return;
|
|
1240
1270
|
}
|
|
1241
1271
|
}
|
|
1272
|
+
if (entry.beforeSection) {
|
|
1273
|
+
const anchor = findPlacementAnchor(entry.beforeSection, container);
|
|
1274
|
+
if (anchor) {
|
|
1275
|
+
anchor.insertAdjacentElement("beforebegin", container);
|
|
1276
|
+
return;
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1242
1279
|
if (entry.afterSection) {
|
|
1243
|
-
const anchor =
|
|
1280
|
+
const anchor = findPlacementAnchor(entry.afterSection, container);
|
|
1244
1281
|
if (anchor) {
|
|
1245
1282
|
anchor.insertAdjacentElement("afterend", container);
|
|
1246
1283
|
return;
|
|
@@ -1253,6 +1290,23 @@ function placeContainer(container, entry) {
|
|
|
1253
1290
|
document.body.appendChild(container);
|
|
1254
1291
|
}
|
|
1255
1292
|
}
|
|
1293
|
+
function syncRemovedSections(state) {
|
|
1294
|
+
const removed = new Set(state.removed ?? []);
|
|
1295
|
+
for (const el of document.querySelectorAll(`[${REMOVED_ATTR}]`)) {
|
|
1296
|
+
const id = el.getAttribute("data-ohw-section") ?? "";
|
|
1297
|
+
if (!removed.has(id)) {
|
|
1298
|
+
el.style.removeProperty("display");
|
|
1299
|
+
el.removeAttribute(REMOVED_ATTR);
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
for (const id of removed) {
|
|
1303
|
+
const section = findTemplateSection(id);
|
|
1304
|
+
if (section && !section.hasAttribute(REPLACED_ATTR)) {
|
|
1305
|
+
section.style.display = "none";
|
|
1306
|
+
section.setAttribute(REMOVED_ATTR, "");
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1256
1310
|
function syncReplacedOriginals(state) {
|
|
1257
1311
|
for (const el of document.querySelectorAll(`[${REPLACED_ATTR}]`)) {
|
|
1258
1312
|
const byId = el.getAttribute(REPLACED_ATTR) ?? "";
|
|
@@ -1317,6 +1371,7 @@ function applyAiSectionsToDom(state, options) {
|
|
|
1317
1371
|
mounted.set(entry.id, { root, container, serialized });
|
|
1318
1372
|
}
|
|
1319
1373
|
syncReplacedOriginals(state);
|
|
1374
|
+
syncRemovedSections(state);
|
|
1320
1375
|
}
|
|
1321
1376
|
|
|
1322
1377
|
// src/useLinkHrefGuardian.ts
|
|
@@ -11668,9 +11723,12 @@ function collectEditableNodes(extraContent, root = document) {
|
|
|
11668
11723
|
text: String(video.muted)
|
|
11669
11724
|
});
|
|
11670
11725
|
});
|
|
11671
|
-
|
|
11672
|
-
|
|
11673
|
-
|
|
11726
|
+
}
|
|
11727
|
+
const carouselKeys = isScoped ? new Set(
|
|
11728
|
+
Array.from(root.querySelectorAll("[data-ohw-carousel]")).map((el) => el.getAttribute("data-ohw-key") ?? "").filter(Boolean)
|
|
11729
|
+
) : listCarouselKeys();
|
|
11730
|
+
for (const key of carouselKeys) {
|
|
11731
|
+
nodes.push({ key, type: "carousel", text: JSON.stringify(readCarouselValue(key)) });
|
|
11674
11732
|
}
|
|
11675
11733
|
const byKey = /* @__PURE__ */ new Map();
|
|
11676
11734
|
for (const node of nodes) {
|
|
@@ -12302,7 +12360,16 @@ function syncNavigationDragCursorAttrs() {
|
|
|
12302
12360
|
el.setAttribute("data-ohw-can-drag", "");
|
|
12303
12361
|
});
|
|
12304
12362
|
}
|
|
12305
|
-
var AI_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
12363
|
+
var AI_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
12364
|
+
"image",
|
|
12365
|
+
"bg-image",
|
|
12366
|
+
"video",
|
|
12367
|
+
"link",
|
|
12368
|
+
"plain",
|
|
12369
|
+
"text/rich",
|
|
12370
|
+
"text",
|
|
12371
|
+
"carousel"
|
|
12372
|
+
]);
|
|
12306
12373
|
function normalizeAiNodeType(type) {
|
|
12307
12374
|
return AI_NODE_TYPES.has(type) ? type : "text";
|
|
12308
12375
|
}
|
|
@@ -16127,6 +16194,24 @@ function OhhwellsBridge() {
|
|
|
16127
16194
|
appliedEl?.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
16128
16195
|
};
|
|
16129
16196
|
window.addEventListener("message", handleAiApplyTree);
|
|
16197
|
+
const handleAiDeleteSection = (e) => {
|
|
16198
|
+
if (e.data?.type !== "ow:ai-delete-section") return;
|
|
16199
|
+
const sectionId = typeof e.data.sectionId === "string" ? e.data.sectionId : "";
|
|
16200
|
+
if (!sectionId || sectionId === "navbar" || sectionId === "footer") return;
|
|
16201
|
+
const exists = document.querySelector(`[data-ohw-section="${CSS.escape(sectionId)}"]`);
|
|
16202
|
+
if (!exists) return;
|
|
16203
|
+
const previous = aiSectionsRef.current;
|
|
16204
|
+
const nextState = deleteSectionFromState(parseAiSectionsState(previous), sectionId);
|
|
16205
|
+
const nextValue = serializeAiSectionsState(nextState);
|
|
16206
|
+
aiSectionsRef.current = nextValue;
|
|
16207
|
+
applyAiSectionsToDom(nextState);
|
|
16208
|
+
const newHeight = document.documentElement.scrollHeight;
|
|
16209
|
+
if (newHeight > 50) postToParentRef.current({ type: "ow:height", height: newHeight });
|
|
16210
|
+
postToParentRef.current({ type: "ow:change", nodes: [{ key: AI_SECTIONS_KEY, text: nextValue }] });
|
|
16211
|
+
postToParentRef.current({ type: "ow:ai-section-deleted", sectionId, previous, value: nextValue });
|
|
16212
|
+
postAiSectionsChanged();
|
|
16213
|
+
};
|
|
16214
|
+
window.addEventListener("message", handleAiDeleteSection);
|
|
16130
16215
|
const handleAiSetSections = (e) => {
|
|
16131
16216
|
if (e.data?.type !== "ow:ai-set-sections") return;
|
|
16132
16217
|
const value = typeof e.data.value === "string" ? e.data.value : "";
|
|
@@ -16449,7 +16534,7 @@ function OhhwellsBridge() {
|
|
|
16449
16534
|
`[data-ohw-section="${CSS.escape(sectionId)}"]`
|
|
16450
16535
|
);
|
|
16451
16536
|
const nodes = sectionEl ? collectEditableNodes(void 0, sectionEl).filter(
|
|
16452
|
-
(n) => n.key && !n.key.startsWith("__ohw_") && !["meta", "sections", "
|
|
16537
|
+
(n) => n.key && !n.key.startsWith("__ohw_") && !["meta", "sections", "video-setting"].includes(n.type)
|
|
16453
16538
|
).map((n) => ({ ...n, text: n.text ?? "", type: normalizeAiNodeType(n.type) })) : [];
|
|
16454
16539
|
const box = sectionEl?.getBoundingClientRect();
|
|
16455
16540
|
const rect = box ? {
|
|
@@ -16776,6 +16861,7 @@ function OhhwellsBridge() {
|
|
|
16776
16861
|
window.removeEventListener("message", handleViewMode);
|
|
16777
16862
|
window.removeEventListener("message", handleHydrate);
|
|
16778
16863
|
window.removeEventListener("message", handleAiApplyTree);
|
|
16864
|
+
window.removeEventListener("message", handleAiDeleteSection);
|
|
16779
16865
|
window.removeEventListener("message", handleAiSetSections);
|
|
16780
16866
|
window.removeEventListener("message", handleDeactivate);
|
|
16781
16867
|
window.removeEventListener("message", handleToastAction);
|
|
@@ -16980,7 +17066,7 @@ function OhhwellsBridge() {
|
|
|
16980
17066
|
postToParent2({
|
|
16981
17067
|
type: "ow:ready",
|
|
16982
17068
|
version: "1",
|
|
16983
|
-
bridgeVersion: "0.1.
|
|
17069
|
+
bridgeVersion: "0.1.54",
|
|
16984
17070
|
path: pathname,
|
|
16985
17071
|
nodes: collectEditableNodes(editContentRef.current),
|
|
16986
17072
|
sections
|