X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fxwalk%2Fapplication%2Fextension%2Fapplication_widget_extension.cc;h=fb94b014d0b173900e82c63a4f7571eb7e3027a0;hb=a3137fbf780cf581b1011fd9024eff767a6c1d4b;hp=af28a65fb14b1b0f62d01918dda2308dc0fe218a;hpb=949d079b90dcfa5fa918e1f366a6efb689615d20;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/xwalk/application/extension/application_widget_extension.cc b/src/xwalk/application/extension/application_widget_extension.cc index af28a65..fb94b01 100644 --- a/src/xwalk/application/extension/application_widget_extension.cc +++ b/src/xwalk/application/extension/application_widget_extension.cc @@ -4,10 +4,15 @@ #include "xwalk/application/extension/application_widget_extension.h" +#include + #include "base/bind.h" #include "base/path_service.h" +#include "base/strings/stringprintf.h" #include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/storage_partition.h" #include "content/public/browser/web_contents.h" @@ -27,12 +32,51 @@ using content::BrowserThread; namespace { + const char kCommandKey[] = "cmd"; const char kWidgetAttributeKey[] = "widgetKey"; const char kPreferencesItemKey[] = "preferencesItemKey"; const char kPreferencesItemValue[] = "preferencesItemValue"; + +void DispatchStorageEvent( + base::DictionaryValue* msg, + content::WebContents* web_contents, + content::RenderFrameHost* frame) { + if (frame == web_contents->GetFocusedFrame()) + return; + + std::string key, oldValue, newValue; + msg->GetString("key", &key); + msg->GetString("oldValue", &oldValue); + msg->GetString("newValue", &newValue); + + std::string code = base::StringPrintf( + "(function() {" + " var old_value = '%s' == '' ? null : '%s';" + " var new_value = '%s' == '' ? null : '%s';" + " var event = {" + " key: '%s'," + " oldValue: old_value," + " newValue: new_value," + " url: window.location.href," + " storageArea: widget.preferences" + " };" + " for (var key in event) {" + " Object.defineProperty(event, key, {" + " value: event[key]," + " writable: false" + " });" + " }" + " for (var i = 0; i < window.eventListenerList.length; i++)" + " window.eventListenerList[i](event);" + "})();", oldValue.c_str(), oldValue.c_str(), + newValue.c_str(), newValue.c_str(), key.c_str()); + + frame->ExecuteJavaScript(base::UTF8ToUTF16(code)); } +} // namespace + namespace xwalk { namespace application { @@ -52,8 +96,7 @@ XWalkExtensionInstance* ApplicationWidgetExtension::CreateInstance() { AppWidgetExtensionInstance::AppWidgetExtensionInstance( Application* application) - : application_(application), - handler_(this) { + : application_(application) { DCHECK(application_); base::ThreadRestrictions::SetIOAllowed(true); @@ -68,7 +111,6 @@ AppWidgetExtensionInstance::AppWidgetExtensionInstance( AppWidgetExtensionInstance::~AppWidgetExtensionInstance() {} void AppWidgetExtensionInstance::HandleMessage(scoped_ptr msg) { - handler_.HandleMessage(msg.Pass()); } void AppWidgetExtensionInstance::HandleSyncMessage( @@ -94,6 +136,8 @@ void AppWidgetExtensionInstance::HandleSyncMessage( result = ClearAllItems(msg.Pass()); } else if (command == "GetAllItems") { result = GetAllItems(msg.Pass()); + } else if (command == "GetItemValueByKey") { + result = GetItemValueByKey(msg.Pass()); } else if (command == "KeyExists") { result = KeyExists(msg.Pass()); } else { @@ -140,9 +184,26 @@ AppWidgetExtensionInstance::SetPreferencesItem(scoped_ptr msg) { return result.Pass(); } - if (widget_storage_->AddEntry(key, value, false)) + std::string old_value; + if (!widget_storage_->GetValueByKey(key, &old_value)) { + old_value = ""; + } + if (old_value == value) { + LOG(WARNING) << "You are trying to set the same value." + << " Nothing will be done."; + result.reset(new base::FundamentalValue(true)); + return result.Pass(); + } + if (widget_storage_->AddEntry(key, value, false)) { result.reset(new base::FundamentalValue(true)); + scoped_ptr event(new base::DictionaryValue()); + event->SetString("key", key); + event->SetString("oldValue", old_value); + event->SetString("newValue", value); + PostMessageToOtherFrames(event.Pass()); + } + return result.Pass(); } @@ -159,8 +220,23 @@ AppWidgetExtensionInstance::RemovePreferencesItem(scoped_ptr msg) { return result.Pass(); } - if (widget_storage_->RemoveEntry(key)) + std::string old_value; + if (!widget_storage_->GetValueByKey(key, &old_value)) { + LOG(WARNING) << "You are trying to remove an entry which doesn't exist." + << " Nothing will be done."; result.reset(new base::FundamentalValue(true)); + return result.Pass(); + } + + if (widget_storage_->RemoveEntry(key)) { + result.reset(new base::FundamentalValue(true)); + + scoped_ptr event(new base::DictionaryValue()); + event->SetString("key", key); + event->SetString("oldValue", old_value); + event->SetString("newValue", ""); + PostMessageToOtherFrames(event.Pass()); + } return result.Pass(); } @@ -170,9 +246,27 @@ scoped_ptr AppWidgetExtensionInstance::ClearAllItems( scoped_ptr result( new base::FundamentalValue(false)); - if (widget_storage_->Clear()) - result.reset(new base::FundamentalValue(true)); + scoped_ptr entries(new base::DictionaryValue()); + widget_storage_->GetAllEntries(entries.get()); + if (!widget_storage_->Clear()) + return result.Pass(); + + for (base::DictionaryValue::Iterator it(*(entries.get())); + !it.IsAtEnd(); it.Advance()) { + std::string key = it.key(); + if (!widget_storage_->EntryExists(key)) { + std::string old_value; + it.value().GetAsString(&old_value); + scoped_ptr event(new base::DictionaryValue()); + event->SetString("key", key); + event->SetString("oldValue", old_value); + event->SetString("newValue", ""); + PostMessageToOtherFrames(event.Pass()); + } + } + + result.reset(new base::FundamentalValue(true)); return result.Pass(); } @@ -184,6 +278,20 @@ scoped_ptr AppWidgetExtensionInstance::GetAllItems( return result.Pass(); } +scoped_ptr AppWidgetExtensionInstance::GetItemValueByKey( + scoped_ptr msg) { + base::DictionaryValue* dict; + msg->GetAsDictionary(&dict); + + std::string key; + std::string value; + if (!dict->GetString(kPreferencesItemKey, &key) || + !widget_storage_->GetValueByKey(key, &value)) + value = ""; + scoped_ptr result(new base::StringValue(value)); + return result.Pass(); +} + scoped_ptr AppWidgetExtensionInstance::KeyExists( scoped_ptr msg) const { scoped_ptr result( @@ -203,5 +311,17 @@ scoped_ptr AppWidgetExtensionInstance::KeyExists( return result.Pass(); } +void AppWidgetExtensionInstance::PostMessageToOtherFrames( + scoped_ptr msg) { + const std::vector& runtime_set = application_->runtimes(); + std::vector::const_iterator it; + for (it = runtime_set.begin(); it != runtime_set.end(); ++it) { + content::WebContents* web_contents = (*it)->web_contents(); + web_contents->ForEachFrame(base::Bind(&DispatchStorageEvent, + msg.get(), + web_contents)); + } +} + } // namespace application } // namespace xwalk