Commit 88843ebb authored by Nektarios Paisios's avatar Nektarios Paisios Committed by Commit Bot

AXSelection: Added the ability for a web app to cancel an accessibility SetSelection action

This functionality is based on the Selection API draft specification and is already supported in Blink by other types of user initiated selection actions:
https://w3c.github.io/selection-api/#selectstart-event

Tests are in the following patch:
https://chromium-review.googlesource.com/c/chromium/src/+/1350195/

R=dmazzoni@chromium.org

Bug: 639340
Change-Id: I5a7793c71b02f2e92fafb7fb9731b6ebf288a412
Tested: with unit tests in another patch
Reviewed-on: https://chromium-review.googlesource.com/c/1347214
Commit-Queue: Nektarios Paisios <nektar@chromium.org>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611400}
parent 7af47362
...@@ -4,8 +4,11 @@ ...@@ -4,8 +4,11 @@
#include "third_party/blink/renderer/modules/accessibility/ax_selection.h" #include "third_party/blink/renderer/modules/accessibility/ax_selection.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/dom/range.h" #include "third_party/blink/renderer/core/dom/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/editing/position.h"
#include "third_party/blink/renderer/core/editing/position_with_affinity.h" #include "third_party/blink/renderer/core/editing/position_with_affinity.h"
#include "third_party/blink/renderer/core/editing/selection_template.h" #include "third_party/blink/renderer/core/editing/selection_template.h"
#include "third_party/blink/renderer/core/editing/set_selection_options.h" #include "third_party/blink/renderer/core/editing/set_selection_options.h"
...@@ -15,6 +18,18 @@ ...@@ -15,6 +18,18 @@
namespace blink { namespace blink {
namespace {
DispatchEventResult DispatchSelectStart(Node* node) {
if (!node)
return DispatchEventResult::kNotCanceled;
return node->DispatchEvent(
*Event::CreateCancelableBubble(event_type_names::kSelectstart));
}
} // namespace
// //
// AXSelection::Builder // AXSelection::Builder
// //
...@@ -80,7 +95,7 @@ const AXSelection AXSelection::Builder::Build() { ...@@ -80,7 +95,7 @@ const AXSelection AXSelection::Builder::Build() {
// //
// static // static
void AXSelection::ClearCurrentSelection(const Document& document) { void AXSelection::ClearCurrentSelection(Document& document) {
LocalFrame* frame = document.GetFrame(); LocalFrame* frame = document.GetFrame();
if (!frame) if (!frame)
return; return;
...@@ -223,10 +238,10 @@ const SelectionInDOMTree AXSelection::AsSelection( ...@@ -223,10 +238,10 @@ const SelectionInDOMTree AXSelection::AsSelection(
return selection_builder.Build(); return selection_builder.Build();
} }
void AXSelection::Select(const AXSelectionBehavior selection_behavior) { bool AXSelection::Select(const AXSelectionBehavior selection_behavior) {
if (!IsValid()) { if (!IsValid()) {
NOTREACHED() << "Trying to select an invalid accessibility selection."; NOTREACHED() << "Trying to select an invalid accessibility selection.";
return; return false;
} }
const SelectionInDOMTree selection = AsSelection(selection_behavior); const SelectionInDOMTree selection = AsSelection(selection_behavior);
...@@ -234,23 +249,31 @@ void AXSelection::Select(const AXSelectionBehavior selection_behavior) { ...@@ -234,23 +249,31 @@ void AXSelection::Select(const AXSelectionBehavior selection_behavior) {
Document* document = selection.Base().GetDocument(); Document* document = selection.Base().GetDocument();
if (!document) { if (!document) {
NOTREACHED(); NOTREACHED();
return; return false;
} }
LocalFrame* frame = document->GetFrame(); LocalFrame* frame = document->GetFrame();
if (!frame) { if (!frame) {
NOTREACHED(); NOTREACHED();
return; return false;
} }
FrameSelection& frame_selection = frame->Selection(); FrameSelection& frame_selection = frame->Selection();
if (!frame_selection.IsAvailable()) if (!frame_selection.IsAvailable())
return; return false;
// See the following section in the Selection API Specification:
// https://w3c.github.io/selection-api/#selectstart-event
if (DispatchSelectStart(selection.Extent().ComputeContainerNode()) !=
DispatchEventResult::kNotCanceled) {
return false;
}
SetSelectionOptions::Builder options_builder; SetSelectionOptions::Builder options_builder;
options_builder.SetIsDirectional(true) options_builder.SetIsDirectional(true)
.SetShouldCloseTyping(true) .SetShouldCloseTyping(true)
.SetShouldClearTypingStyle(true); .SetShouldClearTypingStyle(true)
.SetSetSelectionBy(SetSelectionBy::kUser);
frame_selection.ClearDocumentCachedRange(); frame_selection.ClearDocumentCachedRange();
frame_selection.SetSelection(selection, options_builder.Build()); frame_selection.SetSelection(selection, options_builder.Build());
...@@ -281,6 +304,7 @@ void AXSelection::Select(const AXSelectionBehavior selection_behavior) { ...@@ -281,6 +304,7 @@ void AXSelection::Select(const AXSelectionBehavior selection_behavior) {
selection.Base().ComputeOffsetInContainerNode()); selection.Base().ComputeOffsetInContainerNode());
} }
frame_selection.CacheRangeOfDocument(range); frame_selection.CacheRangeOfDocument(range);
return true;
} }
String AXSelection::ToString() const { String AXSelection::ToString() const {
......
...@@ -39,7 +39,7 @@ class MODULES_EXPORT AXSelection final { ...@@ -39,7 +39,7 @@ class MODULES_EXPORT AXSelection final {
public: public:
class Builder; class Builder;
static void ClearCurrentSelection(const Document&); static void ClearCurrentSelection(Document&);
static AXSelection FromCurrentSelection( static AXSelection FromCurrentSelection(
const Document&, const Document&,
...@@ -66,8 +66,10 @@ class MODULES_EXPORT AXSelection final { ...@@ -66,8 +66,10 @@ class MODULES_EXPORT AXSelection final {
const AXSelectionBehavior = const AXSelectionBehavior =
AXSelectionBehavior::kExtendToValidDOMRange) const; AXSelectionBehavior::kExtendToValidDOMRange) const;
// Tries to set the DOM selection to this. // Tries to set the DOM selection to this. Returns |false| if the selection
void Select( // has been cancelled via the "selectionstart" event or if the selection could
// not be set for any other reason.
bool Select(
const AXSelectionBehavior = AXSelectionBehavior::kExtendToValidDOMRange); const AXSelectionBehavior = AXSelectionBehavior::kExtendToValidDOMRange);
// Returns a string representation of this object. // Returns a string representation of this object.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment