summaryrefslogtreecommitdiffstats
path: root/WebCore/inspector
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/inspector')
-rw-r--r--WebCore/inspector/ConsoleMessage.cpp138
-rw-r--r--WebCore/inspector/ConsoleMessage.h69
-rw-r--r--WebCore/inspector/InspectorClient.h2
-rw-r--r--WebCore/inspector/InspectorController.cpp1335
-rw-r--r--WebCore/inspector/InspectorController.h40
-rw-r--r--WebCore/inspector/InspectorController.idl91
-rw-r--r--WebCore/inspector/InspectorDOMStorageResource.cpp95
-rw-r--r--WebCore/inspector/InspectorDOMStorageResource.h76
-rw-r--r--WebCore/inspector/InspectorDatabaseResource.cpp89
-rw-r--r--WebCore/inspector/InspectorDatabaseResource.h70
-rw-r--r--WebCore/inspector/InspectorResource.cpp181
-rw-r--r--WebCore/inspector/InspectorResource.h109
-rw-r--r--WebCore/inspector/JavaScriptDebugServer.cpp11
-rw-r--r--WebCore/inspector/front-end/Console.js186
-rw-r--r--WebCore/inspector/front-end/DOMStorage.js72
-rw-r--r--WebCore/inspector/front-end/DOMStorageDataGrid.js103
-rw-r--r--WebCore/inspector/front-end/DOMStorageItemsView.js108
-rw-r--r--WebCore/inspector/front-end/DatabaseQueryView.js2
-rw-r--r--WebCore/inspector/front-end/DatabaseTableView.js20
-rw-r--r--WebCore/inspector/front-end/DatabasesPanel.js199
-rw-r--r--WebCore/inspector/front-end/Images/domStorage.pngbin0 -> 442 bytes
-rw-r--r--WebCore/inspector/front-end/Images/userInputResultIcon.pngbin0 -> 259 bytes
-rw-r--r--WebCore/inspector/front-end/ScriptsPanel.js22
-rw-r--r--WebCore/inspector/front-end/SourceFrame.js2
-rw-r--r--WebCore/inspector/front-end/WebKit.qrc4
-rw-r--r--WebCore/inspector/front-end/inspector.css135
-rw-r--r--WebCore/inspector/front-end/inspector.html3
-rw-r--r--WebCore/inspector/front-end/inspector.js9
-rw-r--r--WebCore/inspector/front-end/utilities.js37
29 files changed, 1866 insertions, 1342 deletions
diff --git a/WebCore/inspector/ConsoleMessage.cpp b/WebCore/inspector/ConsoleMessage.cpp
new file mode 100644
index 0000000..b2bf390
--- /dev/null
+++ b/WebCore/inspector/ConsoleMessage.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ConsoleMessage.h"
+
+#include "JSInspectedObjectWrapper.h"
+#include "ScriptCallStack.h"
+#include "ScriptCallFrame.h"
+#include "ScriptFunctionCall.h"
+#include "ScriptObjectQuarantine.h"
+#include "ScriptString.h"
+
+namespace WebCore {
+
+ConsoleMessage::ConsoleMessage(MessageSource s, MessageLevel l, const String& m, unsigned li, const String& u, unsigned g)
+ : m_source(s)
+ , m_level(l)
+ , m_message(m)
+ , m_line(li)
+ , m_url(u)
+ , m_groupLevel(g)
+ , m_repeatCount(1)
+{
+}
+
+ConsoleMessage::ConsoleMessage(MessageSource s, MessageLevel l, ScriptCallStack* callStack, unsigned g, bool storeTrace)
+ : m_source(s)
+ , m_level(l)
+ , m_wrappedArguments(callStack->at(0).argumentCount())
+ , m_frames(storeTrace ? callStack->size() : 0)
+ , m_groupLevel(g)
+ , m_repeatCount(1)
+{
+ const ScriptCallFrame& lastCaller = callStack->at(0);
+ m_line = lastCaller.lineNumber();
+ m_url = lastCaller.sourceURL().string();
+
+ // FIXME: For now, just store function names as strings.
+ // As ScriptCallStack start storing line number and source URL for all
+ // frames, refactor to use that, as well.
+ if (storeTrace) {
+ for (unsigned i = 0; i < callStack->size(); ++i)
+ m_frames[i] = callStack->at(i).functionName();
+ }
+
+ for (unsigned i = 0; i < lastCaller.argumentCount(); ++i)
+ m_wrappedArguments[i] = quarantineValue(callStack->state(), lastCaller.argumentAt(i));
+}
+
+void ConsoleMessage::addToConsole(ScriptState* scriptState, const ScriptObject& webInspector)
+{
+ ScriptFunctionCall messageConstructor(scriptState, webInspector, "ConsoleMessage");
+ messageConstructor.appendArgument(static_cast<unsigned int>(m_source));
+ messageConstructor.appendArgument(static_cast<unsigned int>(m_level));
+ messageConstructor.appendArgument(m_line);
+ messageConstructor.appendArgument(m_url);
+ messageConstructor.appendArgument(m_groupLevel);
+ messageConstructor.appendArgument(m_repeatCount);
+
+ if (!m_frames.isEmpty()) {
+ for (unsigned i = 0; i < m_frames.size(); ++i)
+ messageConstructor.appendArgument(m_frames[i]);
+ } else if (!m_wrappedArguments.isEmpty()) {
+ for (unsigned i = 0; i < m_wrappedArguments.size(); ++i)
+ messageConstructor.appendArgument(m_wrappedArguments[i]);
+ } else
+ messageConstructor.appendArgument(m_message);
+
+ bool hadException = false;
+ ScriptObject message = messageConstructor.construct(hadException);
+ if (hadException)
+ return;
+
+ ScriptFunctionCall addMessageToConsole(scriptState, webInspector, "addMessageToConsole");
+ addMessageToConsole.appendArgument(message);
+ addMessageToConsole.call(hadException);
+}
+
+bool ConsoleMessage::isEqual(ScriptState* state, ConsoleMessage* msg) const
+{
+ if (msg->m_wrappedArguments.size() != m_wrappedArguments.size())
+ return false;
+ if (!state && msg->m_wrappedArguments.size())
+ return false;
+
+ ASSERT_ARG(state, state || msg->m_wrappedArguments.isEmpty());
+
+ for (size_t i = 0; i < msg->m_wrappedArguments.size(); ++i) {
+ if (!m_wrappedArguments[i].isEqual(state, msg->m_wrappedArguments[i]))
+ return false;
+ }
+
+ size_t frameCount = msg->m_frames.size();
+ if (frameCount != m_frames.size())
+ return false;
+
+ for (size_t i = 0; i < frameCount; ++i) {
+ if (m_frames[i] != msg->m_frames[i])
+ return false;
+ }
+
+ return msg->m_source == m_source
+ && msg->m_level == m_level
+ && msg->m_message == m_message
+ && msg->m_line == m_line
+ && msg->m_url == m_url
+ && msg->m_groupLevel == m_groupLevel;
+}
+
+} // namespace WebCore
diff --git a/WebCore/inspector/ConsoleMessage.h b/WebCore/inspector/ConsoleMessage.h
new file mode 100644
index 0000000..d97cbb3
--- /dev/null
+++ b/WebCore/inspector/ConsoleMessage.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ConsoleMessage_h
+#define ConsoleMessage_h
+
+#include "Console.h"
+#include "ScriptObject.h"
+#include "ScriptState.h"
+
+#include <runtime/Protect.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+ class ScriptCallStack;
+ class ScriptString;
+
+ class ConsoleMessage {
+ public:
+ ConsoleMessage(MessageSource, MessageLevel, const String& m, unsigned li, const String& u, unsigned g);
+ ConsoleMessage(MessageSource, MessageLevel, ScriptCallStack*, unsigned g, bool storeTrace = false);
+
+ void addToConsole(ScriptState*, const ScriptObject& webInspector);
+ void incrementCount() { ++m_repeatCount; };
+ bool isEqual(ScriptState*, ConsoleMessage* msg) const;
+
+ private:
+ MessageSource m_source;
+ MessageLevel m_level;
+ String m_message;
+ Vector<ScriptValue> m_wrappedArguments;
+ Vector<ScriptString> m_frames;
+ unsigned m_line;
+ String m_url;
+ unsigned m_groupLevel;
+ unsigned m_repeatCount;
+ };
+
+} // namespace WebCore
+
+#endif // ConsoleMessage_h
diff --git a/WebCore/inspector/InspectorClient.h b/WebCore/inspector/InspectorClient.h
index fcbf79d..2508536 100644
--- a/WebCore/inspector/InspectorClient.h
+++ b/WebCore/inspector/InspectorClient.h
@@ -44,6 +44,8 @@ public:
virtual String localizedStringsURL() = 0;
+ virtual String hiddenPanels() = 0;
+
virtual void showWindow() = 0;
virtual void closeWindow() = 0;
diff --git a/WebCore/inspector/InspectorController.cpp b/WebCore/inspector/InspectorController.cpp
index 5cdc368..ae50769 100644
--- a/WebCore/inspector/InspectorController.cpp
+++ b/WebCore/inspector/InspectorController.cpp
@@ -33,6 +33,7 @@
#include "CString.h"
#include "CachedResource.h"
#include "Console.h"
+#include "ConsoleMessage.h"
#include "DOMWindow.h"
#include "DocLoader.h"
#include "Document.h"
@@ -46,34 +47,40 @@
#include "FrameTree.h"
#include "FrameView.h"
#include "GraphicsContext.h"
-#include "HitTestResult.h"
#include "HTMLFrameOwnerElement.h"
+#include "HitTestResult.h"
#include "InspectorClient.h"
+#include "InspectorDatabaseResource.h"
+#include "InspectorDOMStorageResource.h"
+#include "InspectorResource.h"
#include "JSDOMWindow.h"
#include "JSInspectedObjectWrapper.h"
#include "JSInspectorCallbackWrapper.h"
+#include "JSInspectorController.h"
#include "JSNode.h"
#include "JSRange.h"
#include "JavaScriptProfile.h"
#include "Page.h"
#include "Range.h"
+#include "RenderInline.h"
#include "ResourceRequest.h"
#include "ResourceResponse.h"
-#include "Settings.h"
#include "ScriptCallStack.h"
+#include "ScriptController.h"
+#include "SecurityOrigin.h"
+#include "Settings.h"
#include "SharedBuffer.h"
#include "TextEncoding.h"
#include "TextIterator.h"
-#include "ScriptController.h"
#include <JavaScriptCore/APICast.h>
#include <JavaScriptCore/JSRetainPtr.h>
#include <JavaScriptCore/JSStringRef.h>
#include <JavaScriptCore/OpaqueJSString.h>
-#include <runtime/JSLock.h>
-#include <runtime/UString.h>
-#include <runtime/CollectorHeapIterator.h>
#include <profiler/Profile.h>
#include <profiler/Profiler.h>
+#include <runtime/CollectorHeapIterator.h>
+#include <runtime/JSLock.h>
+#include <runtime/UString.h>
#include <wtf/CurrentTime.h>
#include <wtf/RefCounted.h>
#include <wtf/StdLibExtras.h>
@@ -83,6 +90,12 @@
#include "JSDatabase.h"
#endif
+#if ENABLE(DOM_STORAGE)
+#include "Storage.h"
+#include "StorageArea.h"
+#include "JSStorage.h"
+#endif
+
#if ENABLE(JAVASCRIPT_DEBUGGER)
#include "JavaScriptCallFrame.h"
#include "JavaScriptDebugServer.h"
@@ -158,354 +171,7 @@ JSValueRef InspectorController::callFunction(JSContextRef context, JSObjectRef t
return result;
}
-// ConsoleMessage Struct
-
-struct ConsoleMessage {
- ConsoleMessage(MessageSource s, MessageLevel l, const String& m, unsigned li, const String& u, unsigned g)
- : source(s)
- , level(l)
- , message(m)
- , line(li)
- , url(u)
- , groupLevel(g)
- , repeatCount(1)
- {
- }
-
- ConsoleMessage(MessageSource s, MessageLevel l, ScriptCallStack* callStack, unsigned g, bool storeTrace = false)
- : source(s)
- , level(l)
- , wrappedArguments(callStack->at(0).argumentCount())
- , frames(storeTrace ? callStack->size() : 0)
- , groupLevel(g)
- , repeatCount(1)
- {
- const ScriptCallFrame& lastCaller = callStack->at(0);
- line = lastCaller.lineNumber();
- url = lastCaller.sourceURL().string();
-
- // FIXME: For now, just store function names as strings.
- // As ScriptCallStack start storing line number and source URL for all
- // frames, refactor to use that, as well.
- if (storeTrace) {
- unsigned stackSize = callStack->size();
- for (unsigned i = 0; i < stackSize; ++i)
- frames[i] = callStack->at(i).functionName();
- }
-
- JSLock lock(false);
-
- for (unsigned i = 0; i < lastCaller.argumentCount(); ++i)
- wrappedArguments[i] = JSInspectedObjectWrapper::wrap(callStack->state(), lastCaller.argumentAt(i).jsValue());
- }
-
- bool isEqual(ExecState* exec, ConsoleMessage* msg) const
- {
- if (msg->wrappedArguments.size() != this->wrappedArguments.size() ||
- (!exec && msg->wrappedArguments.size()))
- return false;
-
- for (size_t i = 0; i < msg->wrappedArguments.size(); ++i) {
- ASSERT_ARG(exec, exec);
- if (!JSValueIsEqual(toRef(exec), toRef(msg->wrappedArguments[i].get()), toRef(this->wrappedArguments[i].get()), 0))
- return false;
- }
-
- size_t frameCount = msg->frames.size();
- if (frameCount != this->frames.size())
- return false;
-
- for (size_t i = 0; i < frameCount; ++i) {
- const ScriptString& myFrameFunctionName = this->frames[i];
- if (myFrameFunctionName != msg->frames[i])
- return false;
- }
-
- return msg->source == this->source
- && msg->level == this->level
- && msg->message == this->message
- && msg->line == this->line
- && msg->url == this->url
- && msg->groupLevel == this->groupLevel;
- }
-
- MessageSource source;
- MessageLevel level;
- String message;
- Vector<ProtectedJSValuePtr> wrappedArguments;
- Vector<ScriptString> frames;
- unsigned line;
- String url;
- unsigned groupLevel;
- unsigned repeatCount;
-};
-
-// XMLHttpRequestResource Class
-
-struct XMLHttpRequestResource {
- XMLHttpRequestResource(const JSC::UString& sourceString)
- {
- JSC::JSLock lock(false);
- this->sourceString = sourceString.rep();
- }
-
- ~XMLHttpRequestResource()
- {
- JSC::JSLock lock(false);
- sourceString.clear();
- }
-
- RefPtr<JSC::UString::Rep> sourceString;
-};
-
-// InspectorResource Struct
-
-struct InspectorResource : public RefCounted<InspectorResource> {
- // Keep these in sync with WebInspector.Resource.Type
- enum Type {
- Doc,
- Stylesheet,
- Image,
- Font,
- Script,
- XHR,
- Media,
- Other
- };
-
- static PassRefPtr<InspectorResource> create(long long identifier, DocumentLoader* documentLoader, Frame* frame)
- {
- return adoptRef(new InspectorResource(identifier, documentLoader, frame));
- }
-
- ~InspectorResource()
- {
- setScriptObject(0, 0);
- }
-
- Type type() const
- {
- if (xmlHttpRequestResource)
- return XHR;
-
- if (requestURL == loader->requestURL())
- return Doc;
-
- if (loader->frameLoader() && requestURL == loader->frameLoader()->iconURL())
- return Image;
-
- CachedResource* cachedResource = frame->document()->docLoader()->cachedResource(requestURL.string());
- if (!cachedResource)
- return Other;
-
- switch (cachedResource->type()) {
- case CachedResource::ImageResource:
- return Image;
- case CachedResource::FontResource:
- return Font;
- case CachedResource::CSSStyleSheet:
-#if ENABLE(XSLT)
- case CachedResource::XSLStyleSheet:
-#endif
- return Stylesheet;
- case CachedResource::Script:
- return Script;
- default:
- return Other;
- }
- }
-
- void setScriptObject(JSContextRef context, JSObjectRef newScriptObject)
- {
- if (scriptContext && scriptObject)
- JSValueUnprotect(scriptContext, scriptObject);
-
- scriptObject = newScriptObject;
- scriptContext = context;
-
- ASSERT((context && newScriptObject) || (!context && !newScriptObject));
- if (context && newScriptObject)
- JSValueProtect(context, newScriptObject);
- }
-
- void setXMLHttpRequestProperties(const JSC::UString& data)
- {
- xmlHttpRequestResource.set(new XMLHttpRequestResource(data));
- }
-
- String sourceString() const
- {
- if (xmlHttpRequestResource)
- return JSC::UString(xmlHttpRequestResource->sourceString);
-
- RefPtr<SharedBuffer> buffer;
- String textEncodingName;
-
- if (requestURL == loader->requestURL()) {
- buffer = loader->mainResourceData();
- textEncodingName = frame->document()->inputEncoding();
- } else {
- CachedResource* cachedResource = frame->document()->docLoader()->cachedResource(requestURL.string());
- if (!cachedResource)
- return String();
-
- if (cachedResource->isPurgeable()) {
- // If the resource is purgeable then make it unpurgeable to get
- // get its data. This might fail, in which case we return an
- // empty String.
- // FIXME: should we do something else in the case of a purged
- // resource that informs the user why there is no data in the
- // inspector?
- if (!cachedResource->makePurgeable(false))
- return String();
- }
-
- buffer = cachedResource->data();
- textEncodingName = cachedResource->encoding();
- }
-
- if (!buffer)
- return String();
-
- TextEncoding encoding(textEncodingName);
- if (!encoding.isValid())
- encoding = WindowsLatin1Encoding();
- return encoding.decode(buffer->data(), buffer->size());
- }
-
- long long identifier;
- RefPtr<DocumentLoader> loader;
- RefPtr<Frame> frame;
- OwnPtr<XMLHttpRequestResource> xmlHttpRequestResource;
- KURL requestURL;
- HTTPHeaderMap requestHeaderFields;
- HTTPHeaderMap responseHeaderFields;
- String mimeType;
- String suggestedFilename;
- JSContextRef scriptContext;
- JSObjectRef scriptObject;
- long long expectedContentLength;
- bool cached;
- bool finished;
- bool failed;
- int length;
- int responseStatusCode;
- double startTime;
- double responseReceivedTime;
- double endTime;
-
-protected:
- InspectorResource(long long identifier, DocumentLoader* documentLoader, Frame* frame)
- : identifier(identifier)
- , loader(documentLoader)
- , frame(frame)
- , xmlHttpRequestResource(0)
- , scriptContext(0)
- , scriptObject(0)
- , expectedContentLength(0)
- , cached(false)
- , finished(false)
- , failed(false)
- , length(0)
- , responseStatusCode(0)
- , startTime(-1.0)
- , responseReceivedTime(-1.0)
- , endTime(-1.0)
- {
- }
-};
-
-// InspectorDatabaseResource Struct
-
-#if ENABLE(DATABASE)
-struct InspectorDatabaseResource : public RefCounted<InspectorDatabaseResource> {
- static PassRefPtr<InspectorDatabaseResource> create(Database* database, const String& domain, const String& name, const String& version)
- {
- return adoptRef(new InspectorDatabaseResource(database, domain, name, version));
- }
-
- void setScriptObject(JSContextRef context, JSObjectRef newScriptObject)
- {
- if (scriptContext && scriptObject)
- JSValueUnprotect(scriptContext, scriptObject);
-
- scriptObject = newScriptObject;
- scriptContext = context;
-
- ASSERT((context && newScriptObject) || (!context && !newScriptObject));
- if (context && newScriptObject)
- JSValueProtect(context, newScriptObject);
- }
-
- RefPtr<Database> database;
- String domain;
- String name;
- String version;
- JSContextRef scriptContext;
- JSObjectRef scriptObject;
-
-private:
- InspectorDatabaseResource(Database* database, const String& domain, const String& name, const String& version)
- : database(database)
- , domain(domain)
- , name(name)
- , version(version)
- , scriptContext(0)
- , scriptObject(0)
- {
- }
-};
-#endif
-
-// JavaScript Callbacks
-
-#define SIMPLE_INSPECTOR_CALLBACK(jsFunction, inspectorControllerMethod) \
-static JSValueRef jsFunction(JSContextRef ctx, JSObjectRef, JSObjectRef thisObject, size_t, const JSValueRef[], JSValueRef*) \
-{ \
- if (InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject))) \
- controller->inspectorControllerMethod(); \
- return JSValueMakeUndefined(ctx); \
-}
-
-SIMPLE_INSPECTOR_CALLBACK(hideDOMNodeHighlight, hideHighlight);
-SIMPLE_INSPECTOR_CALLBACK(loaded, scriptObjectReady);
-SIMPLE_INSPECTOR_CALLBACK(unloading, close);
-SIMPLE_INSPECTOR_CALLBACK(attach, attachWindow);
-SIMPLE_INSPECTOR_CALLBACK(detach, detachWindow);
-#if ENABLE(JAVASCRIPT_DEBUGGER)
-SIMPLE_INSPECTOR_CALLBACK(enableDebugger, enableDebugger);
-SIMPLE_INSPECTOR_CALLBACK(disableDebugger, disableDebugger);
-SIMPLE_INSPECTOR_CALLBACK(pauseInDebugger, pauseInDebugger);
-SIMPLE_INSPECTOR_CALLBACK(resumeDebugger, resumeDebugger);
-SIMPLE_INSPECTOR_CALLBACK(stepOverStatementInDebugger, stepOverStatementInDebugger);
-SIMPLE_INSPECTOR_CALLBACK(stepIntoStatementInDebugger, stepIntoStatementInDebugger);
-SIMPLE_INSPECTOR_CALLBACK(stepOutOfFunctionInDebugger, stepOutOfFunctionInDebugger);
-#endif
-SIMPLE_INSPECTOR_CALLBACK(closeWindow, closeWindow);
-SIMPLE_INSPECTOR_CALLBACK(clearMessages, clearConsoleMessages);
-SIMPLE_INSPECTOR_CALLBACK(startProfiling, startUserInitiatedProfilingSoon);
-SIMPLE_INSPECTOR_CALLBACK(stopProfiling, stopUserInitiatedProfiling);
-SIMPLE_INSPECTOR_CALLBACK(enableProfiler, enableProfiler);
-SIMPLE_INSPECTOR_CALLBACK(disableProfiler, disableProfiler);
-SIMPLE_INSPECTOR_CALLBACK(toggleNodeSearch, toggleSearchForNodeInPage);
-
-#define BOOL_INSPECTOR_CALLBACK(jsFunction, inspectorControllerMethod) \
-static JSValueRef jsFunction(JSContextRef ctx, JSObjectRef, JSObjectRef thisObject, size_t, const JSValueRef[], JSValueRef*) \
-{ \
- if (InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject))) \
- return JSValueMakeBoolean(ctx, controller->inspectorControllerMethod()); \
- return JSValueMakeUndefined(ctx); \
-}
-
-#if ENABLE(JAVASCRIPT_DEBUGGER)
-BOOL_INSPECTOR_CALLBACK(debuggerEnabled, debuggerEnabled);
-BOOL_INSPECTOR_CALLBACK(pauseOnExceptions, pauseOnExceptions);
-#endif
-BOOL_INSPECTOR_CALLBACK(profilerEnabled, profilerEnabled);
-BOOL_INSPECTOR_CALLBACK(isWindowVisible, windowVisible);
-BOOL_INSPECTOR_CALLBACK(searchingForNode, searchingForNodeInPage);
-
-static bool addSourceToFrame(const String& mimeType, const String& source, Node* frameNode)
+bool InspectorController::addSourceToFrame(const String& mimeType, const String& source, Node* frameNode)
{
ASSERT_ARG(frameNode, frameNode);
@@ -541,362 +207,7 @@ static bool addSourceToFrame(const String& mimeType, const String& source, Node*
return true;
}
-static JSValueRef addResourceSourceToFrame(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- JSValueRef undefined = JSValueMakeUndefined(ctx);
-
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (argumentCount < 2 || !controller)
- return undefined;
-
- JSValueRef identifierValue = arguments[0];
- if (!JSValueIsNumber(ctx, identifierValue))
- return undefined;
-
- long long identifier = static_cast<long long>(JSValueToNumber(ctx, identifierValue, exception));
- if (exception && *exception)
- return undefined;
-
- RefPtr<InspectorResource> resource = controller->resources().get(identifier);
- ASSERT(resource);
- if (!resource)
- return undefined;
-
- String sourceString = resource->sourceString();
- if (sourceString.isEmpty())
- return undefined;
-
- bool successfullyAddedSource = addSourceToFrame(resource->mimeType, sourceString, toNode(toJS(arguments[1])));
- return JSValueMakeBoolean(ctx, successfullyAddedSource);
-}
-
-static JSValueRef addSourceToFrame(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- JSValueRef undefined = JSValueMakeUndefined(ctx);
-
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (argumentCount < 3 || !controller)
- return undefined;
-
- JSValueRef mimeTypeValue = arguments[0];
- if (!JSValueIsString(ctx, mimeTypeValue))
- return undefined;
-
- JSValueRef sourceValue = arguments[1];
- if (!JSValueIsString(ctx, sourceValue))
- return undefined;
-
- String mimeType = toString(ctx, mimeTypeValue, exception);
- if (mimeType.isEmpty())
- return undefined;
-
- String source = toString(ctx, sourceValue, exception);
- if (source.isEmpty())
- return undefined;
-
- bool successfullyAddedSource = addSourceToFrame(mimeType, source, toNode(toJS(arguments[2])));
- return JSValueMakeBoolean(ctx, successfullyAddedSource);
-}
-
-static JSValueRef getResourceDocumentNode(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- JSValueRef undefined = JSValueMakeUndefined(ctx);
-
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!argumentCount || argumentCount > 1 || !controller)
- return undefined;
-
- JSValueRef identifierValue = arguments[0];
- if (!JSValueIsNumber(ctx, identifierValue))
- return undefined;
-
- long long identifier = static_cast<long long>(JSValueToNumber(ctx, identifierValue, exception));
- if (exception && *exception)
- return undefined;
-
- RefPtr<InspectorResource> resource = controller->resources().get(identifier);
- ASSERT(resource);
- if (!resource)
- return undefined;
-
- Frame* frame = resource->frame.get();
-
- Document* document = frame->document();
- if (!document)
- return undefined;
-
- if (document->isPluginDocument() || document->isImageDocument() || document->isMediaDocument())
- return undefined;
-
- ExecState* exec = toJSDOMWindowShell(resource->frame.get())->window()->globalExec();
-
- JSC::JSLock lock(false);
- JSValueRef documentValue = toRef(JSInspectedObjectWrapper::wrap(exec, toJS(exec, document)));
- return documentValue;
-}
-
-static JSValueRef highlightDOMNode(JSContextRef context, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/)
-{
- JSValueRef undefined = JSValueMakeUndefined(context);
-
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (argumentCount < 1 || !controller)
- return undefined;
-
- JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(toJS(arguments[0]));
- if (!wrapper)
- return undefined;
- Node* node = toNode(wrapper->unwrappedObject());
- if (!node)
- return undefined;
-
- controller->highlight(node);
-
- return undefined;
-}
-
-static JSValueRef search(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 2 || !JSValueIsString(ctx, arguments[1]))
- return JSValueMakeUndefined(ctx);
-
- Node* node = toNode(toJS(arguments[0]));
- if (!node)
- return JSValueMakeUndefined(ctx);
-
- String target = toString(ctx, arguments[1], exception);
-
- JSObjectRef global = JSContextGetGlobalObject(ctx);
-
- JSValueRef arrayProperty = JSObjectGetProperty(ctx, global, jsStringRef("Array").get(), exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef arrayConstructor = JSValueToObject(ctx, arrayProperty, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef result = JSObjectCallAsConstructor(ctx, arrayConstructor, 0, 0, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSValueRef pushProperty = JSObjectGetProperty(ctx, result, jsStringRef("push").get(), exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef pushFunction = JSValueToObject(ctx, pushProperty, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- RefPtr<Range> searchRange(rangeOfContents(node));
-
- ExceptionCode ec = 0;
- do {
- RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, false));
- if (resultRange->collapsed(ec))
- break;
-
- // A non-collapsed result range can in some funky whitespace cases still not
- // advance the range's start position (4509328). Break to avoid infinite loop.
- VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM);
- if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))
- break;
-
- JSC::JSLock lock(false);
- JSValueRef arg0 = toRef(toJS(toJS(ctx), resultRange.get()));
- JSObjectCallAsFunction(ctx, pushFunction, result, 1, &arg0, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- setStart(searchRange.get(), newStart);
- } while (true);
-
- return result;
-}
-
-#if ENABLE(DATABASE)
-static JSValueRef databaseTableNames(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 1)
- return JSValueMakeUndefined(ctx);
-
- JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(toJS(arguments[0]));
- if (!wrapper)
- return JSValueMakeUndefined(ctx);
-
- Database* database = toDatabase(wrapper->unwrappedObject());
- if (!database)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef global = JSContextGetGlobalObject(ctx);
-
- JSValueRef arrayProperty = JSObjectGetProperty(ctx, global, jsStringRef("Array").get(), exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef arrayConstructor = JSValueToObject(ctx, arrayProperty, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef result = JSObjectCallAsConstructor(ctx, arrayConstructor, 0, 0, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSValueRef pushProperty = JSObjectGetProperty(ctx, result, jsStringRef("push").get(), exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef pushFunction = JSValueToObject(ctx, pushProperty, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- Vector<String> tableNames = database->tableNames();
- unsigned length = tableNames.size();
- for (unsigned i = 0; i < length; ++i) {
- String tableName = tableNames[i];
- JSValueRef tableNameValue = JSValueMakeString(ctx, jsStringRef(tableName).get());
-
- JSValueRef pushArguments[] = { tableNameValue };
- JSObjectCallAsFunction(ctx, pushFunction, result, 1, pushArguments, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
- }
-
- return result;
-}
-#endif
-
-static JSValueRef inspectedWindow(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef[] /*arguments[]*/, JSValueRef* /*exception*/)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- JSDOMWindow* inspectedWindow = toJSDOMWindow(controller->inspectedPage()->mainFrame());
- JSLock lock(false);
- return toRef(JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), inspectedWindow));
-}
-
-static JSValueRef setting(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef arguments[], JSValueRef* exception)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- JSValueRef keyValue = arguments[0];
- if (!JSValueIsString(ctx, keyValue))
- return JSValueMakeUndefined(ctx);
-
- const InspectorController::Setting& setting = controller->setting(toString(ctx, keyValue, exception));
-
- switch (setting.type()) {
- default:
- case InspectorController::Setting::NoType:
- return JSValueMakeUndefined(ctx);
- case InspectorController::Setting::StringType:
- return JSValueMakeString(ctx, jsStringRef(setting.string()).get());
- case InspectorController::Setting::DoubleType:
- return JSValueMakeNumber(ctx, setting.doubleValue());
- case InspectorController::Setting::IntegerType:
- return JSValueMakeNumber(ctx, setting.integerValue());
- case InspectorController::Setting::BooleanType:
- return JSValueMakeBoolean(ctx, setting.booleanValue());
- case InspectorController::Setting::StringVectorType: {
- Vector<JSValueRef> stringValues;
- const Vector<String>& strings = setting.stringVector();
- const unsigned length = strings.size();
- for (unsigned i = 0; i < length; ++i)
- stringValues.append(JSValueMakeString(ctx, jsStringRef(strings[i]).get()));
-
- JSObjectRef stringsArray = JSObjectMakeArray(ctx, stringValues.size(), stringValues.data(), exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
- return stringsArray;
- }
- }
-}
-
-static JSValueRef setSetting(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef arguments[], JSValueRef* exception)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- JSValueRef keyValue = arguments[0];
- if (!JSValueIsString(ctx, keyValue))
- return JSValueMakeUndefined(ctx);
-
- InspectorController::Setting setting;
-
- JSValueRef value = arguments[1];
- switch (JSValueGetType(ctx, value)) {
- default:
- case kJSTypeUndefined:
- case kJSTypeNull:
- // Do nothing. The setting is already NoType.
- ASSERT(setting.type() == InspectorController::Setting::NoType);
- break;
- case kJSTypeString:
- setting.set(toString(ctx, value, exception));
- break;
- case kJSTypeNumber:
- setting.set(JSValueToNumber(ctx, value, exception));
- break;
- case kJSTypeBoolean:
- setting.set(JSValueToBoolean(ctx, value));
- break;
- case kJSTypeObject: {
- JSObjectRef object = JSValueToObject(ctx, value, 0);
- JSValueRef lengthValue = JSObjectGetProperty(ctx, object, jsStringRef("length").get(), exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- Vector<String> strings;
- const unsigned length = static_cast<unsigned>(JSValueToNumber(ctx, lengthValue, 0));
- for (unsigned i = 0; i < length; ++i) {
- JSValueRef itemValue = JSObjectGetPropertyAtIndex(ctx, object, i, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
- strings.append(toString(ctx, itemValue, exception));
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
- }
-
- setting.set(strings);
- break;
- }
- }
-
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- controller->setSetting(toString(ctx, keyValue, exception), setting);
-
- return JSValueMakeUndefined(ctx);
-}
-
-static JSValueRef localizedStrings(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef[] /*arguments[]*/, JSValueRef* /*exception*/)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- String url = controller->localizedStringsURL();
- if (url.isNull())
- return JSValueMakeNull(ctx);
-
- return JSValueMakeString(ctx, jsStringRef(url).get());
-}
-
-static JSValueRef platform(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef /*thisObject*/, size_t /*argumentCount*/, const JSValueRef[] /*arguments[]*/, JSValueRef* /*exception*/)
+const String& InspectorController::platform() const
{
#if PLATFORM(MAC)
#ifdef BUILDING_ON_TIGER
@@ -916,184 +227,9 @@ static JSValueRef platform(JSContextRef ctx, JSObjectRef /*function*/, JSObjectR
DEFINE_STATIC_LOCAL(const String, platform, ("unknown"));
#endif
- JSValueRef platformValue = JSValueMakeString(ctx, jsStringRef(platform).get());
-
- return platformValue;
-}
-
-static JSValueRef moveByUnrestricted(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 2)
- return JSValueMakeUndefined(ctx);
-
- double x = JSValueToNumber(ctx, arguments[0], exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- double y = JSValueToNumber(ctx, arguments[1], exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- controller->moveWindowBy(narrowPrecisionToFloat(x), narrowPrecisionToFloat(y));
-
- return JSValueMakeUndefined(ctx);
+ return platform;
}
-static JSValueRef setAttachedWindowHeight(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 1)
- return JSValueMakeUndefined(ctx);
-
- unsigned height = static_cast<unsigned>(JSValueToNumber(ctx, arguments[0], exception));
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- controller->setAttachedWindowHeight(height);
-
- return JSValueMakeUndefined(ctx);
-}
-
-static JSValueRef wrapCallback(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 1)
- return JSValueMakeUndefined(ctx);
-
- JSLock lock(false);
- return toRef(JSInspectorCallbackWrapper::wrap(toJS(ctx), toJS(arguments[0])));
-}
-
-#if ENABLE(JAVASCRIPT_DEBUGGER)
-static JSValueRef currentCallFrame(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef[] /*arguments*/, JSValueRef* /*exception*/)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- JavaScriptCallFrame* callFrame = controller->currentCallFrame();
- if (!callFrame || !callFrame->isValid())
- return JSValueMakeNull(ctx);
-
- ExecState* globalExec = callFrame->scopeChain()->globalObject()->globalExec();
-
- JSLock lock(false);
- return toRef(JSInspectedObjectWrapper::wrap(globalExec, toJS(toJS(ctx), callFrame)));
-}
-
-static JSValueRef setPauseOnExceptions(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 1)
- return JSValueMakeUndefined(ctx);
-
- controller->setPauseOnExceptions(JSValueToBoolean(ctx, arguments[0]));
-
- return JSValueMakeUndefined(ctx);
-}
-
-static JSValueRef addBreakpoint(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 2)
- return JSValueMakeUndefined(ctx);
-
- double sourceID = JSValueToNumber(ctx, arguments[0], exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- double lineNumber = JSValueToNumber(ctx, arguments[1], exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- controller->addBreakpoint(static_cast<int>(sourceID), static_cast<unsigned>(lineNumber));
-
- return JSValueMakeUndefined(ctx);
-}
-
-static JSValueRef removeBreakpoint(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 2)
- return JSValueMakeUndefined(ctx);
-
- double sourceID = JSValueToNumber(ctx, arguments[0], exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- double lineNumber = JSValueToNumber(ctx, arguments[1], exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- controller->removeBreakpoint(static_cast<int>(sourceID), static_cast<unsigned>(lineNumber));
-
- return JSValueMakeUndefined(ctx);
-}
-#endif
-
-static JSValueRef profiles(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef[] /*arguments*/, JSValueRef* exception)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- JSLock lock(false);
-
- const Vector<RefPtr<Profile> >& profiles = controller->profiles();
-
- JSObjectRef global = JSContextGetGlobalObject(ctx);
-
- JSValueRef arrayProperty = JSObjectGetProperty(ctx, global, jsStringRef("Array").get(), exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef arrayConstructor = JSValueToObject(ctx, arrayProperty, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef result = JSObjectCallAsConstructor(ctx, arrayConstructor, 0, 0, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSValueRef pushProperty = JSObjectGetProperty(ctx, result, jsStringRef("push").get(), exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef pushFunction = JSValueToObject(ctx, pushProperty, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- for (size_t i = 0; i < profiles.size(); ++i) {
- JSValueRef arg0 = toRef(toJS(toJS(ctx), profiles[i].get()));
- JSObjectCallAsFunction(ctx, pushFunction, result, 1, &arg0, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
- }
-
- return result;
-}
-
-// InspectorController Class
-
static unsigned s_inspectorControllerCount;
static HashMap<String, InspectorController::Setting*>* s_settingCache;
@@ -1225,6 +361,13 @@ String InspectorController::localizedStringsURL()
return m_client->localizedStringsURL();
}
+String InspectorController::hiddenPanels()
+{
+ if (!enabled())
+ return String();
+ return m_client->hiddenPanels();
+}
+
// Trying to inspect something in a frame with JavaScript disabled would later lead to
// crashes trying to create JavaScript wrappers. Some day we could fix this issue, but
// for now prevent crashes here by never targeting a node in such a frame.
@@ -1297,6 +440,7 @@ void InspectorController::hideHighlight()
{
if (!enabled())
return;
+ m_highlightedNode = 0;
m_client->hideHighlight();
}
@@ -1358,7 +502,7 @@ void InspectorController::addConsoleMessage(ExecState* exec, ConsoleMessage* con
ASSERT_ARG(consoleMessage, consoleMessage);
if (m_previousMessage && m_previousMessage->isEqual(exec, consoleMessage)) {
- ++m_previousMessage->repeatCount;
+ m_previousMessage->incrementCount();
delete consoleMessage;
} else {
m_previousMessage = consoleMessage;
@@ -1366,7 +510,7 @@ void InspectorController::addConsoleMessage(ExecState* exec, ConsoleMessage* con
}
if (windowVisible())
- addScriptConsoleMessage(m_previousMessage);
+ m_previousMessage->addToConsole(toJS(m_scriptContext), ScriptObject(toJS(m_scriptObject)));
}
void InspectorController::clearConsoleMessages()
@@ -1520,83 +664,16 @@ void InspectorController::windowScriptObjectAvailable()
if (!m_page || !enabled())
return;
- m_scriptContext = toRef(m_page->mainFrame()->script()->globalObject()->globalExec());
+ // Grant the inspector the ability to script the inspected page.
+ m_page->mainFrame()->document()->securityOrigin()->grantUniversalAccess();
- JSObjectRef global = JSContextGetGlobalObject(m_scriptContext);
- ASSERT(global);
-
- static JSStaticFunction staticFunctions[] = {
- // SIMPLE_INSPECTOR_CALLBACK
- { "hideDOMNodeHighlight", WebCore::hideDOMNodeHighlight, kJSPropertyAttributeNone },
- { "loaded", WebCore::loaded, kJSPropertyAttributeNone },
- { "windowUnloading", WebCore::unloading, kJSPropertyAttributeNone },
- { "attach", WebCore::attach, kJSPropertyAttributeNone },
- { "detach", WebCore::detach, kJSPropertyAttributeNone },
-#if ENABLE(JAVASCRIPT_DEBUGGER)
- { "enableDebugger", WebCore::enableDebugger, kJSPropertyAttributeNone },
- { "disableDebugger", WebCore::disableDebugger, kJSPropertyAttributeNone },
- { "pauseInDebugger", WebCore::pauseInDebugger, kJSPropertyAttributeNone },
- { "resumeDebugger", WebCore::resumeDebugger, kJSPropertyAttributeNone },
- { "stepOverStatementInDebugger", WebCore::stepOverStatementInDebugger, kJSPropertyAttributeNone },
- { "stepIntoStatementInDebugger", WebCore::stepIntoStatementInDebugger, kJSPropertyAttributeNone },
- { "stepOutOfFunctionInDebugger", WebCore::stepOutOfFunctionInDebugger, kJSPropertyAttributeNone },
-#endif
- { "closeWindow", WebCore::closeWindow, kJSPropertyAttributeNone },
- { "clearMessages", WebCore::clearMessages, kJSPropertyAttributeNone },
- { "startProfiling", WebCore::startProfiling, kJSPropertyAttributeNone },
- { "stopProfiling", WebCore::stopProfiling, kJSPropertyAttributeNone },
- { "enableProfiler", WebCore::enableProfiler, kJSPropertyAttributeNone },
- { "disableProfiler", WebCore::disableProfiler, kJSPropertyAttributeNone },
- { "toggleNodeSearch", WebCore::toggleNodeSearch, kJSPropertyAttributeNone },
-
- // BOOL_INSPECTOR_CALLBACK
-#if ENABLE(JAVASCRIPT_DEBUGGER)
- { "debuggerEnabled", WebCore::debuggerEnabled, kJSPropertyAttributeNone },
- { "pauseOnExceptions", WebCore::pauseOnExceptions, kJSPropertyAttributeNone },
-#endif
- { "profilerEnabled", WebCore::profilerEnabled, kJSPropertyAttributeNone },
- { "isWindowVisible", WebCore::isWindowVisible, kJSPropertyAttributeNone },
- { "searchingForNode", WebCore::searchingForNode, kJSPropertyAttributeNone },
-
- // Custom callbacks
- { "addResourceSourceToFrame", WebCore::addResourceSourceToFrame, kJSPropertyAttributeNone },
- { "addSourceToFrame", WebCore::addSourceToFrame, kJSPropertyAttributeNone },
- { "getResourceDocumentNode", WebCore::getResourceDocumentNode, kJSPropertyAttributeNone },
- { "highlightDOMNode", WebCore::highlightDOMNode, kJSPropertyAttributeNone },
- { "search", WebCore::search, kJSPropertyAttributeNone },
-#if ENABLE(DATABASE)
- { "databaseTableNames", WebCore::databaseTableNames, kJSPropertyAttributeNone },
-#endif
- { "setting", WebCore::setting, kJSPropertyAttributeNone },
- { "setSetting", WebCore::setSetting, kJSPropertyAttributeNone },
- { "inspectedWindow", WebCore::inspectedWindow, kJSPropertyAttributeNone },
- { "localizedStringsURL", WebCore::localizedStrings, kJSPropertyAttributeNone },
- { "platform", WebCore::platform, kJSPropertyAttributeNone },
- { "moveByUnrestricted", WebCore::moveByUnrestricted, kJSPropertyAttributeNone },
- { "setAttachedWindowHeight", WebCore::setAttachedWindowHeight, kJSPropertyAttributeNone },
- { "wrapCallback", WebCore::wrapCallback, kJSPropertyAttributeNone },
-#if ENABLE(JAVASCRIPT_DEBUGGER)
- { "currentCallFrame", WebCore::currentCallFrame, kJSPropertyAttributeNone },
- { "setPauseOnExceptions", WebCore::setPauseOnExceptions, kJSPropertyAttributeNone },
- { "addBreakpoint", WebCore::addBreakpoint, kJSPropertyAttributeNone },
- { "removeBreakpoint", WebCore::removeBreakpoint, kJSPropertyAttributeNone },
-#endif
- { "profiles", WebCore::profiles, kJSPropertyAttributeNone },
- { 0, 0, 0 }
- };
-
- JSClassDefinition inspectorControllerDefinition = {
- 0, kJSClassAttributeNone, "InspectorController", 0, 0, staticFunctions,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
-
- JSClassRef controllerClass = JSClassCreate(&inspectorControllerDefinition);
- ASSERT(controllerClass);
-
- m_controllerScriptObject = JSObjectMake(m_scriptContext, controllerClass, reinterpret_cast<void*>(this));
- ASSERT(m_controllerScriptObject);
-
- JSObjectSetProperty(m_scriptContext, global, jsStringRef("InspectorController").get(), m_controllerScriptObject, kJSPropertyAttributeNone, 0);
+ // FIXME: This should be cleaned up. API Mix-up.
+ JSGlobalObject* globalObject = m_page->mainFrame()->script()->globalObject();
+ ExecState* exec = globalObject->globalExec();
+ m_scriptContext = toRef(exec);
+ JSValuePtr jsInspector = toJS(exec, this);
+ m_controllerScriptObject = toRef(asObject(jsInspector));
+ globalObject->putDirect(Identifier(exec, "InspectorController"), jsInspector);
}
void InspectorController::scriptObjectReady()
@@ -2103,145 +1180,20 @@ void InspectorController::populateScriptObjects()
unsigned messageCount = m_consoleMessages.size();
for (unsigned i = 0; i < messageCount; ++i)
- addScriptConsoleMessage(m_consoleMessages[i]);
+ m_consoleMessages[i]->addToConsole(toJS(m_scriptContext), ScriptObject(toJS(m_scriptObject)));
#if ENABLE(DATABASE)
DatabaseResourcesSet::iterator databasesEnd = m_databaseResources.end();
for (DatabaseResourcesSet::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it)
- addDatabaseScriptResource((*it).get());
+ (*it)->bind(toJS(m_scriptContext), ScriptObject(toJS(m_scriptObject)));
#endif
-
- callSimpleFunction(m_scriptContext, m_scriptObject, "populateInterface");
-}
-
-#if ENABLE(DATABASE)
-JSObjectRef InspectorController::addDatabaseScriptResource(InspectorDatabaseResource* resource)
-{
- ASSERT_ARG(resource, resource);
-
- if (resource->scriptObject)
- return resource->scriptObject;
-
- ASSERT(m_scriptContext);
- ASSERT(m_scriptObject);
- if (!m_scriptContext || !m_scriptObject)
- return 0;
-
- Frame* frame = resource->database->document()->frame();
- if (!frame)
- return 0;
-
- JSValueRef exception = 0;
-
- JSValueRef databaseProperty = JSObjectGetProperty(m_scriptContext, m_scriptObject, jsStringRef("Database").get(), &exception);
- if (HANDLE_EXCEPTION(m_scriptContext, exception))
- return 0;
-
- JSObjectRef databaseConstructor = JSValueToObject(m_scriptContext, databaseProperty, &exception);
- if (HANDLE_EXCEPTION(m_scriptContext, exception))
- return 0;
-
- ExecState* exec = toJSDOMWindow(frame)->globalExec();
-
- JSValueRef database;
-
- {
- JSC::JSLock lock(false);
- database = toRef(JSInspectedObjectWrapper::wrap(exec, toJS(exec, resource->database.get())));
- }
-
- JSValueRef domainValue = JSValueMakeString(m_scriptContext, jsStringRef(resource->domain).get());
- JSValueRef nameValue = JSValueMakeString(m_scriptContext, jsStringRef(resource->name).get());
- JSValueRef versionValue = JSValueMakeString(m_scriptContext, jsStringRef(resource->version).get());
-
- JSValueRef arguments[] = { database, domainValue, nameValue, versionValue };
- JSObjectRef result = JSObjectCallAsConstructor(m_scriptContext, databaseConstructor, 4, arguments, &exception);
- if (HANDLE_EXCEPTION(m_scriptContext, exception))
- return 0;
-
- ASSERT(result);
-
- callFunction(m_scriptContext, m_scriptObject, "addDatabase", 1, &result, exception);
-
- if (exception)
- return 0;
-
- resource->setScriptObject(m_scriptContext, result);
-
- return result;
-}
-
-void InspectorController::removeDatabaseScriptResource(InspectorDatabaseResource* resource)
-{
- ASSERT(m_scriptContext);
- ASSERT(m_scriptObject);
- if (!m_scriptContext || !m_scriptObject)
- return;
-
- ASSERT(resource);
- ASSERT(resource->scriptObject);
- if (!resource || !resource->scriptObject)
- return;
-
- JSObjectRef scriptObject = resource->scriptObject;
- resource->setScriptObject(0, 0);
-
- JSValueRef exception = 0;
- callFunction(m_scriptContext, m_scriptObject, "removeDatabase", 1, &scriptObject, exception);
-}
+#if ENABLE(DOM_STORAGE)
+ DOMStorageResourcesSet::iterator domStorageEnd = m_domStorageResources.end();
+ for (DOMStorageResourcesSet::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it)
+ (*it)->bind(toJS(m_scriptContext), ScriptObject(toJS(m_scriptObject)));
#endif
-void InspectorController::addScriptConsoleMessage(const ConsoleMessage* message)
-{
- ASSERT_ARG(message, message);
-
- JSValueRef exception = 0;
-
- JSValueRef messageConstructorProperty = JSObjectGetProperty(m_scriptContext, m_scriptObject, jsStringRef("ConsoleMessage").get(), &exception);
- if (HANDLE_EXCEPTION(m_scriptContext, exception))
- return;
-
- JSObjectRef messageConstructor = JSValueToObject(m_scriptContext, messageConstructorProperty, &exception);
- if (HANDLE_EXCEPTION(m_scriptContext, exception))
- return;
-
- JSValueRef sourceValue = JSValueMakeNumber(m_scriptContext, message->source);
- JSValueRef levelValue = JSValueMakeNumber(m_scriptContext, message->level);
- JSValueRef lineValue = JSValueMakeNumber(m_scriptContext, message->line);
- JSValueRef urlValue = JSValueMakeString(m_scriptContext, jsStringRef(message->url).get());
- JSValueRef groupLevelValue = JSValueMakeNumber(m_scriptContext, message->groupLevel);
- JSValueRef repeatCountValue = JSValueMakeNumber(m_scriptContext, message->repeatCount);
-
- static const unsigned maximumMessageArguments = 256;
- JSValueRef arguments[maximumMessageArguments];
- unsigned argumentCount = 0;
- arguments[argumentCount++] = sourceValue;
- arguments[argumentCount++] = levelValue;
- arguments[argumentCount++] = lineValue;
- arguments[argumentCount++] = urlValue;
- arguments[argumentCount++] = groupLevelValue;
- arguments[argumentCount++] = repeatCountValue;
-
- if (!message->frames.isEmpty()) {
- unsigned remainingSpaceInArguments = maximumMessageArguments - argumentCount;
- unsigned argumentsToAdd = min(remainingSpaceInArguments, static_cast<unsigned>(message->frames.size()));
- for (unsigned i = 0; i < argumentsToAdd; ++i)
- arguments[argumentCount++] = JSValueMakeString(m_scriptContext, jsStringRef(message->frames[i]).get());
- } else if (!message->wrappedArguments.isEmpty()) {
- unsigned remainingSpaceInArguments = maximumMessageArguments - argumentCount;
- unsigned argumentsToAdd = min(remainingSpaceInArguments, static_cast<unsigned>(message->wrappedArguments.size()));
- for (unsigned i = 0; i < argumentsToAdd; ++i)
- arguments[argumentCount++] = toRef(message->wrappedArguments[i]);
- } else {
- JSValueRef messageValue = JSValueMakeString(m_scriptContext, jsStringRef(message->message).get());
- arguments[argumentCount++] = messageValue;
- }
-
- JSObjectRef messageObject = JSObjectCallAsConstructor(m_scriptContext, messageConstructor, argumentCount, arguments, &exception);
- if (HANDLE_EXCEPTION(m_scriptContext, exception))
- return;
-
- callFunction(m_scriptContext, m_scriptObject, "addMessageToConsole", 1, &messageObject, exception);
+ callSimpleFunction(m_scriptContext, m_scriptObject, "populateInterface");
}
void InspectorController::addScriptProfile(Profile* profile)
@@ -2265,10 +1217,13 @@ void InspectorController::resetScriptObjects()
#if ENABLE(DATABASE)
DatabaseResourcesSet::iterator databasesEnd = m_databaseResources.end();
- for (DatabaseResourcesSet::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it) {
- InspectorDatabaseResource* resource = (*it).get();
- resource->setScriptObject(0, 0);
- }
+ for (DatabaseResourcesSet::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it)
+ (*it)->unbind();
+#endif
+#if ENABLE(DOM_STORAGE)
+ DOMStorageResourcesSet::iterator domStorageEnd = m_domStorageResources.end();
+ for (DOMStorageResourcesSet::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it)
+ (*it)->unbind();
#endif
callSimpleFunction(m_scriptContext, m_scriptObject, "reset");
@@ -2312,6 +1267,9 @@ void InspectorController::didCommitLoad(DocumentLoader* loader)
#if ENABLE(DATABASE)
m_databaseResources.clear();
#endif
+#if ENABLE(DOM_STORAGE)
+ m_domStorageResources.clear();
+#endif
if (windowVisible()) {
resetScriptObjects();
@@ -2555,6 +1513,21 @@ void InspectorController::resourceRetrievedByXMLHttpRequest(unsigned long identi
updateScriptResourceType(resource);
}
+void InspectorController::scriptImported(unsigned long identifier, const JSC::UString& sourceString)
+{
+ if (!enabled())
+ return;
+
+ InspectorResource* resource = m_resources.get(identifier).get();
+ if (!resource)
+ return;
+
+ resource->setXMLHttpRequestProperties(sourceString);
+
+ if (windowVisible() && resource->scriptObject)
+ updateScriptResourceType(resource);
+}
+
#if ENABLE(DATABASE)
void InspectorController::didOpenDatabase(Database* database, const String& domain, const String& name, const String& version)
@@ -2567,7 +1540,27 @@ void InspectorController::didOpenDatabase(Database* database, const String& doma
m_databaseResources.add(resource);
if (windowVisible())
- addDatabaseScriptResource(resource.get());
+ resource->bind(toJS(m_scriptContext), ScriptObject(toJS(m_scriptObject)));
+}
+#endif
+
+#if ENABLE(DOM_STORAGE)
+void InspectorController::didUseDOMStorage(StorageArea* storageArea, bool isLocalStorage, Frame* frame)
+{
+ if (!enabled())
+ return;
+
+ DOMStorageResourcesSet::iterator domStorageEnd = m_domStorageResources.end();
+ for (DOMStorageResourcesSet::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it)
+ if ((*it)->isSameHostAndType(frame, isLocalStorage))
+ return;
+
+ RefPtr<Storage> domStorage = Storage::create(frame, storageArea);
+ RefPtr<InspectorDOMStorageResource> resource = InspectorDOMStorageResource::create(domStorage.get(), isLocalStorage, frame);
+
+ m_domStorageResources.add(resource);
+ if (windowVisible())
+ resource->bind(toJS(m_scriptContext), ScriptObject(toJS(m_scriptObject)));
}
#endif
@@ -2680,26 +1673,23 @@ void InspectorController::removeBreakpoint(intptr_t sourceID, unsigned lineNumbe
}
#endif
-static void drawOutlinedQuad(GraphicsContext& context, const FloatQuad& quad, const Color& fillColor)
+static Path quadToPath(const FloatQuad& quad)
{
- static const int outlineThickness = 2;
- static const Color outlineColor(62, 86, 180, 228);
-
Path quadPath;
quadPath.moveTo(quad.p1());
quadPath.addLineTo(quad.p2());
quadPath.addLineTo(quad.p3());
quadPath.addLineTo(quad.p4());
quadPath.closeSubpath();
-
- // Clear the quad
- {
- context.save();
- context.setCompositeOperation(CompositeClear);
- context.addPath(quadPath);
- context.fillPath();
- context.restore();
- }
+ return quadPath;
+}
+
+static void drawOutlinedQuad(GraphicsContext& context, const FloatQuad& quad, const Color& fillColor)
+{
+ static const int outlineThickness = 2;
+ static const Color outlineColor(62, 86, 180, 228);
+
+ Path quadPath = quadToPath(quad);
// Clip out the quad, then draw with a 2px stroke to get a pixel
// of outline (because inflating a quad is hard)
@@ -2722,29 +1712,40 @@ static void drawOutlinedQuad(GraphicsContext& context, const FloatQuad& quad, co
context.fillPath();
}
-static void drawHighlightForBoxes(GraphicsContext& context, const Vector<FloatQuad>& lineBoxQuads, const FloatQuad& contentQuad, const FloatQuad& paddingQuad, const FloatQuad& borderQuad, const FloatQuad& marginQuad)
+static void drawOutlinedQuadWithClip(GraphicsContext& context, const FloatQuad& quad, const FloatQuad& clipQuad, const Color& fillColor)
+{
+ context.save();
+ Path clipQuadPath = quadToPath(clipQuad);
+ context.clipOut(clipQuadPath);
+ drawOutlinedQuad(context, quad, fillColor);
+ context.restore();
+}
+
+static void drawHighlightForBox(GraphicsContext& context, const FloatQuad& contentQuad, const FloatQuad& paddingQuad, const FloatQuad& borderQuad, const FloatQuad& marginQuad)
{
static const Color contentBoxColor(125, 173, 217, 128);
static const Color paddingBoxColor(125, 173, 217, 160);
static const Color borderBoxColor(125, 173, 217, 192);
static const Color marginBoxColor(125, 173, 217, 228);
- if (!lineBoxQuads.isEmpty()) {
- for (size_t i = 0; i < lineBoxQuads.size(); ++i)
- drawOutlinedQuad(context, lineBoxQuads[i], contentBoxColor);
- return;
- }
-
if (marginQuad != borderQuad)
- drawOutlinedQuad(context, marginQuad, marginBoxColor);
+ drawOutlinedQuadWithClip(context, marginQuad, borderQuad, marginBoxColor);
if (borderQuad != paddingQuad)
- drawOutlinedQuad(context, borderQuad, borderBoxColor);
+ drawOutlinedQuadWithClip(context, borderQuad, paddingQuad, borderBoxColor);
if (paddingQuad != contentQuad)
- drawOutlinedQuad(context, paddingQuad, paddingBoxColor);
+ drawOutlinedQuadWithClip(context, paddingQuad, contentQuad, paddingBoxColor);
drawOutlinedQuad(context, contentQuad, contentBoxColor);
}
+static void drawHighlightForLineBoxes(GraphicsContext& context, const Vector<FloatQuad>& lineBoxQuads)
+{
+ static const Color lineBoxColor(125, 173, 217, 128);
+
+ for (size_t i = 0; i < lineBoxQuads.size(); ++i)
+ drawOutlinedQuad(context, lineBoxQuads[i], lineBoxColor);
+}
+
static inline void convertFromFrameToMainFrame(Frame* frame, IntRect& rect)
{
rect = frame->page()->mainFrame()->view()->windowToContents(frame->view()->contentsToWindow(rect));
@@ -2761,71 +1762,57 @@ void InspectorController::drawNodeHighlight(GraphicsContext& context) const
if (!m_highlightedNode)
return;
- RenderBox* renderer = m_highlightedNode->renderBox();
+ RenderObject* renderer = m_highlightedNode->renderer();
Frame* containingFrame = m_highlightedNode->document()->frame();
if (!renderer || !containingFrame)
return;
- IntRect contentBox = renderer->contentBoxRect();
-
- // FIXME: Should we add methods to RenderObject to obtain these rects?
- IntRect paddingBox(contentBox.x() - renderer->paddingLeft(), contentBox.y() - renderer->paddingTop(),
- contentBox.width() + renderer->paddingLeft() + renderer->paddingRight(), contentBox.height() + renderer->paddingTop() + renderer->paddingBottom());
- IntRect borderBox(paddingBox.x() - renderer->borderLeft(), paddingBox.y() - renderer->borderTop(),
- paddingBox.width() + renderer->borderLeft() + renderer->borderRight(), paddingBox.height() + renderer->borderTop() + renderer->borderBottom());
- IntRect marginBox(borderBox.x() - renderer->marginLeft(), borderBox.y() - renderer->marginTop(),
- borderBox.width() + renderer->marginLeft() + renderer->marginRight(), borderBox.height() + renderer->marginTop() + renderer->marginBottom());
-
-
IntSize mainFrameOffset = frameToMainFrameOffset(containingFrame);
-
- FloatQuad absContentQuad = renderer->localToAbsoluteQuad(FloatRect(contentBox));
- FloatQuad absPaddingQuad = renderer->localToAbsoluteQuad(FloatRect(paddingBox));
- FloatQuad absBorderQuad = renderer->localToAbsoluteQuad(FloatRect(borderBox));
- FloatQuad absMarginQuad = renderer->localToAbsoluteQuad(FloatRect(marginBox));
-
- absContentQuad.move(mainFrameOffset);
- absPaddingQuad.move(mainFrameOffset);
- absBorderQuad.move(mainFrameOffset);
- absMarginQuad.move(mainFrameOffset);
-
IntRect boundingBox = renderer->absoluteBoundingBoxRect(true);
boundingBox.move(mainFrameOffset);
- Vector<FloatQuad> lineBoxQuads;
- if (renderer->isInline() || (renderer->isText() && !m_highlightedNode->isSVGElement())) {
- // FIXME: We should show margins/padding/border for inlines.
- renderer->collectAbsoluteLineBoxQuads(lineBoxQuads);
- }
-
- for (unsigned i = 0; i < lineBoxQuads.size(); ++i)
- lineBoxQuads[i] += mainFrameOffset;
-
- if (lineBoxQuads.isEmpty() && contentBox.isEmpty()) {
- // If we have no line boxes and our content box is empty, we'll just draw our bounding box.
- // This can happen, e.g., with an <a> enclosing an <img style="float:right">.
- // FIXME: Can we make this better/more accurate? The <a> in the above case has no
- // width/height but the highlight makes it appear to be the size of the <img>.
- lineBoxQuads.append(FloatRect(boundingBox));
- }
-
ASSERT(m_inspectedPage);
FrameView* view = m_inspectedPage->mainFrame()->view();
FloatRect overlayRect = view->visibleContentRect();
-
- if (!overlayRect.contains(boundingBox) && !boundingBox.contains(enclosingIntRect(overlayRect))) {
- Element* element;
- if (m_highlightedNode->isElementNode())
- element = static_cast<Element*>(m_highlightedNode.get());
- else
- element = static_cast<Element*>(m_highlightedNode->parent());
+ if (!overlayRect.contains(boundingBox) && !boundingBox.contains(enclosingIntRect(overlayRect)))
overlayRect = view->visibleContentRect();
- }
-
context.translate(-overlayRect.x(), -overlayRect.y());
- drawHighlightForBoxes(context, lineBoxQuads, absContentQuad, absPaddingQuad, absBorderQuad, absMarginQuad);
+ if (renderer->isBox()) {
+ RenderBox* renderBox = toRenderBox(renderer);
+
+ IntRect contentBox = renderBox->contentBoxRect();
+
+ IntRect paddingBox(contentBox.x() - renderBox->paddingLeft(), contentBox.y() - renderBox->paddingTop(),
+ contentBox.width() + renderBox->paddingLeft() + renderBox->paddingRight(), contentBox.height() + renderBox->paddingTop() + renderBox->paddingBottom());
+ IntRect borderBox(paddingBox.x() - renderBox->borderLeft(), paddingBox.y() - renderBox->borderTop(),
+ paddingBox.width() + renderBox->borderLeft() + renderBox->borderRight(), paddingBox.height() + renderBox->borderTop() + renderBox->borderBottom());
+ IntRect marginBox(borderBox.x() - renderBox->marginLeft(), borderBox.y() - renderBox->marginTop(),
+ borderBox.width() + renderBox->marginLeft() + renderBox->marginRight(), borderBox.height() + renderBox->marginTop() + renderBox->marginBottom());
+
+ FloatQuad absContentQuad = renderBox->localToAbsoluteQuad(FloatRect(contentBox));
+ FloatQuad absPaddingQuad = renderBox->localToAbsoluteQuad(FloatRect(paddingBox));
+ FloatQuad absBorderQuad = renderBox->localToAbsoluteQuad(FloatRect(borderBox));
+ FloatQuad absMarginQuad = renderBox->localToAbsoluteQuad(FloatRect(marginBox));
+
+ absContentQuad.move(mainFrameOffset);
+ absPaddingQuad.move(mainFrameOffset);
+ absBorderQuad.move(mainFrameOffset);
+ absMarginQuad.move(mainFrameOffset);
+
+ drawHighlightForBox(context, absContentQuad, absPaddingQuad, absBorderQuad, absMarginQuad);
+ } else if (renderer->isRenderInline()) {
+ RenderInline* renderInline = toRenderInline(renderer);
+
+ // FIXME: We should show margins/padding/border for inlines.
+ Vector<FloatQuad> lineBoxQuads;
+ renderInline->absoluteQuadsForRange(lineBoxQuads);
+ for (unsigned i = 0; i < lineBoxQuads.size(); ++i)
+ lineBoxQuads[i] += mainFrameOffset;
+
+ drawHighlightForLineBoxes(context, lineBoxQuads);
+ }
}
void InspectorController::count(const String& title, unsigned lineNumber, const String& sourceID)
diff --git a/WebCore/inspector/InspectorController.h b/WebCore/inspector/InspectorController.h
index e52bee9..96b5e6f 100644
--- a/WebCore/inspector/InspectorController.h
+++ b/WebCore/inspector/InspectorController.h
@@ -36,6 +36,7 @@
#include <JavaScriptCore/JSContextRef.h>
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
+#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
#if ENABLE(JAVASCRIPT_DEBUGGER)
@@ -57,27 +58,30 @@ class GraphicsContext;
class HitTestResult;
class InspectorClient;
class JavaScriptCallFrame;
+class StorageArea;
class Node;
class Page;
-class ResourceRequest;
+struct ResourceRequest;
class ResourceResponse;
class ResourceError;
class ScriptCallStack;
class SharedBuffer;
-struct ConsoleMessage;
-struct InspectorDatabaseResource;
-struct InspectorResource;
+class ConsoleMessage;
+class InspectorDatabaseResource;
+class InspectorDOMStorageResource;
+class InspectorResource;
-class InspectorController
+class InspectorController : public RefCounted<InspectorController>
#if ENABLE(JAVASCRIPT_DEBUGGER)
- : JavaScriptDebugListener
+ , JavaScriptDebugListener
#endif
{
public:
typedef HashMap<long long, RefPtr<InspectorResource> > ResourcesMap;
typedef HashMap<RefPtr<Frame>, ResourcesMap*> FrameResourcesMap;
typedef HashSet<RefPtr<InspectorDatabaseResource> > DatabaseResourcesSet;
+ typedef HashSet<RefPtr<InspectorDOMStorageResource> > DOMStorageResourcesSet;
typedef enum {
CurrentPanel,
@@ -126,7 +130,11 @@ public:
} m_simpleContent;
};
- InspectorController(Page*, InspectorClient*);
+ static PassRefPtr<InspectorController> create(Page* page, InspectorClient* inspectorClient)
+ {
+ return adoptRef(new InspectorController(page, inspectorClient));
+ }
+
~InspectorController();
void inspectedPageDestroyed();
@@ -140,6 +148,7 @@ public:
void setSetting(const String& key, const Setting&);
String localizedStringsURL();
+ String hiddenPanels();
void inspect(Node*);
void highlight(Node*);
@@ -161,6 +170,7 @@ public:
bool windowVisible();
void setWindowVisible(bool visible = true, bool attached = false);
+ bool addSourceToFrame(const String& mimeType, const String& source, Node*);
void addMessageToConsole(MessageSource, MessageLevel, ScriptCallStack*);
void addMessageToConsole(MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceID);
void clearConsoleMessages();
@@ -205,10 +215,14 @@ public:
void didFinishLoading(DocumentLoader*, unsigned long identifier);
void didFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError&);
void resourceRetrievedByXMLHttpRequest(unsigned long identifier, const JSC::UString& sourceString);
+ void scriptImported(unsigned long identifier, const JSC::UString& sourceString);
#if ENABLE(DATABASE)
void didOpenDatabase(Database*, const String& domain, const String& name, const String& version);
#endif
+#if ENABLE(DOM_STORAGE)
+ void didUseDOMStorage(StorageArea* storageArea, bool isLocalStorage, Frame* frame);
+#endif
const ResourcesMap& resources() const { return m_resources; }
@@ -246,11 +260,13 @@ public:
void startGroup(MessageSource source, ScriptCallStack* callFrame);
void endGroup(MessageSource source, unsigned lineNumber, const String& sourceURL);
+ const String& platform() const;
+
private:
+ InspectorController(Page*, InspectorClient*);
void focusNode();
void addConsoleMessage(JSC::ExecState*, ConsoleMessage*);
- void addScriptConsoleMessage(const ConsoleMessage*);
void addResource(InspectorResource*);
void removeResource(InspectorResource*);
@@ -269,11 +285,6 @@ private:
void pruneResources(ResourcesMap*, DocumentLoader* loaderToKeep = 0);
void removeAllResources(ResourcesMap* map) { pruneResources(map); }
-#if ENABLE(DATABASE)
- JSObjectRef addDatabaseScriptResource(InspectorDatabaseResource*);
- void removeDatabaseScriptResource(InspectorDatabaseResource*);
-#endif
-
JSValueRef callSimpleFunction(JSContextRef, JSObjectRef thisObject, const char* functionName) const;
JSValueRef callFunction(JSContextRef, JSObjectRef thisObject, const char* functionName, size_t argumentCount, const JSValueRef arguments[], JSValueRef& exception) const;
@@ -302,6 +313,9 @@ private:
#if ENABLE(DATABASE)
DatabaseResourcesSet m_databaseResources;
#endif
+#if ENABLE(DOM_STORAGE)
+ DOMStorageResourcesSet m_domStorageResources;
+#endif
JSObjectRef m_scriptObject;
JSObjectRef m_controllerScriptObject;
JSContextRef m_scriptContext;
diff --git a/WebCore/inspector/InspectorController.idl b/WebCore/inspector/InspectorController.idl
new file mode 100644
index 0000000..0cb8041
--- /dev/null
+++ b/WebCore/inspector/InspectorController.idl
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module core {
+ interface [
+ GenerateConstructor
+ ] InspectorController {
+ [ImplementationFunction=hideHighlight] void hideDOMNodeHighlight();
+ [Custom] void highlightDOMNode(in Node node);
+ [ImplementationFunction=scriptObjectReady] void loaded();
+ [ImplementationFunction=close] void windowUnloading();
+ [ImplementationFunction=attachWindow] void attach();
+ [ImplementationFunction=detachWindow] void detach();
+
+ void enableDebugger();
+ void disableDebugger();
+ void pauseInDebugger();
+ void resumeDebugger();
+ void stepOverStatementInDebugger();
+ void stepIntoStatementInDebugger();
+ void stepOutOfFunctionInDebugger();
+
+ void closeWindow();
+ [ImplementationFunction=clearConsoleMessages] void clearMessages();
+ [ImplementationFunction=startUserInitiatedProfiling] void startProfiling();
+ [ImplementationFunction=stopUserInitiatedProfiling] void stopProfiling();
+ void enableProfiler();
+ void disableProfiler();
+ [ImplementationFunction=toggleSearchForNodeInPage] void toggleNodeSearch();
+
+ boolean debuggerEnabled();
+ boolean pauseOnExceptions();
+
+ boolean profilerEnabled();
+ [ImplementationFunction=windowVisible] boolean isWindowVisible();
+ [ImplementationFunction=searchingForNodeInPage] boolean searchingForNode();
+
+ [Custom] void addResourceSourceToFrame(in unsigned long identifier, in Node frame);
+ [Custom] void addSourceToFrame(in DOMString mimeType, in DOMString sourceValue, in Node frame);
+ [Custom] Node getResourceDocumentNode(in unsigned long identifier);
+ [Custom] void search(in Node node, in DOMString query);
+#if ENABLE_DATABASE
+ [Custom] DOMObject databaseTableNames(in Database database);
+#endif
+ [Custom] DOMObject setting(in DOMString key);
+ [Custom] void setSetting(in DOMString key, in DOMObject value);
+ [Custom] DOMWindow inspectedWindow();
+ DOMString localizedStringsURL();
+ DOMString hiddenPanels();
+ DOMString platform();
+ [ImplementationFunction=moveWindowBy] void moveByUnrestricted(in float x, in float y);
+ void setAttachedWindowHeight(in unsigned long height);
+ [Custom] DOMObject wrapCallback(in DOMObject callback);
+
+ [Custom] DOMObject currentCallFrame();
+ void setPauseOnExceptions(in boolean pauseOnExceptions);
+ void addBreakpoint(in unsigned long sourceID, in unsigned long lineNumber);
+ void removeBreakpoint(in unsigned long sourceID, in unsigned long lineNumber);
+
+ [Custom] Array profiles();
+ };
+ }
diff --git a/WebCore/inspector/InspectorDOMStorageResource.cpp b/WebCore/inspector/InspectorDOMStorageResource.cpp
new file mode 100644
index 0000000..33d036e
--- /dev/null
+++ b/WebCore/inspector/InspectorDOMStorageResource.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#if ENABLE(DOM_STORAGE)
+
+#include "InspectorDOMStorageResource.h"
+
+#include "Document.h"
+#include "Frame.h"
+#include "ScriptFunctionCall.h"
+#include "ScriptObjectQuarantine.h"
+#include "ScriptValue.h"
+#include "Storage.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+InspectorDOMStorageResource::InspectorDOMStorageResource(Storage* domStorage, bool isLocalStorage, Frame* frame)
+ : m_domStorage(domStorage)
+ , m_isLocalStorage(isLocalStorage)
+ , m_frame(frame)
+{
+}
+
+bool InspectorDOMStorageResource::isSameHostAndType(Frame* frame, bool isLocalStorage) const
+{
+ return equalIgnoringCase(m_frame->document()->securityOrigin()->host(), frame->document()->securityOrigin()->host()) && m_isLocalStorage == isLocalStorage;
+}
+
+void InspectorDOMStorageResource::bind(ScriptState* scriptState, const ScriptObject& webInspector)
+{
+ if (!m_scriptObject.hasNoValue())
+ return;
+
+ ASSERT(scriptState);
+ ASSERT(!webInspector.hasNoValue());
+ if (!scriptState || webInspector.hasNoValue())
+ return;
+
+ ScriptFunctionCall resourceConstructor(scriptState, webInspector, "DOMStorage");
+ ScriptObject domStorage;
+ if (!getQuarantinedScriptObject(m_frame.get(), m_domStorage.get(), domStorage))
+ return;
+
+ resourceConstructor.appendArgument(domStorage);
+ resourceConstructor.appendArgument(m_frame->document()->securityOrigin()->host());
+ resourceConstructor.appendArgument(m_isLocalStorage);
+
+ bool hadException = false;
+ m_scriptObject = resourceConstructor.construct(hadException);
+ if (hadException)
+ return;
+
+ ScriptFunctionCall addDOMStorage(scriptState, webInspector, "addDOMStorage");
+ addDOMStorage.appendArgument(m_scriptObject);
+ addDOMStorage.call(hadException);
+}
+
+void InspectorDOMStorageResource::unbind()
+{
+ m_scriptObject = ScriptObject();
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/inspector/InspectorDOMStorageResource.h b/WebCore/inspector/InspectorDOMStorageResource.h
new file mode 100644
index 0000000..ad3e196
--- /dev/null
+++ b/WebCore/inspector/InspectorDOMStorageResource.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef InspectorDOMStorageResource_h
+#define InspectorDOMStorageResource_h
+
+#if ENABLE(DOM_STORAGE)
+
+#include "ScriptObject.h"
+#include "ScriptState.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+ class Storage;
+ class Frame;
+
+ class InspectorDOMStorageResource : public RefCounted<InspectorDOMStorageResource> {
+ public:
+ static PassRefPtr<InspectorDOMStorageResource> create(Storage* domStorage, bool isLocalStorage, Frame* frame)
+ {
+ return adoptRef(new InspectorDOMStorageResource(domStorage, isLocalStorage, frame));
+ }
+
+ void bind(ScriptState*, const ScriptObject& webInspector);
+ void unbind();
+
+ bool isSameHostAndType(Frame*, bool isLocalStorage) const;
+
+ private:
+
+ InspectorDOMStorageResource(Storage*, bool isLocalStorage, Frame*);
+
+ ScriptObject m_scriptObject;
+ RefPtr<Storage> m_domStorage;
+ bool m_isLocalStorage;
+ RefPtr<Frame> m_frame;
+
+ private:
+ };
+
+} // namespace WebCore
+
+#endif
+
+#endif // InspectorDOMStorageResource_h
diff --git a/WebCore/inspector/InspectorDatabaseResource.cpp b/WebCore/inspector/InspectorDatabaseResource.cpp
new file mode 100644
index 0000000..43cd8ef
--- /dev/null
+++ b/WebCore/inspector/InspectorDatabaseResource.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#if ENABLE(DATABASE)
+#include "InspectorDatabaseResource.h"
+
+#include "Database.h"
+#include "Document.h"
+#include "Frame.h"
+#include "ScriptFunctionCall.h"
+#include "ScriptObjectQuarantine.h"
+#include "ScriptValue.h"
+
+namespace WebCore {
+
+InspectorDatabaseResource::InspectorDatabaseResource(Database* database, const String& domain, const String& name, const String& version)
+ : m_database(database)
+ , m_domain(domain)
+ , m_name(name)
+ , m_version(version)
+{
+}
+
+void InspectorDatabaseResource::bind(ScriptState* scriptState, const ScriptObject& webInspector)
+{
+ if (!m_scriptObject.hasNoValue())
+ return;
+
+ ASSERT(scriptState);
+ ASSERT(!webInspector.hasNoValue());
+ if (!scriptState || webInspector.hasNoValue())
+ return;
+
+ ScriptFunctionCall resourceConstructor(scriptState, webInspector, "Database");
+ ScriptObject database;
+ if (!getQuarantinedScriptObject(m_database.get(), database))
+ return;
+
+ resourceConstructor.appendArgument(database);
+ resourceConstructor.appendArgument(m_domain);
+ resourceConstructor.appendArgument(m_name);
+ resourceConstructor.appendArgument(m_version);
+
+ bool hadException = false;
+ m_scriptObject = resourceConstructor.construct(hadException);
+ if (hadException)
+ return;
+
+ ScriptFunctionCall addDatabase(scriptState, webInspector, "addDatabase");
+ addDatabase.appendArgument(m_scriptObject);
+ addDatabase.call(hadException);
+}
+
+void InspectorDatabaseResource::unbind()
+{
+ m_scriptObject = ScriptObject();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(DATABASE)
diff --git a/WebCore/inspector/InspectorDatabaseResource.h b/WebCore/inspector/InspectorDatabaseResource.h
new file mode 100644
index 0000000..1be2334
--- /dev/null
+++ b/WebCore/inspector/InspectorDatabaseResource.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef InspectorDatabaseResource_h
+#define InspectorDatabaseResource_h
+
+#if ENABLE(DATABASE)
+
+#include "Database.h"
+#include "ScriptObject.h"
+#include "ScriptState.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+ class InspectorDatabaseResource : public RefCounted<InspectorDatabaseResource> {
+ public:
+ static PassRefPtr<InspectorDatabaseResource> create(Database* database, const String& domain, const String& name, const String& version)
+ {
+ return adoptRef(new InspectorDatabaseResource(database, domain, name, version));
+ }
+
+ void bind(ScriptState*, const ScriptObject& webInspector);
+ void unbind();
+
+ private:
+ InspectorDatabaseResource(Database*, const String& domain, const String& name, const String& version);
+ ScriptObject m_scriptObject;
+
+ RefPtr<Database> m_database;
+ String m_domain;
+ String m_name;
+ String m_version;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(DATABASE)
+
+#endif // InspectorDatabaseResource_h
diff --git a/WebCore/inspector/InspectorResource.cpp b/WebCore/inspector/InspectorResource.cpp
new file mode 100644
index 0000000..7db6cd1
--- /dev/null
+++ b/WebCore/inspector/InspectorResource.cpp
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InspectorResource.h"
+
+#include "CachedResource.h"
+#include "DocLoader.h"
+#include "DocumentLoader.h"
+#include "Frame.h"
+#include "TextEncoding.h"
+
+#include <runtime/JSLock.h>
+
+namespace WebCore {
+
+// XMLHttpRequestResource Class
+
+struct XMLHttpRequestResource {
+ XMLHttpRequestResource(const JSC::UString& sourceString)
+ {
+ JSC::JSLock lock(false);
+ this->sourceString = sourceString.rep();
+ }
+
+ ~XMLHttpRequestResource()
+ {
+ JSC::JSLock lock(false);
+ sourceString.clear();
+ }
+
+ RefPtr<JSC::UString::Rep> sourceString;
+};
+
+ InspectorResource::InspectorResource(long long identifier, DocumentLoader* documentLoader, Frame* frame)
+ : identifier(identifier)
+ , loader(documentLoader)
+ , frame(frame)
+ , scriptContext(0)
+ , scriptObject(0)
+ , expectedContentLength(0)
+ , cached(false)
+ , finished(false)
+ , failed(false)
+ , length(0)
+ , responseStatusCode(0)
+ , startTime(-1.0)
+ , responseReceivedTime(-1.0)
+ , endTime(-1.0)
+ , xmlHttpRequestResource(0)
+ {
+ }
+
+InspectorResource::~InspectorResource()
+{
+ setScriptObject(0, 0);
+}
+
+InspectorResource::Type InspectorResource::type() const
+{
+ if (xmlHttpRequestResource)
+ return XHR;
+
+ if (requestURL == loader->requestURL())
+ return Doc;
+
+ if (loader->frameLoader() && requestURL == loader->frameLoader()->iconURL())
+ return Image;
+
+ CachedResource* cachedResource = frame->document()->docLoader()->cachedResource(requestURL.string());
+ if (!cachedResource)
+ return Other;
+
+ switch (cachedResource->type()) {
+ case CachedResource::ImageResource:
+ return Image;
+ case CachedResource::FontResource:
+ return Font;
+ case CachedResource::CSSStyleSheet:
+#if ENABLE(XSLT)
+ case CachedResource::XSLStyleSheet:
+#endif
+ return Stylesheet;
+ case CachedResource::Script:
+ return Script;
+ default:
+ return Other;
+ }
+}
+
+void InspectorResource::setScriptObject(JSContextRef context, JSObjectRef newScriptObject)
+{
+ if (scriptContext && scriptObject)
+ JSValueUnprotect(scriptContext, scriptObject);
+
+ scriptObject = newScriptObject;
+ scriptContext = context;
+
+ ASSERT((context && newScriptObject) || (!context && !newScriptObject));
+ if (context && newScriptObject)
+ JSValueProtect(context, newScriptObject);
+}
+
+void InspectorResource::setXMLHttpRequestProperties(const JSC::UString& data)
+{
+ xmlHttpRequestResource.set(new XMLHttpRequestResource(data));
+}
+
+void InspectorResource::setScriptProperties(const JSC::UString& data)
+{
+ xmlHttpRequestResource.set(new XMLHttpRequestResource(data));
+}
+
+String InspectorResource::sourceString() const
+{
+ if (xmlHttpRequestResource)
+ return JSC::UString(xmlHttpRequestResource->sourceString);
+
+ RefPtr<SharedBuffer> buffer;
+ String textEncodingName;
+
+ if (requestURL == loader->requestURL()) {
+ buffer = loader->mainResourceData();
+ textEncodingName = frame->document()->inputEncoding();
+ } else {
+ CachedResource* cachedResource = frame->document()->docLoader()->cachedResource(requestURL.string());
+ if (!cachedResource)
+ return String();
+
+ if (cachedResource->isPurgeable()) {
+ // If the resource is purgeable then make it unpurgeable to get
+ // get its data. This might fail, in which case we return an
+ // empty String.
+ // FIXME: should we do something else in the case of a purged
+ // resource that informs the user why there is no data in the
+ // inspector?
+ if (!cachedResource->makePurgeable(false))
+ return String();
+ }
+
+ buffer = cachedResource->data();
+ textEncodingName = cachedResource->encoding();
+ }
+
+ if (!buffer)
+ return String();
+
+ TextEncoding encoding(textEncodingName);
+ if (!encoding.isValid())
+ encoding = WindowsLatin1Encoding();
+ return encoding.decode(buffer->data(), buffer->size());
+}
+
+} // namespace WebCore
diff --git a/WebCore/inspector/InspectorResource.h b/WebCore/inspector/InspectorResource.h
new file mode 100644
index 0000000..46d7fed
--- /dev/null
+++ b/WebCore/inspector/InspectorResource.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef InspectorResource_h
+#define InspectorResource_h
+
+#include <JavaScriptCore/JSContextRef.h>
+
+#include "HTTPHeaderMap.h"
+#include "KURL.h"
+
+#include <wtf/OwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace JSC {
+ class UString;
+}
+
+namespace WebCore {
+ class DocumentLoader;
+ class Frame;
+ struct XMLHttpRequestResource;
+
+ class InspectorResource : public RefCounted<InspectorResource> {
+ public:
+
+ // Keep these in sync with WebInspector.Resource.Type
+ enum Type {
+ Doc,
+ Stylesheet,
+ Image,
+ Font,
+ Script,
+ XHR,
+ Media,
+ Other
+ };
+
+ static PassRefPtr<InspectorResource> create(long long identifier, DocumentLoader* documentLoader, Frame* frame)
+ {
+ return adoptRef(new InspectorResource(identifier, documentLoader, frame));
+ }
+
+ ~InspectorResource();
+ Type type() const;
+ void setScriptObject(JSContextRef, JSObjectRef);
+ void setXMLHttpRequestProperties(const JSC::UString& data);
+ void setScriptProperties(const JSC::UString& data);
+
+ String sourceString() const;
+
+ long long identifier;
+ RefPtr<DocumentLoader> loader;
+ RefPtr<Frame> frame;
+ KURL requestURL;
+ HTTPHeaderMap requestHeaderFields;
+ HTTPHeaderMap responseHeaderFields;
+ String mimeType;
+ String suggestedFilename;
+ JSContextRef scriptContext;
+ JSObjectRef scriptObject;
+ long long expectedContentLength;
+ bool cached;
+ bool finished;
+ bool failed;
+ int length;
+ int responseStatusCode;
+ double startTime;
+ double responseReceivedTime;
+ double endTime;
+
+ private:
+ InspectorResource(long long identifier, DocumentLoader*, Frame*);
+
+ OwnPtr<XMLHttpRequestResource> xmlHttpRequestResource;
+ };
+
+} // namespace WebCore
+
+#endif // InspectorResource_h
diff --git a/WebCore/inspector/JavaScriptDebugServer.cpp b/WebCore/inspector/JavaScriptDebugServer.cpp
index 05dca70..62ccad4 100644
--- a/WebCore/inspector/JavaScriptDebugServer.cpp
+++ b/WebCore/inspector/JavaScriptDebugServer.cpp
@@ -363,12 +363,11 @@ void JavaScriptDebugServer::setJavaScriptPaused(Frame* frame, bool paused)
frame->script()->setPaused(paused);
- if (Document* document = frame->document()) {
- if (paused)
- document->suspendActiveDOMObjects();
- else
- document->resumeActiveDOMObjects();
- }
+ Document* document = frame->document();
+ if (paused)
+ document->suspendActiveDOMObjects();
+ else
+ document->resumeActiveDOMObjects();
setJavaScriptPaused(frame->view(), paused);
}
diff --git a/WebCore/inspector/front-end/Console.js b/WebCore/inspector/front-end/Console.js
index 31e466c..ba879a0 100644
--- a/WebCore/inspector/front-end/Console.js
+++ b/WebCore/inspector/front-end/Console.js
@@ -141,7 +141,7 @@ WebInspector.Console.prototype = {
addMessage: function(msg)
{
- if (msg instanceof WebInspector.ConsoleMessage) {
+ if (msg instanceof WebInspector.ConsoleMessage && !(msg instanceof WebInspector.ConsoleCommandResult)) {
msg.totalRepeatCount = msg.repeatCount;
msg.repeatDelta = msg.repeatCount;
@@ -446,6 +446,9 @@ WebInspector.Console.prototype = {
if (!str.length)
return;
+ var commandMessage = new WebInspector.ConsoleCommand(str);
+ this.addMessage(commandMessage);
+
var result;
var exception = false;
try {
@@ -459,31 +462,12 @@ WebInspector.Console.prototype = {
this.prompt.historyOffset = 0;
this.prompt.text = "";
- var level = exception ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log;
- this.addMessage(new WebInspector.ConsoleCommand(str, result, this._format(result), level));
- },
-
- _mouseOverNode: function(event)
- {
- var anchorElement = event.target.enclosingNodeOrSelfWithNodeName("a");
- WebInspector.hoveredDOMNode = (anchorElement ? anchorElement.representedNode : null);
- },
-
- _mouseOutOfNode: function(event)
- {
- var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY);
- var anchorElement = nodeUnderMouse.enclosingNodeOrSelfWithNodeName("a");
- if (!anchorElement || !anchorElement.representedNode)
- WebInspector.hoveredDOMNode = null;
+ this.addMessage(new WebInspector.ConsoleCommandResult(result, exception, commandMessage));
},
- _format: function(output, inline)
+ _format: function(output, forceObjectFormat)
{
- var type = Object.type(output, InspectorController.inspectedWindow());
- if (type === "object") {
- if (output instanceof InspectorController.inspectedWindow().Node)
- type = "node";
- }
+ var type = (forceObjectFormat ? "object" : Object.type(output, InspectorController.inspectedWindow()));
// We don't perform any special formatting on these types, so we just
// pass them through the simple _formatvalue function.
@@ -497,7 +481,9 @@ WebInspector.Console.prototype = {
};
var formatter;
- if (type in undecoratedTypes)
+ if (forceObjectFormat)
+ formatter = "_formatobject";
+ else if (type in undecoratedTypes)
formatter = "_formatvalue";
else {
formatter = "_format" + type;
@@ -509,77 +495,74 @@ WebInspector.Console.prototype = {
var span = document.createElement("span");
span.addStyleClass("console-formatted-" + type);
- this[formatter](output, span, inline);
+ this[formatter](output, span);
return span;
},
- _formatvalue: function(val, elem, inline)
+ _formatvalue: function(val, elem)
{
elem.appendChild(document.createTextNode(val));
},
- _formatstring: function(str, elem, inline)
+ _formatstring: function(str, elem)
{
elem.appendChild(document.createTextNode("\"" + str + "\""));
},
- _formatregexp: function(re, elem, inline)
+ _formatregexp: function(re, elem)
{
var formatted = String(re).replace(/([\\\/])/g, "\\$1").replace(/\\(\/[gim]*)$/, "$1").substring(1);
elem.appendChild(document.createTextNode(formatted));
},
- _formatarray: function(arr, elem, inline)
+ _formatarray: function(arr, elem)
{
elem.appendChild(document.createTextNode("["));
for (var i = 0; i < arr.length; ++i) {
- elem.appendChild(this._format(arr[i], true));
+ elem.appendChild(this._format(arr[i]));
if (i < arr.length - 1)
elem.appendChild(document.createTextNode(", "));
}
elem.appendChild(document.createTextNode("]"));
},
- _formatnode: function(node, elem, inline)
+ _formatnode: function(node, elem)
{
- var anchor = document.createElement("a");
- anchor.className = "inspectible-node";
- anchor.innerHTML = nodeTitleInfo.call(node).title;
- anchor.representedNode = node;
- anchor.addEventListener("mouseover", this._mouseOverNode.bind(this), false);
- anchor.addEventListener("mouseout", this._mouseOutOfNode.bind(this), false);
-
- if (inline)
- elem.appendChild(anchor);
- else
- elem.appendChild(new WebInspector.ObjectPropertiesSection(node, anchor, null, null, true).element);
+ var treeOutline = new WebInspector.ElementsTreeOutline();
+ treeOutline.rootDOMNode = node;
+ treeOutline.element.addStyleClass("outline-disclosure");
+ if (!treeOutline.children[0].hasChildren)
+ treeOutline.element.addStyleClass("single-node");
+ elem.appendChild(treeOutline.element);
},
- _formatobject: function(obj, elem, inline)
+ _formatobject: function(obj, elem)
{
- if (inline)
- elem.appendChild(document.createTextNode(Object.describe(obj)));
- else
- elem.appendChild(new WebInspector.ObjectPropertiesSection(obj, null, null, null, true).element);
+ elem.appendChild(new WebInspector.ObjectPropertiesSection(obj, null, null, null, true).element);
},
- _formaterror: function(obj, elem, inline)
+ _formaterror: function(obj, elem)
{
- elem.appendChild(document.createTextNode(obj.name + ": " + obj.message + " "));
+ var messageElement = document.createElement("span");
+ messageElement.className = "error-message";
+ messageElement.textContent = obj.name + ": " + obj.message;
+ elem.appendChild(messageElement);
if (obj.sourceURL) {
var urlElement = document.createElement("a");
- urlElement.className = "console-message-url webkit-html-resource-link";
+ urlElement.className = "webkit-html-resource-link";
urlElement.href = obj.sourceURL;
urlElement.lineNumber = obj.line;
urlElement.preferredPanel = "scripts";
if (obj.line > 0)
- urlElement.textContent = WebInspector.UIString("%s (line %d)", obj.sourceURL, obj.line);
+ urlElement.textContent = WebInspector.displayNameForURL(obj.sourceURL) + ":" + obj.line;
else
- urlElement.textContent = obj.sourceURL;
+ urlElement.textContent = WebInspector.displayNameForURL(obj.sourceURL);
+ elem.appendChild(document.createTextNode(" ("));
elem.appendChild(urlElement);
+ elem.appendChild(document.createTextNode(")"));
}
},
}
@@ -596,18 +579,6 @@ WebInspector.ConsoleMessage = function(source, level, line, url, groupLevel, rep
this.repeatCount = repeatCount;
switch (this.level) {
- case WebInspector.ConsoleMessage.MessageLevel.Object:
- var propertiesSection = new WebInspector.ObjectPropertiesSection(arguments[6], null, null, null, true);
- propertiesSection.element.addStyleClass("console-message");
- this.propertiesSection = propertiesSection;
- break;
- case WebInspector.ConsoleMessage.MessageLevel.Node:
- var node = arguments[6];
- if (!(node instanceof InspectorController.inspectedWindow().Node))
- return;
- this.elementsTreeOutline = new WebInspector.ElementsTreeOutline();
- this.elementsTreeOutline.rootDOMNode = node;
- break;
case WebInspector.ConsoleMessage.MessageLevel.Trace:
var span = document.createElement("span");
span.addStyleClass("console-formatted-trace");
@@ -618,14 +589,16 @@ WebInspector.ConsoleMessage = function(source, level, line, url, groupLevel, rep
span.appendChild(document.createTextNode(funcNames.join("\n")));
this.formattedMessage = span;
break;
+ case WebInspector.ConsoleMessage.MessageLevel.Object:
+ this.formattedMessage = this._format(["%O", arguments[6]]);
+ break;
default:
- // The formatedMessage property is used for the rich and interactive console.
this.formattedMessage = this._format(Array.prototype.slice.call(arguments, 6));
-
- // This is used for inline message bubbles in SourceFrames, or other plain-text representations.
- this.message = this.formattedMessage.textContent;
break;
}
+
+ // This is used for inline message bubbles in SourceFrames, or other plain-text representations.
+ this.message = this.formattedMessage.textContent;
}
WebInspector.ConsoleMessage.prototype = {
@@ -643,6 +616,11 @@ WebInspector.ConsoleMessage.prototype = {
function formatForConsole(obj)
{
+ return WebInspector.console._format(obj);
+ }
+
+ function formatAsObjectForConsole(obj)
+ {
return WebInspector.console._format(obj, true);
}
@@ -655,6 +633,8 @@ WebInspector.ConsoleMessage.prototype = {
formatters.o = formatForConsole;
// Firebug allows both %i and %d for formatting integers.
formatters.i = formatters.d;
+ // Support %O to force object formating, instead of the type-based %o formatting.
+ formatters.O = formatAsObjectForConsole;
function append(a, b)
{
@@ -675,10 +655,9 @@ WebInspector.ConsoleMessage.prototype = {
for (var i = 0; i < parameters.length; ++i) {
if (typeof parameters[i] === "string")
formattedResult.appendChild(WebInspector.linkifyStringAsFragment(parameters[i]));
- else if (parameters.length === 1)
- formattedResult.appendChild(WebInspector.console._format(parameters[0]));
else
formattedResult.appendChild(formatForConsole(parameters[i]));
+
if (i < parameters.length - 1)
formattedResult.appendChild(document.createTextNode(" "));
}
@@ -758,7 +737,7 @@ WebInspector.ConsoleMessage.prototype = {
urlElement.preferredPanel = "scripts";
if (this.line > 0)
- urlElement.textContent = WebInspector.UIString("%s (line %d)", WebInspector.displayNameForURL(this.url), this.line);
+ urlElement.textContent = WebInspector.displayNameForURL(this.url) + ":" + this.line;
else
urlElement.textContent = WebInspector.displayNameForURL(this.url);
@@ -814,14 +793,20 @@ WebInspector.ConsoleMessage.prototype = {
case WebInspector.ConsoleMessage.MessageLevel.Object:
levelString = "Object";
break;
- case WebInspector.ConsoleMessage.MessageLevel.GroupTitle:
- levelString = "GroupTitle";
+ case WebInspector.ConsoleMessage.MessageLevel.Trace:
+ levelString = "Trace";
+ break;
+ case WebInspector.ConsoleMessage.MessageLevel.StartGroup:
+ levelString = "Start Group";
+ break;
+ case WebInspector.ConsoleMessage.MessageLevel.EndGroup:
+ levelString = "End Group";
break;
}
return sourceString + " " + levelString + ": " + this.formattedMessage.textContent + "\n" + this.url + " line " + this.line;
},
-
+
isEqual: function(msg, disreguardGroup)
{
if (!msg)
@@ -853,17 +838,14 @@ WebInspector.ConsoleMessage.MessageLevel = {
Warning: 2,
Error: 3,
Object: 4,
- Node: 5,
- Trace: 6,
- StartGroup: 7,
- EndGroup: 8
+ Trace: 5,
+ StartGroup: 6,
+ EndGroup: 7
}
-WebInspector.ConsoleCommand = function(command, result, formattedResultElement, level)
+WebInspector.ConsoleCommand = function(command)
{
this.command = command;
- this.formattedResultElement = formattedResultElement;
- this.level = level;
}
WebInspector.ConsoleCommand.prototype = {
@@ -878,30 +860,33 @@ WebInspector.ConsoleCommand.prototype = {
commandTextElement.textContent = this.command;
element.appendChild(commandTextElement);
- var resultElement = document.createElement("div");
- resultElement.className = "console-message";
- element.appendChild(resultElement);
+ return element;
+ }
+}
- switch (this.level) {
- case WebInspector.ConsoleMessage.MessageLevel.Log:
- resultElement.addStyleClass("console-log-level");
- break;
- case WebInspector.ConsoleMessage.MessageLevel.Warning:
- resultElement.addStyleClass("console-warning-level");
- break;
- case WebInspector.ConsoleMessage.MessageLevel.Error:
- resultElement.addStyleClass("console-error-level");
- }
+WebInspector.ConsoleCommandResult = function(result, exception, originatingCommand)
+{
+ var level = (exception ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log);
+ var message = (exception ? String(result) : result);
+ var line = (exception ? result.line : -1);
+ var url = (exception ? result.sourceURL : null);
+
+ WebInspector.ConsoleMessage.call(this, WebInspector.ConsoleMessage.MessageSource.JS, level, line, url, null, 1, message);
- var resultTextElement = document.createElement("span");
- resultTextElement.className = "console-message-text";
- resultTextElement.appendChild(this.formattedResultElement);
- resultElement.appendChild(resultTextElement);
+ this.originatingCommand = originatingCommand;
+}
+WebInspector.ConsoleCommandResult.prototype = {
+ toMessageElement: function()
+ {
+ var element = WebInspector.ConsoleMessage.prototype.toMessageElement.call(this);
+ element.addStyleClass("console-user-command-result");
return element;
}
}
+WebInspector.ConsoleCommandResult.prototype.__proto__ = WebInspector.ConsoleMessage.prototype;
+
WebInspector.ConsoleGroup = function(parentGroup, level)
{
this.parentGroup = parentGroup;
@@ -928,8 +913,11 @@ WebInspector.ConsoleGroup.prototype = {
element.addEventListener("click", this._titleClicked.bind(this), true);
} else
this.messagesElement.appendChild(element);
+
+ if (element.previousSibling && msg.originatingCommand && element.previousSibling.command === msg.originatingCommand)
+ element.previousSibling.addStyleClass("console-adjacent-user-command-result");
},
-
+
_titleClicked: function(event)
{
var groupTitleElement = event.target.enclosingNodeOrSelfWithClass("console-group-title-level");
diff --git a/WebCore/inspector/front-end/DOMStorage.js b/WebCore/inspector/front-end/DOMStorage.js
new file mode 100644
index 0000000..5207b69
--- /dev/null
+++ b/WebCore/inspector/front-end/DOMStorage.js
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008 Nokia Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.DOMStorage = function(domStorage, domain, isLocalStorage)
+{
+ this.domStorage = domStorage;
+ this.domain = domain;
+ this.isLocalStorage = isLocalStorage;
+}
+
+WebInspector.DOMStorage.prototype = {
+ get domStorage()
+ {
+ return this._domStorage;
+ },
+
+ set domStorage(x)
+ {
+ if (this._domStorage === x)
+ return;
+ this._domStorage = x;
+ },
+
+ get domain()
+ {
+ return this._domain;
+ },
+
+ set domain(x)
+ {
+ if (this._domain === x)
+ return;
+ this._domain = x;
+ },
+
+ get isLocalStorage()
+ {
+ return this._isLocalStorage;
+ },
+
+ set isLocalStorage(x)
+ {
+ if (this._isLocalStorage === x)
+ return;
+ this._isLocalStorage = x;
+ }
+}
diff --git a/WebCore/inspector/front-end/DOMStorageDataGrid.js b/WebCore/inspector/front-end/DOMStorageDataGrid.js
new file mode 100644
index 0000000..9946415
--- /dev/null
+++ b/WebCore/inspector/front-end/DOMStorageDataGrid.js
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2009 Nokia Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.DOMStorageDataGrid = function(columns)
+{
+ WebInspector.DataGrid.call(this, columns);
+ this.dataTableBody.addEventListener("dblclick", this._ondblclick.bind(this), false);
+}
+
+WebInspector.DOMStorageDataGrid.prototype = {
+ _ondblclick: function(event)
+ {
+ if (this._editing)
+ return;
+ if (this._editingNode)
+ return;
+ this._startEditing(event);
+ },
+
+ _startEditing: function(event)
+ {
+ var element = event.target.enclosingNodeOrSelfWithNodeName("td");
+ if (!element)
+ return;
+ this._editingNode = this.dataGridNodeFromEvent(event);
+ if (!this._editingNode)
+ return;
+ this._editing = true;
+
+ WebInspector.startEditing(element, this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent);
+ window.getSelection().setBaseAndExtent(element, 0, element, 1);
+ },
+
+ _editingCommitted: function(element, newText)
+ {
+ if (element.hasStyleClass("0-column"))
+ columnIdentifier = 0;
+ else
+ columnIdentifier = 1;
+ textBeforeEditing = this._editingNode.data[columnIdentifier];
+ if (textBeforeEditing == newText) {
+ this._editingCancelled(element);
+ return;
+ }
+
+ var domStorage = WebInspector.panels.databases.visibleView.domStorage.domStorage;
+ if (domStorage) {
+ if (columnIdentifier == 0) {
+ if (domStorage.getItem(newText) != null) {
+ element.textContent = this._editingNode.data[0];
+ this._editingCancelled(element);
+ return;
+ }
+ domStorage.removeItem(this._editingNode.data[0]);
+ domStorage.setItem(newText, this._editingNode.data[1]);
+ this._editingNode.data[0] = newText;
+ } else {
+ domStorage.setItem(this._editingNode.data[0], newText);
+ this._editingNode.data[1] = newText;
+ }
+ }
+
+ this._editingCancelled(element);
+ },
+
+ _editingCancelled: function(element, context)
+ {
+ delete this._editing;
+ this._editingNode = null;
+ },
+
+ deleteSelectedRow: function()
+ {
+ var node = this.selectedNode;
+ var domStorage = WebInspector.panels.databases.visibleView.domStorage.domStorage;
+ if (node && domStorage)
+ domStorage.removeItem(node.data[0]);
+ }
+}
+
+WebInspector.DOMStorageDataGrid.prototype.__proto__ = WebInspector.DataGrid.prototype;
diff --git a/WebCore/inspector/front-end/DOMStorageItemsView.js b/WebCore/inspector/front-end/DOMStorageItemsView.js
new file mode 100644
index 0000000..912573e
--- /dev/null
+++ b/WebCore/inspector/front-end/DOMStorageItemsView.js
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2008 Nokia Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.DOMStorageItemsView = function(domStorage)
+{
+ WebInspector.View.call(this);
+
+ this.domStorage = domStorage;
+
+ this.element.addStyleClass("storage-view");
+ this.element.addStyleClass("table");
+
+ this.deleteButton = document.createElement("button");
+ this.deleteButton.title = WebInspector.UIString("Delete");
+ this.deleteButton.className = "delete-storage-status-bar-item status-bar-item hidden";
+ this.deleteButton.addEventListener("click", this._deleteButtonClicked.bind(this), false);
+
+ this.refreshButton = document.createElement("button");
+ this.refreshButton.title = WebInspector.UIString("Refresh");
+ this.refreshButton.className = "refresh-storage-status-bar-item status-bar-item";
+ this.refreshButton.addEventListener("click", this._refreshButtonClicked.bind(this), false);
+}
+
+WebInspector.DOMStorageItemsView.prototype = {
+ get statusBarItems()
+ {
+ return [this.refreshButton, this.deleteButton];
+ },
+
+ show: function(parentElement)
+ {
+ WebInspector.View.prototype.show.call(this, parentElement);
+ this.update();
+ },
+
+ hide: function()
+ {
+ WebInspector.View.prototype.hide.call(this);
+ this.deleteButton.addStyleClass("hidden");
+ },
+
+ update: function()
+ {
+ this.element.removeChildren();
+ var hasDOMStorage = this.domStorage;
+ if (hasDOMStorage)
+ hasDOMStorage = this.domStorage.domStorage;
+
+ if (hasDOMStorage) {
+ var dataGrid = WebInspector.panels.databases.dataGridForDOMStorage(this.domStorage.domStorage);
+ if (!dataGrid)
+ hasDOMStorage = 0;
+ else {
+ this._dataGrid = dataGrid;
+ this.element.appendChild(dataGrid.element);
+ this.deleteButton.removeStyleClass("hidden");
+ }
+ }
+
+ if (!hasDOMStorage) {
+ var emptyMsgElement = document.createElement("div");
+ emptyMsgElement.className = "storage-table-empty";
+ if (this.domStorage)
+ emptyMsgElement.textContent = WebInspector.UIString("This storage is empty.");
+ this.element.appendChild(emptyMsgElement);
+ this._dataGrid = null;
+ this.deleteButton.addStyleClass("hidden");
+ }
+ },
+
+ _deleteButtonClicked: function(event)
+ {
+ if (this._dataGrid) {
+ this._dataGrid.deleteSelectedRow();
+
+ this.show();
+ }
+ },
+
+ _refreshButtonClicked: function(event)
+ {
+ this.update();
+ }
+}
+
+WebInspector.DOMStorageItemsView.prototype.__proto__ = WebInspector.View.prototype;
diff --git a/WebCore/inspector/front-end/DatabaseQueryView.js b/WebCore/inspector/front-end/DatabaseQueryView.js
index 6a91625..122707f 100644
--- a/WebCore/inspector/front-end/DatabaseQueryView.js
+++ b/WebCore/inspector/front-end/DatabaseQueryView.js
@@ -29,7 +29,7 @@ WebInspector.DatabaseQueryView = function(database)
this.database = database;
- this.element.addStyleClass("database-view");
+ this.element.addStyleClass("storage-view");
this.element.addStyleClass("query");
this.element.tabIndex = 0;
diff --git a/WebCore/inspector/front-end/DatabaseTableView.js b/WebCore/inspector/front-end/DatabaseTableView.js
index 2e72240..bbca9d0 100644
--- a/WebCore/inspector/front-end/DatabaseTableView.js
+++ b/WebCore/inspector/front-end/DatabaseTableView.js
@@ -30,8 +30,13 @@ WebInspector.DatabaseTableView = function(database, tableName)
this.database = database;
this.tableName = tableName;
- this.element.addStyleClass("database-view");
+ this.element.addStyleClass("storage-view");
this.element.addStyleClass("table");
+
+ this.refreshButton = document.createElement("button");
+ this.refreshButton.title = WebInspector.UIString("Refresh");
+ this.refreshButton.className = "refresh-storage-status-bar-item status-bar-item";
+ this.refreshButton.addEventListener("click", this._refreshButtonClicked.bind(this), false);
}
WebInspector.DatabaseTableView.prototype = {
@@ -41,6 +46,11 @@ WebInspector.DatabaseTableView.prototype = {
this.update();
},
+ get statusBarItems()
+ {
+ return [this.refreshButton];
+ },
+
update: function()
{
function queryTransaction(tx)
@@ -58,7 +68,7 @@ WebInspector.DatabaseTableView.prototype = {
var dataGrid = WebInspector.panels.databases.dataGridForResult(result);
if (!dataGrid) {
var emptyMsgElement = document.createElement("div");
- emptyMsgElement.className = "database-table-empty";
+ emptyMsgElement.className = "storage-table-empty";
emptyMsgElement.textContent = WebInspector.UIString("The ā€œ%sā€\ntable is empty.", this.tableName);
this.element.appendChild(emptyMsgElement);
return;
@@ -72,11 +82,15 @@ WebInspector.DatabaseTableView.prototype = {
this.element.removeChildren();
var errorMsgElement = document.createElement("div");
- errorMsgElement.className = "database-table-error";
+ errorMsgElement.className = "storage-table-error";
errorMsgElement.textContent = WebInspector.UIString("An error occurred trying to\nread the ā€œ%sā€ table.", this.tableName);
this.element.appendChild(errorMsgElement);
},
+ _refreshButtonClicked: function(event)
+ {
+ this.update();
+ }
}
WebInspector.DatabaseTableView.prototype.__proto__ = WebInspector.View.prototype;
diff --git a/WebCore/inspector/front-end/DatabasesPanel.js b/WebCore/inspector/front-end/DatabasesPanel.js
index df5bbb3..4644b3b 100644
--- a/WebCore/inspector/front-end/DatabasesPanel.js
+++ b/WebCore/inspector/front-end/DatabasesPanel.js
@@ -46,9 +46,24 @@ WebInspector.DatabasesPanel = function(database)
this.sidebarTree = new TreeOutline(this.sidebarTreeElement);
- this.databaseViews = document.createElement("div");
- this.databaseViews.id = "database-views";
- this.element.appendChild(this.databaseViews);
+ this.databasesListTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("DATABASES"), {}, true);
+ this.sidebarTree.appendChild(this.databasesListTreeElement);
+ this.databasesListTreeElement.expand();
+
+ this.localStorageListTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("LOCAL STORAGE"), {}, true);
+ this.sidebarTree.appendChild(this.localStorageListTreeElement);
+ this.localStorageListTreeElement.expand();
+
+ this.sessionStorageListTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("SESSION STORAGE"), {}, true);
+ this.sidebarTree.appendChild(this.sessionStorageListTreeElement);
+ this.sessionStorageListTreeElement.expand();
+
+ this.storageViews = document.createElement("div");
+ this.storageViews.id = "storage-views";
+ this.element.appendChild(this.storageViews);
+
+ this.storageViewStatusBarItemsContainer = document.createElement("div");
+ this.storageViewStatusBarItemsContainer.id = "storage-view-status-bar-items";
this.reset();
}
@@ -61,6 +76,11 @@ WebInspector.DatabasesPanel.prototype = {
return WebInspector.UIString("Databases");
},
+ get statusBarItems()
+ {
+ return [this.storageViewStatusBarItemsContainer];
+ },
+
show: function()
{
WebInspector.Panel.prototype.show.call(this);
@@ -81,8 +101,23 @@ WebInspector.DatabasesPanel.prototype = {
this._databases = [];
- this.sidebarTree.removeChildren();
- this.databaseViews.removeChildren();
+ if (this._domStorage) {
+ var domStorageLength = this._domStorage.length;
+ for (var i = 0; i < domStorageLength; ++i) {
+ var domStorage = this._domStorage[i];
+
+ delete domStorage._domStorageView;
+ }
+ }
+
+ this._domStorage = [];
+
+ this.databasesListTreeElement.removeChildren();
+ this.localStorageListTreeElement.removeChildren();
+ this.sessionStorageListTreeElement.removeChildren();
+ this.storageViews.removeChildren();
+
+ this.storageViewStatusBarItemsContainer.removeChildren();
},
handleKeyEvent: function(event)
@@ -96,8 +131,18 @@ WebInspector.DatabasesPanel.prototype = {
var databaseTreeElement = new WebInspector.DatabaseSidebarTreeElement(database);
database._databasesTreeElement = databaseTreeElement;
+ this.databasesListTreeElement.appendChild(databaseTreeElement);
+ },
- this.sidebarTree.appendChild(databaseTreeElement);
+ addDOMStorage: function(domStorage)
+ {
+ this._domStorage.push(domStorage);
+ var domStorageTreeElement = new WebInspector.DOMStorageSidebarTreeElement(domStorage);
+ domStorage._domStorageTreeElement = domStorageTreeElement;
+ if (domStorage.isLocalStorage)
+ this.localStorageListTreeElement.appendChild(domStorageTreeElement);
+ else
+ this.sessionStorageListTreeElement.appendChild(domStorageTreeElement);
},
showDatabase: function(database, tableName)
@@ -105,8 +150,8 @@ WebInspector.DatabasesPanel.prototype = {
if (!database)
return;
- if (this.visibleDatabaseView)
- this.visibleDatabaseView.hide();
+ if (this.visibleView)
+ this.visibleView.hide();
var view;
if (tableName) {
@@ -125,16 +170,46 @@ WebInspector.DatabasesPanel.prototype = {
}
}
- view.show(this.databaseViews);
+ view.show(this.storageViews);
+
+ this.visibleView = view;
- this.visibleDatabaseView = view;
+ this.storageViewStatusBarItemsContainer.removeChildren();
+ var statusBarItems = view.statusBarItems;
+ for (var i = 0; i < statusBarItems.length; ++i)
+ this.storageViewStatusBarItemsContainer.appendChild(statusBarItems[i]);
+ },
+
+ showDOMStorage: function(domStorage)
+ {
+ if (!domStorage)
+ return;
+
+ if (this.visibleView)
+ this.visibleView.hide();
+
+ var view;
+ view = domStorage._domStorageView;
+ if (!view) {
+ view = new WebInspector.DOMStorageItemsView(domStorage);
+ domStorage._domStorageView = view;
+ }
+
+ view.show(this.storageViews);
+
+ this.visibleView = view;
+
+ this.storageViewStatusBarItemsContainer.removeChildren();
+ var statusBarItems = view.statusBarItems;
+ for (var i = 0; i < statusBarItems.length; ++i)
+ this.storageViewStatusBarItemsContainer.appendChild(statusBarItems[i]);
},
closeVisibleView: function()
{
- if (this.visibleDatabaseView)
- this.visibleDatabaseView.hide();
- delete this.visibleDatabaseView;
+ if (this.visibleView)
+ this.visibleView.hide();
+ delete this.visibleView;
},
updateDatabaseTables: function(database)
@@ -155,7 +230,7 @@ WebInspector.DatabasesPanel.prototype = {
for (var tableName in database._tableViews) {
if (!(tableName in tableNamesHash)) {
- if (this.visibleDatabaseView === database._tableViews[tableName])
+ if (this.visibleView === database._tableViews[tableName])
this.closeVisibleView();
delete database._tableViews[tableName];
}
@@ -241,6 +316,60 @@ WebInspector.DatabasesPanel.prototype = {
return dataGrid;
},
+ dataGridForDOMStorage: function(domStorage)
+ {
+ if (!domStorage.length)
+ return null;
+
+ var columns = {};
+ columns[0] = {};
+ columns[1] = {};
+ columns[0].title = WebInspector.UIString("Key");
+ columns[0].width = columns[0].title.length;
+ columns[1].title = WebInspector.UIString("Value");
+ columns[1].width = columns[0].title.length;
+
+ var nodes = [];
+
+ var length = domStorage.length;
+ for (index = 0; index < domStorage.length; index++) {
+ var data = {};
+
+ var key = String(domStorage.key(index));
+ data[0] = key;
+ if (key.length > columns[0].width)
+ columns[0].width = key.length;
+
+ var value = String(domStorage.getItem(key));
+ data[1] = value;
+ if (value.length > columns[1].width)
+ columns[1].width = value.length;
+ var node = new WebInspector.DataGridNode(data, false);
+ node.selectable = true;
+ nodes.push(node);
+ }
+
+ var totalColumnWidths = columns[0].width + columns[1].width;
+ width = Math.round((columns[0].width * 100) / totalColumnWidths);
+ const minimumPrecent = 10;
+ if (width < minimumPrecent)
+ width = minimumPrecent;
+ if (width > 100 - minimumPrecent)
+ width = 100 - minimumPrecent;
+ columns[0].width = width;
+ columns[1].width = 100 - width;
+ columns[0].width += "%";
+ columns[1].width += "%";
+
+ var dataGrid = new WebInspector.DOMStorageDataGrid(columns);
+ var length = nodes.length;
+ for (var i = 0; i < length; ++i)
+ dataGrid.appendChild(nodes[i]);
+ if (length > 0)
+ nodes[0].selected = true;
+ return dataGrid;
+ },
+
_startSidebarDragging: function(event)
{
WebInspector.elementDragStart(this.sidebarResizeElement, this._sidebarDragging.bind(this), this._endSidebarDragging.bind(this), event, "col-resize");
@@ -277,7 +406,8 @@ WebInspector.DatabasesPanel.prototype = {
this._currentSidebarWidth = width;
this.sidebarElement.style.width = width + "px";
- this.databaseViews.style.left = width + "px";
+ this.storageViews.style.left = width + "px";
+ this.storageViewStatusBarItemsContainer.style.left = width + "px";
this.sidebarResizeElement.style.left = (width - 3) + "px";
}
}
@@ -355,3 +485,42 @@ WebInspector.SidebarDatabaseTableTreeElement.prototype = {
}
WebInspector.SidebarDatabaseTableTreeElement.prototype.__proto__ = WebInspector.SidebarTreeElement.prototype;
+
+WebInspector.DOMStorageSidebarTreeElement = function(domStorage)
+{
+
+ this.domStorage = domStorage;
+
+ WebInspector.SidebarTreeElement.call(this, "domstorage-sidebar-tree-item", domStorage, "", null, false);
+
+ this.refreshTitles();
+}
+
+WebInspector.DOMStorageSidebarTreeElement.prototype = {
+ onselect: function()
+ {
+ WebInspector.panels.databases.showDOMStorage(this.domStorage);
+ },
+
+ get mainTitle()
+ {
+ return this.domStorage.domain;
+ },
+
+ set mainTitle(x)
+ {
+ // Do nothing.
+ },
+
+ get subtitle()
+ {
+ return ""; //this.database.displayDomain;
+ },
+
+ set subtitle(x)
+ {
+ // Do nothing.
+ }
+}
+
+WebInspector.DOMStorageSidebarTreeElement.prototype.__proto__ = WebInspector.SidebarTreeElement.prototype;
diff --git a/WebCore/inspector/front-end/Images/domStorage.png b/WebCore/inspector/front-end/Images/domStorage.png
new file mode 100644
index 0000000..028550c
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/domStorage.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/userInputResultIcon.png b/WebCore/inspector/front-end/Images/userInputResultIcon.png
new file mode 100644
index 0000000..794a5ca
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/userInputResultIcon.png
Binary files differ
diff --git a/WebCore/inspector/front-end/ScriptsPanel.js b/WebCore/inspector/front-end/ScriptsPanel.js
index 38a6a96..2792834 100644
--- a/WebCore/inspector/front-end/ScriptsPanel.js
+++ b/WebCore/inspector/front-end/ScriptsPanel.js
@@ -569,11 +569,29 @@ WebInspector.ScriptsPanel.prototype = {
var select = this.filesSelectElement;
- // FIXME: Append in some meaningful order.
var option = document.createElement("option");
option.representedObject = (script.resource || script);
option.text = (script.sourceURL ? WebInspector.displayNameForURL(script.sourceURL) : WebInspector.UIString("(program)"));
- select.appendChild(option);
+
+ var insertionIndex = -1;
+ if (select.childNodes) {
+ insertionIndex = insertionIndexForObjectInListSortedByFunction(option, select.childNodes, function(a, b) {
+ a = a.text.toLowerCase();
+ b = b.text.toLowerCase();
+
+ if (a < b)
+ return -1;
+ else if (a > b)
+ return 1;
+
+ return 0;
+ });
+ }
+
+ if (insertionIndex < 0)
+ select.appendChild(option);
+ else
+ select.insertBefore(option, select.childNodes.item(insertionIndex));
script.filesSelectOption = option;
diff --git a/WebCore/inspector/front-end/SourceFrame.js b/WebCore/inspector/front-end/SourceFrame.js
index 8d6d6d3..26c0626 100644
--- a/WebCore/inspector/front-end/SourceFrame.js
+++ b/WebCore/inspector/front-end/SourceFrame.js
@@ -225,8 +225,10 @@ WebInspector.SourceFrame.prototype = {
this.element.contentWindow.Element.prototype.addStyleClass = Element.prototype.addStyleClass;
this.element.contentWindow.Element.prototype.removeStyleClass = Element.prototype.removeStyleClass;
+ this.element.contentWindow.Element.prototype.removeMatchingStyleClasses = Element.prototype.removeMatchingStyleClasses;
this.element.contentWindow.Element.prototype.hasStyleClass = Element.prototype.hasStyleClass;
this.element.contentWindow.Node.prototype.enclosingNodeOrSelfWithNodeName = Node.prototype.enclosingNodeOrSelfWithNodeName;
+ this.element.contentWindow.Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = Node.prototype.enclosingNodeOrSelfWithNodeNameInArray;
this._addExistingMessagesToSource();
this._addExistingBreakpointsToSource();
diff --git a/WebCore/inspector/front-end/WebKit.qrc b/WebCore/inspector/front-end/WebKit.qrc
index 52a8578..997d4a7 100644
--- a/WebCore/inspector/front-end/WebKit.qrc
+++ b/WebCore/inspector/front-end/WebKit.qrc
@@ -10,6 +10,9 @@
<file>DatabasesPanel.js</file>
<file>DatabaseTableView.js</file>
<file>DataGrid.js</file>
+ <file>DOMStorage.js</file>
+ <file>DOMStorageDataGrid.js</file>
+ <file>DOMStorageItemsView.js</file>
<file>ElementsPanel.js</file>
<file>ElementsTreeOutline.js</file>
<file>FontView.js</file>
@@ -66,6 +69,7 @@
<file>Images/disclosureTriangleSmallRightDownWhite.png</file>
<file>Images/disclosureTriangleSmallRightWhite.png</file>
<file>Images/dockButtons.png</file>
+ <file>Images/domStorage.png</file>
<file>Images/elementsIcon.png</file>
<file>Images/enableButtons.png</file>
<file>Images/errorIcon.png</file>
diff --git a/WebCore/inspector/front-end/inspector.css b/WebCore/inspector/front-end/inspector.css
index 7e3c224..082955e 100644
--- a/WebCore/inspector/front-end/inspector.css
+++ b/WebCore/inspector/front-end/inspector.css
@@ -439,6 +439,7 @@ body.console-visible #console {
#console-messages {
position: absolute;
+ z-index: 0;
top: 0;
left: 0;
right: 0;
@@ -463,6 +464,10 @@ body.console-visible #console {
background-image: url(Images/userInputIcon.png);
}
+.console-user-command-result.console-log-level::before {
+ background-image: url(Images/userInputResultIcon.png);
+}
+
.console-message, .console-user-command {
position: relative;
border-bottom: 1px solid rgb(240, 240, 240);
@@ -470,6 +475,14 @@ body.console-visible #console {
min-height: 16px;
}
+.console-adjacent-user-command-result {
+ border-bottom: none;
+}
+
+.console-adjacent-user-command-result + .console-user-command-result.console-log-level::before {
+ background-image: none;
+}
+
.console-message::before, .console-user-command::before, #console-prompt::before, .console-group-title-level::before {
position: absolute;
display: block;
@@ -561,35 +574,34 @@ body.console-visible #console {
color: rgb(0, 128, 255);
}
-.console-message-url {
- color: rgb(33%, 33%, 33%) !important;
+#console-messages a {
+ color: rgb(33%, 33%, 33%);
cursor: pointer;
- float: right;
}
-.console-message-url:hover {
+#console-messages a:hover {
color: rgb(15%, 15%, 15%);
}
-.console-message-url:hover::after {
- opacity: 1;
+.console-message-url {
+ float: right;
}
.console-group-messages .section {
- margin: 0;
+ margin: 0 0 0 12px !important;
}
.console-group-messages .section .header {
padding: 0 8px 0 0;
background-image: none;
border: none;
- min-height: 16px;
+ min-height: 0;
}
.console-group-messages .section .header::before {
position: absolute;
top: 1px;
- left: 12px;
+ left: 1px;
width: 8px;
height: 8px;
content: url(Images/treeRightTriangleBlack.png);
@@ -601,6 +613,21 @@ body.console-visible #console {
.console-group-messages .section .header .title {
color: black;
+ font-weight: normal;
+}
+
+.console-group-messages .section .properties li .info {
+ padding-top: 0;
+ padding-bottom: 0;
+ color: rgb(60%, 60%, 60%);
+}
+
+.console-group-messages .outline-disclosure {
+ padding-left: 0;
+}
+
+.console-group-messages .outline-disclosure > ol {
+ padding: 0 0 0 12px !important;
}
.console-group-messages .outline-disclosure, .console-group-messages .outline-disclosure ol {
@@ -608,33 +635,39 @@ body.console-visible #console {
line-height: 1em;
}
-.console-group-messages .outline-disclosure li {
- padding-top: 2px;
- padding-bottom: 2px;
+.console-group-messages .outline-disclosure.single-node li {
+ padding-left: 2px;
}
.console-group-messages .outline-disclosure li .selection {
- z-index: 0;
- margin-top: -1px;
+ margin-left: -6px;
+ margin-right: -6px;
+}
+
+.console-formatted-object, .console-formatted-node {
+ position: relative;
+ display: inline-block;
+ vertical-align: top;
}
.console-formatted-object .section, .console-formatted-node .section {
position: static;
}
+.console-formatted-object .properties, .console-formatted-node .properties {
+ padding-left: 0 !important;
+}
+
+.error-message {
+ color: red;
+}
+
.auto-complete-text {
color: rgb(128, 128, 128);
-webkit-user-select: none;
-webkit-user-modify: read-only;
}
-.inspectible-node:hover {
- background-color: rgba(56, 121, 217, 0.1);
- -webkit-border-radius: 5px;
- padding: 0 5px 1px;
- margin: 0 -5px -1px;
-}
-
.panel {
display: none;
overflow: hidden;
@@ -1532,7 +1565,11 @@ body.inactive .sidebar {
content: url(Images/databaseTable.png);
}
-#database-views {
+.domstorage-sidebar-tree-item .icon {
+ content: url(Images/domStorage.png);
+}
+
+#storage-views {
position: absolute;
top: 0;
right: 0;
@@ -1540,7 +1577,7 @@ body.inactive .sidebar {
bottom: 0;
}
-.database-view {
+.storage-view {
display: none;
overflow: hidden;
position: absolute;
@@ -1550,20 +1587,20 @@ body.inactive .sidebar {
bottom: 0;
}
-.database-view.visible {
+.storage-view.visible {
display: block;
}
-.database-view.table {
+.storage-view.table {
overflow: hidden;
}
-.database-view.table .data-grid {
+.storage-view.table .data-grid {
border: none;
height: 100%;
}
-.database-view.table .database-table-empty, .database-view.table .database-table-error {
+.storage-view.table .storage-table-empty, .storage-view.table .storage-table-error {
position: absolute;
top: 0;
bottom: 25%;
@@ -1581,7 +1618,7 @@ body.inactive .sidebar {
white-space: pre-wrap;
}
-.database-view.table .database-table-error {
+.storage-view.table .storage-table-error {
color: rgb(66%, 33%, 33%);
}
@@ -1773,7 +1810,7 @@ body.inactive .data-grid th.sort-ascending, body.inactive .data-grid th.sort-des
text-indent: 10px;
}
-.database-view.query {
+.storage-view.query {
font-size: 10px;
font-family: Monaco, Lucida Console, monospace;
padding: 2px 0;
@@ -2498,6 +2535,10 @@ button.enable-toggle-status-bar-item.toggled-on:active {
padding-left: 37px;
}
+.sidebar-tree > .children > .children > .sidebar-tree-item {
+ padding-left: 37px;
+}
+
.sidebar-tree.hide-disclosure-buttons > .children {
display: none;
}
@@ -2994,3 +3035,39 @@ body.inactive .sidebar-tree-item.selected .bubble.search-matches {
.reset-profile-status-bar-item:active {
background-position: 32px 0;
}
+
+.delete-storage-status-bar-item {
+ background-image: url(Images/excludeButtons.png) !important;
+}
+
+.delete-storage-status-bar-item:active {
+ background-position: 32px 0;
+}
+
+#storage-view-status-bar-items {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 200px;
+ overflow: hidden;
+ border-left: 1px solid rgb(184, 184, 184);
+ margin-left: -1px;
+}
+
+.refresh-storage-status-bar-item {
+ background-image: url(Images/reloadButtons.png) !important;
+}
+
+.refresh-storage-status-bar-item:active {
+ background-position: 32px 0;
+}
+
+#storage-view-status-bar-items {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 200px;
+ overflow: hidden;
+ border-left: 1px solid rgb(184, 184, 184);
+ margin-left: -1px;
+}
diff --git a/WebCore/inspector/front-end/inspector.html b/WebCore/inspector/front-end/inspector.html
index cb38886..77d720b 100644
--- a/WebCore/inspector/front-end/inspector.html
+++ b/WebCore/inspector/front-end/inspector.html
@@ -41,7 +41,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="Resource.js"></script>
<script type="text/javascript" src="ResourceCategory.js"></script>
<script type="text/javascript" src="Database.js"></script>
+ <script type="text/javascript" src="DOMStorage.js"></script>
+ <script type="text/javascript" src="DOMStorageItemsView.js"></script>
<script type="text/javascript" src="DataGrid.js"></script>
+ <script type="text/javascript" src="DOMStorageDataGrid.js"></script>
<script type="text/javascript" src="Script.js"></script>
<script type="text/javascript" src="Breakpoint.js"></script>
<script type="text/javascript" src="SidebarPane.js"></script>
diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js
index 07ae7db..90ffa2b 100644
--- a/WebCore/inspector/front-end/inspector.js
+++ b/WebCore/inspector/front-end/inspector.js
@@ -287,10 +287,14 @@ WebInspector.loaded = function()
databases: new WebInspector.DatabasesPanel()
};
+ var hiddenPanels = (InspectorController.hiddenPanels() || "").split(',');
+
var toolbarElement = document.getElementById("toolbar");
var previousToolbarItem = toolbarElement.children[0];
for (var panelName in this.panels) {
+ if (hiddenPanels.indexOf(panelName) !== -1)
+ continue;
var panel = this.panels[panelName];
var panelToolbarItem = panel.toolbarItem;
panelToolbarItem.addEventListener("click", this._toolbarItemClicked.bind(this));
@@ -795,6 +799,11 @@ WebInspector.addDatabase = function(database)
this.panels.databases.addDatabase(database);
}
+WebInspector.addDOMStorage = function(domStorage)
+{
+ this.panels.databases.addDOMStorage(domStorage);
+}
+
WebInspector.debuggerWasEnabled = function()
{
this.panels.scripts.debuggerWasEnabled();
diff --git a/WebCore/inspector/front-end/utilities.js b/WebCore/inspector/front-end/utilities.js
index 8f86504..7b0a20b 100644
--- a/WebCore/inspector/front-end/utilities.js
+++ b/WebCore/inspector/front-end/utilities.js
@@ -37,6 +37,8 @@ Object.type = function(obj, win)
win = win || window;
+ if (obj instanceof win.Node)
+ return "node";
if (obj instanceof win.String)
return "string";
if (obj instanceof win.Array)
@@ -70,6 +72,7 @@ Object.describe = function(obj, abbreviated)
switch (type1) {
case "object":
+ case "node":
return type2;
case "array":
return "[" + obj.toString() + "]";
@@ -937,6 +940,40 @@ Array.prototype.remove = function(value, onlyFirst)
}
}
+function insertionIndexForObjectInListSortedByFunction(anObject, aList, aFunction)
+{
+ // indexOf returns (-lowerBound - 1). Taking (-result - 1) works out to lowerBound.
+ return (-indexOfObjectInListSortedByFunction(anObject, aList, aFunction) - 1);
+}
+
+function indexOfObjectInListSortedByFunction(anObject, aList, aFunction)
+{
+ var first = 0;
+ var last = aList.length - 1;
+ var floor = Math.floor;
+ var mid, c;
+
+ while (first <= last) {
+ mid = floor((first + last) / 2);
+ c = aFunction(anObject, aList[mid]);
+
+ if (c > 0)
+ first = mid + 1;
+ else if (c < 0)
+ last = mid - 1;
+ else {
+ //we return the first occurance of an item in the list.
+ while (mid > 0 && aFunction(anObject, aList[mid - 1]) === 0)
+ mid--;
+ return mid;
+ }
+ }
+
+ // By returning 1 less than the negative lower search bound, we can reuse this function
+ // for both indexOf and insertionIndexFor, with some simple arithmetic.
+ return (-first - 1);
+}
+
String.sprintf = function(format)
{
return String.vsprintf(format, Array.prototype.slice.call(arguments, 1));