Web Inspector: Remove recompileAllJSFunctions timer in ScriptDebugServer
[WebKit-https.git] / Source / WebCore / inspector / InspectorDOMStorageAgent.cpp
index 6c82c5e..25c6fc0 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2013 Samsung Electronics. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #include "config.h"
 
-#include "InspectorDOMStorageAgent.h"
-
 #if ENABLE(INSPECTOR)
 
-#include "Database.h"
+#include "InspectorDOMStorageAgent.h"
+
 #include "DOMWindow.h"
+#include "Database.h"
+#include "Document.h"
 #include "ExceptionCode.h"
+#include "ExceptionCodeDescription.h"
 #include "Frame.h"
-#include "InspectorDOMStorageResource.h"
-#include "InspectorFrontend.h"
-#include "InspectorState.h"
-#include "InspectorValues.h"
+#include "InspectorPageAgent.h"
+#include "InspectorWebFrontendDispatchers.h"
 #include "InstrumentingAgents.h"
+#include "Page.h"
+#include "PageGroup.h"
+#include "SecurityOrigin.h"
 #include "Storage.h"
 #include "StorageArea.h"
+#include "StorageNamespace.h"
 #include "VoidCallback.h"
-
+#include <inspector/InspectorValues.h>
 #include <wtf/Vector.h>
 
