blob: 1344e64f26e20979bff92e07ec6b117cbe67f254 [file] [log] [blame]
/*
* 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
* 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 "modules/storage/InspectorDOMStorageAgent.h"
#include "bindings/core/v8/ExceptionState.h"
#include "core/dom/DOMException.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
#include "core/frame/LocalDOMWindow.h"
#include "core/frame/LocalFrame.h"
#include "core/inspector/InspectedFrames.h"
#include "core/page/Page.h"
#include "modules/storage/Storage.h"
#include "modules/storage/StorageNamespace.h"
#include "modules/storage/StorageNamespaceController.h"
#include "platform/weborigin/SecurityOrigin.h"
namespace blink {
using protocol::Response;
namespace DOMStorageAgentState {
static const char kDomStorageAgentEnabled[] = "domStorageAgentEnabled";
};
static Response ToResponse(ExceptionState& exception_state) {
if (!exception_state.HadException())
return Response::OK();
return Response::Error(DOMException::GetErrorName(exception_state.Code()) +
" " + exception_state.Message());
}
InspectorDOMStorageAgent::InspectorDOMStorageAgent(Page* page)
: page_(page), is_enabled_(false) {}
InspectorDOMStorageAgent::~InspectorDOMStorageAgent() {}
void InspectorDOMStorageAgent::Trace(blink::Visitor* visitor) {
visitor->Trace(page_);
InspectorBaseAgent::Trace(visitor);
}
void InspectorDOMStorageAgent::Restore() {
if (state_->booleanProperty(DOMStorageAgentState::kDomStorageAgentEnabled,
false)) {
enable();
}
}
Response InspectorDOMStorageAgent::enable() {
if (is_enabled_)
return Response::OK();
is_enabled_ = true;
state_->setBoolean(DOMStorageAgentState::kDomStorageAgentEnabled, true);
if (StorageNamespaceController* controller =
StorageNamespaceController::From(page_))
controller->SetInspectorAgent(this);
return Response::OK();
}
Response InspectorDOMStorageAgent::disable() {
if (!is_enabled_)
return Response::OK();
is_enabled_ = false;
state_->setBoolean(DOMStorageAgentState::kDomStorageAgentEnabled, false);
if (StorageNamespaceController* controller =
StorageNamespaceController::From(page_))
controller->SetInspectorAgent(nullptr);
return Response::OK();
}
Response InspectorDOMStorageAgent::clear(
std::unique_ptr<protocol::DOMStorage::StorageId> storage_id) {
LocalFrame* frame = nullptr;
StorageArea* storage_area = nullptr;
Response response =
FindStorageArea(std::move(storage_id), frame, storage_area);
if (!response.isSuccess())
return response;
DummyExceptionStateForTesting exception_state;
storage_area->Clear(exception_state, frame);
if (exception_state.HadException())
return Response::Error("Could not clear the storage");
return Response::OK();
}
Response InspectorDOMStorageAgent::getDOMStorageItems(
std::unique_ptr<protocol::DOMStorage::StorageId> storage_id,
std::unique_ptr<protocol::Array<protocol::Array<String>>>* items) {
LocalFrame* frame = nullptr;
StorageArea* storage_area = nullptr;
Response response =
FindStorageArea(std::move(storage_id), frame, storage_area);
if (!response.isSuccess())
return response;
std::unique_ptr<protocol::Array<protocol::Array<String>>> storage_items =
protocol::Array<protocol::Array<String>>::create();
DummyExceptionStateForTesting exception_state;
for (unsigned i = 0; i < storage_area->length(exception_state, frame); ++i) {
String name(storage_area->Key(i, exception_state, frame));
response = ToResponse(exception_state);
if (!response.isSuccess())
return response;
String value(storage_area->GetItem(name, exception_state, frame));
response = ToResponse(exception_state);
if (!response.isSuccess())
return response;
std::unique_ptr<protocol::Array<String>> entry =
protocol::Array<String>::create();
entry->addItem(name);
entry->addItem(value);
storage_items->addItem(std::move(entry));
}
*items = std::move(storage_items);
return Response::OK();
}
Response InspectorDOMStorageAgent::setDOMStorageItem(
std::unique_ptr<protocol::DOMStorage::StorageId> storage_id,
const String& key,
const String& value) {
LocalFrame* frame = nullptr;
StorageArea* storage_area = nullptr;
Response response =
FindStorageArea(std::move(storage_id), frame, storage_area);
if (!response.isSuccess())
return response;
DummyExceptionStateForTesting exception_state;
storage_area->SetItem(key, value, exception_state, frame);
return ToResponse(exception_state);
}
Response InspectorDOMStorageAgent::removeDOMStorageItem(
std::unique_ptr<protocol::DOMStorage::StorageId> storage_id,
const String& key) {
LocalFrame* frame = nullptr;
StorageArea* storage_area = nullptr;
Response response =
FindStorageArea(std::move(storage_id), frame, storage_area);
if (!response.isSuccess())
return response;
DummyExceptionStateForTesting exception_state;
storage_area->RemoveItem(key, exception_state, frame);
return ToResponse(exception_state);
}
std::unique_ptr<protocol::DOMStorage::StorageId>
InspectorDOMStorageAgent::GetStorageId(const SecurityOrigin* security_origin,
bool is_local_storage) {
return protocol::DOMStorage::StorageId::create()
.setSecurityOrigin(security_origin->ToRawString())
.setIsLocalStorage(is_local_storage)
.build();
}
void InspectorDOMStorageAgent::DidDispatchDOMStorageEvent(
const String& key,
const String& old_value,
const String& new_value,
StorageType storage_type,
const SecurityOrigin* security_origin) {
if (!GetFrontend())
return;
std::unique_ptr<protocol::DOMStorage::StorageId> id =
GetStorageId(security_origin, storage_type == kLocalStorage);
if (key.IsNull())
GetFrontend()->domStorageItemsCleared(std::move(id));
else if (new_value.IsNull())
GetFrontend()->domStorageItemRemoved(std::move(id), key);
else if (old_value.IsNull())
GetFrontend()->domStorageItemAdded(std::move(id), key, new_value);
else
GetFrontend()->domStorageItemUpdated(std::move(id), key, old_value,
new_value);
}
Response InspectorDOMStorageAgent::FindStorageArea(
std::unique_ptr<protocol::DOMStorage::StorageId> storage_id,
LocalFrame*& frame,
StorageArea*& storage_area) {
String security_origin = storage_id->getSecurityOrigin();
bool is_local_storage = storage_id->getIsLocalStorage();
if (!page_->MainFrame()->IsLocalFrame())
return Response::InternalError();
InspectedFrames* inspected_frames =
new InspectedFrames(page_->DeprecatedLocalMainFrame(), String());
frame = inspected_frames->FrameWithSecurityOrigin(security_origin);
if (!frame)
return Response::Error("Frame not found for the given security origin");
if (is_local_storage) {
storage_area = StorageNamespace::LocalStorageArea(
frame->GetDocument()->GetSecurityOrigin());
return Response::OK();
}
StorageNamespace* session_storage =
StorageNamespaceController::From(page_)->SessionStorage();
if (!session_storage)
return Response::Error("SessionStorage is not supported");
storage_area = session_storage->GetStorageArea(
frame->GetDocument()->GetSecurityOrigin());
return Response::OK();
}
} // namespace blink