<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "config.h"

#include <string>

#include "Document.h"
#include "EventListener.h"
#include "InspectorController.h"
#include "Node.h"
#include "Page.h"
#include "PlatformString.h"
#include "ScriptValue.h"
#include "v8_proxy.h"
#include <wtf/OwnPtr.h>
#undef LOG

#include "base/values.h"
#include "webkit/glue/devtools/debugger_agent_impl.h"
#include "webkit/glue/devtools/debugger_agent_manager.h"
#include "webkit/glue/devtools/dom_agent_impl.h"
#include "webkit/glue/devtools/net_agent_impl.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webdatasource.h"
#include "webkit/glue/webdevtoolsagent_delegate.h"
#include "webkit/glue/webdevtoolsagent_impl.h"
#include "webkit/glue/weburlrequest.h"
#include "webkit/glue/webview_impl.h"

using WebCore::Document;
using WebCore::InspectorController;
using WebCore::Node;
using WebCore::Page;
using WebCore::ScriptValue;
using WebCore::String;

// Maximum size of the console message cache.
static const size_t kMaxConsoleMessages = 200;

WebDevToolsAgentImpl::WebDevToolsAgentImpl(
    WebViewImpl* web_view_impl,
    WebDevToolsAgentDelegate* delegate)
    : host_id_(delegate->GetHostId()),
      delegate_(delegate),
      web_view_impl_(web_view_impl),
      document_(NULL),
      attached_(false) {
  debugger_agent_delegate_stub_.set(new DebuggerAgentDelegateStub(this));
  dom_agent_delegate_stub_.set(new DomAgentDelegateStub(this));
  net_agent_delegate_stub_.set(new NetAgentDelegateStub(this));
  tools_agent_delegate_stub_.set(new ToolsAgentDelegateStub(this));

  // Sniff for requests from the beginning, do not wait for attach.
  net_agent_impl_.set(new NetAgentImpl(net_agent_delegate_stub_.get()));
}

WebDevToolsAgentImpl::~WebDevToolsAgentImpl() {
  DebuggerAgentManager::OnWebViewClosed(web_view_impl_);
  if (!utility_context_.IsEmpty()) {
    utility_context_.Dispose();
    utility_context_.Clear();
  }
}

void WebDevToolsAgentImpl::Attach() {
  if (attached_) {
    return;
  }
  debugger_agent_impl_.set(
      new DebuggerAgentImpl(web_view_impl_,
                            debugger_agent_delegate_stub_.get(),
                            this));
  dom_agent_impl_.set(new DomAgentImpl(dom_agent_delegate_stub_.get()));

  // We are potentially attaching to the running page -> init agents with
  // Document if any.
  Page* page = web_view_impl_->page();
  Document* doc = page->mainFrame()->document();
  if (doc) {
    // Reuse existing context in case detached/attached.
    if (utility_context_.IsEmpty()) {
      debugger_agent_impl_->ResetUtilityContext(doc, &utility_context_);
    }
    dom_agent_impl_->SetDocument(doc);
    net_agent_impl_->SetDocument(doc);
  }

  // Populate console.
  for (Vector<ConsoleMessage>::iterator it = console_log_.begin();
       it != console_log_.end(); ++it) {
    DictionaryValue message;
    Serialize(*it, &message);
    tools_agent_delegate_stub_->AddMessageToConsole(message);
  }

  net_agent_impl_->Attach();
  attached_ = true;
}

void WebDevToolsAgentImpl::Detach() {
  debugger_agent_impl_.set(NULL);
  dom_agent_impl_.set(NULL);
  net_agent_impl_->Detach();
  attached_ = false;
}

void WebDevToolsAgentImpl::SetMainFrameDocumentReady(bool ready) {
  if (!attached_) {
    return;
  }

  // We were attached prior to the page load -> init agents with Document.
  Document* doc;
  if (ready) {
    Page* page = web_view_impl_->page();
    doc = page->mainFrame()->document();
  } else {
    doc = NULL;
  }
  debugger_agent_impl_->ResetUtilityContext(doc, &utility_context_);
  dom_agent_impl_->SetDocument(doc);
  net_agent_impl_->SetDocument(doc);
}

void WebDevToolsAgentImpl::DidCommitLoadForFrame(
    WebViewImpl* webview,
    WebFrame* frame,
    bool is_new_navigation) {
  if (webview->GetMainFrame() == frame) {
    net_agent_impl_->DidCommitMainResourceLoad();
  }
  if (!attached_) {
    return;
  }
  WebDataSource* ds = frame->GetDataSource();
  const WebRequest& request = ds->GetRequest();
  GURL url = ds->HasUnreachableURL() ?
      ds->GetUnreachableURL() :
      request.GetURL();
  tools_agent_delegate_stub_->FrameNavigate(
      url.possibly_invalid_spec(),
      webview->GetMainFrame() == frame);
}

void WebDevToolsAgentImpl::AddMessageToConsole(
    int source,
    int level,
    const String& text,
    unsigned int line_no,
    const String& source_id) {
  ConsoleMessage cm(source, level, text, line_no, source_id);
  console_log_.append(cm);
  if (console_log_.size() >= kMaxConsoleMessages) {
    // Batch shifts to save ticks.
    console_log_.remove(0, kMaxConsoleMessages / 5);
  }
  if (attached_) {
    DictionaryValue message;
    Serialize(cm, &message);
    tools_agent_delegate_stub_->AddMessageToConsole(message);
  }
}

void WebDevToolsAgentImpl::WindowObjectCleared(WebFrameImpl* webframe) {
  DebuggerAgentManager::SetHostId(webframe, host_id_);
}

void WebDevToolsAgentImpl::ForceRepaint() {
  delegate_->ForceRepaint();
}

void WebDevToolsAgentImpl::HighlightDOMNode(int node_id) {
  if (!attached_) {
    return;
  }
  Node* node = dom_agent_impl_->GetNodeForId(node_id);
  if (!node) {
    return;
  }
  Page* page = web_view_impl_->page();
  page->inspectorController()->highlight(node);
}

void WebDevToolsAgentImpl::HideDOMNodeHighlight() {
  Page* page = web_view_impl_->page();
  page->inspectorController()->hideHighlight();
}

void WebDevToolsAgentImpl::EvaluateJavaScript(int call_id, const String& js) {
  Page* page = web_view_impl_->page();
  if (!page->mainFrame()) {
    return;
  }
  ScriptValue result = page->mainFrame()->loader()->executeScript(js);
  String result_string;
  if (!result.hasNoValue()) {
    // toString() may need global context.
    v8::HandleScope scope;
    v8::Handle<v8::Context> context = WebCore::V8Proxy::GetContext(
        page->mainFrame());
    v8::Context::Scope context_scope(context);
    result_string = result.toString(NULL);
  }
  tools_agent_delegate_stub_->DidEvaluateJavaScript(call_id, result_string);
}

