2009-10-07 Pavel Feldman <pfeldman@chromium.org>
authorpfeldman@chromium.org <pfeldman@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Oct 2009 09:32:06 +0000 (09:32 +0000)
committerpfeldman@chromium.org <pfeldman@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Oct 2009 09:32:06 +0000 (09:32 +0000)
        Reviewed by Timothy Hatcher.

        Web Inspector: Migrate database inspection to the injected script-based schema.

        https://bugs.webkit.org/show_bug.cgi?id=29788

        * bindings/js/JSInspectorBackendCustom.cpp:
        (WebCore::JSInspectorBackend::databaseForId):
        * bindings/v8/custom/V8CustomBinding.h:
        * bindings/v8/custom/V8InspectorBackendCustom.cpp:
        (WebCore::CALLBACK_FUNC_DECL):
        * inspector/InspectorBackend.cpp:
        (WebCore::InspectorBackend::dispatchOnInjectedScript):
        (WebCore::InspectorBackend::databaseForId):
        (WebCore::InspectorBackend::selectDatabase):
        (WebCore::InspectorBackend::getDatabaseTableNames):
        (WebCore::InspectorBackend::reportDidDispatchOnInjectedScript):
        * inspector/InspectorBackend.h:
        * inspector/InspectorBackend.idl:
        * inspector/InspectorController.cpp:
        (WebCore::InspectorController::populateScriptObjects):
        (WebCore::InspectorController::resetScriptObjects):
        (WebCore::InspectorController::selectDatabase):
        (WebCore::InspectorController::databaseForId):
        (WebCore::InspectorController::didOpenDatabase):
        (WebCore::InspectorController::didUseDOMStorage):
        (WebCore::InspectorController::selectDOMStorage):
        (WebCore::InspectorController::getDOMStorageResourceForId):
        * inspector/InspectorController.h:
        * inspector/InspectorDatabaseResource.cpp:
        (WebCore::InspectorDatabaseResource::InspectorDatabaseResource):
        (WebCore::InspectorDatabaseResource::bind):
        * inspector/InspectorDatabaseResource.h:
        (WebCore::InspectorDatabaseResource::database):
        (WebCore::InspectorDatabaseResource::id):
        * inspector/InspectorFrontend.cpp:
        (WebCore::InspectorFrontend::addDatabase):
        (WebCore::InspectorFrontend::selectDatabase):
        (WebCore::InspectorFrontend::didGetDatabaseTableNames):
        (WebCore::InspectorFrontend::addDOMStorage):
        * inspector/InspectorFrontend.h:
        * inspector/front-end/Database.js:
        (WebInspector.Database):
        (WebInspector.Database.prototype.get id):
        (WebInspector.Database.prototype.set name):
        (WebInspector.Database.prototype.set version):
        (WebInspector.Database.prototype.set domain):
        (WebInspector.Database.prototype.getTableNames):
        (WebInspector.Database.prototype.executeSql):
        * inspector/front-end/InjectedScript.js:
        (InjectedScript.dispatch):
        (InjectedScript.executeSql):
        (InjectedScript.executeSql.errorCallback):
        (InjectedScript.executeSql.queryTransaction):
        * inspector/front-end/InjectedScriptAccess.js:
        (InjectedScriptAccess._installHandler.InjectedScriptAccess.methodName):
        (InjectedScriptAccess._installHandler):
        * inspector/front-end/StoragePanel.js:
        (WebInspector.StoragePanel.prototype.selectDatabase):
        (WebInspector.StoragePanel.prototype.dataGridForResult):
        * inspector/front-end/inspector.js:
        (WebInspector.addDatabase):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@49234 268f45cc-cd09-0410-ab3c-d52691b4dbfc

18 files changed:
WebCore/ChangeLog
WebCore/bindings/js/JSInspectorBackendCustom.cpp
WebCore/bindings/v8/custom/V8CustomBinding.h
WebCore/bindings/v8/custom/V8InspectorBackendCustom.cpp
WebCore/inspector/InspectorBackend.cpp
WebCore/inspector/InspectorBackend.h
WebCore/inspector/InspectorBackend.idl
WebCore/inspector/InspectorController.cpp
WebCore/inspector/InspectorController.h
WebCore/inspector/InspectorDatabaseResource.cpp
WebCore/inspector/InspectorDatabaseResource.h
WebCore/inspector/InspectorFrontend.cpp
WebCore/inspector/InspectorFrontend.h
WebCore/inspector/front-end/Database.js
WebCore/inspector/front-end/InjectedScript.js
WebCore/inspector/front-end/InjectedScriptAccess.js
WebCore/inspector/front-end/StoragePanel.js
WebCore/inspector/front-end/inspector.js

