190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/renderer/savable_resources.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebString.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebVector.h"
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebDocument.h"
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebElement.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/web/WebElementCollection.h"
177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebInputElement.h"
18a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "third_party/WebKit/public/web/WebLocalFrame.h"
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebNode.h"
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebNodeList.h"
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebView.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebDocument;
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebElement;
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using blink::WebElementCollection;
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebFrame;
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebInputElement;
28a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochusing blink::WebLocalFrame;
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebNode;
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebNodeList;
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebString;
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebVector;
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebView;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace content {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Structure for storage the unique set of all savable resource links for
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// making sure that no duplicated resource link in final result. The consumer
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the SavableResourcesUniqueCheck is responsible for keeping these pointers
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// valid for the lifetime of the SavableResourcesUniqueCheck instance.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct SavableResourcesUniqueCheck {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unique set of all sub resource links.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<GURL>* resources_set;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unique set of all frame links.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<GURL>* frames_set;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Collection of all frames we go through when getting all savable resource
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // links.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<WebFrame*>* frames;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SavableResourcesUniqueCheck()
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : resources_set(NULL),
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        frames_set(NULL),
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        frames(NULL) {}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SavableResourcesUniqueCheck(std::set<GURL>* resources_set,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::set<GURL>* frames_set, std::vector<WebFrame*>* frames)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : resources_set(resources_set),
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        frames_set(frames_set),
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        frames(frames) {}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Get all savable resource links from current element. One element might
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// have more than one resource link. It is possible to have some links
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in one CSS stylesheet.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetSavableResourceLinkForElement(
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebElement& element,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebDocument& current_doc,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SavableResourcesUniqueCheck* unique_check,
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SavableResourcesResult* result) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handle frame and iframe tag.
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (element.hasHTMLTagName("iframe") ||
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      element.hasHTMLTagName("frame")) {
75a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    WebFrame* sub_frame = WebLocalFrame::fromFrameOwnerElement(element);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sub_frame)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unique_check->frames->push_back(sub_frame);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check whether the node has sub resource URL or not.
8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  WebString value = GetSubResourceLinkFromElement(element);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value.isNull())
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get absolute URL.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL u = current_doc.completeURL(value);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ignore invalid URL
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!u.is_valid())
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ignore those URLs which are not standard protocols. Because FTP
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol does no have cache mechanism, we will skip all
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sub-resources if they use FTP protocol.
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!u.SchemeIsHTTPOrHTTPS() && !u.SchemeIs(url::kFileScheme))
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ignore duplicated resource link.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!unique_check->resources_set->insert(u).second)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->resources_list->push_back(u);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Insert referrer for above new resource link.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->referrer_urls_list->push_back(GURL());
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  result->referrer_policies_list->push_back(blink::WebReferrerPolicyDefault);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Get all savable resource links from current WebFrameImpl object pointer.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetAllSavableResourceLinksForFrame(WebFrame* current_frame,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SavableResourcesUniqueCheck* unique_check,
10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SavableResourcesResult* result,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char** savable_schemes) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get current frame's URL.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL current_frame_url = current_frame->document().url();
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If url of current frame is invalid, ignore it.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!current_frame_url.is_valid())
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If url of current frame is not a savable protocol, ignore it.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_valid_protocol = false;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; savable_schemes[i] != NULL; ++i) {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (current_frame_url.SchemeIs(savable_schemes[i])) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_valid_protocol = true;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_valid_protocol)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If find same frame we have recorded, ignore it.
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!unique_check->frames_set->insert(current_frame_url).second)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get current using document.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebDocument current_doc = current_frame->document();
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go through all descent nodes.
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WebElementCollection all = current_doc.all();
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Go through all elements in this frame.
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (WebElement element = all.firstItem(); !element.isNull();
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       element = all.nextItem()) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetSavableResourceLinkForElement(element,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     current_doc,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     unique_check,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     result);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebString GetSubResourceLinkFromElement(const WebElement& element) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* attribute_name = NULL;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (element.hasHTMLTagName("img") ||
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      element.hasHTMLTagName("script")) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    attribute_name = "src";
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (element.hasHTMLTagName("input")) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebInputElement input = element.toConst<WebInputElement>();
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (input.isImageButton()) {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      attribute_name = "src";
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (element.hasHTMLTagName("body") ||
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             element.hasHTMLTagName("table") ||
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             element.hasHTMLTagName("tr") ||
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             element.hasHTMLTagName("td")) {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    attribute_name = "background";
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (element.hasHTMLTagName("blockquote") ||
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             element.hasHTMLTagName("q") ||
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             element.hasHTMLTagName("del") ||
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             element.hasHTMLTagName("ins")) {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    attribute_name = "cite";
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (element.hasHTMLTagName("link")) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If the link element is not linked to css, ignore it.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (LowerCaseEqualsASCII(element.getAttribute("type"), "text/css")) {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // TODO(jnd): Add support for extracting links of sub-resources which
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // are inside style-sheet such as @import, url(), etc.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // See bug: http://b/issue?id=1111667.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      attribute_name = "href";
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!attribute_name)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return WebString();
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebString value = element.getAttribute(WebString::fromUTF8(attribute_name));
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If value has content and not start with "javascript:" then return it,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // otherwise return NULL.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!value.isNull() && !value.isEmpty() &&
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !StartsWithASCII(value.utf8(), "javascript:", false))
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return value;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return WebString();
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Get all savable resource links from current webview, include main
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// frame and sub-frame
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetAllSavableResourceLinksForCurrentPage(WebView* view,
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& page_url, SavableResourcesResult* result,
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char** savable_schemes) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebFrame* main_frame = view->mainFrame();
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!main_frame)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<GURL> resources_set;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<GURL> frames_set;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<WebFrame*> frames;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SavableResourcesUniqueCheck unique_check(&resources_set,
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           &frames_set,
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           &frames);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL main_page_gurl(main_frame->document().url());
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we are saving same page between embedder and webkit.
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If page has being navigated, embedder will get three empty vector,
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // which will make the saving page job ended.
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (page_url != main_page_gurl)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First, process main frame.
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  frames.push_back(main_frame);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check all resource in this page, include sub-frame.
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < static_cast<int>(frames.size()); ++i) {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Get current frame's all savable resource links.
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetAllSavableResourceLinksForFrame(frames[i], &unique_check, result,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       savable_schemes);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since frame's src can also point to sub-resources link, so it is possible
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that some URLs in frames_list are also in resources_list. For those
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // URLs, we will remove it from frame_list, only keep them in resources_list.
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::set<GURL>::iterator it = frames_set.begin();
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != frames_set.end(); ++it) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Append unique frame source to savable frame list.
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (resources_set.find(*it) == resources_set.end())
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result->frames_list->push_back(*it);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace content
236