Percent-encode UTF8 characters in URL fragment identifiers.

This brings us into line with Firefox, Safari, and the spec.

Bug: 758523
Change-Id: I7e354ab441222d9fd08e45f0e70f91ad4e35fafe
Reviewed-on: https://chromium-review.googlesource.com/668363
Commit-Queue: Mike West <mkwst@chromium.org>
Reviewed-by: Jochen Eisinger <jochen@chromium.org>
Reviewed-by: Andy Paicu <andypaicu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#507481}
void RunProgressiveElisionTest(
    const std::vector<ProgressiveTestcase>& testcases,
    ElisionMethod method) {
  const gfx::FontList font_list;
  for (const auto& testcase : testcases) {
    SCOPED_TRACE("Eliding " + testcase.input);
    const GURL url(testcase.input);

    ASSERT_FALSE(testcase.output.empty());
    float width = std::max(
        gfx::GetStringWidthF(base::UTF8ToUTF16(testcase.input), font_list),
        gfx::GetStringWidthF(base::UTF8ToUTF16(testcase.output.front()),
                             font_list));

    int mismatches = 0;
    const int kMaxConsecutiveMismatches = 3;
    for (size_t i = 0; i < testcase.output.size(); i++) {
      const auto& expected = testcase.output[i];
      base::string16 expected_utf16 = base::UTF8ToUTF16(expected);
      base::string16 elided = Elide(url, font_list, width, method);
      if (expected_utf16 != elided) {
        if (i > 0 && i < testcase.output.size() - 1 &&
            mismatches < kMaxConsecutiveMismatches) {
          mismatches++;
          continue;
        }
        EXPECT_EQ(expected_utf16, elided);
        break;
      }
      mismatches = 0;
      float new_width = gfx::GetStringWidthF(elided, font_list);
      EXPECT_LE(new_width, std::ceil(width)) << " at " << elided;
      width = new_width - 1.0f;
    }
  }
}

void RunProgressiveElisionTest(
    const std::vector<ProgressiveTestcase>& testcases,
    ElisionMethod method) {
  const gfx::FontList font_list;
  for (const auto& testcase : testcases) {
    SCOPED_TRACE("Eliding " + testcase.input);
    const GURL url(testcase.input);

    ASSERT_FALSE(testcase.output.empty());
    float width = std::max(
        gfx::GetStringWidthF(base::UTF8ToUTF16(testcase.input), font_list),
        gfx::GetStringWidthF(base::UTF8ToUTF16(testcase.output.front()),
                             font_list));

    int mismatches = 0;
    const int kMaxConsecutiveMismatches = 3;
    for (size_t i = 0; i < testcase.output.size(); i++) {
      const auto& expected = testcase.output[i];
      base::string16 expected_utf16 = base::UTF8ToUTF16(expected);
      base::string16 elided = Elide(url, font_list, width, method);
      if (expected_utf16 != elided) {
        if (i > 0 && i < testcase.output.size() - 1 &&
            mismatches < kMaxConsecutiveMismatches) {
          mismatches++;
          continue;
        }
        EXPECT_EQ(expected_utf16, elided);
        break;
      }
      mismatches = 0;
      float new_width = gfx::GetStringWidthF(elided, font_list);
      EXPECT_LE(new_width, std::ceil(width)) << " at " << elided;
      width = new_width - 1.0f;
    }
  }
}
