summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-19 07:05:43 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-19 07:05:43 +0000
commit2c17977c344d3a6b3501370a8e30c83f0b93af03 (patch)
tree789d57a1e231ac1c088e07421e3d90512de9ed83
parent0bf4dc62111e3329375eb5a87c4276c2f012ee27 (diff)
downloadchromium_src-2c17977c344d3a6b3501370a8e30c83f0b93af03.zip
chromium_src-2c17977c344d3a6b3501370a8e30c83f0b93af03.tar.gz
chromium_src-2c17977c344d3a6b3501370a8e30c83f0b93af03.tar.bz2
Fix exclude_matches functionality
This should allow the manifest to use the exclude_matches field in content scripts successfully. BUG=107505 TEST=See bug. A simple extension to test the exclude matches functionality, compliments of mihaip@chromium.org, is attached. Review URL: http://codereview.chromium.org/8963010 Patch from Devlin Cronin <RDevlin.Cronin@gmail.com>. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@114960 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/extensions/convert_user_script.cc11
-rw-r--r--chrome/browser/extensions/convert_user_script_unittest.cc3
-rw-r--r--chrome/browser/extensions/user_script_master.cc6
-rw-r--r--chrome/browser/extensions/user_script_master_unittest.cc20
-rw-r--r--chrome/common/extensions/user_script.cc102
-rw-r--r--chrome/common/extensions/user_script.h15
-rw-r--r--chrome/common/extensions/user_script_unittest.cc7
-rw-r--r--chrome/test/data/extensions/user_script_basic.user.js1
8 files changed, 112 insertions, 53 deletions
diff --git a/chrome/browser/extensions/convert_user_script.cc b/chrome/browser/extensions/convert_user_script.cc
index dea6035..57e09c5 100644
--- a/chrome/browser/extensions/convert_user_script.cc
+++ b/chrome/browser/extensions/convert_user_script.cc
@@ -114,6 +114,16 @@ scoped_refptr<Extension> ConvertUserScriptToExtension(
matches->Append(Value::CreateStringValue("https://*/*"));
}
+ // Read the exclude matches, if any are present.
+ ListValue* exclude_matches = new ListValue();
+ if (!script.exclude_url_patterns().is_empty()) {
+ for (URLPatternSet::const_iterator i =
+ script.exclude_url_patterns().begin();
+ i != script.exclude_url_patterns().end(); ++i) {
+ exclude_matches->Append(Value::CreateStringValue(i->GetAsString()));
+ }
+ }
+
ListValue* includes = new ListValue();
for (size_t i = 0; i < script.globs().size(); ++i)
includes->Append(Value::CreateStringValue(script.globs().at(i)));
@@ -124,6 +134,7 @@ scoped_refptr<Extension> ConvertUserScriptToExtension(
DictionaryValue* content_script = new DictionaryValue();
content_script->Set(keys::kMatches, matches);
+ content_script->Set(keys::kExcludeMatches, exclude_matches);
content_script->Set(keys::kIncludeGlobs, includes);
content_script->Set(keys::kExcludeGlobs, excludes);
content_script->Set(keys::kJs, js_files);
diff --git a/chrome/browser/extensions/convert_user_script_unittest.cc b/chrome/browser/extensions/convert_user_script_unittest.cc
index a11056e..f44a547 100644
--- a/chrome/browser/extensions/convert_user_script_unittest.cc
+++ b/chrome/browser/extensions/convert_user_script_unittest.cc
@@ -60,6 +60,9 @@ TEST(ExtensionFromUserScript, Basic) {
ASSERT_EQ(1u, script.url_patterns().patterns().size());
EXPECT_EQ("http://www.google.com/*",
script.url_patterns().begin()->GetAsString());
+ ASSERT_EQ(1u, script.exclude_url_patterns().patterns().size());
+ EXPECT_EQ("http://www.google.com/foo*",
+ script.exclude_url_patterns().begin()->GetAsString());
// Make sure the files actually exist on disk.
EXPECT_TRUE(file_util::PathExists(
diff --git a/chrome/browser/extensions/user_script_master.cc b/chrome/browser/extensions/user_script_master.cc
index 2a11f42..77b4d35 100644
--- a/chrome/browser/extensions/user_script_master.cc
+++ b/chrome/browser/extensions/user_script_master.cc
@@ -70,6 +70,7 @@ bool UserScriptMaster::ScriptReloader::ParseMetadataHeader(
static const base::StringPiece kIncludeDeclaration("// @include");
static const base::StringPiece kExcludeDeclaration("// @exclude");
static const base::StringPiece kMatchDeclaration("// @match");
+ static const base::StringPiece kExcludeMatchDeclaration("// @exclude_match");
static const base::StringPiece kRunAtDeclaration("// @run-at");
static const base::StringPiece kRunAtDocumentStartValue("document-start");
static const base::StringPiece kRunAtDocumentEndValue("document-end");
@@ -116,6 +117,11 @@ bool UserScriptMaster::ScriptReloader::ParseMetadataHeader(
if (URLPattern::PARSE_SUCCESS != pattern.Parse(value))
return false;
script->add_url_pattern(pattern);
+ } else if (GetDeclarationValue(line, kExcludeMatchDeclaration, &value)) {
+ URLPattern exclude(UserScript::kValidUserScriptSchemes);
+ if (URLPattern::PARSE_SUCCESS != exclude.Parse(value))
+ return false;
+ script->add_exclude_url_pattern(exclude);
} else if (GetDeclarationValue(line, kRunAtDeclaration, &value)) {
if (value == kRunAtDocumentStartValue)
script->set_run_location(UserScript::DOCUMENT_START);
diff --git a/chrome/browser/extensions/user_script_master_unittest.cc b/chrome/browser/extensions/user_script_master_unittest.cc
index bdea847..dee757e 100644
--- a/chrome/browser/extensions/user_script_master_unittest.cc
+++ b/chrome/browser/extensions/user_script_master_unittest.cc
@@ -208,6 +208,26 @@ TEST_F(UserScriptMasterTest, Parse7) {
script.url_patterns().begin()->GetAsString());
}
+TEST_F(UserScriptMasterTest, Parse8) {
+ const std::string text(
+ "// ==UserScript==\n"
+ "// @name myscript\n"
+ "// @match http://www.google.com/*\n"
+ "// @exclude_match http://www.google.com/foo*\n"
+ "// ==/UserScript==\n");
+
+ UserScript script;
+ EXPECT_TRUE(UserScriptMaster::ScriptReloader::ParseMetadataHeader(
+ text, &script));
+ ASSERT_EQ("myscript", script.name());
+ ASSERT_EQ(1U, script.url_patterns().patterns().size());
+ EXPECT_EQ("http://www.google.com/*",
+ script.url_patterns().begin()->GetAsString());
+ ASSERT_EQ(1U, script.exclude_url_patterns().patterns().size());
+ EXPECT_EQ("http://www.google.com/foo*",
+ script.exclude_url_patterns().begin()->GetAsString());
+}
+
TEST_F(UserScriptMasterTest, SkipBOMAtTheBeginning) {
FilePath path = temp_dir_.path().AppendASCII("script.user.js");
const std::string content("\xEF\xBB\xBF alert('hello');");
diff --git a/chrome/common/extensions/user_script.cc b/chrome/common/extensions/user_script.cc
index 32bc608..d60b421 100644
--- a/chrome/common/extensions/user_script.cc
+++ b/chrome/common/extensions/user_script.cc
@@ -90,51 +90,52 @@ void UserScript::File::Pickle(::Pickle* pickle) const {
}
void UserScript::File::Unpickle(const ::Pickle& pickle, void** iter) {
- // Read url.
+ // Read the url from the pickle.
std::string url;
CHECK(pickle.ReadString(iter, &url));
set_url(GURL(url));
}
void UserScript::Pickle(::Pickle* pickle) const {
- // Write simple types.
+ // Write the simple types to the pickle.
pickle->WriteInt(run_location());
pickle->WriteString(extension_id());
pickle->WriteBool(emulate_greasemonkey());
pickle->WriteBool(match_all_frames());
pickle->WriteBool(is_incognito_enabled());
- // Write globs.
- std::vector<std::string>::const_iterator glob;
- pickle->WriteSize(globs_.size());
- for (glob = globs_.begin(); glob != globs_.end(); ++glob) {
- pickle->WriteString(*glob);
- }
- pickle->WriteSize(exclude_globs_.size());
- for (glob = exclude_globs_.begin(); glob != exclude_globs_.end(); ++glob) {
+ PickleGlobs(pickle, globs_);
+ PickleGlobs(pickle, exclude_globs_);
+ PickleURLPatternSet(pickle, url_set_);
+ PickleURLPatternSet(pickle, exclude_url_set_);
+ PickleScripts(pickle, js_scripts_);
+ PickleScripts(pickle, css_scripts_);
+}
+
+void UserScript::PickleGlobs(::Pickle* pickle,
+ const std::vector<std::string>& globs) const {
+ pickle->WriteSize(globs.size());
+ for (std::vector<std::string>::const_iterator glob = globs.begin();
+ glob != globs.end(); ++glob) {
pickle->WriteString(*glob);
}
+}
- // Write url patterns.
- URLPatternSet pattern_list = url_set_;
+void UserScript::PickleURLPatternSet(::Pickle* pickle,
+ const URLPatternSet& pattern_list) const {
pickle->WriteSize(pattern_list.patterns().size());
for (URLPatternSet::const_iterator pattern = pattern_list.begin();
pattern != pattern_list.end(); ++pattern) {
pickle->WriteInt(pattern->valid_schemes());
pickle->WriteString(pattern->GetAsString());
}
+}
- // Write js scripts.
- pickle->WriteSize(js_scripts_.size());
- for (FileList::const_iterator file = js_scripts_.begin();
- file != js_scripts_.end(); ++file) {
- file->Pickle(pickle);
- }
-
- // Write css scripts.
- pickle->WriteSize(css_scripts_.size());
- for (FileList::const_iterator file = css_scripts_.begin();
- file != css_scripts_.end(); ++file) {
+void UserScript::PickleScripts(::Pickle* pickle,
+ const FileList& scripts) const {
+ pickle->WriteSize(scripts.size());
+ for (FileList::const_iterator file = scripts.begin();
+ file != scripts.end(); ++file) {
file->Pickle(pickle);
}
}
@@ -151,29 +152,32 @@ void UserScript::Unpickle(const ::Pickle& pickle, void** iter) {
CHECK(pickle.ReadBool(iter, &match_all_frames_));
CHECK(pickle.ReadBool(iter, &incognito_enabled_));
- // Read globs.
- size_t num_globs = 0;
- CHECK(pickle.ReadSize(iter, &num_globs));
- globs_.clear();
- for (size_t i = 0; i < num_globs; ++i) {
- std::string glob;
- CHECK(pickle.ReadString(iter, &glob));
- globs_.push_back(glob);
- }
+ UnpickleGlobs(pickle, iter, &globs_);
+ UnpickleGlobs(pickle, iter, &exclude_globs_);
+ UnpickleURLPatternSet(pickle, iter, &url_set_);
+ UnpickleURLPatternSet(pickle, iter, &exclude_url_set_);
+ UnpickleScripts(pickle, iter, &js_scripts_);
+ UnpickleScripts(pickle, iter, &css_scripts_);
+}
+void UserScript::UnpickleGlobs(const ::Pickle& pickle, void** iter,
+ std::vector<std::string>* globs) {
+ size_t num_globs = 0;
CHECK(pickle.ReadSize(iter, &num_globs));
- exclude_globs_.clear();
+ globs->clear();
for (size_t i = 0; i < num_globs; ++i) {
std::string glob;
CHECK(pickle.ReadString(iter, &glob));
- exclude_globs_.push_back(glob);
+ globs->push_back(glob);
}
+}
- // Read url patterns.
+void UserScript::UnpickleURLPatternSet(const ::Pickle& pickle, void** iter,
+ URLPatternSet* pattern_list) {
size_t num_patterns = 0;
CHECK(pickle.ReadSize(iter, &num_patterns));
- url_set_.ClearPatterns();
+ pattern_list->ClearPatterns();
for (size_t i = 0; i < num_patterns; ++i) {
int valid_schemes;
CHECK(pickle.ReadInt(iter, &valid_schemes));
@@ -191,26 +195,18 @@ void UserScript::Unpickle(const ::Pickle& pickle, void** iter) {
if (!had_file_scheme)
pattern.SetValidSchemes(valid_schemes);
- url_set_.AddPattern(pattern);
- }
-
- // Read js scripts.
- size_t num_js_files = 0;
- CHECK(pickle.ReadSize(iter, &num_js_files));
- js_scripts_.clear();
- for (size_t i = 0; i < num_js_files; ++i) {
- File file;
- file.Unpickle(pickle, iter);
- js_scripts_.push_back(file);
+ pattern_list->AddPattern(pattern);
}
+}
- // Read css scripts.
- size_t num_css_files = 0;
- CHECK(pickle.ReadSize(iter, &num_css_files));
- css_scripts_.clear();
- for (size_t i = 0; i < num_css_files; ++i) {
+void UserScript::UnpickleScripts(const ::Pickle& pickle, void** iter,
+ FileList* scripts) {
+ size_t num_files = 0;
+ CHECK(pickle.ReadSize(iter, &num_files));
+ scripts->clear();
+ for (size_t i = 0; i < num_files; ++i) {
File file;
file.Unpickle(pickle, iter);
- css_scripts_.push_back(file);
+ scripts->push_back(file);
}
}
diff --git a/chrome/common/extensions/user_script.h b/chrome/common/extensions/user_script.h
index 71c31ac..53147fc 100644
--- a/chrome/common/extensions/user_script.h
+++ b/chrome/common/extensions/user_script.h
@@ -190,6 +190,21 @@ class UserScript {
void Unpickle(const ::Pickle& pickle, void** iter);
private:
+ // Pickle helper functions used to pickle the individual types of components.
+ void PickleGlobs(::Pickle* pickle,
+ const std::vector<std::string>& globs) const;
+ void PickleURLPatternSet(::Pickle* pickle,
+ const URLPatternSet& pattern_list) const;
+ void PickleScripts(::Pickle* pickle, const FileList& scripts) const;
+
+ // Unpickle helper functions used to unpickle individual types of components.
+ void UnpickleGlobs(const ::Pickle& pickle, void** iter,
+ std::vector<std::string>* globs);
+ void UnpickleURLPatternSet(const ::Pickle& pickle, void** iter,
+ URLPatternSet* pattern_list);
+ void UnpickleScripts(const ::Pickle& pickle, void** iter,
+ FileList* scripts);
+
// The location to run the script inside the document.
RunLocation run_location_;
diff --git a/chrome/common/extensions/user_script_unittest.cc b/chrome/common/extensions/user_script_unittest.cc
index b73df4e..1afe6ab 100644
--- a/chrome/common/extensions/user_script_unittest.cc
+++ b/chrome/common/extensions/user_script_unittest.cc
@@ -159,8 +159,12 @@ TEST(ExtensionUserScriptTest, UrlPatternGlobInteraction) {
TEST(ExtensionUserScriptTest, Pickle) {
URLPattern pattern1(kAllSchemes);
URLPattern pattern2(kAllSchemes);
+ URLPattern exclude1(kAllSchemes);
+ URLPattern exclude2(kAllSchemes);
ASSERT_EQ(URLPattern::PARSE_SUCCESS, pattern1.Parse("http://*/foo*"));
ASSERT_EQ(URLPattern::PARSE_SUCCESS, pattern2.Parse("http://bar/baz*"));
+ ASSERT_EQ(URLPattern::PARSE_SUCCESS, exclude1.Parse("*://*/*bar"));
+ ASSERT_EQ(URLPattern::PARSE_SUCCESS, exclude2.Parse("https://*/*"));
UserScript script1;
script1.js_scripts().push_back(UserScript::File(
@@ -179,6 +183,8 @@ TEST(ExtensionUserScriptTest, Pickle) {
script1.add_url_pattern(pattern1);
script1.add_url_pattern(pattern2);
+ script1.add_exclude_url_pattern(exclude1);
+ script1.add_exclude_url_pattern(exclude2);
Pickle pickle;
script1.Pickle(&pickle);
@@ -201,6 +207,7 @@ TEST(ExtensionUserScriptTest, Pickle) {
}
ASSERT_EQ(script1.url_patterns(), script2.url_patterns());
+ ASSERT_EQ(script1.exclude_url_patterns(), script2.exclude_url_patterns());
}
TEST(ExtensionUserScriptTest, Defaults) {
diff --git a/chrome/test/data/extensions/user_script_basic.user.js b/chrome/test/data/extensions/user_script_basic.user.js
index 65ca67b..4090ade 100644
--- a/chrome/test/data/extensions/user_script_basic.user.js
+++ b/chrome/test/data/extensions/user_script_basic.user.js
@@ -7,6 +7,7 @@
// @include http://www.yahoo.com/*
// @exclude *foo*
// @match http://www.google.com/*
+// @exclude_match http://www.google.com/foo*
// ==/UserScript==
alert("Hello! This is my script.");