index 7b78218..fd9c3c7 100644 (file)
@@ -1,3 +1,68 @@
+2009-10-07  Pavel Feldman  <pfeldman@chromium.org>
+
+        Reviewed by Timothy Hatcher.
+
+        Web Inspector: Migrate database inspection to the injected script-based schema.
+
+        https://bugs.webkit.org/show_bug.cgi?id=29788
+
+        * bindings/js/JSInspectorBackendCustom.cpp:
+        (WebCore::JSInspectorBackend::databaseForId):
+        * bindings/v8/custom/V8CustomBinding.h:
+        * bindings/v8/custom/V8InspectorBackendCustom.cpp:
+        (WebCore::CALLBACK_FUNC_DECL):
+        * inspector/InspectorBackend.cpp:
+        (WebCore::InspectorBackend::dispatchOnInjectedScript):
+        (WebCore::InspectorBackend::databaseForId):
+        (WebCore::InspectorBackend::selectDatabase):
+        (WebCore::InspectorBackend::getDatabaseTableNames):
+        (WebCore::InspectorBackend::reportDidDispatchOnInjectedScript):
+        * inspector/InspectorBackend.h:
+        * inspector/InspectorBackend.idl:
+        * inspector/InspectorController.cpp:
+        (WebCore::InspectorController::populateScriptObjects):
+        (WebCore::InspectorController::resetScriptObjects):
+        (WebCore::InspectorController::selectDatabase):
+        (WebCore::InspectorController::databaseForId):
+        (WebCore::InspectorController::didOpenDatabase):
+        (WebCore::InspectorController::didUseDOMStorage):
+        (WebCore::InspectorController::selectDOMStorage):
+        (WebCore::InspectorController::getDOMStorageResourceForId):
+        * inspector/InspectorController.h:
+        * inspector/InspectorDatabaseResource.cpp:
+        (WebCore::InspectorDatabaseResource::InspectorDatabaseResource):
+        (WebCore::InspectorDatabaseResource::bind):
+        * inspector/InspectorDatabaseResource.h:
+        (WebCore::InspectorDatabaseResource::database):
+        (WebCore::InspectorDatabaseResource::id):
+        * inspector/InspectorFrontend.cpp:
+        (WebCore::InspectorFrontend::addDatabase):
+        (WebCore::InspectorFrontend::selectDatabase):
+        (WebCore::InspectorFrontend::didGetDatabaseTableNames):
+        (WebCore::InspectorFrontend::addDOMStorage):
+        * inspector/InspectorFrontend.h:
+        * inspector/front-end/Database.js:
+        (WebInspector.Database):
+        (WebInspector.Database.prototype.get id):
+        (WebInspector.Database.prototype.set name):
+        (WebInspector.Database.prototype.set version):
+        (WebInspector.Database.prototype.set domain):
+        (WebInspector.Database.prototype.getTableNames):
+        (WebInspector.Database.prototype.executeSql):
+        * inspector/front-end/InjectedScript.js:
+        (InjectedScript.dispatch):
+        (InjectedScript.executeSql):
+        (InjectedScript.executeSql.errorCallback):
+        (InjectedScript.executeSql.queryTransaction):
+        * inspector/front-end/InjectedScriptAccess.js:
+        (InjectedScriptAccess._installHandler.InjectedScriptAccess.methodName):
+        (InjectedScriptAccess._installHandler):
+        * inspector/front-end/StoragePanel.js:
+        (WebInspector.StoragePanel.prototype.selectDatabase):
+        (WebInspector.StoragePanel.prototype.dataGridForResult):
+        * inspector/front-end/inspector.js:
+        (WebInspector.addDatabase):
+
 2009-10-07  Girish Ramakrishnan  <girish@forwardbias.in>
 
         Reviewed by Simon Hausmann.
index cb15e3b..73fa268 100644 (file)
@@ -122,27 +122,20 @@ JSValue JSInspectorBackend::search(ExecState* exec, const ArgList& args)
 }
 
 #if ENABLE(DATABASE)
-JSValue JSInspectorBackend::databaseTableNames(ExecState* exec, const ArgList& args)
+JSValue JSInspectorBackend::databaseForId(ExecState* exec, const ArgList& args)
 {
     if (args.size() < 1)
         return jsUndefined();
 
-    JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(args.at(0));
-    if (!wrapper)
+    InspectorController* ic = impl()->inspectorController();
+    if (!ic)
         return jsUndefined();
 
-    Database* database = toDatabase(wrapper->unwrappedObject());
+    Database* database = impl()->databaseForId(args.at(0).toInt32(exec));
     if (!database)
         return jsUndefined();
-
-    MarkedArgumentBuffer result;
-
-    Vector<String> tableNames = database->tableNames();
-    unsigned length = tableNames.size();
-    for (unsigned i = 0; i < length; ++i)
-        result.append(jsString(exec, tableNames[i]));
-
-    return constructArray(exec, result);
+    JSDOMWindow* inspectedWindow = toJSDOMWindow(ic->inspectedPage()->mainFrame());
+    return JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), toJS(exec, database));
 }
 #endif
 
