1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_SPATIAL_NAVIGATION_CONTROLLER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_SPATIAL_NAVIGATION_CONTROLLER_H_
#include "third_party/blink/public/mojom/page/spatial_navigation.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/page/spatial_navigation.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
struct FocusCandidate;
class KeyboardEvent;
class LayoutRect;
class Node;
class Page;
// Encapsulates logic and state related to "spatial navigation". Spatial
// Navigation is used to move and interact with a page in a purely directional
// way, e.g. keyboard arrows. We use the term "interest" to specify which
// element the user is currently on.
class CORE_EXPORT SpatialNavigationController
: public GarbageCollectedFinalized<SpatialNavigationController> {
public:
explicit SpatialNavigationController(Page& page);
bool HandleArrowKeyboardEvent(KeyboardEvent* event);
bool HandleEnterKeyboardEvent(KeyboardEvent* event);
bool HandleEscapeKeyboardEvent(KeyboardEvent* event);
// Returns the element that's currently interested. i.e. the Element that's
// currently indicated to the user.
Element* GetInterestedElement() const;
void DidDetachFrameView();
void OnSpatialNavigationSettingChanged();
void FocusedNodeChanged(Document*);
void ResetMojoBindings();
void Trace(blink::Visitor*);
private:
// Entry-point into SpatialNavigation advancement. Will return true if an
// action (moving interest or scrolling), false otherwise.
bool Advance(SpatialNavigationDirection direction);
/*
* Advances interest only within the specified container. Returns true if
* interest was advanced or the container was scrolled, false if no
* advancement was possible within the container.
*
* container - The scrollable container within which to limit advancement.
* starting_rect_in_root_frame - The rect to use to begin searching for the
* next node. Intuitively, the interest node's
* rect (but sometimes different for scrollers).
* direction - Direction of advancement
* interest_child_in_container - The inner-most child _within this container_
* where interest is located. This may differ
* from the starting_rect as the interest node
* may be in a nested container.
*/
bool AdvanceWithinContainer(Node& container,
const LayoutRect& starting_rect_in_root_frame,
SpatialNavigationDirection direction,
Node* interest_child_in_container);
// Parameters have same meanings as method above.
FocusCandidate FindNextCandidateInContainer(
Node& container,
const LayoutRect& starting_rect_in_root_frame,
SpatialNavigationDirection direction,
Node* interest_child_in_container);
// Returns which Node we're starting navigation from or nullptr if we should
// abort navigation.
Node* StartingNode();
void MoveInterestTo(Node* next_node);
// Dispatches a fake mouse move event at the center of the given element to
// produce hover state and mouse enter/exit events. If no element is given,
// we dispatch a mouse event outside of the page to simulate the pointer
// leaving the page (and clearing hover, producing mouse leave).
void DispatchMouseMoveAt(Element* element);
// Returns true if the element should be considered for navigation.
bool IsValidCandidate(const Element* element) const;
Element* GetFocusedElement() const;
void UpdateSpatialNavigationState(Element* element);
void OnSpatialNavigationStateChanged();
bool UpdateCanExitFocus(Element* element);
bool UpdateCanSelectInterestedElement(Element* element);
bool UpdateHasNextFormElement(Element* element);
bool UpdateHasDefaultVideoControls(Element* element);
const mojom::blink::SpatialNavigationHostPtr& GetSpatialNavigationHost();
// The currently indicated element or nullptr if no node is indicated by
// spatial navigation.
WeakMember<Element> interest_element_;
Member<Page> page_;
mojom::blink::SpatialNavigationStatePtr spatial_navigation_state_;
mojom::blink::SpatialNavigationHostPtr spatial_navigation_host_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_SPATIAL_NAVIGATION_CONTROLLER_H_
|