-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreateEventChain.js
159 lines (153 loc) · 5.55 KB
/
createEventChain.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/**
* Since ILST 25.3 (AUG 2021) new CORS updates for Chromium 88 are implemented in CEP.
* One byproduct of this is that iframes can no longer receive evalScript return values or access parent document contents, so the DEVELOPER context
* within older bombino templates must be altered to use window.postMessage event chain in order to invoke evalScript and return values correctly.
*
* This particular file is specifically meant to work in tandem with Inventsable/workaround and the evalScript() method contained within.
* If you find a bug, please report it to Inventsable/bombino (unless isolated to this particular template in which case feel free to issue one here)
*/
const DEBUG = false; // If you have multiple depths of iframes, setting DEBUG to true and tracing the event chain may help us debug.
/**
* We don't need an event chain for PRODUCTION context. This code is specifically meant to assist DEVELOPER since we embed our localhost port via iframe within index-dev.html
*/
const CSI = new CSInterface();
// NOTE: You won't see this in bombino unless you have a <Panel debug> or <Panel keep-console> prop, since console is cleared on mounting lifecycle.
if (DEBUG) {
console.log(
"createEventChain.js booted, eventListener for child evalScripts is now live:"
);
}
/**
* Global window listener should catch any children messages propagating upwards, then pass to a global evalScript
*/
window.addEventListener("message", (msg) => {
if (DEBUG) {
console.log("Outer shell receives message");
console.log(msg);
}
// A default message will arrive with an "evalScript" key for any child evalScript invocations:
if (msg.data && msg.data.evalScript && msg.data.uuid) {
evalScript(msg.data.evalScript).then((result) => {
if (DEBUG && result + "" !== "undefined") {
console.log("RESULT:");
console.log(result, msg.data.uuid, msg.origin);
console.log(msg.data.uuid);
}
/**
* This document should be barebones if index-dev.html has not been altered, so querying an iframe should be trivial
*/
let target = getIframe();
if (target && target.contentWindow) {
if (DEBUG)
console.log("SEND TO CHILD:", {
evalScriptResult: result,
uuid: msg.data.uuid,
origin: msg.data.origin,
});
// We then post a message back to the child with the result and original uuid
target.contentWindow.postMessage(
{
evalScriptResult: result,
uuid: msg.data.uuid,
origin: msg.data.origin,
},
msg.origin
);
} else {
console.error("Could not find iframe");
}
});
// Otherwise this may be for a menu like a context or flyout option, containing uuid and type keys
} else if (msg.data && msg.data.uuid && msg.data.type) {
let target = getIframe();
if (DEBUG) {
console.log("");
console.log("ROOT RECEIVED A MENU MESSAGE:");
console.log(msg.data.type);
console.log("");
}
// If the type is Context menu:
if (msg.data.type == "setContextMenu") {
if (DEBUG) console.log("BUILDING CONTEXT MENU");
window.__adobe_cep__.invokeAsync(
msg.data.params[0],
msg.data.params[1],
(evt) => {
if (DEBUG) {
console.log("CLICKED:");
console.log(evt);
console.log(target);
}
target.contentWindow.postMessage(
{
type: "contextMenuClicked",
uuid: msg.data.uuid,
origin: msg.data.origin,
menuItem: evt,
},
msg.origin
);
}
);
}
// If the type is flyout menu:
// } else if (msg.data.type == "setPanelFlyoutMenu") {
// if (DEBUG) console.log("SET FLYOUT MENU?");
// window.__adobe_cep__.invokeSync("setPanelFlyoutMenu", msg.data.params[1]);
// window.__adobe_cep__.addEventListener(
// "com.adobe.csxs.events.flyoutMenuClicked",
// (evt) => {
// if (DEBUG) {
// console.log("FLYOUT CLICK:");
// console.log(evt);
// }
// target.contentWindow.postMessage(
// {
// type: "contextMenuClicked",
// uuid: msg.data.uuid,
// origin: msg.data.origin,
// menuItem: evt,
// },
// msg.origin
// );
// }
// );
// }
}
});
function getIframe() {
let target = document.querySelector("iframe");
return target || null;
}
// Nearly identical to the vanilla evalScript from brutalism and cluecumber here, but using the full reference to host instead of CEP-Spy
// We know this can always be a vanilla evalScript since this should only exist in the startup / onload files of our raw panel HTML
async function evalScript(text, defs = {}) {
if (window.__adobe_cep__) {
return new Promise((resolve, reject) => {
CSI.evalScript(`${text}`, (res) => {
// For some reason this was returning errors in InDesign alone. No idea why
if (
/idsn/i.test(
JSON.parse(window.__adobe_cep__.getHostEnvironment()).appName
)
) {
resolve(res);
} else {
resolve(this.isJson(res) ? JSON.parse(res) : res);
}
});
});
} else {
console.error("evalScript() attempting to return at wrong depth");
return null;
}
}
// Automatic JSON parsing on certain host apps
function isJson(text) {
try {
JSON.parse(text);
return true;
} catch (err) {
return false;
}
}