-namespace WebCore {
-
-namespace DOMStorageAgentState {
-static const char domStorageAgentEnabled[] = "domStorageAgentEnabled";
-};
+using namespace Inspector;
 
-typedef HashMap<int, RefPtr<InspectorDOMStorageResource> > DOMStorageResourcesMap;
+namespace WebCore {
 
-InspectorDOMStorageAgent::InspectorDOMStorageAgent(InstrumentingAgents* instrumentingAgents, InspectorState* state)
-    : m_instrumentingAgents(instrumentingAgents)
-    , m_inspectorState(state)
-    , m_frontend(0)
+InspectorDOMStorageAgent::InspectorDOMStorageAgent(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent)
+    : InspectorAgentBase(ASCIILiteral("DOMStorage"), instrumentingAgents)
+    , m_pageAgent(pageAgent)
     , m_enabled(false)
 {
     m_instrumentingAgents->setInspectorDOMStorageAgent(this);
@@ -66,130 +66,148 @@ InspectorDOMStorageAgent::InspectorDOMStorageAgent(InstrumentingAgents* instrume
 
 InspectorDOMStorageAgent::~InspectorDOMStorageAgent()
 {
-    m_instrumentingAgents->setInspectorDOMStorageAgent(0);
-    m_instrumentingAgents = 0;
+    m_instrumentingAgents->setInspectorDOMStorageAgent(nullptr);
+    m_instrumentingAgents = nullptr;
 }
 
-void InspectorDOMStorageAgent::setFrontend(InspectorFrontend* frontend)
+void InspectorDOMStorageAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher)
 {
-    m_frontend = frontend;
+    m_frontendDispatcher = std::make_unique<InspectorDOMStorageFrontendDispatcher>(frontendChannel);
+    m_backendDispatcher = InspectorDOMStorageBackendDispatcher::create(backendDispatcher, this);
 }
 
-void InspectorDOMStorageAgent::clearFrontend()
+void InspectorDOMStorageAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason)
 {
-    DOMStorageResourcesMap::iterator domStorageEnd = m_resources.end();
-    for (DOMStorageResourcesMap::iterator it = m_resources.begin(); it != domStorageEnd; ++it)
-        it->second->unbind();
-    m_frontend = 0;
-    disable(0);
-}
+    m_frontendDispatcher = nullptr;
+    m_backendDispatcher.clear();
 
-void InspectorDOMStorageAgent::restore()
-{
-    m_enabled =  m_inspectorState->getBoolean(DOMStorageAgentState::domStorageAgentEnabled);
+    disable(nullptr);
 }
 
 void InspectorDOMStorageAgent::enable(ErrorString*)
 {
-    if (m_enabled)
-        return;
     m_enabled = true;
-    m_inspectorState->setBoolean(DOMStorageAgentState::domStorageAgentEnabled, m_enabled);
-
-    DOMStorageResourcesMap::iterator resourcesEnd = m_resources.end();
-    for (DOMStorageResourcesMap::iterator it = m_resources.begin(); it != resourcesEnd; ++it)
-        it->second->bind(m_frontend);
 }
 
 void InspectorDOMStorageAgent::disable(ErrorString*)
 {
-    if (!m_enabled)
-        return;
     m_enabled = false;
-    m_inspectorState->setBoolean(DOMStorageAgentState::domStorageAgentEnabled, m_enabled);
 }
 
-void InspectorDOMStorageAgent::getDOMStorageEntries(ErrorString*, int storageId, RefPtr<InspectorArray>* entries)
+void InspectorDOMStorageAgent::getDOMStorageItems(ErrorString* errorString, const RefPtr<InspectorObject>& storageId, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Array<String>>>& items)
 {
-    InspectorDOMStorageResource* storageResource = getDOMStorageResourceForId(storageId);
-    if (storageResource) {
-        storageResource->startReportingChangesToFrontend();
-        Storage* domStorage = storageResource->domStorage();
-        for (unsigned i = 0; i < domStorage->length(); ++i) {
-            String name(domStorage->key(i));
-            String value(domStorage->getItem(name));
-            RefPtr<InspectorArray> entry = InspectorArray::create();
-            entry->pushString(name);
-            entry->pushString(value);
-            (*entries)->pushArray(entry);
-        }
+    Frame* frame;
+    RefPtr<StorageArea> storageArea = findStorageArea(errorString, storageId, frame);
+    if (!storageArea) {
+        if (errorString)
+            *errorString = "No StorageArea for given storageId";
+        return;
+    }
+
+    RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Array<String>>> storageItems = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Array<String>>::create();
+
+    for (unsigned i = 0; i < storageArea->length(); ++i) {
+        String key = storageArea->key(i);
+        String value = storageArea->item(key);
+
+        RefPtr<Inspector::TypeBuilder::Array<String>> entry = Inspector::TypeBuilder::Array<String>::create();
+        entry->addItem(key);
+        entry->addItem(value);
+        storageItems->addItem(entry.release());
     }
+
+    items = storageItems.release();
 }
 
-void InspectorDOMStorageAgent::setDOMStorageItem(ErrorString*, int storageId, const String& key, const String& value, bool* success)
+void InspectorDOMStorageAgent::setDOMStorageItem(ErrorString* errorString, const RefPtr<InspectorObject>& storageId, const String& key, const String& value)
 {
-    InspectorDOMStorageResource* storageResource = getDOMStorageResourceForId(storageId);
-    if (storageResource) {
-        ExceptionCode exception = 0;
-        storageResource->domStorage()->setItem(key, value, exception);
-        *success = !exception;
+    Frame* frame;
+    RefPtr<StorageArea> storageArea = findStorageArea(nullptr, storageId, frame);
+    if (!storageArea) {
+        *errorString = "Storage not found";
+        return;
     }
+
+    bool quotaException = false;
+    storageArea->setItem(frame, key, value, quotaException);
+    if (quotaException)
+        *errorString = ExceptionCodeDescription(QUOTA_EXCEEDED_ERR).name;
 }
 
-void InspectorDOMStorageAgent::removeDOMStorageItem(ErrorString*, int storageId, const String& key, bool* success)
+void InspectorDOMStorageAgent::removeDOMStorageItem(ErrorString* errorString, const RefPtr<InspectorObject>& storageId, const String& key)
 {
-    InspectorDOMStorageResource* storageResource = getDOMStorageResourceForId(storageId);
-    if (storageResource) {
-        storageResource->domStorage()->removeItem(key);
-        *success = true;
+    Frame* frame;
+    RefPtr<StorageArea> storageArea = findStorageArea(nullptr, storageId, frame);
+    if (!storageArea) {
+        *errorString = "Storage not found";
+        return;
     }
+
+    storageArea->removeItem(frame, key);
 }
 
-int InspectorDOMStorageAgent::storageId(Storage* storage)
+String InspectorDOMStorageAgent::storageId(Storage* storage)
 {
     ASSERT(storage);
-    Frame* frame = storage->frame();
-    ExceptionCode ec = 0;
-    bool isLocalStorage = (frame->domWindow()->localStorage(ec) == storage && !ec);
-    DOMStorageResourcesMap::iterator domStorageEnd = m_resources.end();
-    for (DOMStorageResourcesMap::iterator it = m_resources.begin(); it != domStorageEnd; ++it) {
-        if (it->second->isSameHostAndType(frame, isLocalStorage))
-            return it->first;
-    }
-    return 0;
+    Document* document = storage->frame()->document();
+    ASSERT(document);
+    DOMWindow* window = document->domWindow();
+    ASSERT(window);
+    RefPtr<SecurityOrigin> securityOrigin = document->securityOrigin();
+    bool isLocalStorage = window->optionalLocalStorage() == storage;
+    return storageId(securityOrigin.get(), isLocalStorage)->toJSONString();
 }
 
-InspectorDOMStorageResource* InspectorDOMStorageAgent::getDOMStorageResourceForId(int storageId)
+PassRefPtr<Inspector::TypeBuilder::DOMStorage::StorageId> InspectorDOMStorageAgent::storageId(SecurityOrigin* securityOrigin, bool isLocalStorage)
 {
-    DOMStorageResourcesMap::iterator it = m_resources.find(storageId);
-    if (it == m_resources.end())
-        return 0;
-    return it->second.get();
+    return Inspector::TypeBuilder::DOMStorage::StorageId::create()
+        .setSecurityOrigin(securityOrigin->toRawString())
+        .setIsLocalStorage(isLocalStorage).release();
 }
 
-void InspectorDOMStorageAgent::didUseDOMStorage(StorageArea* storageArea, bool isLocalStorage, Frame* frame)
+void InspectorDOMStorageAgent::didDispatchDOMStorageEvent(const String& key, const String& oldValue, const String& newValue, StorageType storageType, SecurityOrigin* securityOrigin, Page*)
 {
-    DOMStorageResourcesMap::iterator domStorageEnd = m_resources.end();
-    for (DOMStorageResourcesMap::iterator it = m_resources.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);
+    if (!m_frontendDispatcher || !m_enabled)
+        return;
 
-    m_resources.set(resource->id(), resource);
+    RefPtr<Inspector::TypeBuilder::DOMStorage::StorageId> id = storageId(securityOrigin, storageType == LocalStorage);
 
-    // Resources are only bound while visible.
-    if (m_enabled)
-        resource->bind(m_frontend);
+    if (key.isNull())
+        m_frontendDispatcher->domStorageItemsCleared(id);
+    else if (newValue.isNull())
+        m_frontendDispatcher->domStorageItemRemoved(id, key);
+    else if (oldValue.isNull())
+        m_frontendDispatcher->domStorageItemAdded(id, key, newValue);
+    else
+        m_frontendDispatcher->domStorageItemUpdated(id, key, oldValue, newValue);
 }
 
-void InspectorDOMStorageAgent::clearResources()
+PassRefPtr<StorageArea> InspectorDOMStorageAgent::findStorageArea(ErrorString* errorString, const RefPtr<InspectorObject>& storageId, Frame*& targetFrame)
 {
-    m_resources.clear();
-}
+    String securityOrigin;
+    bool isLocalStorage = false;
+    bool success = storageId->getString("securityOrigin", &securityOrigin);
+    if (success)
+        success = storageId->getBoolean("isLocalStorage", &isLocalStorage);
+    if (!success) {
+        if (errorString)
+            *errorString = "Invalid storageId format";
+        targetFrame = nullptr;
+        return nullptr;
+    }
+
+    targetFrame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
+    if (!targetFrame) {
+        if (errorString)
+            *errorString = "Frame not found for the given security origin";
+        return nullptr;
+    }
 
+    Page* page = m_pageAgent->page();
+    if (isLocalStorage)
+        return page->group().localStorage()->storageArea(targetFrame->document()->securityOrigin());
+    return page->sessionStorage()->storageArea(targetFrame->document()->securityOrigin());
+}
 
 } // namespace WebCore