Index: android_webview/browser/aw_devtools_delegate.cc |
diff --git a/android_webview/browser/aw_devtools_delegate.cc b/android_webview/browser/aw_devtools_delegate.cc |
index 7232dd894c9132bde1dd94ea597d586de2a7b283..1138f887dd345ee06ad502b85656f7d02e0c393f 100644 |
--- a/android_webview/browser/aw_devtools_delegate.cc |
+++ b/android_webview/browser/aw_devtools_delegate.cc |
@@ -4,8 +4,11 @@ |
#include "android_webview/browser/aw_devtools_delegate.h" |
+#include "android_webview/browser/browser_view_renderer_impl.h" |
#include "base/bind.h" |
+#include "base/json/json_writer.h" |
#include "base/stringprintf.h" |
+#include "base/values.h" |
#include "content/public/browser/android/devtools_auth.h" |
#include "content/public/browser/devtools_http_handler.h" |
#include "content/public/browser/web_contents.h" |
@@ -33,8 +36,8 @@ AwDevToolsDelegate::~AwDevToolsDelegate() { |
} |
void AwDevToolsDelegate::Stop() { |
- // The HTTP handler will delete our instance. |
devtools_http_handler_->Stop(); |
+ // WARNING: |this| has now been deleted by the method above. |
} |
std::string AwDevToolsDelegate::GetDiscoveryPageHTML() { |
@@ -51,46 +54,89 @@ std::string AwDevToolsDelegate::GetDiscoveryPageHTML() { |
"function onLoad() {" |
" var tabs_list_request = new XMLHttpRequest();" |
" tabs_list_request.open(" |
- "\"GET\", \"/json/list?t=\" + new Date().getTime(), true);" |
+ " 'GET', '/json/list?t=' + new Date().getTime(), true);" |
" tabs_list_request.onreadystatechange = onReady;" |
" tabs_list_request.send();" |
"}" |
+ "function viewsComparator(v1, v2) {" |
+ " if (v1.attached != v2.attached) {" |
+ " return v1.attached ? -1 : 1;" |
+ " } else if (v1.visible != v2.visible) {" |
+ " return v1.visible ? -1 : 1;" |
+ " } else if (v1.empty != v2.empty) {" |
+ " return v1.empty ? 1 : -1;" |
+ " } else if (v1.screenX != v2.screenX) {" |
+ " return v1.screenX - v2.screenX;" |
+ " } else if (v1.screenY != v2.screenY) {" |
+ " return v1.screenY - v2.screenY;" |
+ " }" |
+ " return 0;" |
+ "}" |
+ "function processItem(item) {" |
+ " var result = JSON.parse(item.description);" |
+ " result.debuggable = !!item.devtoolsFrontendUrl;" |
+ " result.debugUrl = item.devtoolsFrontendUrl;" |
+ " result.title = item.title;" |
+ " return result;" |
+ "}" |
"function onReady() {" |
" if(this.readyState == 4 && this.status == 200) {" |
" if(this.response != null)" |
" var responseJSON = JSON.parse(this.response);" |
+ " var items = [];" |
" for (var i = 0; i < responseJSON.length; ++i)" |
- " appendItem(responseJSON[i]);" |
+ " items.push(processItem(responseJSON[i]));" |
+ " items.sort(viewsComparator);" |
+ " for (var i = 0; i < items.length; ++i)" |
+ " displayView(items[i]);" |
" }" |
"}" |
- "function appendItem(item_object) {" |
+ "function addColumn(row, text) {" |
+ " var column = document.createElement('td');" |
+ " column.innerText = text;" |
+ " row.appendChild(column);" |
+ "}" |
+ "function cutTextIfNeeded(text, maxLen) {" |
+ " return text.length <= maxLen ?" |
+ " text : text.substr(0, maxLen) + '\u2026';" |
+ "}" |
+ "function displayView(item) {" |
+ " var row = document.createElement('tr');" |
+ " var column = document.createElement('td');" |
" var frontend_ref;" |
- " if (item_object.devtoolsFrontendUrl) {" |
- " frontend_ref = document.createElement(\"a\");" |
- " frontend_ref.href = item_object.devtoolsFrontendUrl;" |
- " frontend_ref.title = item_object.title;" |
+ " if (item.debuggable) {" |
+ " frontend_ref = document.createElement('a');" |
+ " frontend_ref.href = item.debugUrl;" |
+ " frontend_ref.title = item.title;" |
+ " column.appendChild(frontend_ref);" |
+ " } else {" |
+ " frontend_ref = column;" |
+ " }" |
+ " var text = document.createElement('span');" |
+ " if (item.title) {" |
+ " text.innerText = cutTextIfNeeded(item.title, 64);" |
" } else {" |
- " frontend_ref = document.createElement(\"div\");" |
- " frontend_ref.title = " |
- "\"The view already has active debugging session\";" |
+ " text.innerText = '(untitled)';" |
" }" |
- " var text = document.createElement(\"div\");" |
- " if (item_object.title)" |
- " text.innerText = item_object.title;" |
- " else" |
- " text.innerText = \"(untitled tab)\";" |
- " text.style.cssText = " |
- "\"background-image:url(\" + item_object.faviconUrl + \")\";" |
" frontend_ref.appendChild(text);" |
- " var item = document.createElement(\"p\");" |
- " item.appendChild(frontend_ref);" |
- " document.getElementById(\"items\").appendChild(item);" |
+ " row.appendChild(column);" |
+ " addColumn(row, item.attached ? 'Y' : 'N');" |
+ " addColumn(row, item.visible ? 'Y' : 'N');" |
+ " addColumn(row, item.empty ? 'Y' : 'N');" |
+ " addColumn(row, item.screenX + ', ' + item.screenY);" |
+ " addColumn(row," |
+ " !item.empty ? (item.width + '\u00d7' + item.height) : '');" |
+ " document.getElementById('items').appendChild(row);" |
"}" |
"</script>" |
"</head>" |
"<body onload='onLoad()'>" |
" <div id='caption'>Inspectable WebViews</div>" |
- " <div id='items'></div>" |
+ " <table>" |
+ " <tr><th>Title</th><th>Attached</th><th>Visible</th><th>Empty</th>" |
+ "<th>Position</th><th>Size</th></tr>" |
+ " <tbody id='items'></tbody>" |
+ " </table>" |
"</body>" |
"</html>"; |
return html; |
@@ -117,8 +163,28 @@ AwDevToolsDelegate::GetTargetType(content::RenderViewHost*) { |
return kTargetTypeTab; |
} |
-std::string AwDevToolsDelegate::GetViewDescription(content::RenderViewHost*) { |
- return ""; |
+std::string AwDevToolsDelegate::GetViewDescription( |
+ content::RenderViewHost* rvh) { |
+ content::WebContents* web_contents = |
+ content::WebContents::FromRenderViewHost(rvh); |
+ if (!web_contents) return ""; |
+ BrowserViewRenderer* bvr = |
+ BrowserViewRendererImpl::FromWebContents(web_contents); |
+ if (!bvr) return ""; |
+ base::DictionaryValue description; |
+ description.SetBoolean("attached", bvr->IsAttachedToWindow()); |
+ description.SetBoolean("visible", bvr->IsViewVisible()); |
+ gfx::Rect screen_rect = bvr->GetScreenRect(); |
+ description.SetInteger("screenX", screen_rect.x()); |
+ description.SetInteger("screenY", screen_rect.y()); |
+ description.SetBoolean("empty", screen_rect.size().IsEmpty()); |
+ if (!screen_rect.size().IsEmpty()) { |
+ description.SetInteger("width", screen_rect.width()); |
+ description.SetInteger("height", screen_rect.height()); |
+ } |
+ std::string json; |
+ base::JSONWriter::Write(&description, &json); |
+ return json; |
} |
} // namespace android_webview |