@parhelia/editor-bridge-head 0.1.12875
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/README.md +22 -0
- package/dist/host/v1/parhelia-bridge.js +2699 -0
- package/dist/host/v1/parhelia-stub.js +185 -0
- package/dist/index.d.ts +510 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +189 -0
- package/package.json +40 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
(() => {
|
|
3
|
+
// src/host/origin.ts
|
|
4
|
+
var PARENT_ORIGIN_STORAGE_KEY = "parhelia:parentOrigin";
|
|
5
|
+
function normalizeOrigin(origin) {
|
|
6
|
+
try {
|
|
7
|
+
return new URL(origin).origin;
|
|
8
|
+
} catch (error) {
|
|
9
|
+
return void 0;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function normalizeOrigins(origins) {
|
|
13
|
+
return origins.map(function(origin) {
|
|
14
|
+
return normalizeOrigin(origin);
|
|
15
|
+
}).filter(Boolean);
|
|
16
|
+
}
|
|
17
|
+
function rememberParentOrigin(origin) {
|
|
18
|
+
if (!origin) return;
|
|
19
|
+
try {
|
|
20
|
+
sessionStorage.setItem(PARENT_ORIGIN_STORAGE_KEY, origin);
|
|
21
|
+
} catch (error) {
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function readRememberedParentOrigin() {
|
|
25
|
+
try {
|
|
26
|
+
return normalizeOrigin(sessionStorage.getItem(PARENT_ORIGIN_STORAGE_KEY));
|
|
27
|
+
} catch (error) {
|
|
28
|
+
return void 0;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function resolveParentOrigin(config) {
|
|
32
|
+
config = config || {};
|
|
33
|
+
if (config.parentOrigin || config.editorOrigin) {
|
|
34
|
+
var configuredOrigin = normalizeOrigin(
|
|
35
|
+
config.parentOrigin || config.editorOrigin
|
|
36
|
+
);
|
|
37
|
+
rememberParentOrigin(configuredOrigin);
|
|
38
|
+
return configuredOrigin;
|
|
39
|
+
}
|
|
40
|
+
var referrerOrigin = document.referrer ? normalizeOrigin(document.referrer) : void 0;
|
|
41
|
+
if (referrerOrigin && referrerOrigin !== location.origin) {
|
|
42
|
+
rememberParentOrigin(referrerOrigin);
|
|
43
|
+
return referrerOrigin;
|
|
44
|
+
}
|
|
45
|
+
var rememberedOrigin = readRememberedParentOrigin();
|
|
46
|
+
if (rememberedOrigin) return rememberedOrigin;
|
|
47
|
+
if (referrerOrigin) {
|
|
48
|
+
rememberParentOrigin(referrerOrigin);
|
|
49
|
+
return referrerOrigin;
|
|
50
|
+
}
|
|
51
|
+
return void 0;
|
|
52
|
+
}
|
|
53
|
+
function resolveAllowedParentOrigins(config) {
|
|
54
|
+
config = config || {};
|
|
55
|
+
var parentOrigin = resolveParentOrigin(config);
|
|
56
|
+
var allowedParentOrigins = normalizeOrigins(
|
|
57
|
+
config.allowedParentOrigins || config.parentOrigins || [parentOrigin]
|
|
58
|
+
);
|
|
59
|
+
return {
|
|
60
|
+
parentOrigin,
|
|
61
|
+
allowedParentOrigins
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// src/index.ts
|
|
66
|
+
var PARHELIA_EDITING_BRIDGE_FAMILY = "parhelia/editing-bridge";
|
|
67
|
+
|
|
68
|
+
// src/host/stub-core.ts
|
|
69
|
+
var FAMILY = PARHELIA_EDITING_BRIDGE_FAMILY;
|
|
70
|
+
function readHelloBridgeUrl(data) {
|
|
71
|
+
if (!data || typeof data !== "object" || data.family !== FAMILY || data.direction !== "parent-to-host" || data.name !== "hello") {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
var url = data.payload && data.payload.bridgeUrl;
|
|
75
|
+
return typeof url === "string" && url ? url : null;
|
|
76
|
+
}
|
|
77
|
+
function isHonorableBridgeUrl(url, allowedParentOrigins, selfOrigin) {
|
|
78
|
+
if (!url) return false;
|
|
79
|
+
var origin;
|
|
80
|
+
try {
|
|
81
|
+
origin = new URL(url, selfOrigin).origin;
|
|
82
|
+
} catch (error) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
return !!allowedParentOrigins && allowedParentOrigins.indexOf(origin) >= 0 || origin === selfOrigin;
|
|
86
|
+
}
|
|
87
|
+
function resolveSameOriginBridgeUrl(config, selfScriptSrc) {
|
|
88
|
+
if (config && config.bridgeUrl) return config.bridgeUrl;
|
|
89
|
+
if (selfScriptSrc) {
|
|
90
|
+
try {
|
|
91
|
+
return new URL("parhelia-bridge.js", selfScriptSrc).toString();
|
|
92
|
+
} catch (error) {
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
function isBridgeBooted(win) {
|
|
98
|
+
return !!(win && win.__PARHELIA_EDITING_BRIDGE_RUNTIME__);
|
|
99
|
+
}
|
|
100
|
+
function createBootloader(options) {
|
|
101
|
+
var win = options.win;
|
|
102
|
+
var doc = options.doc;
|
|
103
|
+
var allowedParentOrigins = options.allowedParentOrigins || [];
|
|
104
|
+
var selfOrigin = options.selfOrigin;
|
|
105
|
+
var sameOriginBridgeUrl = options.sameOriginBridgeUrl || null;
|
|
106
|
+
var fallbackMs = options.fallbackMs != null ? options.fallbackMs : 1500;
|
|
107
|
+
var watchdogMs = options.watchdogMs != null ? options.watchdogMs : 1200;
|
|
108
|
+
var booted = false;
|
|
109
|
+
var attempted = {};
|
|
110
|
+
function bootConfirmed() {
|
|
111
|
+
if (booted) return true;
|
|
112
|
+
if (isBridgeBooted(win)) {
|
|
113
|
+
booted = true;
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
function loadFallback() {
|
|
119
|
+
if (!bootConfirmed()) tryLoad(sameOriginBridgeUrl, null);
|
|
120
|
+
}
|
|
121
|
+
function tryLoad(url, onFail) {
|
|
122
|
+
if (bootConfirmed() || !url || attempted[url]) {
|
|
123
|
+
if (onFail) onFail();
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
attempted[url] = true;
|
|
127
|
+
var script = doc.createElement("script");
|
|
128
|
+
script.src = url;
|
|
129
|
+
script.async = false;
|
|
130
|
+
script.onload = function() {
|
|
131
|
+
if (!bootConfirmed() && onFail) onFail();
|
|
132
|
+
};
|
|
133
|
+
script.onerror = function() {
|
|
134
|
+
if (onFail) onFail();
|
|
135
|
+
};
|
|
136
|
+
(doc.head || doc.documentElement).appendChild(script);
|
|
137
|
+
win.setTimeout(function() {
|
|
138
|
+
if (!bootConfirmed() && onFail) onFail();
|
|
139
|
+
}, watchdogMs);
|
|
140
|
+
}
|
|
141
|
+
function honor(url) {
|
|
142
|
+
if (isHonorableBridgeUrl(url, allowedParentOrigins, selfOrigin)) {
|
|
143
|
+
tryLoad(url, loadFallback);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function handleMessage(event) {
|
|
147
|
+
if (allowedParentOrigins.indexOf(event.origin) < 0) return;
|
|
148
|
+
var url = readHelloBridgeUrl(event.data);
|
|
149
|
+
if (url) honor(url);
|
|
150
|
+
}
|
|
151
|
+
function start() {
|
|
152
|
+
win.addEventListener("message", handleMessage);
|
|
153
|
+
win.setTimeout(loadFallback, fallbackMs);
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
start,
|
|
157
|
+
handleMessage,
|
|
158
|
+
honor,
|
|
159
|
+
loadFallback
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// src/host/parhelia-stub.ts
|
|
164
|
+
(function() {
|
|
165
|
+
"use strict";
|
|
166
|
+
var parentWindow = window.parent;
|
|
167
|
+
if (!parentWindow || parentWindow === window) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
var config = window.__PARHELIA_EDITING_BRIDGE__ || {};
|
|
171
|
+
var resolved = resolveAllowedParentOrigins(config);
|
|
172
|
+
if (!resolved.parentOrigin || resolved.allowedParentOrigins.indexOf(resolved.parentOrigin) < 0) {
|
|
173
|
+
console.warn("[Parhelia bridge] Missing or rejected parent origin.");
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
var selfScript = document.currentScript && document.currentScript.src || void 0;
|
|
177
|
+
createBootloader({
|
|
178
|
+
win: window,
|
|
179
|
+
doc: document,
|
|
180
|
+
allowedParentOrigins: resolved.allowedParentOrigins,
|
|
181
|
+
selfOrigin: location.origin,
|
|
182
|
+
sameOriginBridgeUrl: resolveSameOriginBridgeUrl(config, selfScript)
|
|
183
|
+
}).start();
|
|
184
|
+
})();
|
|
185
|
+
})();
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
export declare const PARHELIA_EDITING_BRIDGE_FAMILY: "parhelia/editing-bridge";
|
|
2
|
+
export type BridgeFamily = typeof PARHELIA_EDITING_BRIDGE_FAMILY;
|
|
3
|
+
export declare const PARHELIA_EDITOR_BRIDGE_HEAD_STUB_PATH = "/parhelia/editor-bridge/v1/parhelia-stub.js";
|
|
4
|
+
export declare const PARHELIA_EDITOR_BRIDGE_HEAD_FALLBACK_BRIDGE_PATH = "/parhelia/editor-bridge/v1/parhelia-bridge.js";
|
|
5
|
+
export type ParheliaEditorBridgeHeadConfig = {
|
|
6
|
+
editorOrigin?: string;
|
|
7
|
+
parentOrigin?: string;
|
|
8
|
+
parentOrigins?: string[];
|
|
9
|
+
allowedParentOrigins?: string[];
|
|
10
|
+
bridgeUrl?: string;
|
|
11
|
+
mode?: string;
|
|
12
|
+
pageId?: string;
|
|
13
|
+
source?: string;
|
|
14
|
+
};
|
|
15
|
+
declare global {
|
|
16
|
+
interface Window {
|
|
17
|
+
__PARHELIA_EDITING_BRIDGE__?: ParheliaEditorBridgeHeadConfig;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Protocol version. `major` is the compatibility boundary — peers must share
|
|
22
|
+
* the same major to interoperate. `minor` is additive: a higher minor only
|
|
23
|
+
* adds optional, backwards-compatible messages/fields and is negotiated down to
|
|
24
|
+
* the lower of the two peers (see `negotiateMinor`).
|
|
25
|
+
*/
|
|
26
|
+
export type BridgeVersion = {
|
|
27
|
+
major: number;
|
|
28
|
+
minor: number;
|
|
29
|
+
};
|
|
30
|
+
export declare const PARHELIA_EDITING_BRIDGE_VERSION: BridgeVersion;
|
|
31
|
+
export type BridgeDirection = "parent-to-host" | "host-to-parent";
|
|
32
|
+
export type BridgeEnvelope<TName extends string = string, TPayload = unknown> = {
|
|
33
|
+
family: BridgeFamily;
|
|
34
|
+
version: BridgeVersion;
|
|
35
|
+
direction: BridgeDirection;
|
|
36
|
+
id: string;
|
|
37
|
+
name: TName;
|
|
38
|
+
timestamp: number;
|
|
39
|
+
requestId?: string;
|
|
40
|
+
payload: TPayload;
|
|
41
|
+
};
|
|
42
|
+
export type BridgeRect = {
|
|
43
|
+
x: number;
|
|
44
|
+
y: number;
|
|
45
|
+
width: number;
|
|
46
|
+
height: number;
|
|
47
|
+
top: number;
|
|
48
|
+
right: number;
|
|
49
|
+
bottom: number;
|
|
50
|
+
left: number;
|
|
51
|
+
};
|
|
52
|
+
export type BridgeViewport = {
|
|
53
|
+
width: number;
|
|
54
|
+
height: number;
|
|
55
|
+
};
|
|
56
|
+
export type BridgeScroll = {
|
|
57
|
+
x: number;
|
|
58
|
+
y: number;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Capabilities are an OPEN set of string names. The editor and host each
|
|
62
|
+
* advertise the names they support; the effective session set is the
|
|
63
|
+
* intersection (see `negotiateCapabilities`). Unknown names are ignored by
|
|
64
|
+
* older peers, so adding a capability is always a backwards-compatible (minor)
|
|
65
|
+
* change. `BRIDGE_CAPABILITIES` lists the well-known names for type-safe use.
|
|
66
|
+
*/
|
|
67
|
+
export declare const BRIDGE_CAPABILITIES: {
|
|
68
|
+
readonly structure: "structure";
|
|
69
|
+
readonly geometry: "geometry";
|
|
70
|
+
readonly selection: "selection";
|
|
71
|
+
readonly inlineEditing: "inlineEditing";
|
|
72
|
+
readonly richTextCommands: "richTextCommands";
|
|
73
|
+
readonly captureDom: "captureDom";
|
|
74
|
+
readonly refresh: "refresh";
|
|
75
|
+
readonly zoom: "zoom";
|
|
76
|
+
};
|
|
77
|
+
export type WellKnownBridgeCapability = (typeof BRIDGE_CAPABILITIES)[keyof typeof BRIDGE_CAPABILITIES];
|
|
78
|
+
export type BridgeCapability = WellKnownBridgeCapability | (string & {});
|
|
79
|
+
export type BridgeCapabilitySet = BridgeCapability[];
|
|
80
|
+
export type BridgeRuntimeSource = "alpaca" | "sxa" | "sitecore" | "internal" | (string & {});
|
|
81
|
+
/** Identifying metadata the host attaches to `ready` to aid debugging. */
|
|
82
|
+
export type BridgeRuntimeInfo = {
|
|
83
|
+
source?: BridgeRuntimeSource;
|
|
84
|
+
packageVersion?: string;
|
|
85
|
+
commit?: string;
|
|
86
|
+
builtAt?: string;
|
|
87
|
+
};
|
|
88
|
+
export type BridgeItemDescriptor = {
|
|
89
|
+
id: string;
|
|
90
|
+
language?: string;
|
|
91
|
+
version?: number;
|
|
92
|
+
name?: string;
|
|
93
|
+
displayName?: string;
|
|
94
|
+
path?: string;
|
|
95
|
+
database?: string;
|
|
96
|
+
};
|
|
97
|
+
export type SerializableRenderedItem = BridgeItemDescriptor & {
|
|
98
|
+
renderedFieldIds: string[];
|
|
99
|
+
};
|
|
100
|
+
export type SerializableField = {
|
|
101
|
+
elementKey: string;
|
|
102
|
+
fieldId: string;
|
|
103
|
+
item?: BridgeItemDescriptor;
|
|
104
|
+
componentId?: string;
|
|
105
|
+
textContent?: string;
|
|
106
|
+
isRichText?: boolean;
|
|
107
|
+
editable?: boolean;
|
|
108
|
+
};
|
|
109
|
+
export type SerializablePlaceholder = {
|
|
110
|
+
key: string;
|
|
111
|
+
name?: string;
|
|
112
|
+
elementKey?: string;
|
|
113
|
+
parentComponentId?: string;
|
|
114
|
+
componentIds: string[];
|
|
115
|
+
editable?: boolean;
|
|
116
|
+
};
|
|
117
|
+
export type SerializableComponent = {
|
|
118
|
+
id: string;
|
|
119
|
+
elementKey: string;
|
|
120
|
+
endElementKey?: string;
|
|
121
|
+
name?: string;
|
|
122
|
+
type?: string;
|
|
123
|
+
typeId?: string;
|
|
124
|
+
placeholderKey?: string;
|
|
125
|
+
parentComponentId?: string;
|
|
126
|
+
datasourceItem?: SerializableRenderedItem;
|
|
127
|
+
items: SerializableRenderedItem[];
|
|
128
|
+
placeholders: string[];
|
|
129
|
+
renderedDictionaryKeys: string[];
|
|
130
|
+
editorFields?: Record<string, {
|
|
131
|
+
addFields: string[];
|
|
132
|
+
removeFields: string[];
|
|
133
|
+
}>;
|
|
134
|
+
editable?: boolean;
|
|
135
|
+
visible?: boolean;
|
|
136
|
+
};
|
|
137
|
+
export type SerializablePageStructure = {
|
|
138
|
+
editRevision?: string;
|
|
139
|
+
pageId?: string;
|
|
140
|
+
url: string;
|
|
141
|
+
components: SerializableComponent[];
|
|
142
|
+
placeholders: SerializablePlaceholder[];
|
|
143
|
+
fields: SerializableField[];
|
|
144
|
+
};
|
|
145
|
+
export type SerializableComponentSkeleton = {
|
|
146
|
+
id: string;
|
|
147
|
+
name: string;
|
|
148
|
+
type: string;
|
|
149
|
+
typeId: string;
|
|
150
|
+
parametersTemplateId?: string;
|
|
151
|
+
parameters?: string;
|
|
152
|
+
items: SerializableRenderedItem[];
|
|
153
|
+
placeholders: SerializablePlaceholderSkeleton[];
|
|
154
|
+
datasourceItem?: SerializableRenderedItem;
|
|
155
|
+
isRemovedFromMasterLanguage?: boolean;
|
|
156
|
+
isInheritedFromMasterLanguage?: boolean;
|
|
157
|
+
visible?: boolean;
|
|
158
|
+
renderedDictionaryKeys: string[];
|
|
159
|
+
isShared?: boolean;
|
|
160
|
+
hasPersonalization?: boolean;
|
|
161
|
+
layoutId?: string;
|
|
162
|
+
isSharedLayout?: boolean;
|
|
163
|
+
editorFields: Record<string, {
|
|
164
|
+
addFields: string[];
|
|
165
|
+
removeFields: string[];
|
|
166
|
+
}>;
|
|
167
|
+
editable?: boolean;
|
|
168
|
+
};
|
|
169
|
+
export type SerializablePlaceholderSkeleton = {
|
|
170
|
+
name: string;
|
|
171
|
+
key: string;
|
|
172
|
+
description: string;
|
|
173
|
+
components: SerializableComponentSkeleton[];
|
|
174
|
+
editable?: boolean;
|
|
175
|
+
};
|
|
176
|
+
export type SerializablePageSkeleton = {
|
|
177
|
+
editRevision: string;
|
|
178
|
+
item: SerializableRenderedItem;
|
|
179
|
+
rootComponent: SerializableComponentSkeleton;
|
|
180
|
+
};
|
|
181
|
+
export type BridgeGeometryTargetKind = "component" | "placeholder" | "field" | "textRange" | "dropTarget";
|
|
182
|
+
export type BridgeGeometryTarget = {
|
|
183
|
+
kind: BridgeGeometryTargetKind;
|
|
184
|
+
key: string;
|
|
185
|
+
elementKey?: string;
|
|
186
|
+
componentId?: string;
|
|
187
|
+
placeholderKey?: string;
|
|
188
|
+
fieldId?: string;
|
|
189
|
+
item?: BridgeItemDescriptor;
|
|
190
|
+
orientation?: "horizontal" | "vertical";
|
|
191
|
+
description?: string;
|
|
192
|
+
rect: BridgeRect;
|
|
193
|
+
};
|
|
194
|
+
export type BridgeGeometrySnapshot = {
|
|
195
|
+
viewport: BridgeViewport;
|
|
196
|
+
scroll: BridgeScroll;
|
|
197
|
+
devicePixelRatio: number;
|
|
198
|
+
rectScale?: number;
|
|
199
|
+
scrollScale?: number;
|
|
200
|
+
targets: BridgeGeometryTarget[];
|
|
201
|
+
};
|
|
202
|
+
export type BridgeSelectionSnapshot = {
|
|
203
|
+
activeField?: {
|
|
204
|
+
elementKey: string;
|
|
205
|
+
fieldId: string;
|
|
206
|
+
item?: BridgeItemDescriptor;
|
|
207
|
+
isRichText?: boolean;
|
|
208
|
+
};
|
|
209
|
+
collapsed: boolean;
|
|
210
|
+
rect?: BridgeRect;
|
|
211
|
+
startOffset?: number;
|
|
212
|
+
endOffset?: number;
|
|
213
|
+
text?: string;
|
|
214
|
+
metadata?: Record<string, unknown>;
|
|
215
|
+
};
|
|
216
|
+
export type BridgeMediaTarget = {
|
|
217
|
+
elementKey: string;
|
|
218
|
+
tagName: "img" | "picture" | "source" | string;
|
|
219
|
+
variantName?: string;
|
|
220
|
+
};
|
|
221
|
+
export type ReadyEventPayload = {
|
|
222
|
+
version: BridgeVersion;
|
|
223
|
+
hostUrl: string;
|
|
224
|
+
pageId?: string;
|
|
225
|
+
mode?: string;
|
|
226
|
+
viewport: BridgeViewport;
|
|
227
|
+
scroll: BridgeScroll;
|
|
228
|
+
devicePixelRatio: number;
|
|
229
|
+
capabilities: BridgeCapabilitySet;
|
|
230
|
+
runtime?: BridgeRuntimeInfo;
|
|
231
|
+
};
|
|
232
|
+
export type StructureUpdatedEventPayload = {
|
|
233
|
+
structure: SerializablePageStructure;
|
|
234
|
+
};
|
|
235
|
+
export type PageSkeletonUpdatedEventPayload = {
|
|
236
|
+
pageSkeleton: SerializablePageSkeleton;
|
|
237
|
+
};
|
|
238
|
+
export type GeometryUpdatedEventPayload = {
|
|
239
|
+
geometry: BridgeGeometrySnapshot;
|
|
240
|
+
};
|
|
241
|
+
export type ScrollChangedEventPayload = {
|
|
242
|
+
scroll: BridgeScroll;
|
|
243
|
+
};
|
|
244
|
+
export type ResizeChangedEventPayload = {
|
|
245
|
+
viewport: BridgeViewport;
|
|
246
|
+
devicePixelRatio: number;
|
|
247
|
+
};
|
|
248
|
+
export type InteractionEventPayload = {
|
|
249
|
+
kind: "click" | "doubleClick" | "contextMenu" | "hover" | "dragIntent" | "keydown" | "wheel";
|
|
250
|
+
elementKey?: string;
|
|
251
|
+
componentId?: string;
|
|
252
|
+
fieldId?: string;
|
|
253
|
+
item?: BridgeItemDescriptor;
|
|
254
|
+
media?: BridgeMediaTarget;
|
|
255
|
+
placeholderKey?: string;
|
|
256
|
+
clientX?: number;
|
|
257
|
+
clientY?: number;
|
|
258
|
+
key?: string;
|
|
259
|
+
code?: string;
|
|
260
|
+
button?: number;
|
|
261
|
+
deltaX?: number;
|
|
262
|
+
deltaY?: number;
|
|
263
|
+
ctrlKey?: boolean;
|
|
264
|
+
shiftKey?: boolean;
|
|
265
|
+
altKey?: boolean;
|
|
266
|
+
metaKey?: boolean;
|
|
267
|
+
};
|
|
268
|
+
export type SelectionChangedEventPayload = {
|
|
269
|
+
selection: BridgeSelectionSnapshot;
|
|
270
|
+
};
|
|
271
|
+
export type FieldValueChangedEventPayload = {
|
|
272
|
+
elementKey: string;
|
|
273
|
+
fieldId: string;
|
|
274
|
+
item?: BridgeItemDescriptor;
|
|
275
|
+
value: string;
|
|
276
|
+
isRichText?: boolean;
|
|
277
|
+
};
|
|
278
|
+
export type InlineEditEndedEventPayload = {
|
|
279
|
+
elementKey: string;
|
|
280
|
+
fieldId: string;
|
|
281
|
+
item?: BridgeItemDescriptor;
|
|
282
|
+
value: string;
|
|
283
|
+
isRichText?: boolean;
|
|
284
|
+
reason: "blur" | "commit" | "cancel";
|
|
285
|
+
};
|
|
286
|
+
export type RefreshStartedEventPayload = {
|
|
287
|
+
revision?: string;
|
|
288
|
+
};
|
|
289
|
+
export type RefreshCompletedEventPayload = {
|
|
290
|
+
revision?: string;
|
|
291
|
+
structure?: SerializablePageStructure;
|
|
292
|
+
geometry?: BridgeGeometrySnapshot;
|
|
293
|
+
};
|
|
294
|
+
export type RenderErrorEventPayload = {
|
|
295
|
+
message: string;
|
|
296
|
+
code?: string;
|
|
297
|
+
details?: unknown;
|
|
298
|
+
};
|
|
299
|
+
export type DomUpdatedEventPayload = {
|
|
300
|
+
html: string;
|
|
301
|
+
url: string;
|
|
302
|
+
viewport: BridgeViewport;
|
|
303
|
+
scroll: BridgeScroll;
|
|
304
|
+
scrollWidth: number;
|
|
305
|
+
scrollHeight: number;
|
|
306
|
+
};
|
|
307
|
+
export type CaptureDomResultEventPayload = {
|
|
308
|
+
requestId: string;
|
|
309
|
+
html?: string;
|
|
310
|
+
text?: string;
|
|
311
|
+
error?: string;
|
|
312
|
+
};
|
|
313
|
+
export type BridgeEventPayloadByName = {
|
|
314
|
+
ready: ReadyEventPayload;
|
|
315
|
+
structureUpdated: StructureUpdatedEventPayload;
|
|
316
|
+
pageSkeletonUpdated: PageSkeletonUpdatedEventPayload;
|
|
317
|
+
geometryUpdated: GeometryUpdatedEventPayload;
|
|
318
|
+
scrollChanged: ScrollChangedEventPayload;
|
|
319
|
+
resizeChanged: ResizeChangedEventPayload;
|
|
320
|
+
interaction: InteractionEventPayload;
|
|
321
|
+
selectionChanged: SelectionChangedEventPayload;
|
|
322
|
+
fieldValueChanged: FieldValueChangedEventPayload;
|
|
323
|
+
inlineEditEnded: InlineEditEndedEventPayload;
|
|
324
|
+
refreshStarted: RefreshStartedEventPayload;
|
|
325
|
+
refreshCompleted: RefreshCompletedEventPayload;
|
|
326
|
+
renderError: RenderErrorEventPayload;
|
|
327
|
+
domUpdated: DomUpdatedEventPayload;
|
|
328
|
+
captureDomResult: CaptureDomResultEventPayload;
|
|
329
|
+
};
|
|
330
|
+
export type BridgeEventName = keyof BridgeEventPayloadByName;
|
|
331
|
+
export type BridgeEvent<TName extends BridgeEventName = BridgeEventName> = TName extends BridgeEventName ? BridgeEnvelope<TName, BridgeEventPayloadByName[TName]> & {
|
|
332
|
+
direction: "host-to-parent";
|
|
333
|
+
} : never;
|
|
334
|
+
export type HelloCommandPayload = {
|
|
335
|
+
/** The editor's protocol version, advertised on (re)connect. */
|
|
336
|
+
version?: BridgeVersion;
|
|
337
|
+
/**
|
|
338
|
+
* Absolute URL of the canonical bridge script. A stub bootloader on the host
|
|
339
|
+
* loads the real bridge from here (preferring it over its same-origin
|
|
340
|
+
* fallback). The full bridge ignores this field. The stub only honors a URL
|
|
341
|
+
* whose origin is an allowed parent origin or its own.
|
|
342
|
+
*/
|
|
343
|
+
bridgeUrl?: string;
|
|
344
|
+
};
|
|
345
|
+
export type InitCommandPayload = {
|
|
346
|
+
editorOrigin: string;
|
|
347
|
+
sessionId?: string;
|
|
348
|
+
signedContext?: string;
|
|
349
|
+
mode: "edit" | "preview" | "suggestions" | string;
|
|
350
|
+
selectedComponentIds: string[];
|
|
351
|
+
featureFlags?: Record<string, boolean>;
|
|
352
|
+
/** The editor's protocol version, so the host can record/negotiate. */
|
|
353
|
+
version?: BridgeVersion;
|
|
354
|
+
/**
|
|
355
|
+
* Capabilities the editor acknowledges for this session: the intersection of
|
|
356
|
+
* what the host advertised in `ready` and what the editor supports. The host
|
|
357
|
+
* should only run/advertise behaviors in this set. `init` is the handshake
|
|
358
|
+
* boundary — the host should wait for it before emitting operational events.
|
|
359
|
+
*/
|
|
360
|
+
acknowledgedCapabilities?: BridgeCapabilitySet;
|
|
361
|
+
};
|
|
362
|
+
export type RefreshCommandPayload = {
|
|
363
|
+
url?: string;
|
|
364
|
+
revision?: string;
|
|
365
|
+
route?: string;
|
|
366
|
+
layoutKind?: "final" | "shared" | string;
|
|
367
|
+
};
|
|
368
|
+
export type SetSelectionCommandPayload = {
|
|
369
|
+
componentIds?: string[];
|
|
370
|
+
field?: {
|
|
371
|
+
elementKey?: string;
|
|
372
|
+
fieldId?: string;
|
|
373
|
+
};
|
|
374
|
+
placeholderKey?: string;
|
|
375
|
+
};
|
|
376
|
+
export type ScrollIntoViewCommandPayload = {
|
|
377
|
+
elementKey?: string;
|
|
378
|
+
componentId?: string;
|
|
379
|
+
fieldId?: string;
|
|
380
|
+
placeholderKey?: string;
|
|
381
|
+
block?: "start" | "center" | "end" | "nearest";
|
|
382
|
+
};
|
|
383
|
+
export type ScrollByCommandPayload = {
|
|
384
|
+
x?: number;
|
|
385
|
+
y?: number;
|
|
386
|
+
behavior?: "auto" | "instant" | "smooth";
|
|
387
|
+
};
|
|
388
|
+
export type QueryGeometryCommandPayload = {
|
|
389
|
+
keys?: string[];
|
|
390
|
+
textRanges?: Array<{
|
|
391
|
+
key: string;
|
|
392
|
+
elementKey?: string;
|
|
393
|
+
fieldId?: string;
|
|
394
|
+
item?: BridgeItemDescriptor;
|
|
395
|
+
start: number;
|
|
396
|
+
end: number;
|
|
397
|
+
}>;
|
|
398
|
+
};
|
|
399
|
+
export type BeginInlineEditCommandPayload = {
|
|
400
|
+
elementKey: string;
|
|
401
|
+
fieldId: string;
|
|
402
|
+
clientX?: number;
|
|
403
|
+
clientY?: number;
|
|
404
|
+
};
|
|
405
|
+
export type ApplyFieldPatchCommandPayload = {
|
|
406
|
+
elementKey: string;
|
|
407
|
+
fieldId: string;
|
|
408
|
+
value: string;
|
|
409
|
+
isRichText?: boolean;
|
|
410
|
+
source?: "real" | "suggestion-preview" | "reset" | string;
|
|
411
|
+
};
|
|
412
|
+
export type ApplyRichTextCommandPayload = {
|
|
413
|
+
elementKey: string;
|
|
414
|
+
fieldId: string;
|
|
415
|
+
command: string;
|
|
416
|
+
value?: string;
|
|
417
|
+
};
|
|
418
|
+
export type CommitInlineEditCommandPayload = {
|
|
419
|
+
elementKey: string;
|
|
420
|
+
fieldId: string;
|
|
421
|
+
};
|
|
422
|
+
export type CancelInlineEditCommandPayload = {
|
|
423
|
+
elementKey: string;
|
|
424
|
+
fieldId: string;
|
|
425
|
+
};
|
|
426
|
+
export type SetPreviewModeCommandPayload = {
|
|
427
|
+
enabled: boolean;
|
|
428
|
+
};
|
|
429
|
+
export type SetEditorModeCommandPayload = {
|
|
430
|
+
mode: "edit" | "preview" | "suggestions";
|
|
431
|
+
};
|
|
432
|
+
export type SetLayoutKindCommandPayload = {
|
|
433
|
+
layoutKind: "final" | "shared" | string;
|
|
434
|
+
};
|
|
435
|
+
export type SetChromeVisibilityCommandPayload = {
|
|
436
|
+
visible: boolean;
|
|
437
|
+
};
|
|
438
|
+
export type SetZoomCommandPayload = {
|
|
439
|
+
zoom: number;
|
|
440
|
+
};
|
|
441
|
+
export type CaptureDomCommandPayload = {
|
|
442
|
+
requestId: string;
|
|
443
|
+
selector?: string;
|
|
444
|
+
includeText?: boolean;
|
|
445
|
+
};
|
|
446
|
+
export type BridgeCommandPayloadByName = {
|
|
447
|
+
hello: HelloCommandPayload;
|
|
448
|
+
init: InitCommandPayload;
|
|
449
|
+
refresh: RefreshCommandPayload;
|
|
450
|
+
setSelection: SetSelectionCommandPayload;
|
|
451
|
+
scrollIntoView: ScrollIntoViewCommandPayload;
|
|
452
|
+
scrollBy: ScrollByCommandPayload;
|
|
453
|
+
queryGeometry: QueryGeometryCommandPayload;
|
|
454
|
+
beginInlineEdit: BeginInlineEditCommandPayload;
|
|
455
|
+
applyFieldPatch: ApplyFieldPatchCommandPayload;
|
|
456
|
+
applyRichTextCommand: ApplyRichTextCommandPayload;
|
|
457
|
+
commitInlineEdit: CommitInlineEditCommandPayload;
|
|
458
|
+
cancelInlineEdit: CancelInlineEditCommandPayload;
|
|
459
|
+
setPreviewMode: SetPreviewModeCommandPayload;
|
|
460
|
+
setEditorMode: SetEditorModeCommandPayload;
|
|
461
|
+
setLayoutKind: SetLayoutKindCommandPayload;
|
|
462
|
+
setChromeVisibility: SetChromeVisibilityCommandPayload;
|
|
463
|
+
setZoom: SetZoomCommandPayload;
|
|
464
|
+
captureDom: CaptureDomCommandPayload;
|
|
465
|
+
};
|
|
466
|
+
export type BridgeCommandName = keyof BridgeCommandPayloadByName;
|
|
467
|
+
export type BridgeCommand<TName extends BridgeCommandName = BridgeCommandName> = TName extends BridgeCommandName ? BridgeEnvelope<TName, BridgeCommandPayloadByName[TName]> & {
|
|
468
|
+
direction: "parent-to-host";
|
|
469
|
+
} : never;
|
|
470
|
+
export declare function isKnownBridgeCommandName(value: unknown): value is BridgeCommandName;
|
|
471
|
+
export declare function isKnownBridgeEventName(value: unknown): value is BridgeEventName;
|
|
472
|
+
export declare function createBridgeEnvelope<TName extends BridgeCommandName, TPayload extends BridgeCommandPayloadByName[TName]>(name: TName, payload: TPayload, options?: {
|
|
473
|
+
id?: string;
|
|
474
|
+
timestamp?: number;
|
|
475
|
+
requestId?: string;
|
|
476
|
+
}): BridgeCommand<TName>;
|
|
477
|
+
export declare function createBridgeEnvelope<TName extends BridgeEventName, TPayload extends BridgeEventPayloadByName[TName]>(name: TName, payload: TPayload, options: {
|
|
478
|
+
direction: "host-to-parent";
|
|
479
|
+
id?: string;
|
|
480
|
+
timestamp?: number;
|
|
481
|
+
requestId?: string;
|
|
482
|
+
}): BridgeEvent<TName>;
|
|
483
|
+
export declare function isBridgeEnvelope(value: unknown): value is BridgeEnvelope;
|
|
484
|
+
export declare function isBridgeVersion(value: unknown): value is BridgeVersion;
|
|
485
|
+
/** Compatible when the major version matches; minor differences are additive. */
|
|
486
|
+
export declare function isCompatibleBridgeVersion(peerVersion: unknown): boolean;
|
|
487
|
+
/** The effective minor for a session is the lower of the two peers' minors. */
|
|
488
|
+
export declare function negotiateMinor(peerVersion: BridgeVersion): number;
|
|
489
|
+
export declare function formatBridgeVersion(value: unknown): string;
|
|
490
|
+
/** Intersection of two capability sets, preserving the order of the first. */
|
|
491
|
+
export declare function negotiateCapabilities(editorSupported: readonly BridgeCapability[], hostAdvertised: readonly BridgeCapability[]): BridgeCapability[];
|
|
492
|
+
/**
|
|
493
|
+
* Recognition-only guard: a well-formed bridge envelope from the host,
|
|
494
|
+
* regardless of whether the event name is known. RECOGNIZE messages with this;
|
|
495
|
+
* DISPATCH them with `isKnownBridgeEventName` separately, so that unknown (e.g.
|
|
496
|
+
* newer) events surface in diagnostics instead of being silently dropped.
|
|
497
|
+
*/
|
|
498
|
+
export declare function isBridgeMessageFromHost(value: unknown): value is BridgeEnvelope & {
|
|
499
|
+
direction: "host-to-parent";
|
|
500
|
+
};
|
|
501
|
+
/** Recognition-only guard: a well-formed bridge envelope from the parent. */
|
|
502
|
+
export declare function isBridgeMessageFromParent(value: unknown): value is BridgeEnvelope & {
|
|
503
|
+
direction: "parent-to-host";
|
|
504
|
+
};
|
|
505
|
+
export declare function isBridgeCommandEnvelope(value: unknown): value is BridgeCommand;
|
|
506
|
+
export declare function isBridgeEventEnvelope(value: unknown): value is BridgeEvent;
|
|
507
|
+
export declare function normalizeOrigin(value: string): string | undefined;
|
|
508
|
+
export declare function isAllowedOrigin(origin: string, allowedOrigins: readonly string[]): boolean;
|
|
509
|
+
export declare function assertAllowedOrigin(origin: string, allowedOrigins: readonly string[]): void;
|
|
510
|
+
//# sourceMappingURL=index.d.ts.map
|