[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
yurys at chromium.org
yurys at chromium.org
Wed Dec 22 12:22:30 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit b1167124b340ad0c12f583ece66b7ec6d34260de
Author: yurys at chromium.org <yurys at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Fri Aug 20 13:38:14 2010 +0000
2010-08-19 Pavel Podivilov <podivilov at chromium.org>
Reviewed by Yury Semikhatsky.
Web Inspector: implement breaking on DOM node subtree mutations.
https://bugs.webkit.org/show_bug.cgi?id=42886
Add two entries to Web Inspector DOM element context menu:
1. "Stop on subtree modifications": will break on adding/removing of any element which is a child of the DOM element
2. "Remove breakpoints": will remove all breakpoints associated with the DOM element
* English.lproj/localizedStrings.js:
* bindings/js/ScriptDebugServer.cpp:
(WebCore::ScriptDebugServer::breakProgram):
* bindings/js/ScriptDebugServer.h:
* bindings/v8/ScriptDebugServer.cpp:
(WebCore::ScriptDebugServer::breakProgram):
(WebCore::ScriptDebugServer::breakProgramCallback):
(WebCore::ScriptDebugServer::handleV8DebugEvent):
* bindings/v8/ScriptDebugServer.h:
* inspector/Inspector.idl:
* inspector/InspectorDOMAgent.cpp:
(WebCore::InspectorDOMAgent::~InspectorDOMAgent):
(WebCore::InspectorDOMAgent::discardBindings):
(WebCore::InspectorDOMAgent::setDOMBreakpoint):
(WebCore::InspectorDOMAgent::removeDOMBreakpoint):
(WebCore::InspectorDOMAgent::didInsertDOMNode):
(WebCore::InspectorDOMAgent::didRemoveDOMNode):
(WebCore::InspectorDOMAgent::hasBreakpoint):
(WebCore::InspectorDOMAgent::pauseOnBreakpoint):
(WebCore::InspectorDOMAgent::updateSubtreeBreakpoints):
* inspector/InspectorDOMAgent.h:
* inspector/front-end/ElementsTreeOutline.js:
(WebInspector.ElementsTreeElement.prototype._populateTagContextMenu):
* inspector/front-end/Settings.js:
2010-08-19 Pavel Podivilov <podivilov at chromium.org>
Reviewed by Yury Semikhatsky.
Web Inspector: enable DOM breakpoints for chromium
https://bugs.webkit.org/show_bug.cgi?id=42886
* src/js/DevTools.js:
(WebInspector.loaded):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@65731 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 28df9aa..8a43dbc 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,39 @@
+2010-08-19 Pavel Podivilov <podivilov at chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: implement breaking on DOM node subtree mutations.
+ https://bugs.webkit.org/show_bug.cgi?id=42886
+
+ Add two entries to Web Inspector DOM element context menu:
+ 1. "Stop on subtree modifications": will break on adding/removing of any element which is a child of the DOM element
+ 2. "Remove breakpoints": will remove all breakpoints associated with the DOM element
+
+ * English.lproj/localizedStrings.js:
+ * bindings/js/ScriptDebugServer.cpp:
+ (WebCore::ScriptDebugServer::breakProgram):
+ * bindings/js/ScriptDebugServer.h:
+ * bindings/v8/ScriptDebugServer.cpp:
+ (WebCore::ScriptDebugServer::breakProgram):
+ (WebCore::ScriptDebugServer::breakProgramCallback):
+ (WebCore::ScriptDebugServer::handleV8DebugEvent):
+ * bindings/v8/ScriptDebugServer.h:
+ * inspector/Inspector.idl:
+ * inspector/InspectorDOMAgent.cpp:
+ (WebCore::InspectorDOMAgent::~InspectorDOMAgent):
+ (WebCore::InspectorDOMAgent::discardBindings):
+ (WebCore::InspectorDOMAgent::setDOMBreakpoint):
+ (WebCore::InspectorDOMAgent::removeDOMBreakpoint):
+ (WebCore::InspectorDOMAgent::didInsertDOMNode):
+ (WebCore::InspectorDOMAgent::didRemoveDOMNode):
+ (WebCore::InspectorDOMAgent::hasBreakpoint):
+ (WebCore::InspectorDOMAgent::pauseOnBreakpoint):
+ (WebCore::InspectorDOMAgent::updateSubtreeBreakpoints):
+ * inspector/InspectorDOMAgent.h:
+ * inspector/front-end/ElementsTreeOutline.js:
+ (WebInspector.ElementsTreeElement.prototype._populateTagContextMenu):
+ * inspector/front-end/Settings.js:
+
2010-08-20 Yury Semikhatsky <yurys at chromium.org>
Reviewed by Pavel Feldman.
diff --git a/WebCore/bindings/js/ScriptDebugServer.cpp b/WebCore/bindings/js/ScriptDebugServer.cpp
index cd80de4..ecb7fa6 100644
--- a/WebCore/bindings/js/ScriptDebugServer.cpp
+++ b/WebCore/bindings/js/ScriptDebugServer.cpp
@@ -205,6 +205,11 @@ void ScriptDebugServer::pause()
m_pauseOnNextStatement = true;
}
+void ScriptDebugServer::breakProgram()
+{
+ // FIXME(WK43332): implement this.
+}
+
void ScriptDebugServer::continueProgram()
{
if (!m_paused)
diff --git a/WebCore/bindings/js/ScriptDebugServer.h b/WebCore/bindings/js/ScriptDebugServer.h
index fd8976b..432fe9a 100644
--- a/WebCore/bindings/js/ScriptDebugServer.h
+++ b/WebCore/bindings/js/ScriptDebugServer.h
@@ -79,6 +79,7 @@ public:
void setPauseOnExceptionsState(PauseOnExceptionsState);
void pause();
+ void breakProgram();
void continueProgram();
void stepIntoStatement();
void stepOverStatement();
diff --git a/WebCore/bindings/v8/ScriptDebugServer.cpp b/WebCore/bindings/v8/ScriptDebugServer.cpp
index 0c24678..365d692 100644
--- a/WebCore/bindings/v8/ScriptDebugServer.cpp
+++ b/WebCore/bindings/v8/ScriptDebugServer.cpp
@@ -228,6 +228,28 @@ void ScriptDebugServer::pause()
v8::Debug::DebugBreak();
}
+void ScriptDebugServer::breakProgram()
+{
+ DEFINE_STATIC_LOCAL(v8::Persistent<v8::FunctionTemplate>, callbackTemplate, ());
+
+ if (!v8::Context::InContext())
+ return;
+
+ if (callbackTemplate.IsEmpty()) {
+ callbackTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
+ callbackTemplate->SetCallHandler(&ScriptDebugServer::breakProgramCallback);
+ }
+
+ v8::Handle<v8::Context> context = v8::Context::GetCurrent();
+ if (context.IsEmpty())
+ return;
+
+ m_pausedPageContext = *context;
+ v8::Handle<v8::Function> breakProgramFunction = callbackTemplate->GetFunction();
+ v8::Debug::Call(breakProgramFunction);
+ m_pausedPageContext.Clear();
+}
+
void ScriptDebugServer::continueProgram()
{
if (m_pausedPage)
@@ -323,6 +345,41 @@ void ScriptDebugServer::runPendingTasks()
v8::Debug::ProcessDebugMessages();
}
+v8::Handle<v8::Value> ScriptDebugServer::breakProgramCallback(const v8::Arguments& args)
+{
+ ASSERT(2 == args.Length());
+ ScriptDebugServer::shared().breakProgram(v8::Handle<v8::Object>::Cast(args[0]));
+ return v8::Undefined();
+}
+
+void ScriptDebugServer::breakProgram(v8::Handle<v8::Object> executionState)
+{
+ // Don't allow nested breaks.
+ if (m_pausedPage)
+ return;
+
+ Frame* frame = retrieveFrame(m_pausedPageContext);
+ if (!frame)
+ return;
+
+ ScriptDebugListener* listener = m_listenersMap.get(frame->page());
+ if (!listener)
+ return;
+
+ m_executionState.set(executionState);
+ m_pausedPage = frame->page();
+ ScriptState* currentCallFrameState = ScriptState::forContext(m_pausedPageContext);
+ listener->didPause(currentCallFrameState);
+
+ // Wait for continue or step command.
+ m_clientMessageLoop->run(m_pausedPage);
+ ASSERT(!m_pausedPage);
+
+ // The listener may have been removed in the nested loop.
+ if (ScriptDebugListener* listener = m_listenersMap.get(frame->page()))
+ listener->didContinue();
+}
+
void ScriptDebugServer::v8DebugEventCallback(const v8::Debug::EventDetails& eventDetails)
{
ScriptDebugServer::shared().handleV8DebugEvent(eventDetails);
@@ -365,21 +422,9 @@ void ScriptDebugServer::handleV8DebugEvent(const v8::Debug::EventDetails& eventD
return;
}
- // Don't allow nested breaks.
- if (m_pausedPage)
- return;
- m_executionState.set(eventDetails.GetExecutionState());
- m_pausedPage = frame->page();
- ScriptState* currentCallFrameState = mainWorldScriptState(frame);
- listener->didPause(currentCallFrameState);
-
- // Wait for continue or step command.
- m_clientMessageLoop->run(m_pausedPage);
- ASSERT(!m_pausedPage);
-
- // The listener may have been removed in the nested loop.
- if (ScriptDebugListener* listener = m_listenersMap.get(frame->page()))
- listener->didContinue();
+ m_pausedPageContext = *eventContext;
+ breakProgram(eventDetails.GetExecutionState());
+ m_pausedPageContext.Clear();
}
}
}
diff --git a/WebCore/bindings/v8/ScriptDebugServer.h b/WebCore/bindings/v8/ScriptDebugServer.h
index a1e0a47..1ead86b 100644
--- a/WebCore/bindings/v8/ScriptDebugServer.h
+++ b/WebCore/bindings/v8/ScriptDebugServer.h
@@ -71,6 +71,7 @@ public:
void setPauseOnExceptionsState(PauseOnExceptionsState pauseOnExceptionsState);
void pause();
+ void breakProgram();
void continueProgram();
void stepIntoStatement();
void stepOverStatement();
@@ -111,6 +112,9 @@ private:
ScriptDebugServer();
~ScriptDebugServer() { }
+ static v8::Handle<v8::Value> breakProgramCallback(const v8::Arguments& args);
+ void breakProgram(v8::Handle<v8::Object> executionState);
+
static void v8DebugEventCallback(const v8::Debug::EventDetails& eventDetails);
void handleV8DebugEvent(const v8::Debug::EventDetails& eventDetails);
@@ -128,6 +132,7 @@ private:
OwnHandle<v8::Object> m_executionState;
OwnPtr<ClientMessageLoop> m_clientMessageLoop;
Page* m_pausedPage;
+ v8::Local<v8::Context> m_pausedPageContext;
bool m_enabled;
};
diff --git a/WebCore/inspector/Inspector.idl b/WebCore/inspector/Inspector.idl
index 1c66b59..92ff37b 100644
--- a/WebCore/inspector/Inspector.idl
+++ b/WebCore/inspector/Inspector.idl
@@ -176,6 +176,8 @@ module core {
[handler=DOM] void performSearch(in String query, in boolean runSynchronously);
[handler=DOM] void searchCanceled();
[handler=DOM] void pushNodeByPathToFrontend(in long callId, in String path, out long nodeId);
+ [handler=DOM] void setDOMBreakpoint(in long nodeId, in long type);
+ [handler=DOM] void removeDOMBreakpoint(in long nodeId, in long type);
[handler=Controller] void clearConsoleMessages();
[handler=Controller] void highlightDOMNode(in long nodeId);
diff --git a/WebCore/inspector/InspectorDOMAgent.cpp b/WebCore/inspector/InspectorDOMAgent.cpp
index 6243299..9de620d 100644
--- a/WebCore/inspector/InspectorDOMAgent.cpp
+++ b/WebCore/inspector/InspectorDOMAgent.cpp
@@ -62,6 +62,7 @@
#include "RemoteInspectorFrontend.h"
#include "RenderStyle.h"
#include "RenderStyleConstants.h"
+#include "ScriptDebugServer.h"
#include "ScriptEventListener.h"
#include "StyleSheetList.h"
#include "Text.h"
@@ -196,8 +197,16 @@ public:
virtual ~MatchPlainTextJob() { }
};
+enum DOMBreakpointType {
+ DOMBreakpointTypeSubtreeModified = 0
+};
+
+const int domBreakpointDerivedTypeShift = 16;
+
}
+InspectorDOMAgent* InspectorDOMAgent::s_domAgentOnBreakpoint = 0;
+
InspectorDOMAgent::InspectorDOMAgent(InspectorCSSStore* cssStore, RemoteInspectorFrontend* frontend)
: EventListener(InspectorDOMAgentType)
, m_cssStore(cssStore)
@@ -210,6 +219,9 @@ InspectorDOMAgent::InspectorDOMAgent(InspectorCSSStore* cssStore, RemoteInspecto
InspectorDOMAgent::~InspectorDOMAgent()
{
reset();
+
+ if (this == s_domAgentOnBreakpoint)
+ s_domAgentOnBreakpoint = 0;
}
void InspectorDOMAgent::reset()
@@ -371,6 +383,7 @@ void InspectorDOMAgent::discardBindings()
releaseDanglingNodes();
m_childrenRequested.clear();
m_inspectedNodes.clear();
+ m_breakpoints.clear();
}
Node* InspectorDOMAgent::nodeForId(long id)
@@ -720,6 +733,37 @@ void InspectorDOMAgent::searchCanceled()
m_searchResults.clear();
}
+void InspectorDOMAgent::setDOMBreakpoint(long nodeId, long type)
+{
+ Node* node = nodeForId(nodeId);
+ if (!node)
+ return;
+
+ uint32_t rootBit = 1 << type;
+ m_breakpoints.set(node, m_breakpoints.get(node) | rootBit);
+ for (Node* child = innerFirstChild(node); child; child = innerNextSibling(child))
+ updateSubtreeBreakpoints(child, rootBit, true);
+}
+
+void InspectorDOMAgent::removeDOMBreakpoint(long nodeId, long type)
+{
+ Node* node = nodeForId(nodeId);
+ if (!node)
+ return;
+
+ uint32_t rootBit = 1 << type;
+ uint32_t mask = m_breakpoints.get(node) & ~rootBit;
+ if (mask)
+ m_breakpoints.set(node, mask);
+ else
+ m_breakpoints.remove(node);
+ if (mask & (rootBit << domBreakpointDerivedTypeShift))
+ return;
+
+ for (Node* child = innerFirstChild(node); child; child = innerNextSibling(child))
+ updateSubtreeBreakpoints(child, rootBit, false);
+}
+
String InspectorDOMAgent::documentURLString(Document* document) const
{
if (!document || document->url().isNull())
@@ -920,6 +964,17 @@ void InspectorDOMAgent::didInsertDOMNode(Node* node)
if (isWhitespace(node))
return;
+ if (m_breakpoints.size()) {
+ Node* parent = innerParentNode(node);
+ if (hasBreakpoint(parent, DOMBreakpointTypeSubtreeModified)) {
+ if (!pauseOnBreakpoint())
+ return;
+ }
+ uint32_t mask = m_breakpoints.get(parent);
+ mask = mask | (mask >> domBreakpointDerivedTypeShift) & ((1 << domBreakpointDerivedTypeShift) - 1);
+ updateSubtreeBreakpoints(node, mask, true);
+ }
+
// We could be attaching existing subtree. Forget the bindings.
unbind(node, &m_documentNodeToIdMap);
@@ -946,6 +1001,25 @@ void InspectorDOMAgent::didRemoveDOMNode(Node* node)
if (isWhitespace(node))
return;
+ if (m_breakpoints.size()) {
+ if (hasBreakpoint(innerParentNode(node), DOMBreakpointTypeSubtreeModified)) {
+ if (!pauseOnBreakpoint())
+ return;
+ }
+ // Remove subtree breakpoints.
+ m_breakpoints.remove(node);
+ Vector<Node*> stack(1, innerFirstChild(node));
+ do {
+ Node* node = stack.last();
+ stack.removeLast();
+ if (!node)
+ continue;
+ m_breakpoints.remove(node);
+ stack.append(innerFirstChild(node));
+ stack.append(innerNextSibling(node));
+ } while (!stack.isEmpty());
+ }
+
Node* parent = node->parentNode();
long parentId = m_documentNodeToIdMap.get(parent);
// If parent is not mapped yet -> ignore the event.
@@ -971,6 +1045,42 @@ void InspectorDOMAgent::didModifyDOMAttr(Element* element)
m_frontend->attributesUpdated(id, buildArrayForElementAttributes(element));
}
+bool InspectorDOMAgent::hasBreakpoint(Node* node, long type)
+{
+ uint32_t rootBit = 1 << type;
+ uint32_t derivedBit = rootBit << domBreakpointDerivedTypeShift;
+ return m_breakpoints.get(node) & (rootBit | derivedBit);
+}
+
+bool InspectorDOMAgent::pauseOnBreakpoint()
+{
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ s_domAgentOnBreakpoint = this;
+ ScriptDebugServer::shared().breakProgram();
+ bool deleted = !s_domAgentOnBreakpoint;
+ s_domAgentOnBreakpoint = 0;
+ return !deleted;
+#endif
+}
+
+void InspectorDOMAgent::updateSubtreeBreakpoints(Node* node, uint32_t rootMask, bool set)
+{
+ uint32_t oldMask = m_breakpoints.get(node);
+ uint32_t derivedMask = rootMask << domBreakpointDerivedTypeShift;
+ uint32_t newMask = set ? oldMask | derivedMask : oldMask & ~derivedMask;
+ if (newMask)
+ m_breakpoints.set(node, newMask);
+ else
+ m_breakpoints.remove(node);
+
+ uint32_t newRootMask = rootMask & ~newMask;
+ if (!newRootMask)
+ return;
+
+ for (Node* child = innerFirstChild(node); child; child = innerNextSibling(child))
+ updateSubtreeBreakpoints(child, newRootMask, set);
+}
+
void InspectorDOMAgent::getStyles(long nodeId, bool authorOnly, RefPtr<InspectorValue>* styles)
{
Node* node = nodeForId(nodeId);
diff --git a/WebCore/inspector/InspectorDOMAgent.h b/WebCore/inspector/InspectorDOMAgent.h
index 5317a22..fd8452f 100644
--- a/WebCore/inspector/InspectorDOMAgent.h
+++ b/WebCore/inspector/InspectorDOMAgent.h
@@ -112,6 +112,8 @@ namespace WebCore {
void addInspectedNode(long nodeId);
void performSearch(const String& whitespaceTrimmedQuery, bool runSynchronously);
void searchCanceled();
+ void setDOMBreakpoint(long nodeId, long type);
+ void removeDOMBreakpoint(long nodeId, long type);
// Methods called from the frontend for CSS styles inspection.
void getStyles(long nodeId, bool authorOnly, RefPtr<InspectorValue>* styles);
@@ -156,6 +158,10 @@ namespace WebCore {
bool pushDocumentToFrontend();
+ bool hasBreakpoint(Node* node, long type);
+ bool pauseOnBreakpoint();
+ void updateSubtreeBreakpoints(Node* root, uint32_t rootMask, bool value);
+
PassRefPtr<InspectorObject> buildObjectForAttributeStyles(Element* element);
PassRefPtr<InspectorArray> buildArrayForCSSRules(Document* ownerDocument, CSSRuleList*);
PassRefPtr<InspectorArray> buildArrayForPseudoElements(Element* element, bool authorOnly);
@@ -209,6 +215,9 @@ namespace WebCore {
Timer<InspectorDOMAgent> m_matchJobsTimer;
HashSet<RefPtr<Node> > m_searchResults;
Vector<long> m_inspectedNodes;
+ HashMap<Node*, uint32_t> m_breakpoints;
+
+ static InspectorDOMAgent* s_domAgentOnBreakpoint;
};
#endif
diff --git a/WebCore/inspector/front-end/ElementsTreeOutline.js b/WebCore/inspector/front-end/ElementsTreeOutline.js
index c7d39f1..2ad0bf2 100644
--- a/WebCore/inspector/front-end/ElementsTreeOutline.js
+++ b/WebCore/inspector/front-end/ElementsTreeOutline.js
@@ -326,6 +326,8 @@ WebInspector.ElementsTreeElement.EditTagBlacklist = [
"html", "head", "body"
].keySet();
+WebInspector.ElementsTreeElement.DOMBreakpointTypeSubtreeModified = 0;
+
WebInspector.ElementsTreeElement.prototype = {
highlightSearchResults: function(searchQuery)
{
@@ -761,6 +763,15 @@ WebInspector.ElementsTreeElement.prototype = {
contextMenu.appendItem(WebInspector.UIString("Edit as HTML"), this._editAsHTML.bind(this));
contextMenu.appendItem(WebInspector.UIString("Copy as HTML"), this._copyHTML.bind(this));
contextMenu.appendItem(WebInspector.UIString("Delete Node"), this.remove.bind(this));
+
+ if (Preferences.domBreakpointsEnabled) {
+ // Add debbuging-related actions
+ contextMenu.appendSeparator();
+ contextMenu.appendItem(WebInspector.UIString("Stop on subtree modifications"),
+ InspectorBackend.setDOMBreakpoint.bind(InspectorBackend, this.representedObject.id, WebInspector.ElementsTreeElement.DOMBreakpointTypeSubtreeModified));
+ contextMenu.appendItem(WebInspector.UIString("Remove Breakpoints"),
+ InspectorBackend.removeDOMBreakpoint.bind(InspectorBackend, this.representedObject.id, WebInspector.ElementsTreeElement.DOMBreakpointTypeSubtreeModified));
+ }
},
_populateTextContextMenu: function(contextMenu, textNode)
diff --git a/WebCore/inspector/front-end/Settings.js b/WebCore/inspector/front-end/Settings.js
index c84ba79..68e40c4 100644
--- a/WebCore/inspector/front-end/Settings.js
+++ b/WebCore/inspector/front-end/Settings.js
@@ -43,7 +43,8 @@ var Preferences = {
debuggerAlwaysEnabled: false,
profilerAlwaysEnabled: false,
auditsPanelEnabled: true,
- onlineDetectionEnabled: true
+ onlineDetectionEnabled: true,
+ domBreakpointsEnabled: false
}
WebInspector.populateApplicationSettings = function(settingsString)
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index f486d49..aa07c45 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,13 @@
+2010-08-19 Pavel Podivilov <podivilov at chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: enable DOM breakpoints for chromium
+ https://bugs.webkit.org/show_bug.cgi?id=42886
+
+ * src/js/DevTools.js:
+ (WebInspector.loaded):
+
2010-08-19 Vincent Scheib <scheib at chromium.org>
Reviewed by David Levin.
diff --git a/WebKit/chromium/src/js/DevTools.js b/WebKit/chromium/src/js/DevTools.js
index 0fd66c9..e3e0204 100644
--- a/WebKit/chromium/src/js/DevTools.js
+++ b/WebKit/chromium/src/js/DevTools.js
@@ -74,6 +74,7 @@ WebInspector.loaded = function()
Preferences.profilerAlwaysEnabled = true;
Preferences.canEditScriptSource = true;
Preferences.onlineDetectionEnabled = false;
+ Preferences.domBreakpointsEnabled = true;
oldLoaded.call(WebInspector);
}
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list