index c91f23f..2ff4ea9 100644 (file)
@@ -454,6 +454,7 @@ namespace WebCore {
         DECLARE_CALLBACK(InspectorBackendAddSourceToFrame);
         DECLARE_CALLBACK(InspectorBackendSearch);
         DECLARE_CALLBACK(InspectorBackendSetting);
+        DECLARE_CALLBACK(InspectorBackendDatabaseForId);
         DECLARE_CALLBACK(InspectorBackendInspectedWindow);
         DECLARE_CALLBACK(InspectorBackendSetSetting);
         DECLARE_CALLBACK(InspectorBackendCurrentCallFrame);
@@ -465,7 +466,6 @@ namespace WebCore {
         DECLARE_CALLBACK(InspectorBackendUnwrapObject);
         DECLARE_CALLBACK(InspectorBackendPushNodePathToFrontend);
 #if ENABLE(DATABASE)
-        DECLARE_CALLBACK(InspectorBackendDatabaseTableNames);
         DECLARE_CALLBACK(InspectorBackendSelectDatabase);
 #endif
 #if ENABLE(DOM_STORAGE)
index d48292b..ec9b034 100644 (file)
@@ -31,6 +31,7 @@
 #include "config.h"
 #include "InspectorBackend.h"
 
+#include "Database.h"
 #include "DOMWindow.h"
 #include "Frame.h"
 #include "FrameLoader.h"
@@ -102,11 +103,17 @@ CALLBACK_FUNC_DECL(InspectorBackendSearch)
 }
 
 #if ENABLE(DATABASE)
-CALLBACK_FUNC_DECL(InspectorBackendDatabaseTableNames)
+CALLBACK_FUNC_DECL(InspectorBackendDatabaseForId)
 {
-    INC_STATS("InspectorBackend.databaseTableNames()");
-    v8::Local<v8::Array> result = v8::Array::New(0);
-    return result;
+    INC_STATS("InspectorBackend.databaseForId()");
+    if (args.Length() < 1)
+        return v8::Undefined();
+
+    InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder());
+    Database* database = inspectorBackend->databaseForId(args[0]->ToInt32()->Value());
+    if (!database)
+        return v8::Undefined();
+    return V8DOMWrapper::convertToV8Object<Database>(V8ClassIndex::DATABASE, database);
 }
 #endif
 
index 7b93f45..d705cd7 100644 (file)
@@ -46,6 +46,7 @@
 #include "InspectorFrontend.h"
 #include "InspectorResource.h"
 #include "Pasteboard.h"
+#include "ScriptArray.h"
 #include "ScriptFunctionCall.h"
 
 #if ENABLE(DOM_STORAGE)
@@ -395,7 +396,7 @@ void InspectorBackend::stepOutOfFunctionInDebugger()
 
 #endif
 
