InjectedScript InjectedScriptManager::injectedScriptFor(ExecState* inspectedExecState) { auto it = m_scriptStateToId.find(inspectedExecState); if (it != m_scriptStateToId.end()) { auto it1 = m_idToInjectedScript.find(it->value); if (it1 != m_idToInjectedScript.end()) return it1->value; } if (!m_environment.canAccessInspectedScriptState(inspectedExecState)) return InjectedScript(); int id = injectedScriptIdFor(inspectedExecState); Deprecated::ScriptObject injectedScriptObject = createInjectedScript(injectedScriptSource(), inspectedExecState, id); if (injectedScriptObject.scriptState() != inspectedExecState) { WTFLogAlways("Failed to parse/execute InjectedScriptSource.js!"); WTFLogAlways("%s\n", injectedScriptSource().ascii().data()); RELEASE_ASSERT_NOT_REACHED(); } InjectedScript result(injectedScriptObject, &m_environment); m_idToInjectedScript.set(id, result); didCreateInjectedScript(result); return result; }
InjectedScript InjectedScriptManager::injectedScriptFor(ScriptState* inspectedScriptState) { v8::HandleScope handleScope; v8::Local<v8::Context> context = inspectedScriptState->context(); v8::Context::Scope contextScope(context); v8::Local<v8::Object> global = context->Global(); // Skip proxy object. The proxy object will survive page navigation while we need // an object whose lifetime consides with that of the inspected context. global = v8::Local<v8::Object>::Cast(global->GetPrototype()); v8::Handle<v8::String> key = V8HiddenPropertyName::devtoolsInjectedScript(); v8::Local<v8::Value> val = global->GetHiddenValue(key); if (!val.IsEmpty() && val->IsObject()) return InjectedScript(ScriptObject(inspectedScriptState, v8::Local<v8::Object>::Cast(val)), m_inspectedStateAccessCheck); if (!m_inspectedStateAccessCheck(inspectedScriptState)) return InjectedScript(); pair<long, ScriptObject> injectedScript = injectScript(injectedScriptSource(), inspectedScriptState); InjectedScript result(injectedScript.second, m_inspectedStateAccessCheck); m_idToInjectedScript.set(injectedScript.first, result); global->SetHiddenValue(key, injectedScript.second.v8Object()); return result; }
std::unique_ptr<InjectedScript> InjectedScript::create(InspectedContext* inspectedContext) { v8::Isolate* isolate = inspectedContext->isolate(); v8::HandleScope handles(isolate); v8::Local<v8::Context> context = inspectedContext->context(); v8::Context::Scope scope(context); std::unique_ptr<InjectedScriptNative> injectedScriptNative(new InjectedScriptNative(isolate)); v8::Local<v8::Object> scriptHostWrapper = V8InjectedScriptHost::create(context, inspectedContext->inspector()); injectedScriptNative->setOnInjectedScriptHost(scriptHostWrapper); // Inject javascript into the context. The compiled script is supposed to evaluate into // a single anonymous function(it's anonymous to avoid cluttering the global object with // inspector's stuff) the function is called a few lines below with InjectedScriptHost wrapper, // injected script id and explicit reference to the inspected global object. The function is expected // to create and configure InjectedScript instance that is going to be used by the inspector. String16 injectedScriptSource(reinterpret_cast<const char*>(InjectedScriptSource_js), sizeof(InjectedScriptSource_js)); v8::Local<v8::Value> value; if (!inspectedContext->inspector()->compileAndRunInternalScript(context, toV8String(isolate, injectedScriptSource)).ToLocal(&value)) return nullptr; DCHECK(value->IsFunction()); v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(value); v8::Local<v8::Object> windowGlobal = context->Global(); v8::Local<v8::Value> info[] = { scriptHostWrapper, windowGlobal, v8::Number::New(isolate, inspectedContext->contextId()) }; v8::MicrotasksScope microtasksScope(isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); v8::Local<v8::Value> injectedScriptValue; if (!function->Call(context, windowGlobal, PROTOCOL_ARRAY_LENGTH(info), info).ToLocal(&injectedScriptValue)) return nullptr; if (!injectedScriptValue->IsObject()) return nullptr; return wrapUnique(new InjectedScript(inspectedContext, injectedScriptValue.As<v8::Object>(), std::move(injectedScriptNative))); }
InjectedScript InjectedScriptManager::injectedScriptFor(JSC::ExecState* inspectedExecState) { ExecStateToId::iterator it = m_scriptStateToId.find(inspectedExecState); if (it != m_scriptStateToId.end()) { IdToInjectedScriptMap::iterator it1 = m_idToInjectedScript.find(it->value); if (it1 != m_idToInjectedScript.end()) return it1->value; } if (!m_inspectedStateAccessCheck(inspectedExecState)) return InjectedScript(); int id = injectedScriptIdFor(inspectedExecState); ScriptObject injectedScriptObject = createInjectedScript(injectedScriptSource(), inspectedExecState, id); InjectedScript result(injectedScriptObject, m_inspectedStateAccessCheck); m_idToInjectedScript.set(id, result); return result; }