diff options
| author | yutak@chromium.org <yutak@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-01 05:16:36 +0000 | 
|---|---|---|
| committer | yutak@chromium.org <yutak@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-01 05:16:36 +0000 | 
| commit | 00ccade34090881c8e9917d54877892994dee741 (patch) | |
| tree | afae359311f490532974fc33a5aa34eefcbb007a | |
| parent | 9b880d34421a7d49655aeed6d339b2f7451591a7 (diff) | |
| download | chromium_src-00ccade34090881c8e9917d54877892994dee741.zip chromium_src-00ccade34090881c8e9917d54877892994dee741.tar.gz chromium_src-00ccade34090881c8e9917d54877892994dee741.tar.bz2 | |
Current firefox2 importer import bookmarks with strict rules.
This manner failed to import lazy html-based bookmarks like Epiphany's one.
Add hierarchical structure checs to import tests.
Patch contributed by Takashi Toyoshima <toyoshim@google.com>.
BUG=28517
TEST=Add epiphany bookmark import test into unit_tests and pass it
Review URL: http://codereview.chromium.org/6246024
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@73255 0039d316-1c4b-4281-b951-d872f2087c98
| -rw-r--r-- | chrome/browser/importer/firefox2_importer.cc | 65 | ||||
| -rw-r--r-- | chrome/browser/importer/firefox2_importer.h | 12 | ||||
| -rw-r--r-- | chrome/browser/importer/firefox_importer_unittest.cc | 105 | ||||
| -rw-r--r-- | chrome/test/data/firefox2_importer/epiphany.html | 5 | 
4 files changed, 170 insertions, 17 deletions
| diff --git a/chrome/browser/importer/firefox2_importer.cc b/chrome/browser/importer/firefox2_importer.cc index 2ecccb0..bf68af0 100644 --- a/chrome/browser/importer/firefox2_importer.cc +++ b/chrome/browser/importer/firefox2_importer.cc @@ -195,7 +195,9 @@ void Firefox2Importer::ImportBookmarksFile(      //                keywords yet.      is_bookmark = ParseBookmarkFromLine(line, charset, &title,                                          &url, &favicon, &shortcut, &add_date, -                                        &post_data); +                                        &post_data) || +        ParseMinimumBookmarkFromLine(line, charset, &title, &url); +      if (is_bookmark)        last_folder_is_empty = false; @@ -243,7 +245,7 @@ void Firefox2Importer::ImportBookmarksFile(      }      // Bookmarks in sub-folder are encapsulated with <DL> tag. -    if (StartsWithASCII(line, "<DL>", true)) { +    if (StartsWithASCII(line, "<DL>", false)) {        path.push_back(last_folder);        last_folder.clear();        if (last_folder_on_toolbar && !toolbar_folder) @@ -251,7 +253,7 @@ void Firefox2Importer::ImportBookmarksFile(        // Mark next folder empty as initial state.        last_folder_is_empty = true; -    } else if (StartsWithASCII(line, "</DL>", true)) { +    } else if (StartsWithASCII(line, "</DL>", false)) {        if (path.empty())          break;  // Mismatch <DL>. @@ -400,8 +402,9 @@ void Firefox2Importer::GetSearchEnginesXMLFiles(  bool Firefox2Importer::ParseCharsetFromLine(const std::string& line,                                              std::string* charset) {    const char kCharset[] = "charset="; -  if (StartsWithASCII(line, "<META", true) && -      line.find("CONTENT=\"") != std::string::npos) { +  if (StartsWithASCII(line, "<META", false) && +      (line.find("CONTENT=\"") != std::string::npos || +          line.find("content=\"") != std::string::npos)) {      size_t begin = line.find(kCharset);      if (begin == std::string::npos)        return false; @@ -550,6 +553,58 @@ bool Firefox2Importer::ParseBookmarkFromLine(const std::string& line,  }  // static +bool Firefox2Importer::ParseMinimumBookmarkFromLine(const std::string& line, +                                                    const std::string& charset, +                                                    std::wstring* title, +                                                    GURL* url) { +  const char kItemOpen[] = "<DT><A"; +  const char kItemClose[] = "</"; +  const char kHrefAttributeUpper[] = "HREF"; +  const char kHrefAttributeLower[] = "href"; + +  title->clear(); +  *url = GURL(); + +  // Case-insensitive check of open tag. +  if (!StartsWithASCII(line, kItemOpen, false)) +    return false; + +  // Find any close tag. +  size_t end = line.find(kItemClose); +  size_t tag_end = line.rfind('>', end) + 1; +  if (end == std::string::npos || tag_end < arraysize(kItemOpen)) +    return false;  // No end tag or start tag is broken. + +  std::string attribute_list = line.substr(arraysize(kItemOpen), +      tag_end - arraysize(kItemOpen) - 1); + +  // Title +  base::CodepageToWide(line.substr(tag_end, end - tag_end), charset.c_str(), +                       base::OnStringConversionError::SKIP, title); +  HTMLUnescape(title); + +  // URL +  std::string value; +  if (GetAttribute(attribute_list, kHrefAttributeUpper, &value) || +      GetAttribute(attribute_list, kHrefAttributeLower, &value)) { +    if (charset.length() != 0) { +      std::wstring w_url; +      base::CodepageToWide(value, charset.c_str(), +                           base::OnStringConversionError::SKIP, &w_url); +      HTMLUnescape(&w_url); + +      string16 url16 = WideToUTF16Hack(w_url); + +      *url = GURL(url16); +    } else { +      *url = GURL(value); +    } +  } + +  return true; +} + +// static  bool Firefox2Importer::GetAttribute(const std::string& attribute_list,                                      const std::string& attribute,                                      std::string* value) { diff --git a/chrome/browser/importer/firefox2_importer.h b/chrome/browser/importer/firefox2_importer.h index 8901e6f..7fef5e6 100644 --- a/chrome/browser/importer/firefox2_importer.h +++ b/chrome/browser/importer/firefox2_importer.h @@ -98,6 +98,18 @@ class Firefox2Importer : public Importer {                                      std::wstring* shortcut,                                      base::Time* add_date,                                      std::wstring* post_data); +  // Save bookmarks imported from browsers with Firefox2 compatible bookmark +  // systems such as Epiphany. This bookmark format is the same as that of the +  // basic Firefox bookmark, but it misses additional properties and uses +  // lower-case tag: +  //   ...<h1>Bookmarks</h1><dl> +  //   <dt><a href="url">name</a></dt> +  //   <dt><a href="url">name</a></dt> +  //   </dl> +  static bool ParseMinimumBookmarkFromLine(const std::string& line, +                                           const std::string& charset, +                                           std::wstring* title, +                                           GURL* url);    // Fetches the given attribute value from the |tag|. Returns true if    // successful, and |value| will contain the value. diff --git a/chrome/browser/importer/firefox_importer_unittest.cc b/chrome/browser/importer/firefox_importer_unittest.cc index 12e75f4..15bdb14 100644 --- a/chrome/browser/importer/firefox_importer_unittest.cc +++ b/chrome/browser/importer/firefox_importer_unittest.cc @@ -176,6 +176,14 @@ TEST(FirefoxImporterTest, Firefox2BookmarkParse) {    EXPECT_EQ(L"", shortcut);    EXPECT_EQ(L"", post_data);    EXPECT_TRUE(Time() == add_date); + +  // Epiphany format. +  result = Firefox2Importer::ParseMinimumBookmarkFromLine( +      "<dt><a href=\"http://www.google.com/\">Google</a></dt>", +      charset, &title, &url); +  EXPECT_TRUE(result); +  EXPECT_EQ(L"Google", title); +  EXPECT_EQ("http://www.google.com/", url.spec());  }  TEST(FirefoxImporterTest, Firefox2BookmarkFileImport) { @@ -194,13 +202,46 @@ TEST(FirefoxImporterTest, Firefox2BookmarkFileImport) {                                  first_folder_name, importer, &bookmarks,                                  NULL, NULL);    EXPECT_EQ(3, static_cast<int>(bookmarks.size())); -  std::vector<ProfileWriter::BookmarkEntry>::iterator it = bookmarks.begin(); -  ProfileWriter::BookmarkEntry entry = *it++; -  EXPECT_EQ(L"Empty", entry.title); -  entry = *it++; -  EXPECT_EQ(L"[Tamura Yukari.com]", entry.title); -  entry = *it++; -  EXPECT_EQ(L"Google", entry.title); +  std::vector<ProfileWriter::BookmarkEntry>::iterator it; +  ProfileWriter::BookmarkEntry entry; +  std::vector<std::wstring>::iterator path_it; +  if (bookmarks.size() == 3) { +    it = bookmarks.begin(); +    entry = *it++; +    EXPECT_EQ(L"Empty", entry.title); +    EXPECT_TRUE(entry.is_folder); +    EXPECT_EQ(Time::FromTimeT(1295938143), entry.creation_time); +    EXPECT_EQ(2, static_cast<int>(entry.path.size())); +    if (entry.path.size() == 2) { +      path_it = entry.path.begin(); +      EXPECT_EQ(L"", *path_it++); +      EXPECT_EQ(L"Empty's Parent", *path_it); +    } + +    entry = *it++; +    EXPECT_EQ(L"[Tamura Yukari.com]", entry.title); +    EXPECT_FALSE(entry.is_folder); +    EXPECT_EQ(Time::FromTimeT(1234567890), entry.creation_time); +    EXPECT_EQ(2, static_cast<int>(entry.path.size())); +    if (entry.path.size() == 2) { +      path_it = entry.path.begin(); +      EXPECT_EQ(L"", *path_it++); +      EXPECT_EQ(L"Not Empty", *path_it); +    } +    EXPECT_EQ("http://www.tamurayukari.com/", entry.url.spec()); + +    entry = *it++; +    EXPECT_EQ(L"Google", entry.title); +    EXPECT_FALSE(entry.is_folder); +    EXPECT_EQ(Time::FromTimeT(0000000000), entry.creation_time); +    EXPECT_EQ(2, static_cast<int>(entry.path.size())); +    if (entry.path.size() == 2) { +      path_it = entry.path.begin(); +      EXPECT_EQ(L"", *path_it++); +      EXPECT_EQ(L"Not Empty But Default", *path_it); +    } +    EXPECT_EQ("http://www.google.com/", entry.url.spec()); +  }    // Import non-default bookmarks from a file.    bookmarks.clear(); @@ -209,11 +250,51 @@ TEST(FirefoxImporterTest, Firefox2BookmarkFileImport) {                                  first_folder_name, importer, &bookmarks,                                  NULL, NULL);    EXPECT_EQ(2, static_cast<int>(bookmarks.size())); -  it = bookmarks.begin(); -  entry = *it++; -  EXPECT_EQ(L"Empty", entry.title); -  entry = *it++; -  EXPECT_EQ(L"[Tamura Yukari.com]", entry.title); +  if (bookmarks.size() == 2) { +    it = bookmarks.begin(); +    entry = *it++; +    EXPECT_EQ(L"Empty", entry.title); +    EXPECT_TRUE(entry.is_folder); +    EXPECT_EQ(Time::FromTimeT(1295938143), entry.creation_time); +    EXPECT_EQ(2, static_cast<int>(entry.path.size())); +    if (entry.path.size() == 2) { +      path_it = entry.path.begin(); +      EXPECT_EQ(L"", *path_it++); +      EXPECT_EQ(L"Empty's Parent", *path_it); +    } + +    entry = *it++; +    EXPECT_EQ(L"[Tamura Yukari.com]", entry.title); +    EXPECT_FALSE(entry.is_folder); +    EXPECT_EQ(Time::FromTimeT(1234567890), entry.creation_time); +    EXPECT_EQ(2, static_cast<int>(entry.path.size())); +    if (entry.path.size() == 2) { +      path_it = entry.path.begin(); +      EXPECT_EQ(L"", *path_it++); +      EXPECT_EQ(L"Not Empty", *path_it); +    } +    EXPECT_EQ("http://www.tamurayukari.com/", entry.url.spec()); +  } + +  // Import Epiphany bookmarks from a file +  FilePath epiphany_path = path.AppendASCII("epiphany.html"); +  bookmarks.clear(); +  default_urls.clear(); +  importer->ImportBookmarksFile(epiphany_path, default_urls, false, +                                first_folder_name, importer, &bookmarks, +                                NULL, NULL); +  EXPECT_EQ(2, static_cast<int>(bookmarks.size())); +  if (bookmarks.size() == 2) { +    it = bookmarks.begin(); +    entry = *it++; +    EXPECT_EQ(L"[Tamura Yukari.com]", entry.title); +    EXPECT_EQ("http://www.tamurayukari.com/", entry.url.spec()); +    EXPECT_EQ(0, static_cast<int>(entry.path.size())); +    entry = *it++; +    EXPECT_EQ(L"Google", entry.title); +    EXPECT_EQ("http://www.google.com/", entry.url.spec()); +    EXPECT_EQ(0, static_cast<int>(entry.path.size())); +  }    importer->Release();  } diff --git a/chrome/test/data/firefox2_importer/epiphany.html b/chrome/test/data/firefox2_importer/epiphany.html new file mode 100644 index 0000000..8fa3bbc --- /dev/null +++ b/chrome/test/data/firefox2_importer/epiphany.html @@ -0,0 +1,5 @@ +<!DOCTYPE NETSCAPE-Bookmark-file-1> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Bookmarks</title><h1>Bookmarks</h1><dl> +<dt><a href="http://www.tamurayukari.com/">[Tamura Yukari.com]</a></dt> +<dt><a href="http://www.google.com">Google</a></dt> +</dl> | 
