[Mac] PepperFlash default on DEV channel.
[chromium-blink-merge.git] / webkit / glue / dom_operations.cc
blobcedf58ec04a7e6eea913b057e6bc1f9beb62cac1
1 // Copyright (c) 2012 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.
5 #include "webkit/glue/dom_operations.h"
7 #include <set>
9 #include "base/compiler_specific.h"
10 #include "base/logging.h"
11 #include "base/string_util.h"
12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAnimationController.h"
13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputElement.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNodeCollection.h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNodeList.h"
20 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h"
22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
24 using WebKit::WebAnimationController;
25 using WebKit::WebDocument;
26 using WebKit::WebElement;
27 using WebKit::WebFrame;
28 using WebKit::WebInputElement;
29 using WebKit::WebNode;
30 using WebKit::WebNodeCollection;
31 using WebKit::WebNodeList;
32 using WebKit::WebString;
33 using WebKit::WebVector;
34 using WebKit::WebView;
36 namespace {
38 // Structure for storage the unique set of all savable resource links for
39 // making sure that no duplicated resource link in final result. The consumer
40 // of the SavableResourcesUniqueCheck is responsible for keeping these pointers
41 // valid for the lifetime of the SavableResourcesUniqueCheck instance.
42 struct SavableResourcesUniqueCheck {
43 // Unique set of all sub resource links.
44 std::set<GURL>* resources_set;
45 // Unique set of all frame links.
46 std::set<GURL>* frames_set;
47 // Collection of all frames we go through when getting all savable resource
48 // links.
49 std::vector<WebFrame*>* frames;
51 SavableResourcesUniqueCheck()
52 : resources_set(NULL),
53 frames_set(NULL),
54 frames(NULL) {}
56 SavableResourcesUniqueCheck(std::set<GURL>* resources_set,
57 std::set<GURL>* frames_set, std::vector<WebFrame*>* frames)
58 : resources_set(resources_set),
59 frames_set(frames_set),
60 frames(frames) {}
63 // Get all savable resource links from current element. One element might
64 // have more than one resource link. It is possible to have some links
65 // in one CSS stylesheet.
66 void GetSavableResourceLinkForElement(
67 const WebElement& element,
68 const WebDocument& current_doc,
69 SavableResourcesUniqueCheck* unique_check,
70 webkit_glue::SavableResourcesResult* result) {
72 // Handle frame and iframe tag.
73 if (element.hasTagName("iframe") ||
74 element.hasTagName("frame")) {
75 WebFrame* sub_frame = WebFrame::fromFrameOwnerElement(element);
76 if (sub_frame)
77 unique_check->frames->push_back(sub_frame);
78 return;
81 // Check whether the node has sub resource URL or not.
82 WebString value =
83 webkit_glue::GetSubResourceLinkFromElement(element);
84 if (value.isNull())
85 return;
86 // Get absolute URL.
87 GURL u = current_doc.completeURL(value);
88 // ignore invalid URL
89 if (!u.is_valid())
90 return;
91 // Ignore those URLs which are not standard protocols. Because FTP
92 // protocol does no have cache mechanism, we will skip all
93 // sub-resources if they use FTP protocol.
94 if (!u.SchemeIs("http") && !u.SchemeIs("https") && !u.SchemeIs("file"))
95 return;
96 // Ignore duplicated resource link.
97 if (!unique_check->resources_set->insert(u).second)
98 return;
99 result->resources_list->push_back(u);
100 // Insert referrer for above new resource link.
101 result->referrer_urls_list->push_back(GURL());
102 result->referrer_policies_list->push_back(WebKit::WebReferrerPolicyDefault);
105 // Get all savable resource links from current WebFrameImpl object pointer.
106 void GetAllSavableResourceLinksForFrame(WebFrame* current_frame,
107 SavableResourcesUniqueCheck* unique_check,
108 webkit_glue::SavableResourcesResult* result,
109 const char** savable_schemes) {
110 // Get current frame's URL.
111 GURL current_frame_url = current_frame->document().url();
113 // If url of current frame is invalid, ignore it.
114 if (!current_frame_url.is_valid())
115 return;
117 // If url of current frame is not a savable protocol, ignore it.
118 bool is_valid_protocol = false;
119 for (int i = 0; savable_schemes[i] != NULL; ++i) {
120 if (current_frame_url.SchemeIs(savable_schemes[i])) {
121 is_valid_protocol = true;
122 break;
125 if (!is_valid_protocol)
126 return;
128 // If find same frame we have recorded, ignore it.
129 if (!unique_check->frames_set->insert(current_frame_url).second)
130 return;
132 // Get current using document.
133 WebDocument current_doc = current_frame->document();
134 // Go through all descent nodes.
135 WebNodeCollection all = current_doc.all();
136 // Go through all node in this frame.
137 for (WebNode node = all.firstItem(); !node.isNull();
138 node = all.nextItem()) {
139 // We only save HTML resources.
140 if (!node.isElementNode())
141 continue;
142 WebElement element = node.to<WebElement>();
143 GetSavableResourceLinkForElement(element,
144 current_doc,
145 unique_check,
146 result);
150 } // namespace
152 namespace webkit_glue {
154 WebString GetSubResourceLinkFromElement(const WebElement& element) {
155 const char* attribute_name = NULL;
156 if (element.hasTagName("img") ||
157 element.hasTagName("script")) {
158 attribute_name = "src";
159 } else if (element.hasTagName("input")) {
160 const WebInputElement input = element.toConst<WebInputElement>();
161 if (input.isImageButton()) {
162 attribute_name = "src";
164 } else if (element.hasTagName("body") ||
165 element.hasTagName("table") ||
166 element.hasTagName("tr") ||
167 element.hasTagName("td")) {
168 attribute_name = "background";
169 } else if (element.hasTagName("blockquote") ||
170 element.hasTagName("q") ||
171 element.hasTagName("del") ||
172 element.hasTagName("ins")) {
173 attribute_name = "cite";
174 } else if (element.hasTagName("link")) {
175 // If the link element is not linked to css, ignore it.
176 if (LowerCaseEqualsASCII(element.getAttribute("type"), "text/css")) {
177 // TODO(jnd): Add support for extracting links of sub-resources which
178 // are inside style-sheet such as @import, url(), etc.
179 // See bug: http://b/issue?id=1111667.
180 attribute_name = "href";
183 if (!attribute_name)
184 return WebString();
185 WebString value = element.getAttribute(WebString::fromUTF8(attribute_name));
186 // If value has content and not start with "javascript:" then return it,
187 // otherwise return NULL.
188 if (!value.isNull() && !value.isEmpty() &&
189 !StartsWithASCII(value.utf8(), "javascript:", false))
190 return value;
192 return WebString();
195 // Get all savable resource links from current webview, include main
196 // frame and sub-frame
197 bool GetAllSavableResourceLinksForCurrentPage(WebView* view,
198 const GURL& page_url, SavableResourcesResult* result,
199 const char** savable_schemes) {
200 WebFrame* main_frame = view->mainFrame();
201 if (!main_frame)
202 return false;
204 std::set<GURL> resources_set;
205 std::set<GURL> frames_set;
206 std::vector<WebFrame*> frames;
207 SavableResourcesUniqueCheck unique_check(&resources_set,
208 &frames_set,
209 &frames);
211 GURL main_page_gurl(main_frame->document().url());
213 // Make sure we are saving same page between embedder and webkit.
214 // If page has being navigated, embedder will get three empty vector,
215 // which will make the saving page job ended.
216 if (page_url != main_page_gurl)
217 return true;
219 // First, process main frame.
220 frames.push_back(main_frame);
222 // Check all resource in this page, include sub-frame.
223 for (int i = 0; i < static_cast<int>(frames.size()); ++i) {
224 // Get current frame's all savable resource links.
225 GetAllSavableResourceLinksForFrame(frames[i], &unique_check, result,
226 savable_schemes);
229 // Since frame's src can also point to sub-resources link, so it is possible
230 // that some URLs in frames_list are also in resources_list. For those
231 // URLs, we will remove it from frame_list, only keep them in resources_list.
232 for (std::set<GURL>::iterator it = frames_set.begin();
233 it != frames_set.end(); ++it) {
234 // Append unique frame source to savable frame list.
235 if (resources_set.find(*it) == resources_set.end())
236 result->frames_list->push_back(*it);
239 return true;
242 bool PauseAnimationAtTimeOnElementWithId(WebView* view,
243 const std::string& animation_name,
244 double time,
245 const std::string& element_id) {
246 WebFrame* web_frame = view->mainFrame();
247 if (!web_frame)
248 return false;
250 WebAnimationController* controller = web_frame->animationController();
251 if (!controller)
252 return false;
254 WebElement element =
255 web_frame->document().getElementById(WebString::fromUTF8(element_id));
256 if (element.isNull())
257 return false;
258 return controller->pauseAnimationAtTime(element,
259 WebString::fromUTF8(animation_name),
260 time);
263 bool PauseTransitionAtTimeOnElementWithId(WebView* view,
264 const std::string& property_name,
265 double time,
266 const std::string& element_id) {
267 WebFrame* web_frame = view->mainFrame();
268 if (!web_frame)
269 return false;
271 WebAnimationController* controller = web_frame->animationController();
272 if (!controller)
273 return false;
275 WebElement element =
276 web_frame->document().getElementById(WebString::fromUTF8(element_id));
277 if (element.isNull())
278 return false;
279 return controller->pauseTransitionAtTime(element,
280 WebString::fromUTF8(property_name),
281 time);
284 bool ElementDoesAutoCompleteForElementWithId(WebView* view,
285 const std::string& element_id) {
286 WebFrame* web_frame = view->mainFrame();
287 if (!web_frame)
288 return false;
290 WebElement element = web_frame->document().getElementById(
291 WebString::fromUTF8(element_id));
292 if (element.isNull() || !element.hasTagName("input"))
293 return false;
295 WebInputElement input_element = element.to<WebInputElement>();
296 return input_element.autoComplete();
299 int NumberOfActiveAnimations(WebView* view) {
300 WebFrame* web_frame = view->mainFrame();
301 if (!web_frame)
302 return -1;
304 WebAnimationController* controller = web_frame->animationController();
305 if (!controller)
306 return -1;
308 return controller->numberOfActiveAnimations();
311 void GetMetaElementsWithAttribute(WebDocument* document,
312 const string16& attribute_name,
313 const string16& attribute_value,
314 std::vector<WebElement>* meta_elements) {
315 DCHECK(document);
316 DCHECK(meta_elements);
317 meta_elements->clear();
318 WebElement head = document->head();
319 if (head.isNull() || !head.hasChildNodes())
320 return;
322 WebNodeList children = head.childNodes();
323 for (size_t i = 0; i < children.length(); ++i) {
324 WebNode node = children.item(i);
325 if (!node.isElementNode())
326 continue;
327 WebElement element = node.to<WebElement>();
328 if (!element.hasTagName("meta"))
329 continue;
330 WebString value = element.getAttribute(attribute_name);
331 if (value.isNull() || value != attribute_value)
332 continue;
333 meta_elements->push_back(element);
337 } // webkit_glue