void WebDevToolsAgentImpl::ExecuteUtilityFunction(
      int call_id,
      const String& function_name,
      int node_id,
      const String& json_args) {
  Node* node = dom_agent_impl_->GetNodeForId(node_id);
  String result;
  String exception;
  if (node) {<commit_msg>DevTools: remove node highlight on dev tools window close. BUG=11766 Review URL: http://codereview.chromium.org/115655<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "config.h"

#include <string>

#include "Document.h"
#include "EventListener.h"
#include "InspectorController.h"
#include "Node.h"
#include "Page.h"
#include "PlatformString.h"
#include "ScriptValue.h"
#include "v8_proxy.h"
#include <wtf/OwnPtr.h>
#undef LOG

#include "base/values.h"
#include "webkit/glue/devtools/debugger_agent_impl.h"
#include "webkit/glue/devtools/debugger_agent_manager.h"
#include "webkit/glue/devtools/dom_agent_impl.h"
#include "webkit/glue/devtools/net_agent_impl.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webdatasource.h"
#include "webkit/glue/webdevtoolsagent_delegate.h"
#include "webkit/glue/webdevtoolsagent_impl.h"
#include "webkit/glue/weburlrequest.h"
#include "webkit/glue/webview_impl.h"

using WebCore::Document;
using WebCore::InspectorController;
using WebCore::Node;
using WebCore::Page;
using WebCore::ScriptValue;
using WebCore::String;

// Maximum size of the console message cache.
static const size_t kMaxConsoleMessages = 200;

WebDevToolsAgentImpl::WebDevToolsAgentImpl(
    WebViewImpl* web_view_impl,
    WebDevToolsAgentDelegate* delegate)
    : host_id_(delegate->GetHostId()),
      delegate_(delegate),
      web_view_impl_(web_view_impl),
      document_(NULL),
      attached_(false) {
  debugger_agent_delegate_stub_.set(new DebuggerAgentDelegateStub(this));
  dom_agent_delegate_stub_.set(new DomAgentDelegateStub(this));
  net_agent_delegate_stub_.set(new NetAgentDelegateStub(this));
  tools_agent_delegate_stub_.set(new ToolsAgentDelegateStub(this));

  // Sniff for requests from the beginning, do not wait for attach.
  net_agent_impl_.set(new NetAgentImpl(net_agent_delegate_stub_.get()));
}

WebDevToolsAgentImpl::~WebDevToolsAgentImpl() {
  DebuggerAgentManager::OnWebViewClosed(web_view_impl_);
  if (!utility_context_.IsEmpty()) {
    utility_context_.Dispose();
    utility_context_.Clear();
  }
}

void WebDevToolsAgentImpl::Attach() {
  if (attached_) {
    return;
  }
  debugger_agent_impl_.set(
      new DebuggerAgentImpl(web_view_impl_,
                            debugger_agent_delegate_stub_.get(),
                            this));
  dom_agent_impl_.set(new DomAgentImpl(dom_agent_delegate_stub_.get()));

  // We are potentially attaching to the running page -> init agents with
  // Document if any.
  Page* page = web_view_impl_->page();
  Document* doc = page->mainFrame()->document();
  if (doc) {
    // Reuse existing context in case detached/attached.
    if (utility_context_.IsEmpty()) {
      debugger_agent_impl_->ResetUtilityContext(doc, &utility_context_);
    }
    dom_agent_impl_->SetDocument(doc);
    net_agent_impl_->SetDocument(doc);
  }

  // Populate console.
  for (Vector<ConsoleMessage>::iterator it = console_log_.begin();
       it != console_log_.end(); ++it) {
    DictionaryValue message;
    Serialize(*it, &message);
    tools_agent_delegate_stub_->AddMessageToConsole(message);
  }

  net_agent_impl_->Attach();
  attached_ = true;
}

void WebDevToolsAgentImpl::Detach() {
  HideDOMNodeHighlight();
  debugger_agent_impl_.set(NULL);
  dom_agent_impl_.set(NULL);
  net_agent_impl_->Detach();
  attached_ = false;
}

void WebDevToolsAgentImpl::SetMainFrameDocumentReady(bool ready) {
  if (!attached_) {
    return;
  }

  // We were attached prior to the page load -> init agents with Document.
  Document* doc;
  if (ready) {
    Page* page = web_view_impl_->page();
    doc = page->mainFrame()->document();
  } else {
    doc = NULL;
  }
  debugger_agent_impl_->ResetUtilityContext(doc, &utility_context_);
  dom_agent_impl_->SetDocument(doc);
  net_agent_impl_->SetDocument(doc);
}

void WebDevToolsAgentImpl::DidCommitLoadForFrame(
    WebViewImpl* webview,
    WebFrame* frame,
    bool is_new_navigation) {
  if (webview->GetMainFrame() == frame) {
    net_agent_impl_->DidCommitMainResourceLoad();
  }
  if (!attached_) {
    return;
  }
  WebDataSource* ds = frame->GetDataSource();
  const WebRequest& request = ds->GetRequest();
  GURL url = ds->HasUnreachableURL() ?
      ds->GetUnreachableURL() :
      request.GetURL();
  tools_agent_delegate_stub_->FrameNavigate(
      url.possibly_invalid_spec(),
      webview->GetMainFrame() == frame);
}

void WebDevToolsAgentImpl::AddMessageToConsole(
    int source,
    int level,
    const String& text,
    unsigned int line_no,
    const String& source_id) {
  ConsoleMessage cm(source, level, text, line_no, source_id);
  console_log_.append(cm);
  if (console_log_.size() >= kMaxConsoleMessages) {
    // Batch shifts to save ticks.
    console_log_.remove(0, kMaxConsoleMessages / 5);
  }
  if (attached_) {
    DictionaryValue message;
    Serialize(cm, &message);
    tools_agent_delegate_stub_->AddMessageToConsole(message);
  }
}

void WebDevToolsAgentImpl::WindowObjectCleared(WebFrameImpl* webframe) {
  DebuggerAgentManager::SetHostId(webframe, host_id_);
}

void WebDevToolsAgentImpl::ForceRepaint() {
  delegate_->ForceRepaint();
}

void WebDevToolsAgentImpl::HighlightDOMNode(int node_id) {
  if (!attached_) {
    return;
  }
  Node* node = dom_agent_impl_->GetNodeForId(node_id);
  if (!node) {
    return;
  }
  Page* page = web_view_impl_->page();
  page->inspectorController()->highlight(node);
}

void WebDevToolsAgentImpl::HideDOMNodeHighlight() {
  Page* page = web_view_impl_->page();
  if (page) {
    page->inspectorController()->hideHighlight();
  }
}

void WebDevToolsAgentImpl::EvaluateJavaScript(int call_id, const String& js) {
  Page* page = web_view_impl_->page();
  if (!page->mainFrame()) {
    return;
  }
  ScriptValue result = page->mainFrame()->loader()->executeScript(js);
  String result_string;
  if (!result.hasNoValue()) {
    // toString() may need global context.
    v8::HandleScope scope;
    v8::Handle<v8::Context> context = WebCore::V8Proxy::GetContext(
        page->mainFrame());
    v8::Context::Scope context_scope(context);
    result_string = result.toString(NULL);
  }
  tools_agent_delegate_stub_->DidEvaluateJavaScript(call_id, result_string);
}

void WebDevToolsAgentImpl::ExecuteUtilityFunction(
      int call_id,
      const String& function_name,
      int node_id,
      const String& json_args) {
  Node* node = dom_agent_impl_->GetNodeForId(node_id);
  String result;
  String exception;
  if (node) {
{'fraction_non_alphanumeric': 0.12295018862114096, 'fraction_numerical': 0.0031565170528909075, 'mean_word_length': 4.608808290155441, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 99, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '393644', 'n_tokens_mistral': 4276, 'n_tokens_neox': 4234, 'n_words': 811}