page_zoom.cc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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. #include "components/zoom/page_zoom.h"
  5. #include <stddef.h>
  6. #include <algorithm>
  7. #include <functional>
  8. #include "base/metrics/user_metrics.h"
  9. #include "components/zoom/page_zoom_constants.h"
  10. #include "components/zoom/zoom_controller.h"
  11. #include "content/public/browser/web_contents.h"
  12. #include "content/public/common/page_zoom.h"
  13. #include "third_party/blink/public/common/page/page_zoom.h"
  14. using base::UserMetricsAction;
  15. namespace {
  16. enum PageZoomValueType {
  17. PAGE_ZOOM_VALUE_TYPE_FACTOR,
  18. PAGE_ZOOM_VALUE_TYPE_LEVEL,
  19. };
  20. std::vector<double> PresetZoomValues(PageZoomValueType value_type,
  21. double custom_value) {
  22. // Generate a vector of zoom values from an array of known preset
  23. // factors. The values in content::kPresetZoomFactors will already be in
  24. // sorted order.
  25. std::vector<double> zoom_values;
  26. zoom_values.reserve(zoom::kPresetZoomFactorsSize);
  27. bool found_custom = false;
  28. for (size_t i = 0; i < zoom::kPresetZoomFactorsSize; i++) {
  29. double zoom_value = zoom::kPresetZoomFactors[i];
  30. if (value_type == PAGE_ZOOM_VALUE_TYPE_LEVEL)
  31. zoom_value = blink::PageZoomFactorToZoomLevel(zoom_value);
  32. if (blink::PageZoomValuesEqual(zoom_value, custom_value))
  33. found_custom = true;
  34. zoom_values.push_back(zoom_value);
  35. }
  36. // If the preset array did not contain the custom value, insert the value
  37. // while preserving the ordering.
  38. double min = zoom_values.front();
  39. double max = zoom_values.back();
  40. if (!found_custom && custom_value > min && custom_value < max) {
  41. zoom_values.insert(
  42. std::upper_bound(zoom_values.begin(), zoom_values.end(), custom_value),
  43. custom_value);
  44. }
  45. return zoom_values;
  46. }
  47. } // namespace anonymous
  48. namespace zoom {
  49. // static
  50. std::vector<double> PageZoom::PresetZoomFactors(double custom_factor) {
  51. return PresetZoomValues(PAGE_ZOOM_VALUE_TYPE_FACTOR, custom_factor);
  52. }
  53. // static
  54. std::vector<double> PageZoom::PresetZoomLevels(double custom_level) {
  55. return PresetZoomValues(PAGE_ZOOM_VALUE_TYPE_LEVEL, custom_level);
  56. }
  57. // static
  58. void PageZoom::Zoom(content::WebContents* web_contents,
  59. content::PageZoom zoom) {
  60. zoom::ZoomController* zoom_controller =
  61. zoom::ZoomController::FromWebContents(web_contents);
  62. if (!zoom_controller)
  63. return;
  64. double current_zoom_level = zoom_controller->GetZoomLevel();
  65. double default_zoom_level = zoom_controller->GetDefaultZoomLevel();
  66. if (zoom == content::PAGE_ZOOM_RESET) {
  67. zoom_controller->SetZoomLevel(default_zoom_level);
  68. web_contents->SetPageScale(1.f);
  69. base::RecordAction(UserMetricsAction("ZoomNormal"));
  70. return;
  71. }
  72. // Generate a vector of zoom levels from an array of known presets along with
  73. // the default level added if necessary.
  74. std::vector<double> zoom_levels = PresetZoomLevels(default_zoom_level);
  75. if (zoom == content::PAGE_ZOOM_OUT) {
  76. // Find the zoom level that is next lower than the current level for this
  77. // page.
  78. auto next_lower = std::upper_bound(zoom_levels.rbegin(), zoom_levels.rend(),
  79. current_zoom_level, std::greater<>());
  80. // If the next level is within epsilon of the current, keep going until
  81. // we're taking a meaningful step.
  82. while (next_lower != zoom_levels.rend() &&
  83. blink::PageZoomValuesEqual(*next_lower, current_zoom_level)) {
  84. ++next_lower;
  85. }
  86. if (next_lower == zoom_levels.rend()) {
  87. base::RecordAction(UserMetricsAction("ZoomMinus_AtMinimum"));
  88. } else {
  89. zoom_controller->SetZoomLevel(*next_lower);
  90. base::RecordAction(UserMetricsAction("ZoomMinus"));
  91. }
  92. } else {
  93. // Find the zoom level that is next higher than the current level for this
  94. // page.
  95. auto next_higher = std::upper_bound(zoom_levels.begin(), zoom_levels.end(),
  96. current_zoom_level);
  97. // If the next level is within epsilon of the current, keep going until
  98. // we're taking a meaningful step.
  99. while (next_higher != zoom_levels.end() &&
  100. blink::PageZoomValuesEqual(*next_higher, current_zoom_level)) {
  101. ++next_higher;
  102. }
  103. if (next_higher == zoom_levels.end()) {
  104. base::RecordAction(UserMetricsAction("ZoomPlus_AtMaximum"));
  105. } else {
  106. zoom_controller->SetZoomLevel(*next_higher);
  107. base::RecordAction(UserMetricsAction("ZoomPlus"));
  108. }
  109. }
  110. }
  111. } // namespace zoom