-void InspectorBackend::dispatchOnInjectedScript(long callId, const String& methodName, const String& arguments)
+void InspectorBackend::dispatchOnInjectedScript(long callId, const String& methodName, const String& arguments, bool async)
 {
     InspectorFrontend* frontend = inspectorFrontend();
     if (!frontend)
@@ -404,8 +405,12 @@ void InspectorBackend::dispatchOnInjectedScript(long callId, const String& metho
     ScriptFunctionCall function(m_inspectorController->m_scriptState, m_inspectorController->m_injectedScriptObj, "dispatch");
     function.appendArgument(methodName);
     function.appendArgument(arguments);
+    if (async)
+        function.appendArgument(static_cast<int>(callId));
     bool hadException = false;
     ScriptValue result = function.call(hadException);
+    if (async)
+        return;  // InjectedScript will return result asynchronously by means of ::reportDidDispatchOnInjectedScript.
     if (hadException)
         frontend->didDispatchOnInjectedScript(callId, "", true);
     else
@@ -516,10 +521,32 @@ void InspectorBackend::addNodesToSearchResult(const String& nodeIds)
 }
 
 #if ENABLE(DATABASE)
+Database* InspectorBackend::databaseForId(long databaseId)
+{
+    if (m_inspectorController)
+        return m_inspectorController->databaseForId(databaseId);
+    return 0;
+}
+
 void InspectorBackend::selectDatabase(Database* database)
 {
-    if (InspectorFrontend* frontend = inspectorFrontend())
-        frontend->selectDatabase(database);
+    if (m_inspectorController)
+        m_inspectorController->selectDatabase(database);
+}
+
+void InspectorBackend::getDatabaseTableNames(long callId, long databaseId)
+{
+    if (InspectorFrontend* frontend = inspectorFrontend()) {
+        ScriptArray result = frontend->newScriptArray();
+        Database* database = m_inspectorController->databaseForId(databaseId);
+        if (database) {
+            Vector<String> tableNames = database->tableNames();
+            unsigned length = tableNames.size();
+            for (unsigned i = 0; i < length; ++i)
+                result.set(i, tableNames[i]);
+        }
+        frontend->didGetDatabaseTableNames(callId, result);
+    }
 }
 #endif
 
@@ -555,6 +582,12 @@ void InspectorBackend::didEvaluateForTestInFrontend(long callId, const String& j
         m_inspectorController->didEvaluateForTestInFrontend(callId, jsonResult);
 }
 
+void InspectorBackend::reportDidDispatchOnInjectedScript(long callId, const String& result, bool isException)
+{
+    if (InspectorFrontend* frontend = inspectorFrontend())
+        frontend->didDispatchOnInjectedScript(callId, result, isException);
+}
+
 InspectorDOMAgent* InspectorBackend::inspectorDOMAgent()
 {
     if (!m_inspectorController)
index 9408673..8ade8af 100644 (file)
@@ -130,7 +130,7 @@ public:
     void stepOutOfFunctionInDebugger();
 #endif
 
-    void dispatchOnInjectedScript(long callId, const String& methodName, const String& arguments);
+    void dispatchOnInjectedScript(long callId, const String& methodName, const String& arguments, bool async);
     void getChildNodes(long callId, long nodeId);
     void setAttribute(long callId, long elementId, const String& name, const String& value);
     void removeAttribute(long callId, long elementId, const String& name);
@@ -150,7 +150,9 @@ public:
     long pushNodePathToFrontend(Node* node, bool selectInUI);
     void addNodesToSearchResult(const String& nodeIds);
 #if ENABLE(DATABASE)
+    Database* databaseForId(long databaseId);
     void selectDatabase(Database* database);
+    void getDatabaseTableNames(long callId, long databaseId);
 #endif
 #if ENABLE(DOM_STORAGE)
     void selectDOMStorage(Storage* storage);
@@ -158,6 +160,7 @@ public:
     void setDOMStorageItem(long callId, long storageId, const String& key, const String& value);
     void removeDOMStorageItem(long callId, long storageId, const String& key);
 #endif
+    void reportDidDispatchOnInjectedScript(long callId, const String& result, bool isException);
     void didEvaluateForTestInFrontend(long callId, const String& jsonResult);
 
 private:
index 538f1bc..0b6b591 100644 (file)
@@ -52,8 +52,9 @@ module core {
         boolean addSourceToFrame(in DOMString mimeType, in DOMString sourceValue, in Node frame);
         [Custom] void search(in Node node, in DOMString query);
 #if defined(ENABLE_DATABASE) && ENABLE_DATABASE
-        [Custom] DOMObject databaseTableNames(in Database database);
+        void getDatabaseTableNames(in long callId, in long databaseId);
 #endif
+
         [Custom] DOMObject setting(in DOMString key);
         [Custom] void setSetting(in DOMString key, in DOMObject  value);
         [Custom] DOMWindow inspectedWindow();
@@ -101,7 +102,7 @@ module core {
 
         [Custom] Array profiles();
 #endif
-        void dispatchOnInjectedScript(in long callId, in DOMString methodName, in DOMString arguments);
+        void dispatchOnInjectedScript(in long callId, in DOMString methodName, in DOMString arguments, in boolean async);
         void getChildNodes(in long callId, in long nodeId);
         void setAttribute(in long callId, in long elementId, in DOMString name, in DOMString value);
         void removeAttribute(in long callId, in long elementId, in DOMString name);
@@ -113,6 +114,7 @@ module core {
         void deleteCookie(in DOMString cookieName);
 
         // Called from InjectedScript.
+        // TODO: extract into a separate IDL.
         [Custom] DOMObject nodeForId(in long nodeId);
         [Custom] long wrapObject(in DOMObject object, in DOMString objectGroup);
         [Custom] DOMObject unwrapObject(in long objectId);
@@ -121,6 +123,7 @@ module core {
         void addNodesToSearchResult(in DOMString nodeIds);
 #if defined(ENABLE_DATABASE) && ENABLE_DATABASE
         [Custom] void selectDatabase(in DOMObject database);
+        [Custom] DOMObject databaseForId(in long databaseId);
 #endif
 #if defined(ENABLE_DOM_STORAGE) && ENABLE_DOM_STORAGE
         [Custom] void selectDOMStorage(in DOMObject storage);
@@ -128,6 +131,7 @@ module core {
         void setDOMStorageItem(in long callId, in long storageId, in DOMString key, in DOMString value);
         void removeDOMStorageItem(in long callId, in long storageId, in DOMString key);
 #endif
+        void reportDidDispatchOnInjectedScript(in long callId, in DOMString result, in boolean isException);
         void didEvaluateForTestInFrontend(in long callId, in DOMString jsonResult);
     };
 }
index e989df0..49bebbd 100644 (file)
@@ -660,14 +660,14 @@ void InspectorController::populateScriptObjects()
         m_consoleMessages[i]->addToConsole(m_frontend.get());
 
 #if ENABLE(DATABASE)
-    DatabaseResourcesSet::iterator databasesEnd = m_databaseResources.end();
-    for (DatabaseResourcesSet::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it)
-        (*it)->bind(m_frontend.get());
+    DatabaseResourcesMap::iterator databasesEnd = m_databaseResources.end();
+    for (DatabaseResourcesMap::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it)
+        it->second->bind(m_frontend.get());
 #endif
 #if ENABLE(DOM_STORAGE)
-    DOMStorageResourcesSet::iterator domStorageEnd = m_domStorageResources.end();
-    for (DOMStorageResourcesSet::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it)
-        (*it)->bind(m_frontend.get());
+    DOMStorageResourcesMap::iterator domStorageEnd = m_domStorageResources.end();
+    for (DOMStorageResourcesMap::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it)
+        it->second->bind(m_frontend.get());
 #endif
 
     m_frontend->populateInterface();
@@ -688,14 +688,14 @@ void InspectorController::resetScriptObjects()
         it->second->releaseScriptObject(m_frontend.get(), false);
 
 #if ENABLE(DATABASE)
-    DatabaseResourcesSet::iterator databasesEnd = m_databaseResources.end();
-    for (DatabaseResourcesSet::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it)
-        (*it)->unbind();
+    DatabaseResourcesMap::iterator databasesEnd = m_databaseResources.end();
+    for (DatabaseResourcesMap::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it)
+        it->second->unbind();
 #endif
 #if ENABLE(DOM_STORAGE)
-    DOMStorageResourcesSet::iterator domStorageEnd = m_domStorageResources.end();
-    for (DOMStorageResourcesSet::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it)
-        (*it)->unbind();
+    DOMStorageResourcesMap::iterator domStorageEnd = m_domStorageResources.end();
+    for (DOMStorageResourcesMap::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it)
+        it->second->unbind();
 #endif
 
     if (m_timelineAgent)
@@ -1110,6 +1110,27 @@ bool InspectorController::timelineEnabled() const
 }
 
 #if ENABLE(DATABASE)
+void InspectorController::selectDatabase(Database* database)
+{
+    if (!m_frontend)
+        return;
+
+    for (DatabaseResourcesMap::iterator it = m_databaseResources.begin(); it != m_databaseResources.end(); ++it) {
+        if (it->second->database() == database) {
+            m_frontend->selectDatabase(it->first);
+            break;
+        }
+    }
+}
+
+Database* InspectorController::databaseForId(int databaseId)
+{
+    DatabaseResourcesMap::iterator it = m_databaseResources.find(databaseId);
+    if (it == m_databaseResources.end())
+        return 0;
+    return it->second->database();
+}
+
 void InspectorController::didOpenDatabase(Database* database, const String& domain, const String& name, const String& version)
 {
     if (!enabled())
@@ -1117,7 +1138,7 @@ void InspectorController::didOpenDatabase(Database* database, const String& doma
 
     RefPtr<InspectorDatabaseResource> resource = InspectorDatabaseResource::create(database, domain, name, version);
 
-    m_databaseResources.add(resource);
+    m_databaseResources.set(resource->id(), resource);
 
     // Resources are only bound while visible.
     if (m_frontend && windowVisible())
@@ -1131,15 +1152,15 @@ void InspectorController::didUseDOMStorage(StorageArea* storageArea, bool isLoca
     if (!enabled())
         return;
 
-    DOMStorageResourcesSet::iterator domStorageEnd = m_domStorageResources.end();
-    for (DOMStorageResourcesSet::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it)
-        if ((*it)->isSameHostAndType(frame, isLocalStorage))
+    DOMStorageResourcesMap::iterator domStorageEnd = m_domStorageResources.end();
+    for (DOMStorageResourcesMap::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it)
+        if (it->second->isSameHostAndType(frame, isLocalStorage))
             return;
 
     RefPtr<Storage> domStorage = Storage::create(frame, storageArea);
     RefPtr<InspectorDOMStorageResource> resource = InspectorDOMStorageResource::create(domStorage.get(), isLocalStorage, frame);
 
-    m_domStorageResources.add(resource);
+    m_domStorageResources.set(resource->id(), resource);
 
     // Resources are only bound while visible.
     if (m_frontend && windowVisible())
@@ -1155,10 +1176,10 @@ void InspectorController::selectDOMStorage(Storage* storage)
     Frame* frame = storage->frame();
     bool isLocalStorage = (frame->domWindow()->localStorage() == storage);
     int storageResourceId = 0;
-    DOMStorageResourcesSet::iterator domStorageEnd = m_domStorageResources.end();
-    for (DOMStorageResourcesSet::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it) {
-        if ((*it)->isSameHostAndType(frame, isLocalStorage)) {
-            storageResourceId = (*it)->id();
+    DOMStorageResourcesMap::iterator domStorageEnd = m_domStorageResources.end();
+    for (DOMStorageResourcesMap::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it) {
+        if (it->second->isSameHostAndType(frame, isLocalStorage)) {
+            storageResourceId = it->first;
             break;
         }
     }
@@ -1219,11 +1240,10 @@ void InspectorController::removeDOMStorageItem(long callId, long storageId, cons
 
 InspectorDOMStorageResource* InspectorController::getDOMStorageResourceForId(int storageId)
 {
-    DOMStorageResourcesSet::iterator domStorageEnd = m_domStorageResources.end();
-    for (DOMStorageResourcesSet::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it)
-        if ((*it)->id() == storageId)
-            return it->get();
-    return 0;
+    DOMStorageResourcesMap::iterator it = m_domStorageResources.find(storageId);
+    if (it == m_domStorageResources.end())
+        return 0;
+    return it->second.get();
 }
 #endif
 
index 04653dd..767a64c 100644 (file)
@@ -90,8 +90,8 @@ class InspectorController
 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 HashMap<int, RefPtr<InspectorDatabaseResource> > DatabaseResourcesMap;
+    typedef HashMap<int, RefPtr<InspectorDOMStorageResource> > DOMStorageResourcesMap;
     typedef HashMap<String, Vector<String> > ObjectGroupsMap;
 
     typedef enum {
@@ -314,6 +314,10 @@ private:
     void toggleRecordButton(bool);
     void enableDebuggerFromFrontend(bool always);
 #endif
+#if ENABLE(DATABASE)
+    void selectDatabase(Database* database);
+    Database* databaseForId(int databaseId);
+#endif
 #if ENABLE(DOM_STORAGE)
     InspectorDOMStorageResource* getDOMStorageResourceForId(int storageId);
 #endif
@@ -353,10 +357,10 @@ private:
     HashMap<String, double> m_times;
     HashMap<String, unsigned> m_counts;
 #if ENABLE(DATABASE)
-    DatabaseResourcesSet m_databaseResources;
+    DatabaseResourcesMap m_databaseResources;
 #endif
 #if ENABLE(DOM_STORAGE)
-    DOMStorageResourcesSet m_domStorageResources;
+    DOMStorageResourcesMap m_domStorageResources;
 #endif
     ScriptState* m_scriptState;
     bool m_windowVisible;
index a58968f..c2dc5c6 100644 (file)
 
 namespace WebCore {
 
+int InspectorDatabaseResource::s_nextUnusedId = 1;
+
 InspectorDatabaseResource::InspectorDatabaseResource(Database* database, const String& domain, const String& name, const String& version)
     : m_database(database)
+    , m_id(s_nextUnusedId++)
     , m_domain(domain)
     , m_name(name)
     , m_version(version)
@@ -59,7 +62,7 @@ void InspectorDatabaseResource::bind(InspectorFrontend* frontend)
     ScriptObject database;
     if (!getQuarantinedScriptObject(m_database.get(), database))
         return;
-    jsonObject.set("database", database);
+    jsonObject.set("id", m_id);
     jsonObject.set("domain", m_domain);
     jsonObject.set("name", m_name);
     jsonObject.set("version", m_version);
index 38f9fa1..f82d898 100644 (file)
@@ -53,16 +53,19 @@ namespace WebCore {
 
         void bind(InspectorFrontend* frontend);
         void unbind();
-
+        Database* database() { return m_database.get(); }
+        long id() const { return m_id; }
     private:
         InspectorDatabaseResource(Database*, const String& domain, const String& name, const String& version);
         
         RefPtr<Database> m_database;
+        int m_id;
         String m_domain;
         String m_name;
         String m_version;
         bool m_scriptObjectCreated;
 
+        static int s_nextUnusedId;
     };
 
 } // namespace WebCore
index 25711cb..084770f 100644 (file)
@@ -281,28 +281,6 @@ void InspectorFrontend::resumedScript()
 }
 #endif
 
-#if ENABLE(DATABASE)
-bool InspectorFrontend::addDatabase(const ScriptObject& dbObject)
-{
-    OwnPtr<ScriptFunctionCall> function(newFunctionCall("addDatabase"));
-    function->appendArgument(dbObject);
-    bool hadException = false;
-    function->call(hadException);
-    return !hadException;
-}
-#endif
-
-#if ENABLE(DOM_STORAGE)
-bool InspectorFrontend::addDOMStorage(const ScriptObject& domStorageObj)
-{
-    OwnPtr<ScriptFunctionCall> function(newFunctionCall("addDOMStorage"));
-    function->appendArgument(domStorageObj);
-    bool hadException = false;
-    function->call(hadException);
-    return !hadException;
-}
-#endif
-
 void InspectorFrontend::setDocument(const ScriptObject& root)
 {
     OwnPtr<ScriptFunctionCall> function(newFunctionCall("setDocument"));
@@ -401,18 +379,40 @@ void InspectorFrontend::didDispatchOnInjectedScript(int callId, const String& re
 }
 
 #if ENABLE(DATABASE)
-void InspectorFrontend::selectDatabase(Database* database)
+bool InspectorFrontend::addDatabase(const ScriptObject& dbObject)
+{
+    OwnPtr<ScriptFunctionCall> function(newFunctionCall("addDatabase"));
+    function->appendArgument(dbObject);
+    bool hadException = false;
+    function->call(hadException);
+    return !hadException;
+}
+
+void InspectorFrontend::selectDatabase(int databaseId)
 {
     OwnPtr<ScriptFunctionCall> function(newFunctionCall("selectDatabase"));
-    ScriptObject quarantinedObject;
-    if (!getQuarantinedScriptObject(database, quarantinedObject))
-        return;
-    function->appendArgument(quarantinedObject);
+    function->appendArgument(databaseId);
+    function->call();
+}
+void InspectorFrontend::didGetDatabaseTableNames(int callId, const ScriptArray& tableNames)
+{
+    OwnPtr<ScriptFunctionCall> function(newFunctionCall("didGetDatabaseTableNames"));
+    function->appendArgument(callId);
+    function->appendArgument(tableNames);
     function->call();
 }
 #endif
 
 #if ENABLE(DOM_STORAGE)
+bool InspectorFrontend::addDOMStorage(const ScriptObject& domStorageObj)
+{
+    OwnPtr<ScriptFunctionCall> function(newFunctionCall("addDOMStorage"));
+    function->appendArgument(domStorageObj);
+    bool hadException = false;
+    function->call(hadException);
+    return !hadException;
+}
+
 void InspectorFrontend::selectDOMStorage(int storageId)
 {
     OwnPtr<ScriptFunctionCall> function(newFunctionCall("selectDOMStorage"));
index b414c7c..ebabd85 100644 (file)
@@ -95,7 +95,8 @@ namespace WebCore {
 
 #if ENABLE(DATABASE)
         bool addDatabase(const ScriptObject& dbObj);
-        void selectDatabase(Database* database);
+        void selectDatabase(int databaseId);
+        void didGetDatabaseTableNames(int callId, const ScriptArray& tableNames);
 #endif
         
 #if ENABLE(DOM_STORAGE)
index dcab2ab..1a348fc 100644 (file)
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-WebInspector.Database = function(database, domain, name, version)
+WebInspector.Database = function(id, domain, name, version)
 {
-    this._database = database;
-    this.domain = domain;
-    this.name = name;
-    this.version = version;
+    this._id = id;
+    this._domain = domain;
+    this._name = name;
+    this._version = version;
 }
 
 WebInspector.Database.prototype = {
-    isDatabase: function(db)
+    get id()
     {
-        return this._database === db;
+        return this._id;
     },
 
     get name()
@@ -47,8 +47,6 @@ WebInspector.Database.prototype = {
 
     set name(x)
     {
-        if (this._name === x)
-            return;
         this._name = x;
     },
 
@@ -59,8 +57,6 @@ WebInspector.Database.prototype = {
 
     set version(x)
     {
-        if (this._version === x)
-            return;
         this._version = x;
     },
 
@@ -71,8 +67,6 @@ WebInspector.Database.prototype = {
 
     set domain(x)
     {
-        if (this._domain === x)
-            return;
         this._domain = x;
     },
 
@@ -83,31 +77,26 @@ WebInspector.Database.prototype = {
 
     getTableNames: function(callback)
     {
-        var names = InspectorController.databaseTableNames(this._database);
-        function sortingCallback()
+        function sortingCallback(names)
         {
             callback(names.sort());
         }
-        setTimeout(sortingCallback, 0);
+        var callId = WebInspector.Callback.wrap(sortingCallback);
+        InspectorController.getDatabaseTableNames(callId, this._id);
     },
     
     executeSql: function(query, onSuccess, onError)
     {
-        function successCallback(tx, result)
+        function callback(result)
         {
+            if (!(result instanceof Array)) {
+                onError(result);
+                return;
+            }
             onSuccess(result);
         }
-
-        function errorCallback(tx, error)
-        {
-            onError(error);
-        }
-
-        var self = this;
-        function queryTransaction(tx)
-        {
-            tx.executeSql(query, null, InspectorController.wrapCallback(successCallback.bind(self)), InspectorController.wrapCallback(errorCallback.bind(self)));
-        }
-        this._database.transaction(InspectorController.wrapCallback(queryTransaction.bind(this)), InspectorController.wrapCallback(errorCallback.bind(this)));
+        InjectedScriptAccess.executeSql(this._id, query, callback);
     }
 }
+
+WebInspector.didGetDatabaseTableNames = WebInspector.Callback.processCallback;
index 57a3b38..8391894 100644 (file)
@@ -41,9 +41,12 @@ InjectedScript.reset = function()
 
 InjectedScript.reset();
 
-InjectedScript.dispatch = function(methodName, args)
+InjectedScript.dispatch = function(methodName, args, callId)
 {
-    var result = InjectedScript[methodName].apply(InjectedScript, JSON.parse(args));
+    var argsArray = JSON.parse(args);
+    if (callId)
+        argsArray.splice(0, 0, callId);  // Methods that run asynchronously have a call back id parameter.
+    var result = InjectedScript[methodName].apply(InjectedScript, argsArray);
     if (typeof result === "undefined") {
         InjectedScript._window().console.error("Web Inspector error: InjectedScript.%s returns undefined", methodName);
         result = null;
@@ -1041,6 +1044,45 @@ InjectedScript.CallFrameProxy.prototype = {
     }
 }
 
+InjectedScript.executeSql = function(callId, databaseId, query)
+{
+    function successCallback(tx, result)
+    {
+        var rows = result.rows;
+        var result = [];
+        var length = rows.length;
+        for (var i = 0; i < length; ++i) {
+            var data = {};
+            result.push(data);
+            var row = rows.item(i);
+            for (var columnIdentifier in row) {
+                // FIXME: (Bug 19439) We should specially format SQL NULL here
+                // (which is represented by JavaScript null here, and turned
+                // into the string "null" by the String() function).
+                var text = row[columnIdentifier];
+                data[columnIdentifier] = String(text);
+            }
+        }
+        InspectorController.reportDidDispatchOnInjectedScript(callId, JSON.stringify(result), false);
+    }
+
+    function errorCallback(tx, error)
+    {
+        InspectorController.reportDidDispatchOnInjectedScript(callId, JSON.stringify(error), false);
+    }
+
+    function queryTransaction(tx)
+    {
+        tx.executeSql(query, null, InspectorController.wrapCallback(successCallback), InspectorController.wrapCallback(errorCallback));
+    }
+
+    var database = InspectorController.databaseForId(databaseId);
+    if (!database)
+        errorCallback(null, { code : 2 });  // Return as unexpected version.
+    database.transaction(InspectorController.wrapCallback(queryTransaction), InspectorController.wrapCallback(errorCallback));
+    return true;
+}
+
 Object.type = function(obj)
 {
     if (obj === null)
index 67312f7..c6d4b65 100644 (file)
@@ -31,7 +31,7 @@
 
 var InjectedScriptAccess = {};
 
-InjectedScriptAccess._installHandler = function(methodName)
+InjectedScriptAccess._installHandler = function(methodName, async)
 {
     InjectedScriptAccess[methodName] = function()
     {
@@ -47,35 +47,37 @@ InjectedScriptAccess._installHandler = function(methodName)
                 WebInspector.console.addMessage(new WebInspector.ConsoleTextMessage("Error dispatching: " + methodName));
         }
         var callId = WebInspector.Callback.wrap(myCallback);
-        InspectorController.dispatchOnInjectedScript(callId, methodName, argsString);
+        InspectorController.dispatchOnInjectedScript(callId, methodName, argsString, !!async);
     };
 }
 
 // InjectedScriptAccess message forwarding puts some constraints on the way methods are imlpemented and called:
 // - Make sure corresponding methods in InjectedScript return non-null and non-undefined values,
 // - Make sure last parameter of all the InjectedSriptAccess.* calls is a callback function.
-InjectedScriptAccess._installHandler("getStyles");
+// We keep these sorted.
+InjectedScriptAccess._installHandler("addInspectedNode");
+InjectedScriptAccess._installHandler("addStyleSelector");
+InjectedScriptAccess._installHandler("applyStyleRuleText");
+InjectedScriptAccess._installHandler("applyStyleText");
+InjectedScriptAccess._installHandler("evaluate");
+InjectedScriptAccess._installHandler("evaluateInCallFrame");
+InjectedScriptAccess._installHandler("getCompletions");
 InjectedScriptAccess._installHandler("getComputedStyle");
 InjectedScriptAccess._installHandler("getInlineStyle");
-InjectedScriptAccess._installHandler("applyStyleText");
-InjectedScriptAccess._installHandler("setStyleText");
-InjectedScriptAccess._installHandler("toggleStyleEnabled");
-InjectedScriptAccess._installHandler("applyStyleRuleText");
-InjectedScriptAccess._installHandler("addStyleSelector");
-InjectedScriptAccess._installHandler("setStyleProperty");
-InjectedScriptAccess._installHandler("getPrototypes");
 InjectedScriptAccess._installHandler("getProperties");
-InjectedScriptAccess._installHandler("setPropertyValue");
-InjectedScriptAccess._installHandler("getCompletions");
-InjectedScriptAccess._installHandler("evaluate");
-InjectedScriptAccess._installHandler("addInspectedNode");
-InjectedScriptAccess._installHandler("pushNodeToFrontend");
-InjectedScriptAccess._installHandler("evaluate");
-InjectedScriptAccess._installHandler("addInspectedNode");
-InjectedScriptAccess._installHandler("pushNodeToFrontend");
+InjectedScriptAccess._installHandler("getPrototypes");
+InjectedScriptAccess._installHandler("getStyles");
+InjectedScriptAccess._installHandler("openInInspectedWindow");
 InjectedScriptAccess._installHandler("performSearch");
+InjectedScriptAccess._installHandler("pushNodeToFrontend");
 InjectedScriptAccess._installHandler("searchCanceled");
-InjectedScriptAccess._installHandler("openInInspectedWindow");
-InjectedScriptAccess._installHandler("evaluateInCallFrame");
+InjectedScriptAccess._installHandler("setPropertyValue");
+InjectedScriptAccess._installHandler("setStyleProperty");
+InjectedScriptAccess._installHandler("setStyleText");
+InjectedScriptAccess._installHandler("toggleStyleEnabled");
+
+// Some methods can't run synchronously even on the injected script side (such as DB transactions).
+// Mark them as asynchronous here.
+InjectedScriptAccess._installHandler("executeSql", true);
 
 WebInspector.didDispatchOnInjectedScript = WebInspector.Callback.processCallback;
index 9e5c284..b319ec5 100644 (file)
@@ -158,12 +158,12 @@ WebInspector.StoragePanel.prototype = {
             this.sessionStorageListTreeElement.appendChild(domStorageTreeElement);
     },
 
-    selectDatabase: function(db)
+    selectDatabase: function(databaseId)
     {
         var database;
         for (var i = 0, len = this._databases.length; i < len; ++i) {
             database = this._databases[i];
-            if (database.isDatabase(db)) {
+            if (database.id === databaseId) {
                 this.showDatabase(database);
                 database._databasesTreeElement.select();
                 return;
@@ -297,16 +297,15 @@ WebInspector.StoragePanel.prototype = {
         database.getTableNames(tableNamesCallback);
     },
 
-    dataGridForResult: function(result)
+    dataGridForResult: function(rows)
     {
-        if (!result.rows.length)
+        if (!rows.length)
             return null;
 
         var columns = {};
         var numColumns = 0;
 
-        var rows = result.rows;
-        for (var columnIdentifier in rows.item(0)) {
+        for (var columnIdentifier in rows[0]) {
             var column = {};
             column.width = columnIdentifier.length;
             column.title = columnIdentifier;
@@ -320,12 +319,9 @@ WebInspector.StoragePanel.prototype = {
         for (var i = 0; i < length; ++i) {
             var data = {};
 
-            var row = rows.item(i);
+            var row = rows[i];
             for (var columnIdentifier in row) {
-                // FIXME: (Bug 19439) We should specially format SQL NULL here
-                // (which is represented by JavaScript null here, and turned
-                // into the string "null" by the String() function).
-                var text = String(row[columnIdentifier]);
+                var text = row[columnIdentifier];
                 data[columnIdentifier] = text;
                 if (text.length > columns[columnIdentifier].width)
                     columns[columnIdentifier].width = text.length;
index 49f6398..2a69e90 100644 (file)
@@ -1034,7 +1034,7 @@ WebInspector.removeResource = function(identifier)
 WebInspector.addDatabase = function(payload)
 {
     var database = new WebInspector.Database(
-        payload.database,
+        payload.id,
         payload.domain,
         payload.name,
         payload.version);