[Blink] Expose selection region bounding box to Browser
This CL adds an extra parameter to SelectionBoundsChanged() to expose the bounds of the rectangle which encloses the selection region, i.e. bounding box, to the browser side. The bounding box's value should be same with the result from Window.getSelection(). This CL is a part of the efforts to polish the multipaste's HTML preview with knowledge of bounding box. No visual difference should be introduced. Bug: 1165302 Change-Id: I33dfad2b93a9580e1937b203da6d3a1874141d03 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2791842 Reviewed-by: Tommy Li <tommycli@chromium.org> Reviewed-by: Kinuko Yasuda <kinuko@chromium.org> Reviewed-by: Peter Kasting <pkasting@chromium.org> Reviewed-by: Ken Buchanan <kenrb@chromium.org> Commit-Queue: Andrew Xu <andrewxu@chromium.org> Cr-Commit-Position: refs/heads/master@{#868540}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
601cc26c0d
commit
4725d23b1d
components/plugins/renderer
content
browser
renderer_host
public
third_party/blink
public
mojom
page
renderer
@ -191,6 +191,7 @@ class WebViewPlugin : public blink::WebPlugin, public blink::WebViewObserver {
|
|||||||
base::i18n::TextDirection anchor_dir,
|
base::i18n::TextDirection anchor_dir,
|
||||||
const gfx::Rect& focus_rect,
|
const gfx::Rect& focus_rect,
|
||||||
base::i18n::TextDirection focus_dir,
|
base::i18n::TextDirection focus_dir,
|
||||||
|
const gfx::Rect& bounding_box,
|
||||||
bool is_anchor_first) override {}
|
bool is_anchor_first) override {}
|
||||||
void CreateFrameSink(
|
void CreateFrameSink(
|
||||||
mojo::PendingReceiver<viz::mojom::CompositorFrameSink>
|
mojo::PendingReceiver<viz::mojom::CompositorFrameSink>
|
||||||
|
@ -2145,6 +2145,7 @@ void RenderWidgetHostImpl::SelectionBoundsChanged(
|
|||||||
base::i18n::TextDirection anchor_dir,
|
base::i18n::TextDirection anchor_dir,
|
||||||
const gfx::Rect& focus_rect,
|
const gfx::Rect& focus_rect,
|
||||||
base::i18n::TextDirection focus_dir,
|
base::i18n::TextDirection focus_dir,
|
||||||
|
const gfx::Rect& bounding_box,
|
||||||
bool is_anchor_first) {
|
bool is_anchor_first) {
|
||||||
if (view_)
|
if (view_)
|
||||||
view_->SelectionBoundsChanged(anchor_rect, anchor_dir, focus_rect,
|
view_->SelectionBoundsChanged(anchor_rect, anchor_dir, focus_rect,
|
||||||
|
@ -301,6 +301,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl
|
|||||||
base::i18n::TextDirection anchor_dir,
|
base::i18n::TextDirection anchor_dir,
|
||||||
const gfx::Rect& focus_rect,
|
const gfx::Rect& focus_rect,
|
||||||
base::i18n::TextDirection focus_dir,
|
base::i18n::TextDirection focus_dir,
|
||||||
|
const gfx::Rect& bounding_box,
|
||||||
bool is_anchor_first) override;
|
bool is_anchor_first) override;
|
||||||
void CreateFrameSink(
|
void CreateFrameSink(
|
||||||
mojo::PendingReceiver<viz::mojom::CompositorFrameSink>
|
mojo::PendingReceiver<viz::mojom::CompositorFrameSink>
|
||||||
|
@ -60,6 +60,7 @@ void FakeRenderWidgetHost::SelectionBoundsChanged(
|
|||||||
base::i18n::TextDirection anchor_dir,
|
base::i18n::TextDirection anchor_dir,
|
||||||
const gfx::Rect& focus_rect,
|
const gfx::Rect& focus_rect,
|
||||||
base::i18n::TextDirection focus_dir,
|
base::i18n::TextDirection focus_dir,
|
||||||
|
const gfx::Rect& bounding_box,
|
||||||
bool is_anchor_first) {}
|
bool is_anchor_first) {}
|
||||||
|
|
||||||
void FakeRenderWidgetHost::CreateFrameSink(
|
void FakeRenderWidgetHost::CreateFrameSink(
|
||||||
|
@ -61,6 +61,7 @@ class FakeRenderWidgetHost : public blink::mojom::FrameWidgetHost,
|
|||||||
base::i18n::TextDirection anchor_dir,
|
base::i18n::TextDirection anchor_dir,
|
||||||
const gfx::Rect& focus_rect,
|
const gfx::Rect& focus_rect,
|
||||||
base::i18n::TextDirection focus_dir,
|
base::i18n::TextDirection focus_dir,
|
||||||
|
const gfx::Rect& bounding_box,
|
||||||
bool is_anchor_first) override;
|
bool is_anchor_first) override;
|
||||||
void CreateFrameSink(
|
void CreateFrameSink(
|
||||||
mojo::PendingReceiver<viz::mojom::CompositorFrameSink>
|
mojo::PendingReceiver<viz::mojom::CompositorFrameSink>
|
||||||
|
@ -254,6 +254,7 @@ interface WidgetHost {
|
|||||||
mojo_base.mojom.TextDirection anchor_dir,
|
mojo_base.mojom.TextDirection anchor_dir,
|
||||||
gfx.mojom.Rect focus_rect,
|
gfx.mojom.Rect focus_rect,
|
||||||
mojo_base.mojom.TextDirection focus_dir,
|
mojo_base.mojom.TextDirection focus_dir,
|
||||||
|
gfx.mojom.Rect bounding_box_rect,
|
||||||
bool is_anchor_first);
|
bool is_anchor_first);
|
||||||
|
|
||||||
// Create a CompositorFrameSink that is associated with this widget.
|
// Create a CompositorFrameSink that is associated with this widget.
|
||||||
|
@ -869,6 +869,7 @@ void TestWebFrameWidgetHost::SelectionBoundsChanged(
|
|||||||
base::i18n::TextDirection anchor_dir,
|
base::i18n::TextDirection anchor_dir,
|
||||||
const gfx::Rect& focus_rect,
|
const gfx::Rect& focus_rect,
|
||||||
base::i18n::TextDirection focus_dir,
|
base::i18n::TextDirection focus_dir,
|
||||||
|
const gfx::Rect& bounding_box,
|
||||||
bool is_anchor_first) {}
|
bool is_anchor_first) {}
|
||||||
|
|
||||||
void TestWebFrameWidgetHost::CreateFrameSink(
|
void TestWebFrameWidgetHost::CreateFrameSink(
|
||||||
|
@ -195,6 +195,7 @@ class TestWebFrameWidgetHost : public mojom::blink::WidgetHost,
|
|||||||
base::i18n::TextDirection anchor_dir,
|
base::i18n::TextDirection anchor_dir,
|
||||||
const gfx::Rect& focus_rect,
|
const gfx::Rect& focus_rect,
|
||||||
base::i18n::TextDirection focus_dir,
|
base::i18n::TextDirection focus_dir,
|
||||||
|
const gfx::Rect& bounding_box,
|
||||||
bool is_anchor_first) override;
|
bool is_anchor_first) override;
|
||||||
void CreateFrameSink(
|
void CreateFrameSink(
|
||||||
mojo::PendingReceiver<viz::mojom::blink::CompositorFrameSink>
|
mojo::PendingReceiver<viz::mojom::blink::CompositorFrameSink>
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
#include "third_party/blink/renderer/core/core_initializer.h"
|
#include "third_party/blink/renderer/core/core_initializer.h"
|
||||||
#include "third_party/blink/renderer/core/dom/element.h"
|
#include "third_party/blink/renderer/core/dom/element.h"
|
||||||
#include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h"
|
#include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h"
|
||||||
|
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
|
||||||
#include "third_party/blink/renderer/core/editing/frame_selection.h"
|
#include "third_party/blink/renderer/core/editing/frame_selection.h"
|
||||||
#include "third_party/blink/renderer/core/events/current_input_event.h"
|
#include "third_party/blink/renderer/core/events/current_input_event.h"
|
||||||
#include "third_party/blink/renderer/core/events/web_input_event_conversion.h"
|
#include "third_party/blink/renderer/core/events/web_input_event_conversion.h"
|
||||||
@ -3013,6 +3014,7 @@ void WebFrameWidgetImpl::ResetVirtualKeyboardVisibilityRequest() {
|
|||||||
bool WebFrameWidgetImpl::GetSelectionBoundsInWindow(
|
bool WebFrameWidgetImpl::GetSelectionBoundsInWindow(
|
||||||
gfx::Rect* focus,
|
gfx::Rect* focus,
|
||||||
gfx::Rect* anchor,
|
gfx::Rect* anchor,
|
||||||
|
gfx::Rect* bounding_box,
|
||||||
base::i18n::TextDirection* focus_dir,
|
base::i18n::TextDirection* focus_dir,
|
||||||
base::i18n::TextDirection* anchor_dir,
|
base::i18n::TextDirection* anchor_dir,
|
||||||
bool* is_anchor_first) {
|
bool* is_anchor_first) {
|
||||||
@ -3031,17 +3033,22 @@ bool WebFrameWidgetImpl::GetSelectionBoundsInWindow(
|
|||||||
}
|
}
|
||||||
gfx::Rect focus_root_frame;
|
gfx::Rect focus_root_frame;
|
||||||
gfx::Rect anchor_root_frame;
|
gfx::Rect anchor_root_frame;
|
||||||
CalculateSelectionBounds(focus_root_frame, anchor_root_frame);
|
gfx::Rect bounding_box_root_frame;
|
||||||
|
CalculateSelectionBounds(focus_root_frame, anchor_root_frame,
|
||||||
|
&bounding_box_root_frame);
|
||||||
gfx::Rect focus_rect_in_dips =
|
gfx::Rect focus_rect_in_dips =
|
||||||
widget_base_->BlinkSpaceToEnclosedDIPs(gfx::Rect(focus_root_frame));
|
widget_base_->BlinkSpaceToEnclosedDIPs(gfx::Rect(focus_root_frame));
|
||||||
gfx::Rect anchor_rect_in_dips =
|
gfx::Rect anchor_rect_in_dips =
|
||||||
widget_base_->BlinkSpaceToEnclosedDIPs(gfx::Rect(anchor_root_frame));
|
widget_base_->BlinkSpaceToEnclosedDIPs(gfx::Rect(anchor_root_frame));
|
||||||
|
gfx::Rect bounding_box_in_dips = widget_base_->BlinkSpaceToEnclosedDIPs(
|
||||||
|
gfx::Rect(bounding_box_root_frame));
|
||||||
|
|
||||||
// if the bounds are the same return false.
|
// if the bounds are the same return false.
|
||||||
if (focus_rect_in_dips == *focus && anchor_rect_in_dips == *anchor)
|
if (focus_rect_in_dips == *focus && anchor_rect_in_dips == *anchor)
|
||||||
return false;
|
return false;
|
||||||
*focus = focus_rect_in_dips;
|
*focus = focus_rect_in_dips;
|
||||||
*anchor = anchor_rect_in_dips;
|
*anchor = anchor_rect_in_dips;
|
||||||
|
*bounding_box = bounding_box_in_dips;
|
||||||
|
|
||||||
WebLocalFrame* focused_frame = FocusedWebLocalFrameInWidget();
|
WebLocalFrame* focused_frame = FocusedWebLocalFrameInWidget();
|
||||||
if (!focused_frame)
|
if (!focused_frame)
|
||||||
@ -3606,15 +3613,18 @@ void WebFrameWidgetImpl::ForEachRemoteFrameControlledByWidget(
|
|||||||
callback);
|
callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebFrameWidgetImpl::CalculateSelectionBounds(gfx::Rect& anchor_root_frame,
|
void WebFrameWidgetImpl::CalculateSelectionBounds(
|
||||||
gfx::Rect& focus_root_frame) {
|
gfx::Rect& anchor_root_frame,
|
||||||
|
gfx::Rect& focus_root_frame,
|
||||||
|
gfx::Rect* bounding_box_in_root_frame) {
|
||||||
const LocalFrame* local_frame = FocusedLocalFrameInWidget();
|
const LocalFrame* local_frame = FocusedLocalFrameInWidget();
|
||||||
if (!local_frame)
|
if (!local_frame)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IntRect anchor;
|
IntRect anchor;
|
||||||
IntRect focus;
|
IntRect focus;
|
||||||
if (!local_frame->Selection().ComputeAbsoluteBounds(anchor, focus))
|
auto& selection = local_frame->Selection();
|
||||||
|
if (!selection.ComputeAbsoluteBounds(anchor, focus))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Apply the visual viewport for main frames this will apply the page scale.
|
// Apply the visual viewport for main frames this will apply the page scale.
|
||||||
@ -3625,6 +3635,15 @@ void WebFrameWidgetImpl::CalculateSelectionBounds(gfx::Rect& anchor_root_frame,
|
|||||||
local_frame->View()->ConvertToRootFrame(anchor));
|
local_frame->View()->ConvertToRootFrame(anchor));
|
||||||
focus_root_frame = visual_viewport.RootFrameToViewport(
|
focus_root_frame = visual_viewport.RootFrameToViewport(
|
||||||
local_frame->View()->ConvertToRootFrame(focus));
|
local_frame->View()->ConvertToRootFrame(focus));
|
||||||
|
|
||||||
|
// Calculate the bounding box of the selection area.
|
||||||
|
if (bounding_box_in_root_frame) {
|
||||||
|
const IntRect bounding_box = EnclosingIntRect(
|
||||||
|
CreateRange(selection.GetSelectionInDOMTree().ComputeRange())
|
||||||
|
->BoundingRect());
|
||||||
|
*bounding_box_in_root_frame = visual_viewport.RootFrameToViewport(
|
||||||
|
local_frame->View()->ConvertToRootFrame(bounding_box));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebFrameWidgetImpl::BatterySavingsChanged(BatterySavingsFlags savings) {
|
void WebFrameWidgetImpl::BatterySavingsChanged(BatterySavingsFlags savings) {
|
||||||
|
@ -229,6 +229,7 @@ class CORE_EXPORT WebFrameWidgetImpl
|
|||||||
void ResetVirtualKeyboardVisibilityRequest() override;
|
void ResetVirtualKeyboardVisibilityRequest() override;
|
||||||
bool GetSelectionBoundsInWindow(gfx::Rect* focus,
|
bool GetSelectionBoundsInWindow(gfx::Rect* focus,
|
||||||
gfx::Rect* anchor,
|
gfx::Rect* anchor,
|
||||||
|
gfx::Rect* bounding_box,
|
||||||
base::i18n::TextDirection* focus_dir,
|
base::i18n::TextDirection* focus_dir,
|
||||||
base::i18n::TextDirection* anchor_dir,
|
base::i18n::TextDirection* anchor_dir,
|
||||||
bool* is_anchor_first) override;
|
bool* is_anchor_first) override;
|
||||||
@ -538,8 +539,10 @@ class CORE_EXPORT WebFrameWidgetImpl
|
|||||||
|
|
||||||
// Calculates the selection bounds in the root frame. Returns bounds unchanged
|
// Calculates the selection bounds in the root frame. Returns bounds unchanged
|
||||||
// when there is no focused frame or no selection.
|
// when there is no focused frame or no selection.
|
||||||
void CalculateSelectionBounds(gfx::Rect& anchor_in_root_frame,
|
void CalculateSelectionBounds(
|
||||||
gfx::Rect& focus_in_root_frame);
|
gfx::Rect& anchor_in_root_frame,
|
||||||
|
gfx::Rect& focus_in_root_frame,
|
||||||
|
gfx::Rect* bounding_box_in_root_frame = nullptr);
|
||||||
|
|
||||||
// Returns if auto resize mode is enabled.
|
// Returns if auto resize mode is enabled.
|
||||||
bool AutoResizeMode();
|
bool AutoResizeMode();
|
||||||
|
@ -162,6 +162,7 @@ class PLATFORM_EXPORT FrameWidget {
|
|||||||
// bounds returned were different than the passed in focus and anchor bounds.
|
// bounds returned were different than the passed in focus and anchor bounds.
|
||||||
virtual bool GetSelectionBoundsInWindow(gfx::Rect* focus,
|
virtual bool GetSelectionBoundsInWindow(gfx::Rect* focus,
|
||||||
gfx::Rect* anchor,
|
gfx::Rect* anchor,
|
||||||
|
gfx::Rect* bounding_box,
|
||||||
base::i18n::TextDirection* focus_dir,
|
base::i18n::TextDirection* focus_dir,
|
||||||
base::i18n::TextDirection* anchor_dir,
|
base::i18n::TextDirection* anchor_dir,
|
||||||
bool* is_anchor_first) = 0;
|
bool* is_anchor_first) = 0;
|
||||||
|
@ -1150,11 +1150,12 @@ void WidgetBase::UpdateSelectionBounds() {
|
|||||||
if (!frame_widget)
|
if (!frame_widget)
|
||||||
return;
|
return;
|
||||||
if (frame_widget->GetSelectionBoundsInWindow(
|
if (frame_widget->GetSelectionBoundsInWindow(
|
||||||
&selection_focus_rect_, &selection_anchor_rect_, &focus_dir,
|
&selection_focus_rect_, &selection_anchor_rect_,
|
||||||
&anchor_dir, &is_anchor_first)) {
|
&selection_bounding_box_, &focus_dir, &anchor_dir,
|
||||||
widget_host_->SelectionBoundsChanged(selection_anchor_rect_, anchor_dir,
|
&is_anchor_first)) {
|
||||||
selection_focus_rect_, focus_dir,
|
widget_host_->SelectionBoundsChanged(
|
||||||
is_anchor_first);
|
selection_anchor_rect_, anchor_dir, selection_focus_rect_, focus_dir,
|
||||||
|
selection_bounding_box_, is_anchor_first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UpdateCompositionInfo(false /* not an immediate request */);
|
UpdateCompositionInfo(false /* not an immediate request */);
|
||||||
|
@ -396,6 +396,7 @@ class PLATFORM_EXPORT WidgetBase : public mojom::blink::Widget,
|
|||||||
// Stores the current selection bounds.
|
// Stores the current selection bounds.
|
||||||
gfx::Rect selection_focus_rect_;
|
gfx::Rect selection_focus_rect_;
|
||||||
gfx::Rect selection_anchor_rect_;
|
gfx::Rect selection_anchor_rect_;
|
||||||
|
gfx::Rect selection_bounding_box_;
|
||||||
|
|
||||||
// Stores the current composition character bounds.
|
// Stores the current composition character bounds.
|
||||||
Vector<gfx::Rect> composition_character_bounds_;
|
Vector<gfx::Rect> composition_character_bounds_;
|
||||||
|
Reference in New Issue
Block a user