diff options
author | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-19 07:05:43 +0000 |
---|---|---|
committer | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-19 07:05:43 +0000 |
commit | 2c17977c344d3a6b3501370a8e30c83f0b93af03 (patch) | |
tree | 789d57a1e231ac1c088e07421e3d90512de9ed83 | |
parent | 0bf4dc62111e3329375eb5a87c4276c2f012ee27 (diff) | |
download | chromium_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.cc | 11 | ||||
-rw-r--r-- | chrome/browser/extensions/convert_user_script_unittest.cc | 3 | ||||
-rw-r--r-- | chrome/browser/extensions/user_script_master.cc | 6 | ||||
-rw-r--r-- | chrome/browser/extensions/user_script_master_unittest.cc | 20 | ||||
-rw-r--r-- | chrome/common/extensions/user_script.cc | 102 | ||||
-rw-r--r-- | chrome/common/extensions/user_script.h | 15 | ||||
-rw-r--r-- | chrome/common/extensions/user_script_unittest.cc | 7 | ||||
-rw-r--r-- | chrome/test/data/extensions/user_script_basic.user.js | 1 |
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."); |