Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Side by Side Diff: chrome/renderer/user_script_slave.cc

Issue 2932007: Use WebCore's built in support for user styles (Closed)
Patch Set: whoops Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/common/extensions/url_pattern_unittest.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/renderer/user_script_slave.h" 5 #include "chrome/renderer/user_script_slave.h"
6 6
7 #include "app/resource_bundle.h" 7 #include "app/resource_bundle.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/histogram.h" 9 #include "base/histogram.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/perftimer.h" 11 #include "base/perftimer.h"
12 #include "base/pickle.h" 12 #include "base/pickle.h"
13 #include "base/shared_memory.h" 13 #include "base/shared_memory.h"
14 #include "base/string_util.h" 14 #include "base/string_util.h"
15 #include "chrome/common/chrome_switches.h" 15 #include "chrome/common/chrome_switches.h"
16 #include "chrome/common/extensions/extension.h" 16 #include "chrome/common/extensions/extension.h"
17 #include "chrome/common/url_constants.h"
17 #include "chrome/renderer/extension_groups.h" 18 #include "chrome/renderer/extension_groups.h"
18 #include "chrome/renderer/render_thread.h" 19 #include "chrome/renderer/render_thread.h"
19 #include "googleurl/src/gurl.h" 20 #include "googleurl/src/gurl.h"
20 #include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" 21 #include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
22 #include "third_party/WebKit/WebKit/chromium/public/WebVector.h"
23 #include "third_party/WebKit/WebKit/chromium/public/WebView.h"
21 24
22 #include "grit/renderer_resources.h" 25 #include "grit/renderer_resources.h"
23 26
24 using WebKit::WebFrame; 27 using WebKit::WebFrame;
25 using WebKit::WebString; 28 using WebKit::WebString;
29 using WebKit::WebVector;
30 using WebKit::WebView;
26 31
27 // These two strings are injected before and after the Greasemonkey API and 32 // These two strings are injected before and after the Greasemonkey API and
28 // user script to wrap it in an anonymous scope. 33 // user script to wrap it in an anonymous scope.
29 static const char kUserScriptHead[] = "(function (unsafeWindow) {\n"; 34 static const char kUserScriptHead[] = "(function (unsafeWindow) {\n";
30 static const char kUserScriptTail[] = "\n})(window);"; 35 static const char kUserScriptTail[] = "\n})(window);";
31 36
32 // Sets up the chrome.extension module. This may be run multiple times per 37 // Sets up the chrome.extension module. This may be run multiple times per
33 // context, but the init method deletes itself after the first time. 38 // context, but the init method deletes itself after the first time.
34 static const char kInitExtension[] = 39 static const char kInitExtension[] =
35 "if (chrome.initExtension) chrome.initExtension('%s', true, %s);"; 40 "if (chrome.initExtension) chrome.initExtension('%s', true, %s);";
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 base::StringPiece(body, body_length)); 126 base::StringPiece(body, body_length));
122 } 127 }
123 128
124 if (only_inject_incognito && !script->is_incognito_enabled()) { 129 if (only_inject_incognito && !script->is_incognito_enabled()) {
125 // This script shouldn't run in an incognito tab. 130 // This script shouldn't run in an incognito tab.
126 delete script; 131 delete script;
127 scripts_.pop_back(); 132 scripts_.pop_back();
128 } 133 }
129 } 134 }
130 135
136 // Push user styles down into WebCore
137 WebView::removeAllUserContent();
138 for (size_t i = 0; i < scripts_.size(); ++i) {
139 UserScript* script = scripts_[i];
140 if (script->css_scripts().empty())
141 continue;
142
143 WebVector<WebString> patterns;
144 std::vector<WebString> temp_patterns;
145 for (size_t k = 0; k < script->url_patterns().size(); ++k) {
146 std::vector<URLPattern> explicit_patterns =
147 script->url_patterns()[k].ConvertToExplicitSchemes();
148 for (size_t m = 0; m < explicit_patterns.size(); ++m) {
149 // Only include file schemes if the user has opted into that.
150 if (!explicit_patterns[m].MatchesScheme(chrome::kFileScheme) ||
151 script->allow_file_access()) {
152 temp_patterns.push_back(WebString::fromUTF8(
153 explicit_patterns[m].GetAsString()));
154 }
155 }
156 }
157 patterns.assign(temp_patterns);
158
159 for (size_t j = 0; j < script->css_scripts().size(); ++j) {
160 const UserScript::File& file = scripts_[i]->css_scripts()[j];
161 std::string content = file.GetContent().as_string();
162
163 WebView::addUserStyleSheet(
164 WebString::fromUTF8(content),
165 patterns,
166 script->match_all_frames() ?
167 WebView::UserContentInjectInAllFrames :
168 WebView::UserContentInjectInTopFrameOnly);
169 }
170 }
171
131 return true; 172 return true;
132 } 173 }
133 174
134 // static 175 // static
135 void UserScriptSlave::InsertInitExtensionCode( 176 void UserScriptSlave::InsertInitExtensionCode(
136 std::vector<WebScriptSource>* sources, const std::string& extension_id) { 177 std::vector<WebScriptSource>* sources, const std::string& extension_id) {
137 DCHECK(sources); 178 DCHECK(sources);
138 bool incognito = RenderThread::current()->is_incognito_process(); 179 bool incognito = RenderThread::current()->is_incognito_process();
139 sources->insert(sources->begin(), WebScriptSource(WebString::fromUTF8( 180 sources->insert(sources->begin(), WebScriptSource(WebString::fromUTF8(
140 StringPrintf(kInitExtension, extension_id.c_str(), 181 StringPrintf(kInitExtension, extension_id.c_str(),
(...skipping 26 matching lines...) Expand all
167 208
168 if (frame->parent() && !script->match_all_frames()) 209 if (frame->parent() && !script->match_all_frames())
169 continue; // Only match subframes if the script declared it wanted to. 210 continue; // Only match subframes if the script declared it wanted to.
170 211
171 if (!script->MatchesUrl(frame->url())) 212 if (!script->MatchesUrl(frame->url()))
172 continue; // This frame doesn't match the script url pattern, skip it. 213 continue; // This frame doesn't match the script url pattern, skip it.
173 214
174 if (frame_url.SchemeIsFile() && !script->allow_file_access()) 215 if (frame_url.SchemeIsFile() && !script->allow_file_access())
175 continue; // This script isn't allowed to run on file URLs. 216 continue; // This script isn't allowed to run on file URLs.
176 217
177 // CSS files are always injected on document start before js scripts. 218 // We rely on WebCore for CSS injection, but it's still useful to know how
178 if (location == UserScript::DOCUMENT_START) { 219 // many css files there are.
220 if (location == UserScript::DOCUMENT_START)
179 num_css += script->css_scripts().size(); 221 num_css += script->css_scripts().size();
180 for (size_t j = 0; j < script->css_scripts().size(); ++j) { 222
181 PerfTimer insert_timer;
182 UserScript::File& file = script->css_scripts()[j];
183 frame->insertStyleText(
184 WebString::fromUTF8(file.GetContent().as_string()), WebString());
185 UMA_HISTOGRAM_TIMES("Extensions.InjectCssTime", insert_timer.Elapsed());
186 }
187 }
188 if (script->run_location() == location) { 223 if (script->run_location() == location) {
189 num_scripts += script->js_scripts().size(); 224 num_scripts += script->js_scripts().size();
190 for (size_t j = 0; j < script->js_scripts().size(); ++j) { 225 for (size_t j = 0; j < script->js_scripts().size(); ++j) {
191 UserScript::File &file = script->js_scripts()[j]; 226 UserScript::File &file = script->js_scripts()[j];
192 std::string content = file.GetContent().as_string(); 227 std::string content = file.GetContent().as_string();
193 228
194 // We add this dumb function wrapper for standalone user script to 229 // We add this dumb function wrapper for standalone user script to
195 // emulate what Greasemonkey does. 230 // emulate what Greasemonkey does.
196 if (script->is_standalone() || script->emulate_greasemonkey()) { 231 if (script->is_standalone() || script->emulate_greasemonkey()) {
197 content.insert(0, kUserScriptHead); 232 content.insert(0, kUserScriptHead);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 if (num_scripts) 277 if (num_scripts)
243 UMA_HISTOGRAM_TIMES("Extensions.InjectIdle_Time", timer.Elapsed()); 278 UMA_HISTOGRAM_TIMES("Extensions.InjectIdle_Time", timer.Elapsed());
244 } else { 279 } else {
245 NOTREACHED(); 280 NOTREACHED();
246 } 281 }
247 282
248 LOG(INFO) << "Injected " << num_scripts << " scripts and " << num_css << 283 LOG(INFO) << "Injected " << num_scripts << " scripts and " << num_css <<
249 " css files into " << frame->url().spec().data(); 284 " css files into " << frame->url().spec().data();
250 return; 285 return;
251 } 286 }
OLDNEW
« no previous file with comments | « chrome/common/extensions/url_pattern_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698