summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrdevlin.cronin@chromium.org <rdevlin.cronin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-24 01:36:16 +0000
committerrdevlin.cronin@chromium.org <rdevlin.cronin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-24 01:36:16 +0000
commit334ec0a0edaae51da3a9b267a1c5af441fe50f7c (patch)
tree1287c852f3f785918e397080556dceba5cc2e591
parent62049567333baa9069fbc1e251334a97505bd0d7 (diff)
downloadchromium_src-334ec0a0edaae51da3a9b267a1c5af441fe50f7c.zip
chromium_src-334ec0a0edaae51da3a9b267a1c5af441fe50f7c.tar.gz
chromium_src-334ec0a0edaae51da3a9b267a1c5af441fe50f7c.tar.bz2
Move ContentScripts out of Extension
TBR=ben@chromium.org (gypis) BUG=159265 Review URL: https://chromiumcodereview.appspot.com/11724002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@190141 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chromeos/accessibility/accessibility_util.cc7
-rw-r--r--chrome/browser/extensions/content_scripts_parser.cc28
-rw-r--r--chrome/browser/extensions/content_scripts_parser.h37
-rw-r--r--chrome/browser/extensions/convert_user_script_unittest.cc52
-rw-r--r--chrome/browser/extensions/extension_service_unittest.cc16
-rw-r--r--chrome/browser/extensions/extension_ui_unittest.cc8
-rw-r--r--chrome/browser/extensions/user_script_listener.cc8
-rw-r--r--chrome/browser/extensions/user_script_master.cc4
-rw-r--r--chrome/browser/profiles/profile_dependency_manager.cc2
-rw-r--r--chrome/chrome_browser_extensions.gypi2
-rw-r--r--chrome/chrome_common.gypi4
-rw-r--r--chrome/chrome_tests_unit.gypi4
-rw-r--r--chrome/common/extensions/extension.cc299
-rw-r--r--chrome/common/extensions/extension.h30
-rw-r--r--chrome/common/extensions/extension_file_util.cc64
-rw-r--r--chrome/common/extensions/extension_file_util_unittest.cc2
-rw-r--r--chrome/common/extensions/extension_unittest.cc38
-rw-r--r--chrome/common/extensions/manifest_handlers/content_scripts_handler.cc446
-rw-r--r--chrome/common/extensions/manifest_handlers/content_scripts_handler.h51
-rw-r--r--chrome/common/extensions/manifest_handlers/content_scripts_manifest_unittest.cc (renamed from chrome/common/extensions/manifest_tests/extension_manifests_contentscript_unittest.cc)32
-rw-r--r--chrome/common/extensions/manifest_handlers/exclude_matches_manifest_unittest.cc (renamed from chrome/common/extensions/manifest_tests/extension_manifests_excludematches_unittest.cc)19
-rw-r--r--chrome/common/extensions/manifest_tests/extension_manifests_initvalue_unittest.cc2
-rw-r--r--chrome/common/extensions/permissions/permission_set.cc6
-rw-r--r--chrome/common/extensions/permissions/permission_set_unittest.cc4
24 files changed, 730 insertions, 435 deletions
diff --git a/chrome/browser/chromeos/accessibility/accessibility_util.cc b/chrome/browser/chromeos/accessibility/accessibility_util.cc
index f8f71aa..2b3aee2 100644
--- a/chrome/browser/chromeos/accessibility/accessibility_util.cc
+++ b/chrome/browser/chromeos/accessibility/accessibility_util.cc
@@ -28,6 +28,7 @@
#include "chrome/browser/ui/singleton_tabs.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_messages.h"
+#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "chrome/common/extensions/user_script.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
@@ -197,8 +198,10 @@ void EnableSpokenFeedback(bool enabled,
extension->id(), render_view_host->GetProcess()->GetID(),
render_view_host->GetRoutingID());
- for (size_t i = 0; i < extension->content_scripts().size(); i++) {
- const extensions::UserScript& script = extension->content_scripts()[i];
+ const extensions::UserScriptList& content_scripts =
+ extensions::ContentScriptsInfo::GetContentScripts(extension);
+ for (size_t i = 0; i < content_scripts.size(); i++) {
+ const extensions::UserScript& script = content_scripts[i];
for (size_t j = 0; j < script.js_scripts().size(); ++j) {
const extensions::UserScript::File &file = script.js_scripts()[j];
extensions::ExtensionResource resource = extension->GetResource(
diff --git a/chrome/browser/extensions/content_scripts_parser.cc b/chrome/browser/extensions/content_scripts_parser.cc
new file mode 100644
index 0000000..4229195
--- /dev/null
+++ b/chrome/browser/extensions/content_scripts_parser.cc
@@ -0,0 +1,28 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/content_scripts_parser.h"
+
+#include "base/lazy_instance.h"
+#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
+
+namespace extensions {
+
+static base::LazyInstance<ProfileKeyedAPIFactory<ContentScriptsParser> >
+ g_factory = LAZY_INSTANCE_INITIALIZER;
+
+// static
+ProfileKeyedAPIFactory<ContentScriptsParser>*
+ContentScriptsParser::GetFactoryInstance() {
+ return &g_factory.Get();
+}
+
+ContentScriptsParser::ContentScriptsParser(Profile* profile) {
+ (new ContentScriptsHandler)->Register();
+}
+
+ContentScriptsParser::~ContentScriptsParser() {
+}
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/content_scripts_parser.h b/chrome/browser/extensions/content_scripts_parser.h
new file mode 100644
index 0000000..e6f20d4
--- /dev/null
+++ b/chrome/browser/extensions/content_scripts_parser.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_CONTENT_SCRIPTS_PARSER_H_
+#define CHROME_BROWSER_EXTENSIONS_CONTENT_SCRIPTS_PARSER_H_
+
+#include "chrome/browser/extensions/api/profile_keyed_api_factory.h"
+#include "chrome/browser/profiles/profile_keyed_service.h"
+
+class Profile;
+
+namespace extensions {
+
+// The profile-keyed service that manages the content scripts API.
+class ContentScriptsParser : public ProfileKeyedAPI {
+ public:
+ explicit ContentScriptsParser(Profile* profile);
+ virtual ~ContentScriptsParser();
+
+ // ProfileKeyedAPI implementation.
+ static ProfileKeyedAPIFactory<ContentScriptsParser>* GetFactoryInstance();
+
+ private:
+ friend class ProfileKeyedAPIFactory<ContentScriptsParser>;
+
+ // ProfileKeyedAPI implementation.
+ static const char* service_name() {
+ return "ContentScriptsParser";
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(ContentScriptsParser);
+};
+
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_CONTENT_SCRIPTS_PARSER_H_
diff --git a/chrome/browser/extensions/convert_user_script_unittest.cc b/chrome/browser/extensions/convert_user_script_unittest.cc
index 9985909..bce2d17 100644
--- a/chrome/browser/extensions/convert_user_script_unittest.cc
+++ b/chrome/browser/extensions/convert_user_script_unittest.cc
@@ -14,6 +14,8 @@
#include "chrome/browser/extensions/convert_user_script.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/manifest_handler.h"
+#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "extensions/common/constants.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -28,7 +30,20 @@ static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
}
-TEST(ExtensionFromUserScript, Basic) {
+class ExtensionFromUserScript : public testing::Test {
+ public:
+ virtual void SetUp() OVERRIDE {
+ testing::Test::SetUp();
+ (new ContentScriptsHandler)->Register();
+ }
+
+ virtual void TearDown() OVERRIDE {
+ testing::Test::TearDown();
+ ManifestHandler::ClearRegistryForTesting();
+ }
+};
+
+TEST_F(ExtensionFromUserScript, Basic) {
base::ScopedTempDir extensions_dir;
ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
@@ -56,8 +71,9 @@ TEST(ExtensionFromUserScript, Basic) {
EXPECT_EQ("IhCFCg9PMQTAcJdc9ytUP99WME+4yh6aMnM1uupkovo=",
extension->public_key());
- ASSERT_EQ(1u, extension->content_scripts().size());
- const UserScript& script = extension->content_scripts()[0];
+ ASSERT_EQ(1u, ContentScriptsInfo::GetContentScripts(extension).size());
+ const UserScript& script =
+ ContentScriptsInfo::GetContentScripts(extension)[0];
EXPECT_EQ(UserScript::DOCUMENT_IDLE, script.run_location());
ASSERT_EQ(2u, script.globs().size());
EXPECT_EQ("http://www.google.com/*", script.globs().at(0));
@@ -78,7 +94,7 @@ TEST(ExtensionFromUserScript, Basic) {
extension->path().Append(kManifestFilename)));
}
-TEST(ExtensionFromUserScript, NoMetdata) {
+TEST_F(ExtensionFromUserScript, NoMetdata) {
base::ScopedTempDir extensions_dir;
ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
@@ -106,8 +122,9 @@ TEST(ExtensionFromUserScript, NoMetdata) {
EXPECT_EQ("k1WxKx54hX6tfl5gQaXD/m4d9QUMwRdXWM4RW+QkWcY=",
extension->public_key());
- ASSERT_EQ(1u, extension->content_scripts().size());
- const UserScript& script = extension->content_scripts()[0];
+ ASSERT_EQ(1u, ContentScriptsInfo::GetContentScripts(extension).size());
+ const UserScript& script =
+ ContentScriptsInfo::GetContentScripts(extension)[0];
ASSERT_EQ(1u, script.globs().size());
EXPECT_EQ("*", script.globs()[0]);
EXPECT_EQ(0u, script.exclude_globs().size());
@@ -124,7 +141,7 @@ TEST(ExtensionFromUserScript, NoMetdata) {
extension->path().Append(kManifestFilename)));
}
-TEST(ExtensionFromUserScript, NotUTF8) {
+TEST_F(ExtensionFromUserScript, NotUTF8) {
base::ScopedTempDir extensions_dir;
ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
@@ -142,7 +159,7 @@ TEST(ExtensionFromUserScript, NotUTF8) {
EXPECT_EQ(ASCIIToUTF16("User script must be UTF8 encoded."), error);
}
-TEST(ExtensionFromUserScript, RunAtDocumentStart) {
+TEST_F(ExtensionFromUserScript, RunAtDocumentStart) {
base::ScopedTempDir extensions_dir;
ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
@@ -170,12 +187,13 @@ TEST(ExtensionFromUserScript, RunAtDocumentStart) {
extension->public_key());
// Validate run location.
- ASSERT_EQ(1u, extension->content_scripts().size());
- const UserScript& script = extension->content_scripts()[0];
+ ASSERT_EQ(1u, ContentScriptsInfo::GetContentScripts(extension).size());
+ const UserScript& script =
+ ContentScriptsInfo::GetContentScripts(extension)[0];
EXPECT_EQ(UserScript::DOCUMENT_START, script.run_location());
}
-TEST(ExtensionFromUserScript, RunAtDocumentEnd) {
+TEST_F(ExtensionFromUserScript, RunAtDocumentEnd) {
base::ScopedTempDir extensions_dir;
ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
@@ -203,12 +221,13 @@ TEST(ExtensionFromUserScript, RunAtDocumentEnd) {
extension->public_key());
// Validate run location.
- ASSERT_EQ(1u, extension->content_scripts().size());
- const UserScript& script = extension->content_scripts()[0];
+ ASSERT_EQ(1u, ContentScriptsInfo::GetContentScripts(extension).size());
+ const UserScript& script =
+ ContentScriptsInfo::GetContentScripts(extension)[0];
EXPECT_EQ(UserScript::DOCUMENT_END, script.run_location());
}
-TEST(ExtensionFromUserScript, RunAtDocumentIdle) {
+TEST_F(ExtensionFromUserScript, RunAtDocumentIdle) {
base::ScopedTempDir extensions_dir;
ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
@@ -237,8 +256,9 @@ TEST(ExtensionFromUserScript, RunAtDocumentIdle) {
extension->public_key());
// Validate run location.
- ASSERT_EQ(1u, extension->content_scripts().size());
- const UserScript& script = extension->content_scripts()[0];
+ ASSERT_EQ(1u, ContentScriptsInfo::GetContentScripts(extension).size());
+ const UserScript& script =
+ ContentScriptsInfo::GetContentScripts(extension)[0];
EXPECT_EQ(UserScript::DOCUMENT_IDLE, script.run_location());
}
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index ad0134d..76e1100 100644
--- a/chrome/browser/extensions/extension_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -69,6 +69,7 @@
#include "chrome/common/extensions/extension_l10n_util.h"
#include "chrome/common/extensions/extension_manifest_constants.h"
#include "chrome/common/extensions/manifest_handler.h"
+#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "chrome/common/extensions/manifest_url_handler.h"
#include "chrome/common/extensions/permissions/permission_set.h"
#include "chrome/common/pref_names.h"
@@ -549,6 +550,7 @@ void ExtensionServiceTestBase::SetUp() {
testing::Test::SetUp();
ExtensionErrorReporter::GetInstance()->ClearErrors();
(new extensions::BackgroundManifestHandler)->Register();
+ (new extensions::ContentScriptsHandler)->Register();
(new extensions::DefaultLocaleHandler)->Register();
(new extensions::PluginsHandler)->Register();
}
@@ -1156,7 +1158,8 @@ TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
AddPattern(&expected_patterns, "http://*.google.com/*");
AddPattern(&expected_patterns, "https://*.google.com/*");
const Extension* extension = loaded_[0];
- const extensions::UserScriptList& scripts = extension->content_scripts();
+ const extensions::UserScriptList& scripts =
+ extensions::ContentScriptsInfo::GetContentScripts(extension);
ASSERT_EQ(2u, scripts.size());
EXPECT_EQ(expected_patterns, scripts[0].url_patterns());
EXPECT_EQ(2u, scripts[0].js_scripts().size());
@@ -1195,7 +1198,8 @@ TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
EXPECT_EQ(std::string(""), loaded_[1]->description());
EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
extensions::BackgroundInfo::GetBackgroundURL(loaded_[1]));
- EXPECT_EQ(0u, loaded_[1]->content_scripts().size());
+ EXPECT_EQ(
+ 0u, extensions::ContentScriptsInfo::GetContentScripts(loaded_[1]).size());
// We don't parse the plugins section on Chrome OS.
#if defined(OS_CHROMEOS)
@@ -1220,7 +1224,9 @@ TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
EXPECT_EQ(std::string(good2), loaded_[index]->id());
EXPECT_EQ(std::string("My extension 3"), loaded_[index]->name());
EXPECT_EQ(std::string(""), loaded_[index]->description());
- EXPECT_EQ(0u, loaded_[index]->content_scripts().size());
+ EXPECT_EQ(
+ 0u,
+ extensions::ContentScriptsInfo::GetContentScripts(loaded_[index]).size());
EXPECT_EQ(Manifest::INTERNAL, loaded_[index]->location());
};
@@ -2107,7 +2113,9 @@ TEST_F(ExtensionServiceTest, InstallTheme) {
ValidatePrefKeyCount(++pref_count);
ASSERT_TRUE(extension);
EXPECT_TRUE(extension->is_theme());
- EXPECT_EQ(0u, extension->content_scripts().size());
+ EXPECT_EQ(
+ 0u,
+ extensions::ContentScriptsInfo::GetContentScripts(extension).size());
}
// A theme with image resources missing (misspelt path).
diff --git a/chrome/browser/extensions/extension_ui_unittest.cc b/chrome/browser/extensions/extension_ui_unittest.cc
index 5623429..a623506 100644
--- a/chrome/browser/extensions/extension_ui_unittest.cc
+++ b/chrome/browser/extensions/extension_ui_unittest.cc
@@ -13,6 +13,8 @@
#include "chrome/browser/ui/webui/extensions/extension_settings_handler.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/manifest_handler.h"
+#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/test_browser_thread.h"
#include "extensions/common/constants.h"
@@ -29,6 +31,8 @@ class ExtensionUITest : public testing::Test {
protected:
virtual void SetUp() OVERRIDE {
+ testing::Test::SetUp();
+
// Create an ExtensionService and ManagementPolicy to inject into the
// ExtensionSettingsHandler.
profile_.reset(new TestingProfile());
@@ -41,6 +45,8 @@ class ExtensionUITest : public testing::Test {
handler_.reset(new ExtensionSettingsHandler(extension_service_,
management_policy_));
+
+ (new extensions::ContentScriptsHandler)->Register();
}
virtual void TearDown() OVERRIDE {
@@ -48,6 +54,8 @@ class ExtensionUITest : public testing::Test {
profile_.reset();
// Execute any pending deletion tasks.
message_loop_.RunUntilIdle();
+ extensions::ManifestHandler::ClearRegistryForTesting();
+ testing::Test::TearDown();
}
static DictionaryValue* DeserializeJSONTestData(const base::FilePath& path,
diff --git a/chrome/browser/extensions/user_script_listener.cc b/chrome/browser/extensions/user_script_listener.cc
index ec93cf7..de663b4 100644
--- a/chrome/browser/extensions/user_script_listener.cc
+++ b/chrome/browser/extensions/user_script_listener.cc
@@ -9,6 +9,7 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/resource_controller.h"
@@ -185,7 +186,8 @@ void UserScriptListener::CollectURLPatterns(const Extension* extension,
URLPatterns* patterns) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- const UserScriptList& scripts = extension->content_scripts();
+ const UserScriptList& scripts =
+ ContentScriptsInfo::GetContentScripts(extension);
for (UserScriptList::const_iterator iter = scripts.begin();
iter != scripts.end(); ++iter) {
patterns->insert(patterns->end(),
@@ -204,7 +206,7 @@ void UserScriptListener::Observe(int type,
Profile* profile = content::Source<Profile>(source).ptr();
const Extension* extension =
content::Details<const Extension>(details).ptr();
- if (extension->content_scripts().empty())
+ if (ContentScriptsInfo::GetContentScripts(extension).empty())
return; // no new patterns from this extension.
URLPatterns new_patterns;
@@ -221,7 +223,7 @@ void UserScriptListener::Observe(int type,
Profile* profile = content::Source<Profile>(source).ptr();
const Extension* unloaded_extension =
content::Details<UnloadedExtensionInfo>(details)->extension;
- if (unloaded_extension->content_scripts().empty())
+ if (ContentScriptsInfo::GetContentScripts(unloaded_extension).empty())
return; // no patterns to delete for this extension.
// Clear all our patterns and reregister all the still-loaded extensions.
diff --git a/chrome/browser/extensions/user_script_master.cc b/chrome/browser/extensions/user_script_master.cc
index dcd5804..999c0f7 100644
--- a/chrome/browser/extensions/user_script_master.cc
+++ b/chrome/browser/extensions/user_script_master.cc
@@ -24,6 +24,7 @@
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/extensions/extension_set.h"
+#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "chrome/common/extensions/message_bundle.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_process_host.h"
@@ -363,7 +364,8 @@ void UserScriptMaster::Observe(int type,
extension->path(), LocaleInfo::GetDefaultLocale(extension));
bool incognito_enabled = extensions::ExtensionSystem::Get(profile_)->
extension_service()->IsIncognitoEnabled(extension->id());
- const UserScriptList& scripts = extension->content_scripts();
+ const UserScriptList& scripts =
+ ContentScriptsInfo::GetContentScripts(extension);
for (UserScriptList::const_iterator iter = scripts.begin();
iter != scripts.end(); ++iter) {
user_scripts_.push_back(*iter);
diff --git a/chrome/browser/profiles/profile_dependency_manager.cc b/chrome/browser/profiles/profile_dependency_manager.cc
index 3bfe9ab..e1add09 100644
--- a/chrome/browser/profiles/profile_dependency_manager.cc
+++ b/chrome/browser/profiles/profile_dependency_manager.cc
@@ -48,6 +48,7 @@
#include "chrome/browser/extensions/api/tab_capture/tab_capture_registry_factory.h"
#include "chrome/browser/extensions/api/tabs/tabs_windows_api.h"
#include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h"
+#include "chrome/browser/extensions/content_scripts_parser.h"
#include "chrome/browser/extensions/csp_parser.h"
#include "chrome/browser/extensions/extension_system_factory.h"
#include "chrome/browser/extensions/install_tracker_factory.h"
@@ -273,6 +274,7 @@ void ProfileDependencyManager::AssertFactoriesBuilt() {
extensions::BookmarksAPI::GetFactoryInstance();
extensions::BluetoothAPIFactory::GetInstance();
extensions::CommandService::GetFactoryInstance();
+ extensions::ContentScriptsParser::GetFactoryInstance();
extensions::CookiesAPI::GetFactoryInstance();
extensions::CSPParser::GetFactoryInstance();
extensions::DialAPIFactory::GetInstance();
diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi
index 7a6af0e..537d0ec 100644
--- a/chrome/chrome_browser_extensions.gypi
+++ b/chrome/chrome_browser_extensions.gypi
@@ -496,6 +496,8 @@
'browser/extensions/crx_installer.cc',
'browser/extensions/crx_installer.h',
'browser/extensions/crx_installer_error.h',
+ 'browser/extensions/content_scripts_parser.cc',
+ 'browser/extensions/content_scripts_parser.h',
'browser/extensions/csp_parser.cc',
'browser/extensions/csp_parser.h',
'browser/extensions/data_deleter.cc',
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index 9e56307..73aeddb4 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -240,6 +240,8 @@
'common/extensions/manifest_handler.h',
'common/extensions/manifest_handler_helpers.cc',
'common/extensions/manifest_handler_helpers.h',
+ 'common/extensions/manifest_handlers/content_scripts_handler.cc',
+ 'common/extensions/manifest_handlers/content_scripts_handler.h',
'common/extensions/manifest_url_handler.cc',
'common/extensions/manifest_url_handler.h',
'common/extensions/message_bundle.cc',
@@ -410,6 +412,8 @@
['include', 'common/extensions/api/extension_action/action_info.h'],
['include', 'common/extensions/api/extension_action/browser_action_handler.cc'],
['include', 'common/extensions/api/extension_action/browser_action_handler.h'],
+ ['include', 'common/extensions/api/content_scripts/content_scripts_handler.cc'],
+ ['include', 'common/extensions/api/content_scripts/content_scripts_handler.h'],
['include', 'common/extensions/api/extension_action/page_action_handler.cc'],
['include', 'common/extensions/api/extension_action/page_action_handler.h'],
['include', 'common/extensions/api/icons/icons_handler.cc'],
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index 5394b2e..a6eb3f1 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -1520,14 +1520,14 @@
'common/extensions/features/base_feature_provider_unittest.cc',
'common/extensions/features/complex_feature_unittest.cc',
'common/extensions/features/simple_feature_unittest.cc',
+ 'common/extensions/manifest_handlers/content_scripts_manifest_unittest.cc',
+ 'common/extensions/manifest_handlers/exclude_matches_manifest_unittest.cc',
'common/extensions/manifest_tests/extension_manifest_test.cc',
'common/extensions/manifest_tests/extension_manifests_background_unittest.cc',
'common/extensions/manifest_tests/extension_manifests_chromepermission_unittest.cc',
- 'common/extensions/manifest_tests/extension_manifests_contentscript_unittest.cc',
'common/extensions/manifest_tests/extension_manifests_contentsecuritypolicy_unittest.cc',
'common/extensions/manifest_tests/extension_manifests_default_extent_path_unittest.cc',
'common/extensions/manifest_tests/extension_manifests_devtools_unittest.cc',
- 'common/extensions/manifest_tests/extension_manifests_excludematches_unittest.cc',
'common/extensions/manifest_tests/extension_manifests_experimental_unittest.cc',
'common/extensions/manifest_tests/extension_manifests_homepage_unittest.cc',
'common/extensions/manifest_tests/extension_manifests_initvalue_unittest.cc',
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
index fe25d22..a83392e 100644
--- a/chrome/common/extensions/extension.cc
+++ b/chrome/common/extensions/extension.cc
@@ -979,15 +979,6 @@ bool Extension::ShouldDisplayInExtensionSettings() const {
return true;
}
-bool Extension::HasContentScriptAtURL(const GURL& url) const {
- for (UserScriptList::const_iterator it = content_scripts_.begin();
- it != content_scripts_.end(); ++it) {
- if (it->MatchesURL(url))
- return true;
- }
- return false;
-}
-
scoped_refptr<const PermissionSet> Extension::GetTabSpecificPermissions(
int tab_id) const {
base::AutoLock auto_lock(runtime_data_lock_);
@@ -1927,46 +1918,13 @@ bool Extension::LoadExtensionFeatures(string16* error) {
manifest_->GetBoolean(keys::kConvertedFromUserScript,
&converted_from_user_script_);
- if (!LoadContentScripts(error) ||
- !LoadSystemIndicator(error) ||
+ if (!LoadSystemIndicator(error) ||
!LoadIncognitoMode(error))
return false;
return true;
}
-bool Extension::LoadContentScripts(string16* error) {
- if (!manifest_->HasKey(keys::kContentScripts))
- return true;
-
- const ListValue* list_value;
- if (!manifest_->GetList(keys::kContentScripts, &list_value)) {
- *error = ASCIIToUTF16(errors::kInvalidContentScriptsList);
- return false;
- }
-
- for (size_t i = 0; i < list_value->GetSize(); ++i) {
- const DictionaryValue* content_script = NULL;
- if (!list_value->GetDictionary(i, &content_script)) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidContentScript, base::IntToString(i));
- return false;
- }
-
- UserScript script;
- if (!LoadUserScriptHelper(content_script, i, error, &script))
- return false; // Failed to parse script context definition.
-
- script.set_extension_id(id());
- if (converted_from_user_script_) {
- script.set_emulate_greasemonkey(true);
- script.set_match_all_frames(true); // Greasemonkey matches all frames.
- }
- content_scripts_.push_back(script);
- }
- return true;
-}
-
bool Extension::LoadSystemIndicator(string16* error) {
if (!manifest_->HasKey(keys::kSystemIndicator)) {
// There was no manifest entry for the system indicator.
@@ -2015,261 +1973,6 @@ bool Extension::LoadIncognitoMode(string16* error) {
return true;
}
-// Helper method that loads a UserScript object from a dictionary in the
-// content_script list of the manifest.
-bool Extension::LoadUserScriptHelper(const DictionaryValue* content_script,
- int definition_index,
- string16* error,
- UserScript* result) {
- // run_at
- if (content_script->HasKey(keys::kRunAt)) {
- std::string run_location;
- if (!content_script->GetString(keys::kRunAt, &run_location)) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidRunAt,
- base::IntToString(definition_index));
- return false;
- }
-
- if (run_location == values::kRunAtDocumentStart) {
- result->set_run_location(UserScript::DOCUMENT_START);
- } else if (run_location == values::kRunAtDocumentEnd) {
- result->set_run_location(UserScript::DOCUMENT_END);
- } else if (run_location == values::kRunAtDocumentIdle) {
- result->set_run_location(UserScript::DOCUMENT_IDLE);
- } else {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidRunAt,
- base::IntToString(definition_index));
- return false;
- }
- }
-
- // all frames
- if (content_script->HasKey(keys::kAllFrames)) {
- bool all_frames = false;
- if (!content_script->GetBoolean(keys::kAllFrames, &all_frames)) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidAllFrames, base::IntToString(definition_index));
- return false;
- }
- result->set_match_all_frames(all_frames);
- }
-
- // matches (required)
- const ListValue* matches = NULL;
- if (!content_script->GetList(keys::kMatches, &matches)) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidMatches,
- base::IntToString(definition_index));
- return false;
- }
-
- if (matches->GetSize() == 0) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidMatchCount,
- base::IntToString(definition_index));
- return false;
- }
- for (size_t j = 0; j < matches->GetSize(); ++j) {
- std::string match_str;
- if (!matches->GetString(j, &match_str)) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidMatch,
- base::IntToString(definition_index),
- base::IntToString(j),
- errors::kExpectString);
- return false;
- }
-
- URLPattern pattern(
- UserScript::ValidUserScriptSchemes(CanExecuteScriptEverywhere()));
-
- URLPattern::ParseResult parse_result = pattern.Parse(match_str);
- if (parse_result != URLPattern::PARSE_SUCCESS) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidMatch,
- base::IntToString(definition_index),
- base::IntToString(j),
- URLPattern::GetParseResultString(parse_result));
- return false;
- }
-
- // TODO(aboxhall): check for webstore
- if (!CanExecuteScriptEverywhere() &&
- pattern.scheme() != chrome::kChromeUIScheme) {
- // Exclude SCHEME_CHROMEUI unless it's been explicitly requested.
- // If the --extensions-on-chrome-urls flag has not been passed, requesting
- // a chrome:// url will cause a parse failure above, so there's no need to
- // check the flag here.
- pattern.SetValidSchemes(
- pattern.valid_schemes() & ~URLPattern::SCHEME_CHROMEUI);
- }
-
- if (pattern.MatchesScheme(chrome::kFileScheme) &&
- !CanExecuteScriptEverywhere()) {
- wants_file_access_ = true;
- if (!(creation_flags_ & ALLOW_FILE_ACCESS)) {
- pattern.SetValidSchemes(
- pattern.valid_schemes() & ~URLPattern::SCHEME_FILE);
- }
- }
-
- result->add_url_pattern(pattern);
- }
-
- // exclude_matches
- if (content_script->HasKey(keys::kExcludeMatches)) { // optional
- const ListValue* exclude_matches = NULL;
- if (!content_script->GetList(keys::kExcludeMatches, &exclude_matches)) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidExcludeMatches,
- base::IntToString(definition_index));
- return false;
- }
-
- for (size_t j = 0; j < exclude_matches->GetSize(); ++j) {
- std::string match_str;
- if (!exclude_matches->GetString(j, &match_str)) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidExcludeMatch,
- base::IntToString(definition_index),
- base::IntToString(j),
- errors::kExpectString);
- return false;
- }
-
- int valid_schemes =
- UserScript::ValidUserScriptSchemes(CanExecuteScriptEverywhere());
- URLPattern pattern(valid_schemes);
- URLPattern::ParseResult parse_result = pattern.Parse(match_str);
- if (parse_result != URLPattern::PARSE_SUCCESS) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidExcludeMatch,
- base::IntToString(definition_index), base::IntToString(j),
- URLPattern::GetParseResultString(parse_result));
- return false;
- }
-
- result->add_exclude_url_pattern(pattern);
- }
- }
-
- // include/exclude globs (mostly for Greasemonkey compatibility)
- if (!LoadGlobsHelper(content_script, definition_index, keys::kIncludeGlobs,
- error, &UserScript::add_glob, result)) {
- return false;
- }
-
- if (!LoadGlobsHelper(content_script, definition_index, keys::kExcludeGlobs,
- error, &UserScript::add_exclude_glob, result)) {
- return false;
- }
-
- // js and css keys
- const ListValue* js = NULL;
- if (content_script->HasKey(keys::kJs) &&
- !content_script->GetList(keys::kJs, &js)) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidJsList,
- base::IntToString(definition_index));
- return false;
- }
-
- const ListValue* css = NULL;
- if (content_script->HasKey(keys::kCss) &&
- !content_script->GetList(keys::kCss, &css)) {
- *error = ErrorUtils::
- FormatErrorMessageUTF16(errors::kInvalidCssList,
- base::IntToString(definition_index));
- return false;
- }
-
- // The manifest needs to have at least one js or css user script definition.
- if (((js ? js->GetSize() : 0) + (css ? css->GetSize() : 0)) == 0) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kMissingFile,
- base::IntToString(definition_index));
- return false;
- }
-
- if (js) {
- for (size_t script_index = 0; script_index < js->GetSize();
- ++script_index) {
- const Value* value;
- std::string relative;
- if (!js->Get(script_index, &value) || !value->GetAsString(&relative)) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidJs,
- base::IntToString(definition_index),
- base::IntToString(script_index));
- return false;
- }
- GURL url = GetResourceURL(relative);
- ExtensionResource resource = GetResource(relative);
- result->js_scripts().push_back(UserScript::File(
- resource.extension_root(), resource.relative_path(), url));
- }
- }
-
- if (css) {
- for (size_t script_index = 0; script_index < css->GetSize();
- ++script_index) {
- const Value* value;
- std::string relative;
- if (!css->Get(script_index, &value) || !value->GetAsString(&relative)) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidCss,
- base::IntToString(definition_index),
- base::IntToString(script_index));
- return false;
- }
- GURL url = GetResourceURL(relative);
- ExtensionResource resource = GetResource(relative);
- result->css_scripts().push_back(UserScript::File(
- resource.extension_root(), resource.relative_path(), url));
- }
- }
-
- return true;
-}
-
-bool Extension::LoadGlobsHelper(
- const DictionaryValue* content_script,
- int content_script_index,
- const char* globs_property_name,
- string16* error,
- void(UserScript::*add_method)(const std::string& glob),
- UserScript* instance) {
- if (!content_script->HasKey(globs_property_name))
- return true; // they are optional
-
- const ListValue* list = NULL;
- if (!content_script->GetList(globs_property_name, &list)) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidGlobList,
- base::IntToString(content_script_index),
- globs_property_name);
- return false;
- }
-
- for (size_t i = 0; i < list->GetSize(); ++i) {
- std::string glob;
- if (!list->GetString(i, &glob)) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidGlob,
- base::IntToString(content_script_index),
- globs_property_name,
- base::IntToString(i));
- return false;
- }
-
- (instance->*add_method)(glob);
- }
-
- return true;
-}
-
bool Extension::HasMultipleUISurfaces() const {
int num_surfaces = 0;
diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h
index 53e3a8f..86f7f96 100644
--- a/chrome/common/extensions/extension.h
+++ b/chrome/common/extensions/extension.h
@@ -386,9 +386,6 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
// settings page (i.e. chrome://extensions).
bool ShouldDisplayInExtensionSettings() const;
- // Returns true if the extension has a content script declared at |url|.
- bool HasContentScriptAtURL(const GURL& url) const;
-
// Gets the tab-specific host permissions of |tab_id|, or NULL if there
// aren't any.
scoped_refptr<const PermissionSet> GetTabSpecificPermissions(int tab_id)
@@ -432,7 +429,6 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
bool converted_from_user_script() const {
return converted_from_user_script_;
}
- const UserScriptList& content_scripts() const { return content_scripts_; }
const ActionInfo* system_indicator_info() const {
return system_indicator_info_.get();
}
@@ -466,6 +462,12 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
bool kiosk_enabled() const { return kiosk_enabled_; }
bool offline_enabled() const { return offline_enabled_; }
bool wants_file_access() const { return wants_file_access_; }
+ // TODO(rdevlin.cronin): This is needed for ContentScriptsHandler, and should
+ // be moved out as part of crbug.com/159265. This should not be used anywhere
+ // else.
+ void set_wants_file_access(bool wants_file_access) {
+ wants_file_access_ = wants_file_access;
+ }
int creation_flags() const { return creation_flags_; }
bool from_webstore() const { return (creation_flags_ & FROM_WEBSTORE) != 0; }
bool from_bookmark() const { return (creation_flags_ & FROM_BOOKMARK) != 0; }
@@ -578,7 +580,6 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
bool LoadKioskEnabled(string16* error);
bool LoadOfflineEnabled(string16* error);
bool LoadExtensionFeatures(string16* error);
- bool LoadContentScripts(string16* error);
bool LoadBrowserAction(string16* error);
bool LoadSystemIndicator(string16* error);
bool LoadTextToSpeechVoices(string16* error);
@@ -591,22 +592,6 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
const base::DictionaryValue* content_pack_value,
string16* error);
- // Helper method that loads a UserScript object from a
- // dictionary in the content_script list of the manifest.
- bool LoadUserScriptHelper(const base::DictionaryValue* content_script,
- int definition_index,
- string16* error,
- UserScript* result);
-
- // Helper method that loads either the include_globs or exclude_globs list
- // from an entry in the content_script lists of the manifest.
- bool LoadGlobsHelper(const base::DictionaryValue* content_script,
- int content_script_index,
- const char* globs_property_name,
- string16* error,
- void(UserScript::*add_method)(const std::string& glob),
- UserScript* instance);
-
// Returns true if the extension has more than one "UI surface". For example,
// an extension that has a browser action and a page action.
bool HasMultipleUISurfaces() const;
@@ -699,9 +684,6 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
// different UI if so).
bool converted_from_user_script_;
- // Paths to the content scripts the extension contains.
- UserScriptList content_scripts_;
-
// The extension's system indicator, if any.
scoped_ptr<ActionInfo> system_indicator_info_;
diff --git a/chrome/common/extensions/extension_file_util.cc b/chrome/common/extensions/extension_file_util.cc
index 1ed7356..4c2fbb0 100644
--- a/chrome/common/extensions/extension_file_util.cc
+++ b/chrome/common/extensions/extension_file_util.cc
@@ -49,12 +49,6 @@ const base::FilePath::CharType kTempDirectoryName[] = FILE_PATH_LITERAL("Temp");
namespace extension_file_util {
-// Returns false and sets the error if script file can't be loaded,
-// or if it's not UTF-8 encoded.
-static bool IsScriptValid(const base::FilePath& path,
- const base::FilePath& relative_path,
- int message_id, std::string* error);
-
base::FilePath InstallExtension(const base::FilePath& unpacked_source_dir,
const std::string& id,
const std::string& version,
@@ -254,41 +248,6 @@ bool ValidateExtension(const Extension* extension,
extension, error, warnings))
return false;
- // TODO(yoz): Move this to content scripts manifest handler.
- // Validate that claimed script resources actually exist,
- // and are UTF-8 encoded.
- ExtensionResource::SymlinkPolicy symlink_policy;
- if ((extension->creation_flags() &
- Extension::FOLLOW_SYMLINKS_ANYWHERE) != 0) {
- symlink_policy = ExtensionResource::FOLLOW_SYMLINKS_ANYWHERE;
- } else {
- symlink_policy = ExtensionResource::SYMLINKS_MUST_RESOLVE_WITHIN_ROOT;
- }
-
- for (size_t i = 0; i < extension->content_scripts().size(); ++i) {
- const extensions::UserScript& script = extension->content_scripts()[i];
-
- for (size_t j = 0; j < script.js_scripts().size(); j++) {
- const extensions::UserScript::File& js_script = script.js_scripts()[j];
- const base::FilePath& path = ExtensionResource::GetFilePath(
- js_script.extension_root(), js_script.relative_path(),
- symlink_policy);
- if (!IsScriptValid(path, js_script.relative_path(),
- IDS_EXTENSION_LOAD_JAVASCRIPT_FAILED, error))
- return false;
- }
-
- for (size_t j = 0; j < script.css_scripts().size(); j++) {
- const extensions::UserScript::File& css_script = script.css_scripts()[j];
- const base::FilePath& path = ExtensionResource::GetFilePath(
- css_script.extension_root(), css_script.relative_path(),
- symlink_policy);
- if (!IsScriptValid(path, css_script.relative_path(),
- IDS_EXTENSION_LOAD_CSS_FAILED, error))
- return false;
- }
- }
-
// Check children of extension root to see if any of them start with _ and is
// not on the reserved list.
if (!CheckForIllegalFilenames(extension->path(), error)) {
@@ -452,29 +411,6 @@ SubstitutionMap* LoadMessageBundleSubstitutionMap(
return returnValue;
}
-static bool IsScriptValid(const base::FilePath& path,
- const base::FilePath& relative_path,
- int message_id,
- std::string* error) {
- std::string content;
- if (!file_util::PathExists(path) ||
- !file_util::ReadFileToString(path, &content)) {
- *error = l10n_util::GetStringFUTF8(
- message_id,
- relative_path.LossyDisplayName());
- return false;
- }
-
- if (!IsStringUTF8(content)) {
- *error = l10n_util::GetStringFUTF8(
- IDS_EXTENSION_BAD_FILE_ENCODING,
- relative_path.LossyDisplayName());
- return false;
- }
-
- return true;
-}
-
bool CheckForIllegalFilenames(const base::FilePath& extension_path,
std::string* error) {
// Reserved underscore names.
diff --git a/chrome/common/extensions/extension_file_util_unittest.cc b/chrome/common/extensions/extension_file_util_unittest.cc
index db0e38b..cb9260f 100644
--- a/chrome/common/extensions/extension_file_util_unittest.cc
+++ b/chrome/common/extensions/extension_file_util_unittest.cc
@@ -20,6 +20,7 @@
#include "chrome/common/extensions/extension_manifest_constants.h"
#include "chrome/common/extensions/manifest.h"
#include "chrome/common/extensions/manifest_handler.h"
+#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "extensions/common/constants.h"
#include "grit/generated_resources.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -40,6 +41,7 @@ class ExtensionFileUtilTest : public testing::Test {
(new extensions::DefaultLocaleHandler)->Register();
(new extensions::IconsHandler)->Register();
(new extensions::PageActionHandler)->Register();
+ (new extensions::ContentScriptsHandler)->Register();
}
virtual void TearDown() OVERRIDE {
diff --git a/chrome/common/extensions/extension_unittest.cc b/chrome/common/extensions/extension_unittest.cc
index 8f01536..696de8b 100644
--- a/chrome/common/extensions/extension_unittest.cc
+++ b/chrome/common/extensions/extension_unittest.cc
@@ -24,6 +24,7 @@
#include "chrome/common/extensions/features/feature.h"
#include "chrome/common/extensions/manifest.h"
#include "chrome/common/extensions/manifest_handler.h"
+#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "chrome/common/extensions/permissions/api_permission.h"
#include "chrome/common/extensions/permissions/permission_set.h"
#include "chrome/common/extensions/permissions/socket_permission.h"
@@ -109,6 +110,7 @@ class ExtensionTest : public testing::Test {
testing::Test::SetUp();
(new BackgroundManifestHandler)->Register();
(new CommandsHandler)->Register();
+ (new ContentScriptsHandler)->Register();
(new PluginsHandler)->Register();
}
@@ -479,34 +481,58 @@ TEST_F(ExtensionTest, WantsFileAccess) {
extension = LoadManifest("permissions", "content_script_all_urls.json");
EXPECT_TRUE(extension->wants_file_access());
EXPECT_FALSE(extension->CanExecuteScriptOnPage(
- file_url, file_url, -1, &extension->content_scripts()[0], NULL));
+ file_url,
+ file_url,
+ -1,
+ &ContentScriptsInfo::GetContentScripts(extension)[0],
+ NULL));
extension = LoadManifest("permissions", "content_script_all_urls.json",
Extension::ALLOW_FILE_ACCESS);
EXPECT_TRUE(extension->wants_file_access());
EXPECT_TRUE(extension->CanExecuteScriptOnPage(
- file_url, file_url, -1, &extension->content_scripts()[0], NULL));
+ file_url,
+ file_url,
+ -1,
+ &ContentScriptsInfo::GetContentScripts(extension)[0],
+ NULL));
// file:///* content script match
extension = LoadManifest("permissions", "content_script_file_scheme.json");
EXPECT_TRUE(extension->wants_file_access());
EXPECT_FALSE(extension->CanExecuteScriptOnPage(
- file_url, file_url, -1, &extension->content_scripts()[0], NULL));
+ file_url,
+ file_url,
+ -1,
+ &ContentScriptsInfo::GetContentScripts(extension)[0],
+ NULL));
extension = LoadManifest("permissions", "content_script_file_scheme.json",
Extension::ALLOW_FILE_ACCESS);
EXPECT_TRUE(extension->wants_file_access());
EXPECT_TRUE(extension->CanExecuteScriptOnPage(
- file_url, file_url, -1, &extension->content_scripts()[0], NULL));
+ file_url,
+ file_url,
+ -1,
+ &ContentScriptsInfo::GetContentScripts(extension)[0],
+ NULL));
// http://* content script match
extension = LoadManifest("permissions", "content_script_http_scheme.json");
EXPECT_FALSE(extension->wants_file_access());
EXPECT_FALSE(extension->CanExecuteScriptOnPage(
- file_url, file_url, -1, &extension->content_scripts()[0], NULL));
+ file_url,
+ file_url,
+ -1,
+ &ContentScriptsInfo::GetContentScripts(extension)[0],
+ NULL));
extension = LoadManifest("permissions", "content_script_http_scheme.json",
Extension::ALLOW_FILE_ACCESS);
EXPECT_FALSE(extension->wants_file_access());
EXPECT_FALSE(extension->CanExecuteScriptOnPage(
- file_url, file_url, -1, &extension->content_scripts()[0], NULL));
+ file_url,
+ file_url,
+ -1,
+ &ContentScriptsInfo::GetContentScripts(extension)[0],
+ NULL));
}
TEST_F(ExtensionTest, ExtraFlags) {
diff --git a/chrome/common/extensions/manifest_handlers/content_scripts_handler.cc b/chrome/common/extensions/manifest_handlers/content_scripts_handler.cc
new file mode 100644
index 0000000..a2edb9a
--- /dev/null
+++ b/chrome/common/extensions/manifest_handlers/content_scripts_handler.cc
@@ -0,0 +1,446 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
+
+#include "base/file_util.h"
+#include "base/lazy_instance.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/string_number_conversions.h"
+#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_manifest_constants.h"
+#include "content/public/common/url_constants.h"
+#include "extensions/common/error_utils.h"
+#include "extensions/common/extension_resource.h"
+#include "extensions/common/url_pattern.h"
+#include "googleurl/src/gurl.h"
+#include "grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace extensions {
+
+namespace keys = extension_manifest_keys;
+namespace values = extension_manifest_values;
+namespace errors = extension_manifest_errors;
+
+namespace {
+
+// Helper method that loads either the include_globs or exclude_globs list
+// from an entry in the content_script lists of the manifest.
+bool LoadGlobsHelper(const DictionaryValue* content_script,
+ int content_script_index,
+ const char* globs_property_name,
+ string16* error,
+ void(UserScript::*add_method)(const std::string& glob),
+ UserScript* instance) {
+ if (!content_script->HasKey(globs_property_name))
+ return true; // they are optional
+
+ const ListValue* list = NULL;
+ if (!content_script->GetList(globs_property_name, &list)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidGlobList,
+ base::IntToString(content_script_index),
+ globs_property_name);
+ return false;
+ }
+
+ for (size_t i = 0; i < list->GetSize(); ++i) {
+ std::string glob;
+ if (!list->GetString(i, &glob)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidGlob,
+ base::IntToString(content_script_index),
+ globs_property_name,
+ base::IntToString(i));
+ return false;
+ }
+
+ (instance->*add_method)(glob);
+ }
+
+ return true;
+}
+
+// Helper method that loads a UserScript object from a dictionary in the
+// content_script list of the manifest.
+bool LoadUserScriptFromDictionary(const DictionaryValue* content_script,
+ int definition_index,
+ Extension* extension,
+ string16* error,
+ UserScript* result) {
+ // run_at
+ if (content_script->HasKey(keys::kRunAt)) {
+ std::string run_location;
+ if (!content_script->GetString(keys::kRunAt, &run_location)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidRunAt,
+ base::IntToString(definition_index));
+ return false;
+ }
+
+ if (run_location == values::kRunAtDocumentStart) {
+ result->set_run_location(UserScript::DOCUMENT_START);
+ } else if (run_location == values::kRunAtDocumentEnd) {
+ result->set_run_location(UserScript::DOCUMENT_END);
+ } else if (run_location == values::kRunAtDocumentIdle) {
+ result->set_run_location(UserScript::DOCUMENT_IDLE);
+ } else {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidRunAt,
+ base::IntToString(definition_index));
+ return false;
+ }
+ }
+
+ // all frames
+ if (content_script->HasKey(keys::kAllFrames)) {
+ bool all_frames = false;
+ if (!content_script->GetBoolean(keys::kAllFrames, &all_frames)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidAllFrames, base::IntToString(definition_index));
+ return false;
+ }
+ result->set_match_all_frames(all_frames);
+ }
+
+ // matches (required)
+ const ListValue* matches = NULL;
+ if (!content_script->GetList(keys::kMatches, &matches)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidMatches,
+ base::IntToString(definition_index));
+ return false;
+ }
+
+ if (matches->GetSize() == 0) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidMatchCount,
+ base::IntToString(definition_index));
+ return false;
+ }
+ for (size_t j = 0; j < matches->GetSize(); ++j) {
+ std::string match_str;
+ if (!matches->GetString(j, &match_str)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidMatch,
+ base::IntToString(definition_index),
+ base::IntToString(j),
+ errors::kExpectString);
+ return false;
+ }
+
+ URLPattern pattern(UserScript::ValidUserScriptSchemes(
+ extension->CanExecuteScriptEverywhere()));
+
+ URLPattern::ParseResult parse_result = pattern.Parse(match_str);
+ if (parse_result != URLPattern::PARSE_SUCCESS) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidMatch,
+ base::IntToString(definition_index),
+ base::IntToString(j),
+ URLPattern::GetParseResultString(parse_result));
+ return false;
+ }
+
+ // TODO(aboxhall): check for webstore
+ if (!extension->CanExecuteScriptEverywhere() &&
+ pattern.scheme() != chrome::kChromeUIScheme) {
+ // Exclude SCHEME_CHROMEUI unless it's been explicitly requested.
+ // If the --extensions-on-chrome-urls flag has not been passed, requesting
+ // a chrome:// url will cause a parse failure above, so there's no need to
+ // check the flag here.
+ pattern.SetValidSchemes(
+ pattern.valid_schemes() & ~URLPattern::SCHEME_CHROMEUI);
+ }
+
+ if (pattern.MatchesScheme(chrome::kFileScheme) &&
+ !extension->CanExecuteScriptEverywhere()) {
+ extension->set_wants_file_access(true);
+ if (!(extension->creation_flags() & Extension::ALLOW_FILE_ACCESS)) {
+ pattern.SetValidSchemes(
+ pattern.valid_schemes() & ~URLPattern::SCHEME_FILE);
+ }
+ }
+
+ result->add_url_pattern(pattern);
+ }
+
+ // exclude_matches
+ if (content_script->HasKey(keys::kExcludeMatches)) { // optional
+ const ListValue* exclude_matches = NULL;
+ if (!content_script->GetList(keys::kExcludeMatches, &exclude_matches)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidExcludeMatches,
+ base::IntToString(definition_index));
+ return false;
+ }
+
+ for (size_t j = 0; j < exclude_matches->GetSize(); ++j) {
+ std::string match_str;
+ if (!exclude_matches->GetString(j, &match_str)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidExcludeMatch,
+ base::IntToString(definition_index),
+ base::IntToString(j),
+ errors::kExpectString);
+ return false;
+ }
+
+ int valid_schemes = UserScript::ValidUserScriptSchemes(
+ extension->CanExecuteScriptEverywhere());
+ URLPattern pattern(valid_schemes);
+
+ URLPattern::ParseResult parse_result = pattern.Parse(match_str);
+ if (parse_result != URLPattern::PARSE_SUCCESS) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidExcludeMatch,
+ base::IntToString(definition_index), base::IntToString(j),
+ URLPattern::GetParseResultString(parse_result));
+ return false;
+ }
+
+ result->add_exclude_url_pattern(pattern);
+ }
+ }
+
+ // include/exclude globs (mostly for Greasemonkey compatibility)
+ if (!LoadGlobsHelper(content_script, definition_index, keys::kIncludeGlobs,
+ error, &UserScript::add_glob, result)) {
+ return false;
+ }
+
+ if (!LoadGlobsHelper(content_script, definition_index, keys::kExcludeGlobs,
+ error, &UserScript::add_exclude_glob, result)) {
+ return false;
+ }
+
+ // js and css keys
+ const ListValue* js = NULL;
+ if (content_script->HasKey(keys::kJs) &&
+ !content_script->GetList(keys::kJs, &js)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidJsList,
+ base::IntToString(definition_index));
+ return false;
+ }
+
+ const ListValue* css = NULL;
+ if (content_script->HasKey(keys::kCss) &&
+ !content_script->GetList(keys::kCss, &css)) {
+ *error = ErrorUtils::
+ FormatErrorMessageUTF16(errors::kInvalidCssList,
+ base::IntToString(definition_index));
+ return false;
+ }
+
+ // The manifest needs to have at least one js or css user script definition.
+ if (((js ? js->GetSize() : 0) + (css ? css->GetSize() : 0)) == 0) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kMissingFile,
+ base::IntToString(definition_index));
+ return false;
+ }
+
+ if (js) {
+ for (size_t script_index = 0; script_index < js->GetSize();
+ ++script_index) {
+ const Value* value;
+ std::string relative;
+ if (!js->Get(script_index, &value) || !value->GetAsString(&relative)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidJs,
+ base::IntToString(definition_index),
+ base::IntToString(script_index));
+ return false;
+ }
+ GURL url = extension->GetResourceURL(relative);
+ ExtensionResource resource = extension->GetResource(relative);
+ result->js_scripts().push_back(UserScript::File(
+ resource.extension_root(), resource.relative_path(), url));
+ }
+ }
+
+ if (css) {
+ for (size_t script_index = 0; script_index < css->GetSize();
+ ++script_index) {
+ const Value* value;
+ std::string relative;
+ if (!css->Get(script_index, &value) || !value->GetAsString(&relative)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidCss,
+ base::IntToString(definition_index),
+ base::IntToString(script_index));
+ return false;
+ }
+ GURL url = extension->GetResourceURL(relative);
+ ExtensionResource resource = extension->GetResource(relative);
+ result->css_scripts().push_back(UserScript::File(
+ resource.extension_root(), resource.relative_path(), url));
+ }
+ }
+
+ return true;
+}
+
+// Returns false and sets the error if script file can't be loaded,
+// or if it's not UTF-8 encoded.
+static bool IsScriptValid(const base::FilePath& path,
+ const base::FilePath& relative_path,
+ int message_id,
+ std::string* error) {
+ std::string content;
+ if (!file_util::PathExists(path) ||
+ !file_util::ReadFileToString(path, &content)) {
+ *error = l10n_util::GetStringFUTF8(
+ message_id,
+ relative_path.LossyDisplayName());
+ return false;
+ }
+
+ if (!IsStringUTF8(content)) {
+ *error = l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_BAD_FILE_ENCODING,
+ relative_path.LossyDisplayName());
+ return false;
+ }
+
+ return true;
+}
+
+struct EmptyUserScriptList {
+ UserScriptList user_script_list;
+};
+
+static base::LazyInstance<EmptyUserScriptList> g_empty_script_list =
+ LAZY_INSTANCE_INITIALIZER;
+
+} // namespace
+
+ContentScriptsInfo::ContentScriptsInfo() {
+}
+
+ContentScriptsInfo::~ContentScriptsInfo() {
+}
+
+// static
+const UserScriptList& ContentScriptsInfo::GetContentScripts(
+ const Extension* extension) {
+ ContentScriptsInfo* info = static_cast<ContentScriptsInfo*>(
+ extension->GetManifestData(keys::kContentScripts));
+ return info ? info->content_scripts
+ : g_empty_script_list.Get().user_script_list;
+}
+
+// static
+bool ContentScriptsInfo::ExtensionHasScriptAtURL(const Extension* extension,
+ const GURL& url) {
+ const UserScriptList& content_scripts = GetContentScripts(extension);
+ for (UserScriptList::const_iterator iter = content_scripts.begin();
+ iter != content_scripts.end(); ++iter) {
+ if (iter->MatchesURL(url))
+ return true;
+ }
+ return false;
+}
+
+ContentScriptsHandler::ContentScriptsHandler() {
+}
+
+ContentScriptsHandler::~ContentScriptsHandler() {
+}
+
+const std::vector<std::string> ContentScriptsHandler::Keys() const {
+ static const char* keys[] = {
+ keys::kContentScripts
+ };
+ return std::vector<std::string>(keys, keys + arraysize(keys));
+}
+
+bool ContentScriptsHandler::Parse(Extension* extension, string16* error) {
+ scoped_ptr<ContentScriptsInfo> content_scripts_info(new ContentScriptsInfo);
+ const ListValue* scripts_list = NULL;
+ if (!extension->manifest()->GetList(keys::kContentScripts, &scripts_list)) {
+ *error = ASCIIToUTF16(errors::kInvalidContentScriptsList);
+ return false;
+ }
+
+ for (size_t i = 0; i < scripts_list->GetSize(); ++i) {
+ const DictionaryValue* script_dict = NULL;
+ if (!scripts_list->GetDictionary(i, &script_dict)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidContentScript,
+ base::IntToString(i));
+ return false;
+ }
+
+ UserScript user_script;
+ if (!LoadUserScriptFromDictionary(script_dict,
+ i,
+ extension,
+ error,
+ &user_script)) {
+ return false; // Failed to parse script context definition.
+ }
+
+ user_script.set_extension_id(extension->id());
+ if (extension->converted_from_user_script()) {
+ user_script.set_emulate_greasemonkey(true);
+ // Greasemonkey matches all frames.
+ user_script.set_match_all_frames(true);
+ }
+ content_scripts_info->content_scripts.push_back(user_script);
+ }
+ extension->SetManifestData(keys::kContentScripts,
+ content_scripts_info.release());
+ return true;
+}
+
+bool ContentScriptsHandler::Validate(
+ const Extension* extension,
+ std::string* error,
+ std::vector<InstallWarning>* warnings) const {
+ // Validate that claimed script resources actually exist,
+ // and are UTF-8 encoded.
+ ExtensionResource::SymlinkPolicy symlink_policy;
+ if ((extension->creation_flags() &
+ Extension::FOLLOW_SYMLINKS_ANYWHERE) != 0) {
+ symlink_policy = ExtensionResource::FOLLOW_SYMLINKS_ANYWHERE;
+ } else {
+ symlink_policy = ExtensionResource::SYMLINKS_MUST_RESOLVE_WITHIN_ROOT;
+ }
+
+ const extensions::UserScriptList& content_scripts =
+ extensions::ContentScriptsInfo::GetContentScripts(extension);
+ for (size_t i = 0; i < content_scripts.size(); ++i) {
+ const extensions::UserScript& script = content_scripts[i];
+
+ for (size_t j = 0; j < script.js_scripts().size(); j++) {
+ const extensions::UserScript::File& js_script = script.js_scripts()[j];
+ const base::FilePath& path = ExtensionResource::GetFilePath(
+ js_script.extension_root(), js_script.relative_path(),
+ symlink_policy);
+ if (!IsScriptValid(path, js_script.relative_path(),
+ IDS_EXTENSION_LOAD_JAVASCRIPT_FAILED, error))
+ return false;
+ }
+
+ for (size_t j = 0; j < script.css_scripts().size(); j++) {
+ const extensions::UserScript::File& css_script = script.css_scripts()[j];
+ const base::FilePath& path = ExtensionResource::GetFilePath(
+ css_script.extension_root(), css_script.relative_path(),
+ symlink_policy);
+ if (!IsScriptValid(path, css_script.relative_path(),
+ IDS_EXTENSION_LOAD_CSS_FAILED, error))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+} // namespace extensions
diff --git a/chrome/common/extensions/manifest_handlers/content_scripts_handler.h b/chrome/common/extensions/manifest_handlers/content_scripts_handler.h
new file mode 100644
index 0000000..c3b8d06
--- /dev/null
+++ b/chrome/common/extensions/manifest_handlers/content_scripts_handler.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_CONTENT_SCRIPTS_HANDLER_H_
+#define CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_CONTENT_SCRIPTS_HANDLER_H_
+
+#include <string>
+
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/manifest_handler.h"
+#include "chrome/common/extensions/user_script.h"
+
+namespace extensions {
+
+struct ContentScriptsInfo : public Extension::ManifestData {
+ ContentScriptsInfo();
+ virtual ~ContentScriptsInfo();
+
+ // Paths to the content scripts the extension contains (possibly empty).
+ UserScriptList content_scripts;
+
+ // Returns the content scripts for the extension (if the extension has
+ // no content scripts, this returns an empty list).
+ static const UserScriptList& GetContentScripts(const Extension* extension);
+
+ // Returns true if the extension has a content script declared at |url|.
+ static bool ExtensionHasScriptAtURL(const Extension* extension,
+ const GURL& url);
+};
+
+// Parses the "content_scripts" manifest key.
+class ContentScriptsHandler : public ManifestHandler {
+ public:
+ ContentScriptsHandler();
+ virtual ~ContentScriptsHandler();
+
+ virtual bool Parse(Extension* extension, string16* error) OVERRIDE;
+ virtual bool Validate(const Extension* extension,
+ std::string* error,
+ std::vector<InstallWarning>* warnings) const OVERRIDE;
+
+ private:
+ virtual const std::vector<std::string> Keys() const OVERRIDE;
+
+ DISALLOW_COPY_AND_ASSIGN(ContentScriptsHandler);
+};
+
+} // namespace extensions
+
+#endif // CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_CONTENT_SCRIPTS_HANDLER_H_
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_contentscript_unittest.cc b/chrome/common/extensions/manifest_handlers/content_scripts_manifest_unittest.cc
index 8470893..679357c0 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_contentscript_unittest.cc
+++ b/chrome/common/extensions/manifest_handlers/content_scripts_manifest_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,17 +7,28 @@
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_manifest_constants.h"
+#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "chrome/common/extensions/manifest_tests/extension_manifest_test.h"
#include "extensions/common/error_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace errors = extension_manifest_errors;
-TEST_F(ExtensionManifestTest, ContentScriptMatchPattern) {
+namespace extensions {
+
+class ContentScriptsManifestTest : public ExtensionManifestTest {
+ protected:
+ virtual void SetUp() OVERRIDE {
+ ExtensionManifestTest::SetUp();
+ (new ContentScriptsHandler)->Register();
+ }
+};
+
+TEST_F(ContentScriptsManifestTest, ContentScriptMatchPattern) {
Testcase testcases[] = {
// chrome:// urls are not allowed.
Testcase("content_script_chrome_url_invalid.json",
- extensions::ErrorUtils::FormatErrorMessage(
+ ErrorUtils::FormatErrorMessage(
errors::kInvalidMatch,
base::IntToString(0),
base::IntToString(0),
@@ -26,10 +37,10 @@ TEST_F(ExtensionManifestTest, ContentScriptMatchPattern) {
// Match paterns must be strings.
Testcase("content_script_match_pattern_not_string.json",
- extensions::ErrorUtils::FormatErrorMessage(errors::kInvalidMatch,
- base::IntToString(0),
- base::IntToString(0),
- errors::kExpectString))
+ ErrorUtils::FormatErrorMessage(errors::kInvalidMatch,
+ base::IntToString(0),
+ base::IntToString(0),
+ errors::kExpectString))
};
RunTestcases(testcases, arraysize(testcases),
EXPECT_TYPE_ERROR);
@@ -37,7 +48,7 @@ TEST_F(ExtensionManifestTest, ContentScriptMatchPattern) {
LoadAndExpectSuccess("ports_in_content_scripts.json");
}
-TEST_F(ExtensionManifestTest, ContentScriptsOnChromeUrlsWithFlag) {
+TEST_F(ContentScriptsManifestTest, ContentScriptsOnChromeUrlsWithFlag) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kExtensionsOnChromeURLs);
std::string error;
@@ -45,5 +56,8 @@ TEST_F(ExtensionManifestTest, ContentScriptsOnChromeUrlsWithFlag) {
LoadAndExpectSuccess("content_script_chrome_url_invalid.json");
EXPECT_EQ("", error);
const GURL newtab_url("chrome://newtab/");
- EXPECT_TRUE(extension->HasContentScriptAtURL(newtab_url));
+ EXPECT_TRUE(ContentScriptsInfo::ExtensionHasScriptAtURL(extension,
+ newtab_url));
}
+
+} // namespace extensions
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_excludematches_unittest.cc b/chrome/common/extensions/manifest_handlers/exclude_matches_manifest_unittest.cc
index 0f01638..37a4ae5 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_excludematches_unittest.cc
+++ b/chrome/common/extensions/manifest_handlers/exclude_matches_manifest_unittest.cc
@@ -1,13 +1,24 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/common/extensions/manifest_tests/extension_manifest_test.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
+#include "chrome/common/extensions/manifest_tests/extension_manifest_test.h"
#include "testing/gtest/include/gtest/gtest.h"
-TEST_F(ExtensionManifestTest, ExcludeMatchPatterns) {
+namespace extensions {
+
+class ExcludeMatchesManifestTest : public ExtensionManifestTest {
+ protected:
+ virtual void SetUp() OVERRIDE {
+ ExtensionManifestTest::SetUp();
+ (new ContentScriptsHandler)->Register();
+ }
+};
+
+TEST_F(ExcludeMatchesManifestTest, ExcludeMatchPatterns) {
Testcase testcases[] = {
Testcase("exclude_matches.json"),
Testcase("exclude_matches_empty.json")
@@ -25,3 +36,5 @@ TEST_F(ExtensionManifestTest, ExcludeMatchPatterns) {
RunTestcases(testcases2, arraysize(testcases2),
EXPECT_TYPE_ERROR);
}
+
+} // namespace extensions
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_initvalue_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_initvalue_unittest.cc
index 9dc40e4..580e52e 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_initvalue_unittest.cc
+++ b/chrome/common/extensions/manifest_tests/extension_manifests_initvalue_unittest.cc
@@ -12,6 +12,7 @@
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_manifest_constants.h"
#include "chrome/common/extensions/manifest_handler.h"
+#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "chrome/common/extensions/manifest_tests/extension_manifest_test.h"
#include "chrome/common/extensions/manifest_url_handler.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -34,6 +35,7 @@ class InitValueManifestTest : public ExtensionManifestTest {
(new extensions::IconsHandler)->Register();
(new extensions::OptionsPageHandler)->Register();
(new extensions::PageActionHandler)->Register();
+ (new extensions::ContentScriptsHandler)->Register();
}
};
diff --git a/chrome/common/extensions/permissions/permission_set.cc b/chrome/common/extensions/permissions/permission_set.cc
index 380f72a..704255b 100644
--- a/chrome/common/extensions/permissions/permission_set.cc
+++ b/chrome/common/extensions/permissions/permission_set.cc
@@ -10,6 +10,7 @@
#include "chrome/common/extensions/api/plugins/plugins_handler.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "chrome/common/extensions/manifest_url_handler.h"
#include "chrome/common/extensions/permissions/permissions_info.h"
#include "content/public/common/url_constants.h"
@@ -535,8 +536,9 @@ void PermissionSet::InitImplicitExtensionPermissions(
// Add the scriptable hosts.
for (extensions::UserScriptList::const_iterator content_script =
- extension->content_scripts().begin();
- content_script != extension->content_scripts().end(); ++content_script) {
+ ContentScriptsInfo::GetContentScripts(extension).begin();
+ content_script != ContentScriptsInfo::GetContentScripts(extension).end();
+ ++content_script) {
URLPatternSet::const_iterator pattern =
content_script->url_patterns().begin();
for (; pattern != content_script->url_patterns().end(); ++pattern)
diff --git a/chrome/common/extensions/permissions/permission_set_unittest.cc b/chrome/common/extensions/permissions/permission_set_unittest.cc
index 478aa5e..c569f49 100644
--- a/chrome/common/extensions/permissions/permission_set_unittest.cc
+++ b/chrome/common/extensions/permissions/permission_set_unittest.cc
@@ -14,6 +14,7 @@
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/features/feature.h"
#include "chrome/common/extensions/manifest_handler.h"
+#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "chrome/common/extensions/permissions/permission_set.h"
#include "chrome/common/extensions/permissions/permissions_info.h"
#include "chrome/common/extensions/permissions/socket_permission.h"
@@ -77,11 +78,12 @@ bool Contains(const std::vector<string16>& warnings,
} // namespace
-
class PermissionsTest : public testing::Test {
+ protected:
virtual void SetUp() OVERRIDE {
testing::Test::SetUp();
(new BackgroundManifestHandler)->Register();
+ (new ContentScriptsHandler)->Register();
(new PluginsHandler)->Register();
}