https://bugs.webkit.org/show_bug.cgi?id=77972
When object popover is shown the object under cursor is resolved and its
wrapper is put into 'popover' object wrapper group. The group is discarded
when the popover closes.
Reviewed by Pavel Feldman.
* bindings/js/ScriptProfiler.cpp:
(WebCore::ScriptProfiler::objectByHeapObjectId):
* bindings/js/ScriptProfiler.h:
(WebCore):
(ScriptProfiler):
* bindings/v8/ScriptProfiler.cpp:
(WebCore::ScriptProfiler::objectByHeapObjectId):
(WebCore):
* bindings/v8/ScriptProfiler.h:
(WebCore):
(ScriptProfiler):
* inspector/Inspector.json:
* inspector/InspectorProfilerAgent.cpp:
(WebCore::InspectorProfilerAgent::getObjectByHeapObjectId):
* inspector/InspectorProfilerAgent.h:
(InspectorProfilerAgent):
* inspector/front-end/DetailedHeapshotGridNodes.js:
(WebInspector.HeapSnapshotGenericObjectNode.prototype.queryObjectContent):
* inspector/front-end/DetailedHeapshotView.js:
(WebInspector.DetailedHeapshotView.prototype._resolveObjectForPopover):
* inspector/front-end/JavaScriptSourceFrame.js:
(WebInspector.JavaScriptSourceFrame):
(WebInspector.JavaScriptSourceFrame.prototype._resolveObjectForPopover):
(WebInspector.JavaScriptSourceFrame.prototype._onHidePopover):
* inspector/front-end/ObjectPopoverHelper.js:
(WebInspector.ObjectPopoverHelper):
(WebInspector.ObjectPopoverHelper.prototype._showObjectPopover):
(WebInspector.ObjectPopoverHelper.prototype._onHideObjectPopover):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@107089
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2012-02-07 Yury Semikhatsky <yurys@chromium.org>
+
+ Web Inspector: inspected object wrapper should be released by InjectedScript when popover closes
+ https://bugs.webkit.org/show_bug.cgi?id=77972
+
+ When object popover is shown the object under cursor is resolved and its
+ wrapper is put into 'popover' object wrapper group. The group is discarded
+ when the popover closes.
+
+ Reviewed by Pavel Feldman.
+
+ * bindings/js/ScriptProfiler.cpp:
+ (WebCore::ScriptProfiler::objectByHeapObjectId):
+ * bindings/js/ScriptProfiler.h:
+ (WebCore):
+ (ScriptProfiler):
+ * bindings/v8/ScriptProfiler.cpp:
+ (WebCore::ScriptProfiler::objectByHeapObjectId):
+ (WebCore):
+ * bindings/v8/ScriptProfiler.h:
+ (WebCore):
+ (ScriptProfiler):
+ * inspector/Inspector.json:
+ * inspector/InspectorProfilerAgent.cpp:
+ (WebCore::InspectorProfilerAgent::getObjectByHeapObjectId):
+ * inspector/InspectorProfilerAgent.h:
+ (InspectorProfilerAgent):
+ * inspector/front-end/DetailedHeapshotGridNodes.js:
+ (WebInspector.HeapSnapshotGenericObjectNode.prototype.queryObjectContent):
+ * inspector/front-end/DetailedHeapshotView.js:
+ (WebInspector.DetailedHeapshotView.prototype._resolveObjectForPopover):
+ * inspector/front-end/JavaScriptSourceFrame.js:
+ (WebInspector.JavaScriptSourceFrame):
+ (WebInspector.JavaScriptSourceFrame.prototype._resolveObjectForPopover):
+ (WebInspector.JavaScriptSourceFrame.prototype._onHidePopover):
+ * inspector/front-end/ObjectPopoverHelper.js:
+ (WebInspector.ObjectPopoverHelper):
+ (WebInspector.ObjectPopoverHelper.prototype._showObjectPopover):
+ (WebInspector.ObjectPopoverHelper.prototype._onHideObjectPopover):
+
2012-02-08 Mario Sanchez Prada <msanchez@igalia.com>
[Gtk] atk_text_get_text_at_offset() fails to provide the correct line for list items whose text wraps
#include "ScriptProfiler.h"
#include "GCController.h"
-#include "InspectorValues.h"
#include "JSDOMBinding.h"
+#include "ScriptObject.h"
#include <profiler/Profiler.h>
namespace WebCore {
gcController().garbageCollectNow();
}
-PassRefPtr<InspectorValue> ScriptProfiler::objectByHeapObjectId(unsigned, InjectedScriptManager*)
+ScriptObject ScriptProfiler::objectByHeapObjectId(unsigned)
{
- return InspectorValue::null();
+ return ScriptObject();
}
void ScriptProfiler::start(ScriptState* state, const String& title)
#define ScriptProfiler_h
#if ENABLE(JAVASCRIPT_DEBUGGER)
-#include "InspectorValues.h"
#include "ScriptHeapSnapshot.h"
#include "ScriptProfile.h"
#include "ScriptState.h"
namespace WebCore {
class DOMWrapperVisitor;
-class InjectedScriptManager;
+class ScriptObject;
class ScriptProfiler {
WTF_MAKE_NONCOPYABLE(ScriptProfiler);
};
static void collectGarbage();
- static PassRefPtr<InspectorValue> objectByHeapObjectId(unsigned id, InjectedScriptManager*);
+ static ScriptObject objectByHeapObjectId(unsigned id);
static void start(ScriptState* state, const String& title);
static PassRefPtr<ScriptProfile> stop(ScriptState* state, const String& title);
static PassRefPtr<ScriptHeapSnapshot> takeHeapSnapshot(const String&, HeapSnapshotProgress*) { return 0; }
#include "ScriptProfiler.h"
#include "DOMWrapperVisitor.h"
-#include "InjectedScript.h"
-#include "InspectorValues.h"
#include "RetainedDOMInfo.h"
+#include "ScriptObject.h"
#include "V8Binding.h"
#include "V8DOMMap.h"
#include "V8Node.h"
v8::V8::LowMemoryNotification();
}
-PassRefPtr<InspectorValue> ScriptProfiler::objectByHeapObjectId(unsigned id, InjectedScriptManager* injectedScriptManager)
+ScriptObject ScriptProfiler::objectByHeapObjectId(unsigned id)
{
// As ids are unique, it doesn't matter which HeapSnapshot owns HeapGraphNode.
// We need to find first HeapSnapshot containing a node with the specified id.
break;
}
if (!node)
- return InspectorValue::null();
+ return ScriptObject();
v8::HandleScope scope;
v8::Handle<v8::Value> value = node->GetHeapValue();
if (!value->IsObject())
- return InspectorValue::null();
-
- v8::Handle<v8::Object> object(value.As<v8::Object>());
- v8::Local<v8::Context> creationContext = object->CreationContext();
- v8::Context::Scope creationScope(creationContext);
- ScriptState* scriptState = ScriptState::forContext(creationContext);
- InjectedScript injectedScript = injectedScriptManager->injectedScriptFor(scriptState);
- return !injectedScript.hasNoValue() ?
- RefPtr<InspectorValue>(injectedScript.wrapObject(value, "")).release() : InspectorValue::null();
+ return ScriptObject();
+
+ v8::Handle<v8::Object> object = value.As<v8::Object>();
+ ScriptState* scriptState = ScriptState::forContext(object->CreationContext());
+ return ScriptObject(scriptState, object);
}
namespace {
#ifndef ScriptProfiler_h
#define ScriptProfiler_h
-#include "InspectorValues.h"
#include "PlatformString.h"
#include "ScriptHeapSnapshot.h"
#include "ScriptProfile.h"
namespace WebCore {
class DOMWrapperVisitor;
-class InjectedScriptManager;
+class ScriptObject;
class ScriptProfiler {
WTF_MAKE_NONCOPYABLE(ScriptProfiler);
};
static void collectGarbage();
- static PassRefPtr<InspectorValue> objectByHeapObjectId(unsigned id, InjectedScriptManager*);
+ static ScriptObject objectByHeapObjectId(unsigned id);
static void start(ScriptState* state, const String& title);
static PassRefPtr<ScriptProfile> stop(ScriptState* state, const String& title);
static PassRefPtr<ScriptHeapSnapshot> takeHeapSnapshot(const String& title, HeapSnapshotProgress*);
{
"name": "getObjectByHeapObjectId",
"parameters": [
- { "name": "objectId", "type": "integer" }
+ { "name": "objectId", "type": "integer" },
+ { "name": "objectGroup", "type": "string", "optional": true, "description": "Symbolic group name that can be used to release multiple objects." }
],
"returns": [
{ "name": "result", "$ref": "Runtime.RemoteObject", "description": "Evaluation result." }
#if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR)
#include "Console.h"
+#include "InjectedScript.h"
#include "InspectorConsoleAgent.h"
#include "InspectorFrontend.h"
#include "InspectorState.h"
#include "Page.h"
#include "PageScriptDebugServer.h"
#include "ScriptHeapSnapshot.h"
+#include "ScriptObject.h"
#include "ScriptProfile.h"
#include "ScriptProfiler.h"
#include <wtf/OwnPtr.h>
m_frontend->setRecordingProfile(isProfiling);
}
-void InspectorProfilerAgent::getObjectByHeapObjectId(ErrorString* error, int id, RefPtr<InspectorObject>& result)
+void InspectorProfilerAgent::getObjectByHeapObjectId(ErrorString* error, int id, const String* objectGroup, RefPtr<InspectorObject>& result)
{
- RefPtr<InspectorValue> heapObject = ScriptProfiler::objectByHeapObjectId(id, m_injectedScriptManager);
- if (!heapObject->isNull())
- heapObject->asObject(&result);
- else
+ ScriptObject heapObject = ScriptProfiler::objectByHeapObjectId(id);
+ if (heapObject.hasNoValue()) {
*error = "Object is not available.";
+ return;
+ }
+ InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(heapObject.scriptState());
+ if (injectedScript.hasNoValue()) {
+ *error = "Object is not available. Inspected context is gone.";
+ return;
+ }
+ result = injectedScript.wrapObject(heapObject, objectGroup ? *objectGroup : "");
+ if (!result)
+ *error = "Failed to wrap object.";
}
} // namespace WebCore
virtual void takeHeapSnapshot(ErrorString*);
void toggleRecordButton(bool isProfiling);
- virtual void getObjectByHeapObjectId(ErrorString*, int id, RefPtr<InspectorObject>& result);
+ virtual void getObjectByHeapObjectId(ErrorString*, int id, const String* objectGroup, RefPtr<InspectorObject>& result);
private:
typedef HashMap<unsigned int, RefPtr<ScriptProfile> > ProfilesMap;
return this._enhanceData ? this._enhanceData(data) : data;
},
- queryObjectContent: function(callback)
+ queryObjectContent: function(callback, objectGroupName)
{
if (this._type === "string")
callback(WebInspector.RemoteObject.fromPrimitiveValue(this._name));
else
callback(WebInspector.RemoteObject.fromPrimitiveValue(WebInspector.UIString("Not available")));
}
- ProfilerAgent.getObjectByHeapObjectId(this.snapshotNodeId, formatResult);
+ ProfilerAgent.getObjectByHeapObjectId(this.snapshotNodeId, objectGroupName, formatResult);
}
},
this.helpButton = new WebInspector.StatusBarButton("", "heapshot-help-status-bar-item status-bar-item");
this.helpButton.addEventListener("click", this._helpClicked.bind(this), false);
- this._popoverHelper = new WebInspector.ObjectPopoverHelper(this.element, this._getHoverAnchor.bind(this), this._showObjectPopover.bind(this), null, true);
+ this._popoverHelper = new WebInspector.ObjectPopoverHelper(this.element, this._getHoverAnchor.bind(this), this._resolveObjectForPopover.bind(this), null, true);
this._loadProfile(this._profileUid, profileCallback.bind(this));
this.refreshShowPercents();
},
- _showObjectPopover: function(element, showCallback)
+ _resolveObjectForPopover: function(element, showCallback, objectGroupName)
{
- element.node.queryObjectContent(showCallback);
+ element.node.queryObjectContent(showCallback, objectGroupName);
},
_helpClicked: function(event)
this._scriptsPanel = scriptsPanel;
this._model = model;
this._uiSourceCode = uiSourceCode;
- this._popoverObjectGroup = "popover";
this._breakpoints = {};
WebInspector.SourceFrame.call(this, uiSourceCode.url);
this._popoverHelper = new WebInspector.ObjectPopoverHelper(this.textViewer.element,
- this._getPopoverAnchor.bind(this), this._onShowPopover.bind(this), this._onHidePopover.bind(this), true);
+ this._getPopoverAnchor.bind(this), this._resolveObjectForPopover.bind(this), this._onHidePopover.bind(this), true);
this.textViewer.element.addEventListener("mousedown", this._onMouseDown.bind(this), true);
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.ContentChanged, this._onContentChanged, this);
return element;
},
- _onShowPopover: function(element, showCallback)
+ _resolveObjectForPopover: function(element, showCallback, objectGroupName)
{
if (!this.readOnly) {
this._popoverHelper.hidePopover();
}
var selectedCallFrame = this._model.selectedCallFrame;
- selectedCallFrame.evaluate(this._highlightElement.textContent, this._popoverObjectGroup, false, false, showObjectPopover.bind(this));
+ selectedCallFrame.evaluate(this._highlightElement.textContent, objectGroupName, false, false, showObjectPopover.bind(this));
},
_onHidePopover: function()
parentElement.removeChild(highlightElement);
}
delete this._highlightElement;
- RuntimeAgent.releaseObjectGroup(this._popoverObjectGroup);
},
_highlightExpression: function(element)
WebInspector.PopoverHelper.call(this, panelElement, getAnchor, this._showObjectPopover.bind(this), this._onHideObjectPopover.bind(this), disableOnClick);
this._queryObject = queryObject;
this._onHideCallback = onHide;
+ this._popoverObjectGroup = "popover";
panelElement.addEventListener("scroll", this.hidePopover.bind(this), true);
};
popover.show(popoverContentElement, element, popoverWidth, popoverHeight);
}
}
- this._queryObject(element, showObjectPopover.bind(this));
+ this._queryObject(element, showObjectPopover.bind(this), this._popoverObjectGroup);
},
_onHideObjectPopover: function()
}
if (this._onHideCallback)
this._onHideCallback();
+ RuntimeAgent.releaseObjectGroup(this._popoverObjectGroup);
},
_updateHTMLId: function(properties, rootTreeElementConstructor, rootPropertyComparer)