|
195 | 195 | let uuid = () => (Math.random() * Date.now()).toString(16); |
196 | 196 | let docUrl = document.URL; |
197 | 197 | browser.runtime.sendSyncMessage = (msg, callback) => { |
| 198 | + // we interrogate the canScript() callback to know whether the caller |
| 199 | + // wants scripts deferred by sendSyncMessage to be eventually executed: |
| 200 | + // - undefined -> too soon to tell, suspend |
| 201 | + // - true -> go on and execute |
| 202 | + // - false -> block |
198 | 203 | let canScript; |
199 | 204 | if (callback && typeof callback === "object") { |
200 | 205 | ({canScript, callback} = callback); |
201 | | - } else { |
| 206 | + } |
| 207 | + if (typeof canScript !== "function") { |
| 208 | + // if no canScript() callback was passed, default to execute scripts |
202 | 209 | canScript = () => true; |
203 | 210 | } |
204 | 211 |
|
|
213 | 220 |
|
214 | 221 | if (MOZILLA) { |
215 | 222 | // In order to cope with inconsistencies in XHR synchronicity, |
216 | | - // allowing DOM element to be inserted and script to be executed |
217 | | - // (seen with file:// and ftp:// loads) we additionally suspend on |
218 | | - // Mutation notifications and beforescriptexecute events |
| 223 | + // allowing scripts to be executed (especially with synchronous loads |
| 224 | + // or when other extensions manipulate the DOM early) we additionally |
| 225 | + // suspend on beforescriptexecute events |
| 226 | + |
219 | 227 | let suspendURL = url + "&suspend=true"; |
220 | 228 | let suspended = false; |
221 | 229 | let suspend = () => { |
|
230 | 238 | } |
231 | 239 | suspended = false; |
232 | 240 | }; |
233 | | - let domSuspender = new MutationObserver(records => { |
234 | | - suspend(); |
235 | | - }); |
236 | | - domSuspender.observe(document.documentElement, {childList: true}); |
237 | 241 |
|
238 | 242 | let onBeforeScript = e => { |
239 | | - suspend(); |
240 | | - if (!canScript()) e.preventDefault(); |
| 243 | + while(typeof canScript() === "undefined") { |
| 244 | + suspend(); |
| 245 | + } |
| 246 | + if (!canScript()) { |
| 247 | + console.debug("sendSyncMessage blocked a script element", e.target); |
| 248 | + e.preventDefault(); |
| 249 | + } |
241 | 250 | }; |
| 251 | + |
242 | 252 | addEventListener("beforescriptexecute", onBeforeScript, true); |
243 | 253 |
|
244 | 254 | let finalize = () => { |
245 | 255 | removeEventListener("beforescriptexecute", onBeforeScript, true); |
246 | | - domSuspender.disconnect(); |
247 | 256 | }; |
248 | 257 |
|
249 | 258 | // on Firefox we first need to send an async message telling the |
|
0 commit comments