Web Inspector: Remove recompileAllJSFunctions timer in ScriptDebugServer
[WebKit-https.git] / Source / WebCore / inspector / InspectorDOMStorageAgent.cpp
index c32ea29..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 "InspectorDOMStorageAgent.h"
 
-#include "Database.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 {
+using namespace Inspector;
 
-namespace DOMStorageAgentState {
-static const char domStorageAgentEnabled[] = "domStorageAgentEnabled";
-};
+namespace WebCore {
 
-InspectorDOMStorageAgent::InspectorDOMStorageAgent(InstrumentingAgents* instrumentingAgents, InspectorState* state)
-    : InspectorBaseAgent<InspectorDOMStorageAgent>("DOMStorage", instrumentingAgents, state)
-    , m_frontend(0)
+InspectorDOMStorageAgent::InspectorDOMStorageAgent(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent)
+    : InspectorAgentBase(ASCIILiteral("DOMStorage"), instrumentingAgents)
+    , m_pageAgent(pageAgent)
     , m_enabled(false)
 {
     m_instrumentingAgents->setInspectorDOMStorageAgent(this);
@@ -64,165 +66,149 @@ 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->value->unbind();
-    m_frontend = 0;
-    disable(0);
-}
+    m_frontendDispatcher = nullptr;
+    m_backendDispatcher.clear();
 
-void InspectorDOMStorageAgent::restore()
-{
-    m_enabled =  m_state->getBoolean(DOMStorageAgentState::domStorageAgentEnabled);
+    disable(nullptr);
 }
 
 void InspectorDOMStorageAgent::enable(ErrorString*)
 {
-    if (m_enabled)
-        return;
     m_enabled = true;
-    m_state->setBoolean(DOMStorageAgentState::domStorageAgentEnabled, m_enabled);
-
-    DOMStorageResourcesMap::iterator resourcesEnd = m_resources.end();
-    for (DOMStorageResourcesMap::iterator it = m_resources.begin(); it != resourcesEnd; ++it)
-        it->value->bind(m_frontend);
 }
 
 void InspectorDOMStorageAgent::disable(ErrorString*)
 {
-    if (!m_enabled)
-        return;
     m_enabled = false;
-    m_state->setBoolean(DOMStorageAgentState::domStorageAgentEnabled, m_enabled);
 }
 
-void InspectorDOMStorageAgent::getDOMStorageEntries(ErrorString*, const String& storageId, RefPtr<TypeBuilder::Array<TypeBuilder::Array<String> > >& entries)
+void InspectorDOMStorageAgent::getDOMStorageItems(ErrorString* errorString, const RefPtr<InspectorObject>& storageId, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Array<String>>>& items)
 {
-    // FIXME: consider initializing this array after 2 checks below. The checks should return error messages in this case.
-    entries = TypeBuilder::Array<TypeBuilder::Array<String> >::create();
-
-    InspectorDOMStorageResource* storageResource = getDOMStorageResourceForId(storageId);
-    if (!storageResource)
+    Frame* frame;
+    RefPtr<StorageArea> storageArea = findStorageArea(errorString, storageId, frame);
+    if (!storageArea) {
+        if (errorString)
+            *errorString = "No StorageArea for given storageId";
         return;
-    Frame* frame = storageResource->frame();
-    if (!frame)
-        return;
-        
-    StorageArea* storageArea = storageResource->storageArea();
-    for (unsigned i = 0; i < storageArea->length(frame); ++i) {
-        String name(storageArea->key(i, frame));
-        String value(storageArea->getItem(name, frame));
-        RefPtr<TypeBuilder::Array<String> > entry = TypeBuilder::Array<String>::create();
-        entry->addItem(name);
+    }
+
+    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);
-        entries->addItem(entry);
+        storageItems->addItem(entry.release());
     }
-}
 
-void InspectorDOMStorageAgent::setDOMStorageItem(ErrorString*, const String& storageId, const String& key, const String& value, bool* success)
-{
-    InspectorDOMStorageResource* storageResource = getDOMStorageResourceForId(storageId);
-    if (storageResource) {
-        ExceptionCode exception = 0;
-        storageResource->storageArea()->setItem(key, value, exception, storageResource->frame());
-        *success = !exception;
-    } else
-        *success = false;
+    items = storageItems.release();
 }
 
-void InspectorDOMStorageAgent::removeDOMStorageItem(ErrorString*, const String& storageId, const String& key, bool* success)
+void InspectorDOMStorageAgent::setDOMStorageItem(ErrorString* errorString, const RefPtr<InspectorObject>& storageId, const String& key, const String& value)
 {
-    InspectorDOMStorageResource* storageResource = getDOMStorageResourceForId(storageId);
-    if (storageResource) {
-        storageResource->storageArea()->removeItem(key, storageResource->frame());
-        *success = true;
-    } else
-        *success = false;
-}
+    Frame* frame;
+    RefPtr<StorageArea> storageArea = findStorageArea(nullptr, storageId, frame);
+    if (!storageArea) {
+        *errorString = "Storage not found";
+        return;
+    }
 
-String InspectorDOMStorageAgent::storageId(Storage* storage)
-{
-    ASSERT(storage);
-    Frame* frame = storage->frame();
-    ExceptionCode ec = 0;
-    bool isLocalStorage = (frame->document()->domWindow()->localStorage(ec) == storage && !ec);
-    return storageId(frame->document()->securityOrigin(), isLocalStorage);
+    bool quotaException = false;
+    storageArea->setItem(frame, key, value, quotaException);
+    if (quotaException)
+        *errorString = ExceptionCodeDescription(QUOTA_EXCEEDED_ERR).name;
 }
 
-String InspectorDOMStorageAgent::storageId(SecurityOrigin* securityOrigin, bool isLocalStorage)
+void InspectorDOMStorageAgent::removeDOMStorageItem(ErrorString* errorString, const RefPtr<InspectorObject>& storageId, const String& key)
 {
-    ASSERT(securityOrigin);
-    DOMStorageResourcesMap::iterator domStorageEnd = m_resources.end();
-    for (DOMStorageResourcesMap::iterator it = m_resources.begin(); it != domStorageEnd; ++it) {
-        if (it->value->isSameOriginAndType(securityOrigin, isLocalStorage))
-            return it->key;
+    Frame* frame;
+    RefPtr<StorageArea> storageArea = findStorageArea(nullptr, storageId, frame);
+    if (!storageArea) {
+        *errorString = "Storage not found";
+        return;
     }
-    return String();
+
+    storageArea->removeItem(frame, key);
 }
 
-InspectorDOMStorageResource* InspectorDOMStorageAgent::getDOMStorageResourceForId(const String& storageId)
+String InspectorDOMStorageAgent::storageId(Storage* storage)
 {
-    DOMStorageResourcesMap::iterator it = m_resources.find(storageId);
-    if (it == m_resources.end())
-        return 0;
-    return it->value.get();
+    ASSERT(storage);
+    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();
 }
 
-void InspectorDOMStorageAgent::didUseDOMStorage(StorageArea* storageArea, bool isLocalStorage, Frame* frame)
+PassRefPtr<Inspector::TypeBuilder::DOMStorage::StorageId> InspectorDOMStorageAgent::storageId(SecurityOrigin* securityOrigin, bool isLocalStorage)
 {
-    DOMStorageResourcesMap::iterator domStorageEnd = m_resources.end();
-    for (DOMStorageResourcesMap::iterator it = m_resources.begin(); it != domStorageEnd; ++it) {
-        if (it->value->isSameOriginAndType(frame->document()->securityOrigin(), isLocalStorage))
-            return;
-    }
-
-    RefPtr<InspectorDOMStorageResource> resource = InspectorDOMStorageResource::create(storageArea, isLocalStorage, frame);
-
-    m_resources.set(resource->id(), resource);
-
-    // Resources are only bound while visible.
-    if (m_enabled)
-        resource->bind(m_frontend);
+    return Inspector::TypeBuilder::DOMStorage::StorageId::create()
+        .setSecurityOrigin(securityOrigin->toRawString())
+        .setIsLocalStorage(isLocalStorage).release();
 }
 
-void InspectorDOMStorageAgent::didDispatchDOMStorageEvent(const String&, const String&, const String&, StorageType storageType, SecurityOrigin* securityOrigin, Page*)
+void InspectorDOMStorageAgent::didDispatchDOMStorageEvent(const String& key, const String& oldValue, const String& newValue, StorageType storageType, SecurityOrigin* securityOrigin, Page*)
 {
-    if (!m_frontend || !m_enabled)
+    if (!m_frontendDispatcher || !m_enabled)
         return;
 
-    String id = storageId(securityOrigin, storageType == LocalStorage);
-
-    if (id.isEmpty())
-        return;
-
-    m_frontend->domstorage()->domStorageUpdated(id);
-}
+    RefPtr<Inspector::TypeBuilder::DOMStorage::StorageId> id = storageId(securityOrigin, storageType == LocalStorage);
+
+    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);
+}
+
+PassRefPtr<StorageArea> InspectorDOMStorageAgent::findStorageArea(ErrorString* errorString, const RefPtr<InspectorObject>& storageId, Frame*& targetFrame)
+{
+    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;
+    }
 
-void InspectorDOMStorageAgent::clearResources()
-{
-    m_resources.clear();
-}
+    targetFrame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
+    if (!targetFrame) {
+        if (errorString)
+            *errorString = "Frame not found for the given security origin";
+        return nullptr;
+    }
 
-size_t InspectorDOMStorageAgent::memoryBytesUsedByStorageCache() const
-{
-    size_t size = 0;
-    for (DOMStorageResourcesMap::const_iterator it = m_resources.begin(); it != m_resources.end(); ++it)
-        size += it->value->storageArea()->memoryBytesUsedByCache();
-    return size;
+    Page* page = m_pageAgent->page();
+    if (isLocalStorage)
+        return page->group().localStorage()->storageArea(targetFrame->document()->securityOrigin());
+    return page->sessionStorage()->storageArea(targetFrame->document()->securityOrigin());
 }
 
-
 } // namespace WebCore
 
 #endif // ENABLE(INSPECTOR)