Index: chrome/renderer/extensions/extension_dispatcher.cc |
diff --git a/chrome/renderer/extensions/extension_dispatcher.cc b/chrome/renderer/extensions/extension_dispatcher.cc |
index 9ed183928dfd4d046998e2a11da09f4c1641016d..3223ef559fcc42cb0489ed8688470dbc5924c393 100644 |
--- a/chrome/renderer/extensions/extension_dispatcher.cc |
+++ b/chrome/renderer/extensions/extension_dispatcher.cc |
@@ -29,6 +29,8 @@ |
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityPolicy.h" |
#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" |
#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h" |
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
+#include "ui/base/resource/resource_bundle.h" |
#include "v8/include/v8.h" |
namespace { |
@@ -40,13 +42,16 @@ using WebKit::WebDataSource; |
using WebKit::WebFrame; |
using WebKit::WebSecurityPolicy; |
using WebKit::WebString; |
+using WebKit::WebVector; |
+using WebKit::WebView; |
using content::RenderThread; |
ExtensionDispatcher::ExtensionDispatcher() |
: is_webkit_initialized_(false), |
webrequest_adblock_(false), |
webrequest_adblock_plus_(false), |
- webrequest_other_(false) { |
+ webrequest_other_(false), |
+ is_batch_load_in_progress_(false) { |
const CommandLine& command_line = *(CommandLine::ForCurrentProcess()); |
is_extension_process_ = |
command_line.HasSwitch(switches::kExtensionProcess) || |
@@ -71,6 +76,8 @@ bool ExtensionDispatcher::OnControlMessageReceived( |
IPC_MESSAGE_HANDLER(ExtensionMsg_DeliverMessage, OnDeliverMessage) |
IPC_MESSAGE_HANDLER(ExtensionMsg_SetFunctionNames, OnSetFunctionNames) |
IPC_MESSAGE_HANDLER(ExtensionMsg_Loaded, OnLoaded) |
+ IPC_MESSAGE_HANDLER(ExtensionMsg_StartBatchLoad, OnStartBatchLoad) |
+ IPC_MESSAGE_HANDLER(ExtensionMsg_EndBatchLoad, OnEndBatchLoad) |
IPC_MESSAGE_HANDLER(ExtensionMsg_Unloaded, OnUnloaded) |
IPC_MESSAGE_HANDLER(ExtensionMsg_SetScriptingWhitelist, |
OnSetScriptingWhitelist) |
@@ -189,6 +196,58 @@ void ExtensionDispatcher::OnLoaded(const ExtensionMsg_Loaded_Params& params) { |
} |
extensions_.Insert(extension); |
+ |
+ if (extension->is_platform_app()) { |
+ extensions_needing_stylesheet_.Insert(extension); |
+ if (is_batch_load_in_progress_) { |
+ // Do nothing; we'll expect the ExtensionMsg_EndBatchLoad message as our |
+ // signal to do the cleanup work of creating a single stylesheet matching |
+ // all the platform-app URL patterns observed in the batch. |
+ } else { |
+ DCHECK(extensions_needing_stylesheet_.size() == 1u); |
+ // This ExtensionMsg_Loaded was not sent as part of a batch. But to |
+ // simplify, let's treat it as a synthetic batch of one, then run the |
+ // batch-ending code. |
+ is_batch_load_in_progress_ = true; |
+ OnEndBatchLoad(); |
+ } |
+ } |
+} |
+ |
+void ExtensionDispatcher::OnStartBatchLoad() { |
+ DCHECK(extensions_needing_stylesheet_.size() == 0u); |
+ DCHECK(!is_batch_load_in_progress_); |
+ is_batch_load_in_progress_ = true; |
+} |
+ |
+void ExtensionDispatcher::OnEndBatchLoad() { |
+ DCHECK(is_batch_load_in_progress_); |
+ |
+ // We have collected a set of platform-app extensions, so let's tell WebKit |
+ // about them so that it can provide a default stylesheet for them. |
+ // |
+ // TODO: consider enhancing WebView to allow removing single stylesheets, or |
+ // else to edit the pattern set associated with one. |
+ std::vector<WebString> temp_patterns; |
+ for (ExtensionSet::const_iterator i = extensions_needing_stylesheet_.begin(); |
+ i != extensions_needing_stylesheet_.end(); ++i) { |
+ temp_patterns.push_back( |
+ WebString::fromUTF8(i->second->url().spec() + "*")); |
+ } |
+ WebVector<WebString> patterns; |
+ patterns.assign(temp_patterns); |
+ if (patterns.size() > 0) { |
+ WebView::addUserStyleSheet( |
+ WebString::fromUTF8(ResourceBundle::GetSharedInstance(). |
+ GetRawDataResource(IDR_PLATFORM_APP_CSS)), |
+ patterns, |
+ WebView::UserContentInjectInAllFrames, |
+ WebView::UserStyleInjectInExistingDocuments); |
+ } |
+ |
+ // We have fully processed the batch. Clean things up for the next one. |
+ extensions_needing_stylesheet_.Clear(); |
+ is_batch_load_in_progress_ = false; |
} |
void ExtensionDispatcher::OnUnloaded(const std::string& id) { |
@@ -197,6 +256,10 @@ void ExtensionDispatcher::OnUnloaded(const std::string& id) { |
// we'd like it to get a new isolated world ID, so that it can pick up the |
// changed origin whitelist. |
user_script_slave_->RemoveIsolatedWorld(id); |
+ |
+ // We don't do anything with existing platform-app stylesheets. They will |
+ // stay resident, but the URL pattern corresponding to the unloaded |
+ // extension's URL just won't match anything anymore. |
} |
void ExtensionDispatcher::OnSetScriptingWhitelist( |