@ohhwells/bridge 0.1.158 → 0.1.160
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 +203 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +58 -1
- package/dist/index.d.ts +58 -1
- package/dist/index.js +203 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -220,6 +220,56 @@ function isRenderableTree(value) {
|
|
|
220
220
|
return AI_TREE_SCHEMA_VERSIONS.includes(tree.schemaVersion) && tree.type === "section" && Array.isArray(tree.rows);
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
+
// src/lib/headline-size.ts
|
|
224
|
+
var HEADLINE_SIZE_MULTIPLIERS = {
|
|
225
|
+
xs: 0.7,
|
|
226
|
+
sm: 0.85,
|
|
227
|
+
base: 1,
|
|
228
|
+
lg: 1.2,
|
|
229
|
+
xl: 1.45,
|
|
230
|
+
"2xl": 1.75
|
|
231
|
+
};
|
|
232
|
+
var HEADLINE_SIZE_ATTR = "data-ohw-style-headlinesize";
|
|
233
|
+
var PREV_ATTR = "data-ohw-style-prev-fsmul";
|
|
234
|
+
var NODE_FONT_SIZE_ATTR = "data-ohw-style-prev-font-size";
|
|
235
|
+
function headingsIn(section) {
|
|
236
|
+
return Array.from(section.querySelectorAll("h1, h2, h3"));
|
|
237
|
+
}
|
|
238
|
+
function clearHeadlineSizes(root = document) {
|
|
239
|
+
for (const el of Array.from(root.querySelectorAll(`[${PREV_ATTR}]`))) {
|
|
240
|
+
const prev = el.getAttribute(PREV_ATTR) ?? "";
|
|
241
|
+
if (prev) el.style.setProperty("font-size", prev);
|
|
242
|
+
else el.style.removeProperty("font-size");
|
|
243
|
+
el.removeAttribute(PREV_ATTR);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
function applyHeadlineSizes(root = document) {
|
|
247
|
+
clearHeadlineSizes(root);
|
|
248
|
+
for (const section of Array.from(
|
|
249
|
+
root.querySelectorAll(`[${HEADLINE_SIZE_ATTR}]`)
|
|
250
|
+
)) {
|
|
251
|
+
const multiplier = HEADLINE_SIZE_MULTIPLIERS[section.getAttribute(HEADLINE_SIZE_ATTR) ?? ""];
|
|
252
|
+
if (!multiplier || multiplier === 1) continue;
|
|
253
|
+
for (const heading of headingsIn(section)) {
|
|
254
|
+
if (heading.hasAttribute(NODE_FONT_SIZE_ATTR)) continue;
|
|
255
|
+
const base = Number.parseFloat(window.getComputedStyle(heading).fontSize);
|
|
256
|
+
if (!Number.isFinite(base) || base <= 0) continue;
|
|
257
|
+
heading.setAttribute(PREV_ATTR, heading.style.getPropertyValue("font-size"));
|
|
258
|
+
heading.style.setProperty("font-size", `${Math.round(base * multiplier * 100) / 100}px`, "important");
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
var resizeInstalled = false;
|
|
263
|
+
function installHeadlineSizeResize() {
|
|
264
|
+
if (resizeInstalled || typeof window === "undefined") return;
|
|
265
|
+
resizeInstalled = true;
|
|
266
|
+
let timer;
|
|
267
|
+
window.addEventListener("resize", () => {
|
|
268
|
+
if (timer) clearTimeout(timer);
|
|
269
|
+
timer = setTimeout(() => applyHeadlineSizes(), 120);
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
|
|
223
273
|
// src/lib/sections.ts
|
|
224
274
|
var LINK_PICKER_EXCLUDED_IDS = /* @__PURE__ */ new Set(["navbar", "footer"]);
|
|
225
275
|
function isChromeSection(el) {
|
|
@@ -6011,6 +6061,7 @@ var SECTION_ATTRS = {
|
|
|
6011
6061
|
sectionBackground: "data-ohw-style-bg",
|
|
6012
6062
|
textDistribution: "data-ohw-style-distribution",
|
|
6013
6063
|
headlineScale: "data-ohw-style-headline",
|
|
6064
|
+
headlineSize: HEADLINE_SIZE_ATTR,
|
|
6014
6065
|
imageAspect: "data-ohw-style-aspect",
|
|
6015
6066
|
spacing: "data-ohw-style-spacing",
|
|
6016
6067
|
verticalPadding: "data-ohw-style-vpadding",
|
|
@@ -6079,6 +6130,15 @@ function clearSectionAttrs(root) {
|
|
|
6079
6130
|
}
|
|
6080
6131
|
}
|
|
6081
6132
|
var ITEM_WROTE_ATTR = "data-ohw-style-item";
|
|
6133
|
+
function paintIcon(slot, color) {
|
|
6134
|
+
for (const el of [slot, ...Array.from(slot.querySelectorAll("svg, svg *"))]) {
|
|
6135
|
+
const styled = el;
|
|
6136
|
+
if (!styled.style) continue;
|
|
6137
|
+
saveInline(styled, "color");
|
|
6138
|
+
styled.style.setProperty("color", color, "important");
|
|
6139
|
+
styled.setAttribute(NODE_WROTE_ATTR, "");
|
|
6140
|
+
}
|
|
6141
|
+
}
|
|
6082
6142
|
function clearNodeProps(root) {
|
|
6083
6143
|
for (const el of Array.from(root.querySelectorAll(`[${NODE_WROTE_ATTR}]`))) {
|
|
6084
6144
|
const h = el;
|
|
@@ -6116,6 +6176,7 @@ function applyStylesToDom(store) {
|
|
|
6116
6176
|
ensureStyleSheet();
|
|
6117
6177
|
clearSectionAttrs(document);
|
|
6118
6178
|
clearNodeProps(document);
|
|
6179
|
+
clearHeadlineSizes(document);
|
|
6119
6180
|
loadStyleFonts(
|
|
6120
6181
|
store ? [
|
|
6121
6182
|
...Object.values(store.nodes).flatMap((n) => n.fontFamily ? [n.fontFamily] : []),
|
|
@@ -6189,9 +6250,13 @@ function applyStylesToDom(store) {
|
|
|
6189
6250
|
const nodes = document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`);
|
|
6190
6251
|
for (const el of Array.from(nodes)) {
|
|
6191
6252
|
if (override.color !== void 0) {
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
|
|
6253
|
+
if (el.dataset.ohwEditable === "icon") {
|
|
6254
|
+
paintIcon(el, override.color);
|
|
6255
|
+
} else {
|
|
6256
|
+
saveInline(el, "color");
|
|
6257
|
+
el.style.setProperty("color", override.color, "important");
|
|
6258
|
+
el.setAttribute(NODE_WROTE_ATTR, "");
|
|
6259
|
+
}
|
|
6195
6260
|
}
|
|
6196
6261
|
if (override.fontFamily !== void 0) {
|
|
6197
6262
|
saveInline(el, "font-family");
|
|
@@ -6248,6 +6313,18 @@ function applyStylesToDom(store) {
|
|
|
6248
6313
|
}
|
|
6249
6314
|
}
|
|
6250
6315
|
}
|
|
6316
|
+
for (const [sectionId, override] of Object.entries(store.sections)) {
|
|
6317
|
+
if (override.iconColor === void 0) continue;
|
|
6318
|
+
const escaped = CSS.escape(sectionId);
|
|
6319
|
+
const byInstance = document.querySelectorAll(`[data-ohw-instance="${escaped}"]`);
|
|
6320
|
+
const sections = byInstance.length ? byInstance : document.querySelectorAll(`[data-ohw-section="${escaped}"]`);
|
|
6321
|
+
for (const marker of Array.from(sections)) {
|
|
6322
|
+
const icons = marker.querySelectorAll('[data-ohw-editable="icon"]');
|
|
6323
|
+
for (const el of Array.from(icons)) paintIcon(el, override.iconColor);
|
|
6324
|
+
}
|
|
6325
|
+
}
|
|
6326
|
+
applyHeadlineSizes(document);
|
|
6327
|
+
installHeadlineSizeResize();
|
|
6251
6328
|
}
|
|
6252
6329
|
|
|
6253
6330
|
// src/lib/ai-sections-store.ts
|
|
@@ -6287,17 +6364,21 @@ function resolveSectionTree(sectionId, aiSectionsRaw) {
|
|
|
6287
6364
|
return parseAiSectionsState(aiSectionsRaw).sections.find((entry) => entry.id === sectionId)?.tree;
|
|
6288
6365
|
}
|
|
6289
6366
|
function resolveSectionSettingsContext(sectionId, aiSectionsRaw, stylesRaw) {
|
|
6367
|
+
const styleOverride = parseStyleStore(stylesRaw)?.sections[sectionId];
|
|
6368
|
+
const headlineSize = styleOverride?.headlineSize;
|
|
6290
6369
|
const genSettings = parseAiSectionsState(aiSectionsRaw).sections.find(
|
|
6291
6370
|
(entry) => entry.id === sectionId
|
|
6292
6371
|
)?.tree.settings;
|
|
6293
|
-
if (genSettings)
|
|
6294
|
-
|
|
6295
|
-
|
|
6372
|
+
if (genSettings) {
|
|
6373
|
+
return { ...genSettings, ...headlineSize ? { headlineSize } : {} };
|
|
6374
|
+
}
|
|
6375
|
+
if (!styleOverride?.verticalPadding && !styleOverride?.minHeight && !styleOverride?.spacing && !headlineSize) {
|
|
6296
6376
|
return void 0;
|
|
6297
6377
|
}
|
|
6298
6378
|
return {
|
|
6299
|
-
verticalPadding: styleOverride
|
|
6300
|
-
minHeight: styleOverride
|
|
6379
|
+
verticalPadding: styleOverride?.verticalPadding ?? legacyVerticalPaddingAlias(styleOverride?.spacing),
|
|
6380
|
+
minHeight: styleOverride?.minHeight,
|
|
6381
|
+
...headlineSize ? { headlineSize } : {}
|
|
6301
6382
|
};
|
|
6302
6383
|
}
|
|
6303
6384
|
function applyTreeToState(state, payload) {
|
|
@@ -7302,6 +7383,23 @@ function applyCustomCodeToHead(content) {
|
|
|
7302
7383
|
if (beforeNodes.length > 0) document.head.append(...beforeNodes);
|
|
7303
7384
|
}
|
|
7304
7385
|
|
|
7386
|
+
// src/lib/node-font-size.ts
|
|
7387
|
+
var TEXT_NODE_TYPES = /* @__PURE__ */ new Set(["text", "text/rich", "plain", "link"]);
|
|
7388
|
+
function escapeKey(key) {
|
|
7389
|
+
return typeof CSS !== "undefined" && typeof CSS.escape === "function" ? CSS.escape(key) : key.replace(/["\\]/g, "\\$&");
|
|
7390
|
+
}
|
|
7391
|
+
function measureNodeFontSize(key, type, root) {
|
|
7392
|
+
if (!TEXT_NODE_TYPES.has(type)) return void 0;
|
|
7393
|
+
const el = root.querySelector(`[data-ohw-editable][data-ohw-key="${escapeKey(key)}"]`);
|
|
7394
|
+
if (!el) return void 0;
|
|
7395
|
+
const size = Number.parseFloat(window.getComputedStyle(el).fontSize);
|
|
7396
|
+
return Number.isFinite(size) && size > 0 ? Math.round(size) : void 0;
|
|
7397
|
+
}
|
|
7398
|
+
function withNodeFontSize(node, root) {
|
|
7399
|
+
const fontSize = measureNodeFontSize(node.key, node.type, root);
|
|
7400
|
+
return fontSize === void 0 ? node : { ...node, fontSize };
|
|
7401
|
+
}
|
|
7402
|
+
|
|
7305
7403
|
// src/lib/selectNavContainer.ts
|
|
7306
7404
|
function isOnScreen(el) {
|
|
7307
7405
|
const rect = el.getBoundingClientRect();
|
|
@@ -17241,7 +17339,7 @@ function apiBase() {
|
|
|
17241
17339
|
function bridgeVersion() {
|
|
17242
17340
|
try {
|
|
17243
17341
|
if (true) {
|
|
17244
|
-
return "0.1.
|
|
17342
|
+
return "0.1.160";
|
|
17245
17343
|
}
|
|
17246
17344
|
} catch {
|
|
17247
17345
|
}
|
|
@@ -17255,7 +17353,7 @@ function stampBridgeVersionOnDocument() {
|
|
|
17255
17353
|
return;
|
|
17256
17354
|
}
|
|
17257
17355
|
try {
|
|
17258
|
-
const v = true ? "0.1.
|
|
17356
|
+
const v = true ? "0.1.160" : "";
|
|
17259
17357
|
if (v) {
|
|
17260
17358
|
document.documentElement.setAttribute("data-ohw-bridge-version", v);
|
|
17261
17359
|
window.__OHW_BRIDGE_VERSION__ = v;
|
|
@@ -18164,6 +18262,89 @@ function CarouselOverlay({
|
|
|
18164
18262
|
// src/ui/ai-section/AiSectionOverlay.tsx
|
|
18165
18263
|
var import_react9 = require("react");
|
|
18166
18264
|
var import_lucide_react7 = require("lucide-react");
|
|
18265
|
+
|
|
18266
|
+
// src/lib/ai-change-highlight.ts
|
|
18267
|
+
var STYLE_ID = "ohw-ai-changed-style";
|
|
18268
|
+
var MARK_ATTR = "data-ohw-ai-changed";
|
|
18269
|
+
var HIGHLIGHT_MS = 2200;
|
|
18270
|
+
var HIGHLIGHT_CSS = `
|
|
18271
|
+
@keyframes ohw-ai-changed-pulse {
|
|
18272
|
+
0% { outline-color: rgba(0, 120, 229, 0.95); box-shadow: 0 0 0 5px rgba(0, 120, 229, 0.20); }
|
|
18273
|
+
72% { outline-color: rgba(0, 120, 229, 0.95); box-shadow: 0 0 0 5px rgba(0, 120, 229, 0.12); }
|
|
18274
|
+
100% { outline-color: rgba(0, 120, 229, 0); box-shadow: 0 0 0 5px rgba(0, 120, 229, 0); }
|
|
18275
|
+
}
|
|
18276
|
+
[${MARK_ATTR}] {
|
|
18277
|
+
outline: 2px solid rgba(0, 120, 229, 0.95) !important;
|
|
18278
|
+
outline-offset: 3px !important;
|
|
18279
|
+
animation: ohw-ai-changed-pulse ${HIGHLIGHT_MS}ms ease-out forwards !important;
|
|
18280
|
+
}
|
|
18281
|
+
@media (prefers-reduced-motion: reduce) {
|
|
18282
|
+
[${MARK_ATTR}] { animation: none !important; }
|
|
18283
|
+
}
|
|
18284
|
+
`;
|
|
18285
|
+
function ensureStyleSheet2() {
|
|
18286
|
+
if (document.getElementById(STYLE_ID)) return;
|
|
18287
|
+
const el = document.createElement("style");
|
|
18288
|
+
el.id = STYLE_ID;
|
|
18289
|
+
el.textContent = HIGHLIGHT_CSS;
|
|
18290
|
+
document.head.appendChild(el);
|
|
18291
|
+
}
|
|
18292
|
+
function targetsFor(keys, item) {
|
|
18293
|
+
const out = /* @__PURE__ */ new Set();
|
|
18294
|
+
for (const key of keys) {
|
|
18295
|
+
if (!key) continue;
|
|
18296
|
+
for (const el of Array.from(
|
|
18297
|
+
document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`)
|
|
18298
|
+
)) {
|
|
18299
|
+
out.add(el);
|
|
18300
|
+
}
|
|
18301
|
+
}
|
|
18302
|
+
if (item) {
|
|
18303
|
+
const section = document.querySelector(`[data-ohw-instance="${CSS.escape(item.sectionId)}"]`) ?? document.querySelector(`[data-ohw-section="${CSS.escape(item.sectionId)}"]`);
|
|
18304
|
+
const stamp = `${item.group}:${item.index}`;
|
|
18305
|
+
const el = section?.querySelector(`[data-ohw-item="${CSS.escape(stamp)}"]`);
|
|
18306
|
+
if (el) out.add(el);
|
|
18307
|
+
}
|
|
18308
|
+
return [...out];
|
|
18309
|
+
}
|
|
18310
|
+
var clearTimer = null;
|
|
18311
|
+
function clearChangeHighlight() {
|
|
18312
|
+
if (clearTimer !== null) {
|
|
18313
|
+
clearTimeout(clearTimer);
|
|
18314
|
+
clearTimer = null;
|
|
18315
|
+
}
|
|
18316
|
+
for (const el of Array.from(document.querySelectorAll(`[${MARK_ATTR}]`))) {
|
|
18317
|
+
el.removeAttribute(MARK_ATTR);
|
|
18318
|
+
}
|
|
18319
|
+
}
|
|
18320
|
+
function highlightChangedElements(keys, item) {
|
|
18321
|
+
clearChangeHighlight();
|
|
18322
|
+
const targets = targetsFor(keys, item);
|
|
18323
|
+
if (targets.length === 0) return 0;
|
|
18324
|
+
ensureStyleSheet2();
|
|
18325
|
+
for (const el of targets) el.setAttribute(MARK_ATTR, "");
|
|
18326
|
+
const rect = targets[0].getBoundingClientRect();
|
|
18327
|
+
if (rect.bottom < 0 || rect.top > window.innerHeight) {
|
|
18328
|
+
targets[0].scrollIntoView({ behavior: "smooth", block: "center" });
|
|
18329
|
+
}
|
|
18330
|
+
clearTimer = setTimeout(clearChangeHighlight, HIGHLIGHT_MS);
|
|
18331
|
+
return targets.length;
|
|
18332
|
+
}
|
|
18333
|
+
function installAiChangeHighlight() {
|
|
18334
|
+
const onMessage = (e) => {
|
|
18335
|
+
const data = e.data;
|
|
18336
|
+
if (data?.type !== "ow:ai-highlight") return;
|
|
18337
|
+
const keys = Array.isArray(data.keys) ? data.keys.filter((k) => typeof k === "string") : [];
|
|
18338
|
+
const raw = data.item;
|
|
18339
|
+
const item = raw && typeof raw.sectionId === "string" && typeof raw.group === "string" && typeof raw.index === "number" ? { sectionId: raw.sectionId, group: raw.group, index: raw.index } : void 0;
|
|
18340
|
+
const found = highlightChangedElements(keys, item);
|
|
18341
|
+
window.parent?.postMessage({ type: "ow:ai-highlight-done", found }, "*");
|
|
18342
|
+
};
|
|
18343
|
+
window.addEventListener("message", onMessage);
|
|
18344
|
+
return () => window.removeEventListener("message", onMessage);
|
|
18345
|
+
}
|
|
18346
|
+
|
|
18347
|
+
// src/ui/ai-section/AiSectionOverlay.tsx
|
|
18167
18348
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
18168
18349
|
var findSectionElement = findByInstanceId;
|
|
18169
18350
|
function readRect(instanceId) {
|
|
@@ -18415,6 +18596,7 @@ function AiSectionOverlay({
|
|
|
18415
18596
|
window.addEventListener("message", onMessage);
|
|
18416
18597
|
return () => window.removeEventListener("message", onMessage);
|
|
18417
18598
|
}, [postToParent2]);
|
|
18599
|
+
(0, import_react9.useEffect)(() => installAiChangeHighlight(), []);
|
|
18418
18600
|
const [hoveredId, setHoveredId] = (0, import_react9.useState)(null);
|
|
18419
18601
|
(0, import_react9.useEffect)(() => {
|
|
18420
18602
|
const onMove = (e) => {
|
|
@@ -31328,13 +31510,15 @@ function OhhwellsBridge() {
|
|
|
31328
31510
|
if (e.data?.type !== "ow:collect-section") return;
|
|
31329
31511
|
const sectionId = e.data.sectionId;
|
|
31330
31512
|
if (typeof sectionId !== "string" || !sectionId) return;
|
|
31331
|
-
const
|
|
31332
|
-
|
|
31513
|
+
const escapedSectionId = CSS.escape(sectionId);
|
|
31514
|
+
const instanceEl = document.querySelector(
|
|
31515
|
+
`[data-ohw-instance="${escapedSectionId}"]`
|
|
31333
31516
|
);
|
|
31517
|
+
const foundEl = instanceEl ? sectionElementOf(instanceEl) : document.querySelector(`[data-ohw-section="${escapedSectionId}"]`);
|
|
31334
31518
|
const sectionEl = foundEl && !foundEl.hasAttribute("data-ohw-ai-template-hidden") && !foundEl.hasAttribute("data-ohw-ai-removed") && !foundEl.hasAttribute("data-ohw-ai-replaced-by") ? foundEl : null;
|
|
31335
31519
|
const nodes = sectionEl ? collectEditableNodes(void 0, sectionEl).filter(
|
|
31336
31520
|
(n) => n.key && !n.key.startsWith("__ohw_") && !["meta", "sections", "video-setting"].includes(n.type)
|
|
31337
|
-
).map((n) => ({ ...n, text: n.text ?? "", type: normalizeAiNodeType(n.type) })) : [];
|
|
31521
|
+
).map((n) => ({ ...n, text: n.text ?? "", type: normalizeAiNodeType(n.type) })).map((n) => withNodeFontSize(n, sectionEl)) : [];
|
|
31338
31522
|
const items = sectionEl ? collectItemGroups(sectionEl) : [];
|
|
31339
31523
|
const box = sectionEl?.getBoundingClientRect();
|
|
31340
31524
|
const rect = box ? {
|
|
@@ -31343,7 +31527,11 @@ function OhhwellsBridge() {
|
|
|
31343
31527
|
width: box.width,
|
|
31344
31528
|
height: box.height
|
|
31345
31529
|
} : null;
|
|
31346
|
-
const settings = resolveSectionSettingsContext(
|
|
31530
|
+
const settings = resolveSectionSettingsContext(
|
|
31531
|
+
sectionId,
|
|
31532
|
+
aiSectionsRef.current,
|
|
31533
|
+
stylesRef.current
|
|
31534
|
+
);
|
|
31347
31535
|
const tree = resolveSectionTree(sectionId, aiSectionsRef.current);
|
|
31348
31536
|
postToParentRef.current({
|
|
31349
31537
|
type: "ow:section-nodes",
|
|
@@ -32074,7 +32262,7 @@ function OhhwellsBridge() {
|
|
|
32074
32262
|
postToParent2({
|
|
32075
32263
|
type: "ow:ready",
|
|
32076
32264
|
version: "1",
|
|
32077
|
-
bridgeVersion: "0.1.
|
|
32265
|
+
bridgeVersion: "0.1.160",
|
|
32078
32266
|
path: pathname,
|
|
32079
32267
|
nodes: collectEditableNodes(editContentRef.current),
|
|
32080
32268
|
sections
|