diff options
Diffstat (limited to 'remote/webdriver-bidi/modules/Intercept.sys.mjs')
-rw-r--r-- | remote/webdriver-bidi/modules/Intercept.sys.mjs | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/remote/webdriver-bidi/modules/Intercept.sys.mjs b/remote/webdriver-bidi/modules/Intercept.sys.mjs new file mode 100644 index 0000000000..4e3a9bb9e7 --- /dev/null +++ b/remote/webdriver-bidi/modules/Intercept.sys.mjs @@ -0,0 +1,101 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const lazy = {}; + +ChromeUtils.defineESModuleGetters(lazy, { + getSeenNodesForBrowsingContext: + "chrome://remote/content/shared/webdriver/Session.sys.mjs", + TabManager: "chrome://remote/content/shared/TabManager.sys.mjs", +}); + +/** + * The serialization of JavaScript objects in the content process might produce + * extra data that needs to be transfered and then processed by the parent + * process. This extra data is part of the payload as returned by commands + * and events and can contain the following: + * + * - {Map<BrowsingContext, Array<string>>} seenNodeIds + * DOM nodes that need to be added to the navigable seen nodes map. + * + * @param {string} sessionId + * Id of the WebDriver session + * @param {object} payload + * Payload of the response for the command and event that might contain + * a `_extraData` field. + * + * @returns {object} + * The payload with the extra data removed if it was present. + */ +export function processExtraData(sessionId, payload) { + // Process extra data if present and delete it from the payload + if ("_extraData" in payload) { + const { seenNodeIds } = payload._extraData; + + // Updates the seen nodes for the current session and browsing context. + seenNodeIds?.forEach((nodeIds, browsingContext) => { + const seenNodes = lazy.getSeenNodesForBrowsingContext( + sessionId, + browsingContext + ); + + nodeIds.forEach(nodeId => seenNodes.add(nodeId)); + }); + + delete payload._extraData; + } + + // Find serialized WindowProxy and resolve browsing context to a navigable id. + if (payload?.result) { + payload.result = addContextIdToSerializedWindow(payload.result); + } else if (payload.exceptionDetails) { + payload.exceptionDetails = addContextIdToSerializedWindow( + payload.exceptionDetails + ); + } + + return payload; +} + +function addContextIdToSerializedWindow(serialized) { + if (serialized.value) { + switch (serialized.type) { + case "array": + case "htmlcollection": + case "nodelist": + case "set": { + serialized.value = serialized.value.map(value => + addContextIdToSerializedWindow(value) + ); + break; + } + + case "map": + case "object": { + serialized.value = serialized.value.map(([key, value]) => [ + key, + addContextIdToSerializedWindow(value), + ]); + break; + } + + case "window": { + if (serialized.value.isTopBrowsingContext) { + const browsingContext = BrowsingContext.getCurrentTopByBrowserId( + serialized.value.context + ); + + serialized.value = { + context: lazy.TabManager.getIdForBrowsingContext(browsingContext), + }; + } + break; + } + } + } else if (serialized.exception) { + serialized.exception = addContextIdToSerializedWindow(serialized.exception); + } + + return serialized; +} |