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

Side by Side Diff: extensions/browser/web_ui_user_script_loader.cc

Issue 1056533002: Implement <webview>.addContentScript/removeContentScript API [2] (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@webview_addremove_contentscripts_2
Patch Set: Clean up. Created 5 years, 8 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
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "extensions/browser/web_ui_user_script_loader.h"
6
7 #include "base/bind.h"
8 #include "base/strings/string_util.h"
9 #include "content/public/browser/browser_context.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "extensions/browser/guest_view/web_view/web_ui/web_ui_url_fetcher.h"
12
13 namespace {
14
15 void SerializeOnFileThread(
16 scoped_ptr<extensions::UserScriptList> user_scripts,
17 extensions::UserScriptLoader::LoadScriptsCallback callback) {
18 scoped_ptr<base::SharedMemory> memory =
19 extensions::UserScriptLoader::Serialize(*user_scripts);
20 content::BrowserThread::PostTask(
21 content::BrowserThread::UI, FROM_HERE,
22 base::Bind(callback, base::Passed(&user_scripts), base::Passed(&memory)));
23 }
24
25 } // namespace
26
27 struct WebUIUserScriptLoader::UserScriptRenderInfo {
28 int render_process_id;
29 int render_view_id;
30
31 UserScriptRenderInfo() : render_process_id(-1), render_view_id(-1) {}
32
33 UserScriptRenderInfo(int render_process_id, int render_view_id)
34 : render_process_id(render_process_id), render_view_id(render_view_id) {}
35 };
36
37 WebUIUserScriptLoader::WebUIUserScriptLoader(
38 content::BrowserContext* browser_context,
39 const HostID& host_id)
40 : UserScriptLoader(browser_context, host_id), complete_fetchers_(0) {
41 SetReady(true);
42 }
43
44 WebUIUserScriptLoader::~WebUIUserScriptLoader() {
45 }
46
47 void WebUIUserScriptLoader::AddScripts(
48 const std::set<extensions::UserScript>& scripts,
49 int render_process_id,
50 int render_view_id) {
51 UserScriptRenderInfo info(render_process_id, render_view_id);
52 for (const extensions::UserScript& script : scripts) {
53 script_render_info_map_.insert(
54 std::pair<int, UserScriptRenderInfo>(script.id(), info));
55 }
56
57 extensions::UserScriptLoader::AddScripts(scripts);
58 }
59
60 void WebUIUserScriptLoader::LoadScripts(
61 scoped_ptr<extensions::UserScriptList> user_scripts,
62 const std::set<HostID>& changed_hosts,
63 const std::set<int>& added_script_ids,
64 LoadScriptsCallback callback) {
65 user_scripts_cache_.swap(user_scripts);
66 scripts_loaded_callback_ = callback;
67
68 // The total number of the tasks is used to trace whether all the fetches
69 // are complete. Therefore, we store all the fetcher pointers in |fetchers_|
70 // before we get theis number. Once we get the total number, start each
71 // fetch tasks.
72 complete_fetchers_ = 0;
Devlin 2015/04/24 17:50:59 It might be better to DCHECK_EQ(0u, complete_fetch
Xi Han 2015/04/24 18:28:54 Updated.
73
74 for (extensions::UserScript& script : *user_scripts_cache_) {
75 if (added_script_ids.count(script.id()) == 0)
76 continue;
77
78 auto iter = script_render_info_map_.find(script.id());
79 DCHECK(iter != script_render_info_map_.end());
80 int render_process_id = iter->second.render_process_id;
81 int render_view_id = iter->second.render_view_id;
82
83 CreateWebUIURLFetchers(&script.js_scripts(), render_process_id,
84 render_view_id);
85 CreateWebUIURLFetchers(&script.css_scripts(), render_process_id,
86 render_view_id);
87
88 script_render_info_map_.erase(script.id());
89 }
90
91 // If no fetch is needed, call OnWebUIURLFetchComplete directly.
92 if (fetchers_.empty()) {
93 OnWebUIURLFetchComplete();
94 return;
95 }
96 for (auto fetcher : fetchers_)
97 fetcher->Start();
98 }
99
100 void WebUIUserScriptLoader::CreateWebUIURLFetchers(
101 extensions::UserScript::FileList* script_files,
102 int render_process_id,
103 int render_view_id) {
104 for (extensions::UserScript::File& file : *script_files) {
105 if (file.GetContent().empty()) {
106 // The WebUIUserScriptLoader owns these WebUIURLFetchers. Once the
107 // loader is destroyed, all the fetchers will be destroyed. Therefore,
108 // we are sure it is safe to use base::Unretained(this) here.
109 scoped_ptr<WebUIURLFetcher> fetcher(new WebUIURLFetcher(
110 browser_context(), render_process_id, render_view_id, file.url(),
111 base::Bind(&WebUIUserScriptLoader::OnSingleWebUIURLFetchComplete,
112 base::Unretained(this), &file)));
113 fetchers_.push_back(fetcher.release());
114 }
115 }
116 }
117
118 void WebUIUserScriptLoader::OnSingleWebUIURLFetchComplete(
119 extensions::UserScript::File* script_file,
120 bool success,
121 const std::string& data) {
122 if (success) {
123 // Remove BOM from the content.
124 std::string::size_type index = data.find(base::kUtf8ByteOrderMark);
125 if (index == 0)
126 script_file->set_content(data.substr(strlen(base::kUtf8ByteOrderMark)));
127 else
128 script_file->set_content(data);
129 }
130
131 ++complete_fetchers_;
132 if (complete_fetchers_ == fetchers_.size()) {
133 complete_fetchers_ = 0;
134 OnWebUIURLFetchComplete();
135 fetchers_.clear();
136 }
137 }
138
139 void WebUIUserScriptLoader::OnWebUIURLFetchComplete() {
140 content::BrowserThread::PostTask(
141 content::BrowserThread::FILE, FROM_HERE,
142 base::Bind(&SerializeOnFileThread, base::Passed(&user_scripts_cache_),
143 scripts_loaded_callback_));
144 scripts_loaded_callback_.Reset();
145 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698