1/* 2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include "config.h" 32#include "core/inspector/PageRuntimeAgent.h" 33 34#include "bindings/core/v8/DOMWrapperWorld.h" 35#include "bindings/core/v8/ScriptController.h" 36#include "bindings/core/v8/ScriptState.h" 37#include "core/frame/FrameConsole.h" 38#include "core/frame/LocalFrame.h" 39#include "core/inspector/InjectedScript.h" 40#include "core/inspector/InjectedScriptManager.h" 41#include "core/inspector/InspectorClient.h" 42#include "core/inspector/InspectorPageAgent.h" 43#include "core/inspector/InstrumentingAgents.h" 44#include "core/page/Page.h" 45#include "platform/weborigin/SecurityOrigin.h" 46 47namespace blink { 48 49PageRuntimeAgent::PageRuntimeAgent(InjectedScriptManager* injectedScriptManager, InspectorClient* client, ScriptDebugServer* scriptDebugServer, Page* page, InspectorPageAgent* pageAgent) 50 : InspectorRuntimeAgent(injectedScriptManager, scriptDebugServer) 51 , m_client(client) 52 , m_inspectedPage(page) 53 , m_pageAgent(pageAgent) 54 , m_mainWorldContextCreated(false) 55{ 56} 57 58PageRuntimeAgent::~PageRuntimeAgent() 59{ 60#if !ENABLE(OILPAN) 61 m_instrumentingAgents->setPageRuntimeAgent(0); 62#endif 63} 64 65void PageRuntimeAgent::trace(Visitor* visitor) 66{ 67 visitor->trace(m_inspectedPage); 68 visitor->trace(m_pageAgent); 69 InspectorRuntimeAgent::trace(visitor); 70} 71 72void PageRuntimeAgent::init() 73{ 74 m_instrumentingAgents->setPageRuntimeAgent(this); 75} 76 77void PageRuntimeAgent::enable(ErrorString* errorString) 78{ 79 if (m_enabled) 80 return; 81 82 InspectorRuntimeAgent::enable(errorString); 83 84 // Only report existing contexts if the page did commit load, otherwise we may 85 // unintentionally initialize contexts in the frames which may trigger some listeners 86 // that are expected to be triggered only after the load is committed, see http://crbug.com/131623 87 if (m_mainWorldContextCreated) 88 reportExecutionContextCreation(); 89} 90 91void PageRuntimeAgent::run(ErrorString* errorString) 92{ 93 m_client->resumeStartup(); 94} 95 96void PageRuntimeAgent::didClearDocumentOfWindowObject(LocalFrame* frame) 97{ 98 m_mainWorldContextCreated = true; 99 100 if (!m_enabled) 101 return; 102 ASSERT(m_frontend); 103 104 if (frame == m_inspectedPage->mainFrame()) { 105 m_scriptStateToId.clear(); 106 m_frontend->executionContextsCleared(); 107 } 108 String frameId = m_pageAgent->frameId(frame); 109 addExecutionContextToFrontend(ScriptState::forMainWorld(frame), true, "", frameId); 110} 111 112void PageRuntimeAgent::didCreateIsolatedContext(LocalFrame* frame, ScriptState* scriptState, SecurityOrigin* origin) 113{ 114 if (!m_enabled) 115 return; 116 ASSERT(m_frontend); 117 String frameId = m_pageAgent->frameId(frame); 118 addExecutionContextToFrontend(scriptState, false, origin->toRawString(), frameId); 119} 120 121InjectedScript PageRuntimeAgent::injectedScriptForEval(ErrorString* errorString, const int* executionContextId) 122{ 123 if (!executionContextId) { 124 ScriptState* scriptState = ScriptState::forMainWorld(m_inspectedPage->deprecatedLocalMainFrame()); 125 InjectedScript result = injectedScriptManager()->injectedScriptFor(scriptState); 126 if (result.isEmpty()) 127 *errorString = "Internal error: main world execution context not found."; 128 return result; 129 } 130 InjectedScript injectedScript = injectedScriptManager()->injectedScriptForId(*executionContextId); 131 if (injectedScript.isEmpty()) 132 *errorString = "Execution context with given id not found."; 133 return injectedScript; 134} 135 136void PageRuntimeAgent::muteConsole() 137{ 138 FrameConsole::mute(); 139} 140 141void PageRuntimeAgent::unmuteConsole() 142{ 143 FrameConsole::unmute(); 144} 145 146void PageRuntimeAgent::reportExecutionContextCreation() 147{ 148 Vector<std::pair<ScriptState*, SecurityOrigin*> > isolatedContexts; 149 for (Frame* frame = m_inspectedPage->mainFrame(); frame; frame = frame->tree().traverseNext()) { 150 if (!frame->isLocalFrame()) 151 continue; 152 LocalFrame* localFrame = toLocalFrame(frame); 153 if (!localFrame->script().canExecuteScripts(NotAboutToExecuteScript)) 154 continue; 155 String frameId = m_pageAgent->frameId(localFrame); 156 157 ScriptState* scriptState = ScriptState::forMainWorld(localFrame); 158 addExecutionContextToFrontend(scriptState, true, "", frameId); 159 localFrame->script().collectIsolatedContexts(isolatedContexts); 160 if (isolatedContexts.isEmpty()) 161 continue; 162 for (size_t i = 0; i< isolatedContexts.size(); i++) 163 addExecutionContextToFrontend(isolatedContexts[i].first, false, isolatedContexts[i].second->toRawString(), frameId); 164 isolatedContexts.clear(); 165 } 166} 167 168void PageRuntimeAgent::frameWindowDiscarded(LocalDOMWindow* window) 169{ 170 Vector<RefPtr<ScriptState> > scriptStatesToRemove; 171 for (ScriptStateToId::iterator it = m_scriptStateToId.begin(); it != m_scriptStateToId.end(); ++it) { 172 RefPtr<ScriptState> scriptState = it->key; 173 if (scriptState->contextIsValid() || window == scriptState->domWindow()) { 174 scriptStatesToRemove.append(scriptState); 175 m_frontend->executionContextDestroyed(it->value); 176 } 177 } 178 m_scriptStateToId.removeAll(scriptStatesToRemove); 179} 180 181} // namespace blink 182 183