|
21 | 21 | #include <folly/json.h> |
22 | 22 | #include <jsinspector-modern/cdp/CdpJson.h> |
23 | 23 |
|
| 24 | +#include <algorithm> |
24 | 25 | #include <chrono> |
25 | 26 | #include <functional> |
| 27 | +#include <string> |
26 | 28 | #include <string_view> |
27 | 29 |
|
28 | 30 | using namespace std::chrono; |
@@ -236,6 +238,53 @@ class HostAgent::Impl final { |
236 | 238 | }; |
237 | 239 | } |
238 | 240 | } |
| 241 | + if (req.method == "Page.addScriptToEvaluateOnNewDocument") { |
| 242 | + // @cdp Page.addScriptToEvaluateOnNewDocument registers a script that |
| 243 | + // will be evaluated in every new JS runtime created for this Host |
| 244 | + // (e.g. after a reload), BEFORE the app's main bundle runs. We store |
| 245 | + // it as session state and let each new RuntimeAgent replay it onto its |
| 246 | + // runtime, mirroring the handling of @cdp Runtime.addBinding. Per CDP |
| 247 | + // semantics the script does NOT run in the runtime that is current |
| 248 | + // when it is registered; the client must reload to apply it. |
| 249 | + std::string source = |
| 250 | + req.params.isObject() && (req.params.count("source") != 0u) |
| 251 | + ? req.params.at("source").asString() |
| 252 | + : std::string(); |
| 253 | + std::string identifier = |
| 254 | + std::to_string(sessionState_.nextScriptToEvaluateOnNewDocumentId++); |
| 255 | + sessionState_.scriptsToEvaluateOnNewDocument.push_back( |
| 256 | + {.identifier = identifier, .source = std::move(source)}); |
| 257 | + |
| 258 | + frontendChannel_( |
| 259 | + cdp::jsonResult( |
| 260 | + req.id, folly::dynamic::object("identifier", identifier))); |
| 261 | + |
| 262 | + return { |
| 263 | + .isFinishedHandlingRequest = true, |
| 264 | + .shouldSendOKResponse = false, |
| 265 | + }; |
| 266 | + } |
| 267 | + if (req.method == "Page.removeScriptToEvaluateOnNewDocument") { |
| 268 | + std::string identifier = |
| 269 | + req.params.isObject() && (req.params.count("identifier") != 0u) |
| 270 | + ? req.params.at("identifier").asString() |
| 271 | + : std::string(); |
| 272 | + auto& scripts = sessionState_.scriptsToEvaluateOnNewDocument; |
| 273 | + scripts.erase( |
| 274 | + std::remove_if( |
| 275 | + scripts.begin(), |
| 276 | + scripts.end(), |
| 277 | + [&identifier]( |
| 278 | + const SessionState::ScriptToEvaluateOnNewDocument& script) { |
| 279 | + return script.identifier == identifier; |
| 280 | + }), |
| 281 | + scripts.end()); |
| 282 | + |
| 283 | + return { |
| 284 | + .isFinishedHandlingRequest = true, |
| 285 | + .shouldSendOKResponse = true, |
| 286 | + }; |
| 287 | + } |
239 | 288 | if (req.method == "Overlay.setPausedInDebuggerMessage") { |
240 | 289 | auto message = |
241 | 290 | req.params.isObject() && (req.params.count("message") != 0u) |
@@ -397,6 +446,11 @@ class HostAgent::Impl final { |
397 | 446 | return; |
398 | 447 | } |
399 | 448 |
|
| 449 | + if (requestState.isFinishedHandlingRequest) { |
| 450 | + // The handler already sent its own response via frontendChannel_. |
| 451 | + return; |
| 452 | + } |
| 453 | + |
400 | 454 | throw NotImplementedException(req.method); |
401 | 455 | } |
402 | 456 |
|
|
0 commit comments