Changeset 274812 in webkit


Ignore:
Timestamp:
Mar 22, 2021 3:29:52 PM (3 years ago)
Author:
commit-queue@webkit.org
Message:

Enable ability to prevent scrolling in Element.focus()
https://bugs.webkit.org/show_bug.cgi?id=178583

Patch by Rob Buis <rbuis@igalia.com> on 2021-03-22
Reviewed by Simon Fraser.

LayoutTests/imported/w3c:

Update improved test result.

  • web-platform-tests/html/interaction/focus/processing-model/preventScroll-nested-scroll-elements-expected.txt: Added.
  • web-platform-tests/html/interaction/focus/processing-model/preventScroll-nested-scroll-elements.html: Added.
  • web-platform-tests/html/interaction/focus/processing-model/preventScroll-textarea-expected.txt:

Source/WebCore:

Add FocusOptions parameter to the focus method [1] both
to the IDL as the C++ side. Change Element.focus to not
scroll if FocusOptions.preventScroll is true.

Behavior matches Chrome and Firefox.

Tests: imported/w3c/web-platform-tests/html/interaction/focus/processing-model/preventScroll-textarea.html

imported/w3c/web-platform-tests/html/interaction/focus/processing-model/preventScroll-nested-scroll-elements.html

Test: imported/w3c/web-platform-tests/html/interaction/focus/processing-model/preventScroll-nested-scroll-elements.html

  • CMakeLists.txt:
  • DerivedSources-input.xcfilelist:
  • DerivedSources-output.xcfilelist:
  • DerivedSources.make:
  • Headers.cmake:
  • Sources.txt:
  • WebCore.xcodeproj/project.pbxproj:
  • dom/Element.cpp:

(WebCore::Element::focus):

  • dom/Element.h:

(WebCore::Element::focus):

  • dom/FocusOptions.h: Copied from Source/WebCore/html/HTMLOrForeignElement.idl.
  • dom/FocusOptions.idl: Copied from Source/WebCore/html/HTMLOrForeignElement.idl.
  • html/HTMLFormControlElement.cpp:

(WebCore::HTMLFormControlElement::didAttachRenderers):

  • html/HTMLLabelElement.cpp:

(WebCore::HTMLLabelElement::focus):

  • html/HTMLLabelElement.h:
  • html/HTMLLegendElement.cpp:

(WebCore::HTMLLegendElement::focus):

  • html/HTMLLegendElement.h:
  • html/HTMLOrForeignElement.idl:
  • html/InputType.cpp:

(WebCore::InputType::accessKeyAction):

  • page/FocusController.cpp:

(WebCore::FocusController::advanceFocusInDocumentOrder):
(WebCore::FocusController::advanceFocusDirectionallyInContainer):

LayoutTests:

The test preventScroll-textarea.html now passes on all platforms.

  • platform/ios-wk2/imported/w3c/web-platform-tests/html/interaction/focus/processing-model/preventScroll-textarea-expected.txt: Removed.
  • platform/mac-wk1/imported/w3c/web-platform-tests/html/interaction/focus/processing-model/preventScroll-textarea-expected.txt: Removed.
Location:
trunk
Files:
2 added
2 deleted
21 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r274810 r274812  
     12021-03-22  Rob Buis  <rbuis@igalia.com>
     2
     3        Enable ability to prevent scrolling in Element.focus()
     4        https://bugs.webkit.org/show_bug.cgi?id=178583
     5
     6        Reviewed by Simon Fraser.
     7
     8        The test preventScroll-textarea.html now passes on all platforms.
     9
     10        * platform/ios-wk2/imported/w3c/web-platform-tests/html/interaction/focus/processing-model/preventScroll-textarea-expected.txt: Removed.
     11        * platform/mac-wk1/imported/w3c/web-platform-tests/html/interaction/focus/processing-model/preventScroll-textarea-expected.txt: Removed.
     12
    1132021-03-22  Devin Rousso  <drousso@apple.com>
    214
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r274794 r274812  
     12021-03-22  Rob Buis  <rbuis@igalia.com>
     2
     3        Enable ability to prevent scrolling in Element.focus()
     4        https://bugs.webkit.org/show_bug.cgi?id=178583
     5
     6        Reviewed by Simon Fraser.
     7
     8        Update improved test result.
     9
     10        * web-platform-tests/html/interaction/focus/processing-model/preventScroll-nested-scroll-elements-expected.txt: Added.
     11        * web-platform-tests/html/interaction/focus/processing-model/preventScroll-nested-scroll-elements.html: Added.
     12        * web-platform-tests/html/interaction/focus/processing-model/preventScroll-textarea-expected.txt:
     13
    1142021-03-22  Chris Dumez  <cdumez@apple.com>
    215
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/interaction/focus/processing-model/preventScroll-textarea-expected.txt

    r267646 r274812  
    11
    22
    3 FAIL preventScroll: true on a textarea element assert_equals: TEXTAREA: Should not have scrolled after a couple event loop ticks expected 0 but got 920
     3PASS preventScroll: true on a textarea element
    44
  • trunk/Source/WebCore/CMakeLists.txt

    r274557 r274812  
    849849    dom/EventTarget.idl
    850850    dom/FocusEvent.idl
     851    dom/FocusOptions.idl
    851852    dom/GlobalEventHandlers+PointerEvents.idl
    852853    dom/GlobalEventHandlers+Selection.idl
  • trunk/Source/WebCore/ChangeLog

    r274810 r274812  
     12021-03-22  Rob Buis  <rbuis@igalia.com>
     2
     3        Enable ability to prevent scrolling in Element.focus()
     4        https://bugs.webkit.org/show_bug.cgi?id=178583
     5
     6        Reviewed by Simon Fraser.
     7
     8        Add FocusOptions parameter to the focus method [1] both
     9        to the IDL as the C++ side. Change Element.focus to not
     10        scroll if FocusOptions.preventScroll is true.
     11
     12        Behavior matches Chrome and Firefox.
     13
     14        Tests: imported/w3c/web-platform-tests/html/interaction/focus/processing-model/preventScroll-textarea.html
     15               imported/w3c/web-platform-tests/html/interaction/focus/processing-model/preventScroll-nested-scroll-elements.html
     16
     17        Test: imported/w3c/web-platform-tests/html/interaction/focus/processing-model/preventScroll-nested-scroll-elements.html
     18
     19        * CMakeLists.txt:
     20        * DerivedSources-input.xcfilelist:
     21        * DerivedSources-output.xcfilelist:
     22        * DerivedSources.make:
     23        * Headers.cmake:
     24        * Sources.txt:
     25        * WebCore.xcodeproj/project.pbxproj:
     26        * dom/Element.cpp:
     27        (WebCore::Element::focus):
     28        * dom/Element.h:
     29        (WebCore::Element::focus):
     30        * dom/FocusOptions.h: Copied from Source/WebCore/html/HTMLOrForeignElement.idl.
     31        * dom/FocusOptions.idl: Copied from Source/WebCore/html/HTMLOrForeignElement.idl.
     32        * html/HTMLFormControlElement.cpp:
     33        (WebCore::HTMLFormControlElement::didAttachRenderers):
     34        * html/HTMLLabelElement.cpp:
     35        (WebCore::HTMLLabelElement::focus):
     36        * html/HTMLLabelElement.h:
     37        * html/HTMLLegendElement.cpp:
     38        (WebCore::HTMLLegendElement::focus):
     39        * html/HTMLLegendElement.h:
     40        * html/HTMLOrForeignElement.idl:
     41        * html/InputType.cpp:
     42        (WebCore::InputType::accessKeyAction):
     43        * page/FocusController.cpp:
     44        (WebCore::FocusController::advanceFocusInDocumentOrder):
     45        (WebCore::FocusController::advanceFocusDirectionallyInContainer):
     46
    1472021-03-22  Devin Rousso  <drousso@apple.com>
    248
  • trunk/Source/WebCore/DerivedSources-input.xcfilelist

    r274613 r274812  
    856856$(PROJECT_DIR)/dom/EventTargetFactory.in
    857857$(PROJECT_DIR)/dom/FocusEvent.idl
     858$(PROJECT_DIR)/dom/FocusOptions.idl
    858859$(PROJECT_DIR)/dom/GlobalEventHandlers+PointerEvents.idl
    859860$(PROJECT_DIR)/dom/GlobalEventHandlers+Selection.idl
  • trunk/Source/WebCore/DerivedSources-output.xcfilelist

    r274613 r274812  
    831831$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSFocusEvent.cpp
    832832$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSFocusEvent.h
     833$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSFocusOptions.cpp
     834$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSFocusOptions.h
    833835$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSFontFace.cpp
    834836$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSFontFace.h
  • trunk/Source/WebCore/DerivedSources.make

    r274625 r274812  
    728728    $(WebCore)/dom/EventTarget.idl \
    729729    $(WebCore)/dom/FocusEvent.idl \
     730    $(WebCore)/dom/FocusOptions.idl \
    730731    $(WebCore)/dom/GlobalEventHandlers+PointerEvents.idl \
    731732    $(WebCore)/dom/GlobalEventHandlers+Selection.idl \
  • trunk/Source/WebCore/Headers.cmake

    r274758 r274812  
    468468    dom/ExceptionData.h
    469469    dom/ExceptionOr.h
     470    dom/FocusOptions.h
    470471    dom/FragmentScriptingPermission.h
    471472    dom/FullscreenManager.h
  • trunk/Source/WebCore/Sources.txt

    r274758 r274812  
    30253025JSFillMode.cpp
    30263026JSFocusEvent.cpp
     3027JSFocusOptions.cpp
    30273028JSFontFace.cpp
    30283029JSFontFaceSet.cpp
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r274810 r274812  
    36083608                AAA728F716D1D8BC00D3BBC6 /* WebAccessibilityObjectWrapperIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = AAA728F116D1D8BC00D3BBC6 /* WebAccessibilityObjectWrapperIOS.h */; };
    36093609                AAC08CF315F941FD00F1E188 /* AccessibilitySVGRoot.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC08CF115F941FC00F1E188 /* AccessibilitySVGRoot.h */; };
     3610                AADEFE4525AF4FD60040DD67 /* FocusOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = AADEFE4325AF4FCB0040DD67 /* FocusOptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
    36103611                AB23A32809BBA7D00067CC53 /* BeforeTextInsertedEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = AB23A32609BBA7D00067CC53 /* BeforeTextInsertedEvent.h */; };
    36113612                AB247A6D0AFD6383003FA5FD /* RenderSlider.h in Headers */ = {isa = PBXBuildFile; fileRef = AB247A6B0AFD6383003FA5FD /* RenderSlider.h */; };
     
    1317413175                AA2A5AC716A485D500975A25 /* SpeechSynthesisVoice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SpeechSynthesisVoice.h; sourceTree = "<group>"; };
    1317513176                AA2A5AC816A485D500975A25 /* SpeechSynthesisVoice.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = SpeechSynthesisVoice.idl; sourceTree = "<group>"; };
     13177                AA2E0D0925AF5104007693BA /* FocusOptions.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = FocusOptions.idl; sourceTree = "<group>"; };
    1317613178                AA478A7D16CD70C3007D1BB4 /* WebAccessibilityObjectWrapperMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebAccessibilityObjectWrapperMac.h; sourceTree = "<group>"; };
    1317713179                AA478A7E16CD70C3007D1BB4 /* WebAccessibilityObjectWrapperMac.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = WebAccessibilityObjectWrapperMac.mm; sourceTree = "<group>"; };
     
    1319813200                AAD9D0B121DFA80C001B11C7 /* LazyLoadImageObserver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LazyLoadImageObserver.cpp; sourceTree = "<group>"; };
    1319913201                AAD9D0B321DFA80E001B11C7 /* LazyLoadImageObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LazyLoadImageObserver.h; sourceTree = "<group>"; };
     13202                AADEFE4325AF4FCB0040DD67 /* FocusOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FocusOptions.h; sourceTree = "<group>"; };
    1320013203                AAE27B7416CBFC0D00623043 /* PlatformSpeechSynthesizerMock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformSpeechSynthesizerMock.cpp; sourceTree = "<group>"; };
    1320113204                AAE27B7516CBFC0D00623043 /* PlatformSpeechSynthesizerMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformSpeechSynthesizerMock.h; sourceTree = "<group>"; };
     
    3033030333                                B6D9D23314EABD260090D75E /* FocusEvent.h */,
    3033130334                                B6D9D27214EABF030090D75E /* FocusEvent.idl */,
     30335                                AADEFE4325AF4FCB0040DD67 /* FocusOptions.h */,
     30336                                AA2E0D0925AF5104007693BA /* FocusOptions.idl */,
    3033230337                                A853123C11D0471B00D4D077 /* FragmentScriptingPermission.h */,
    3033330338                                CD92F5172261038200F87BB3 /* FullscreenManager.cpp */,
     
    3231832323                                062287840B4DB322000C34DF /* FocusDirection.h in Headers */,
    3231932324                                B6D9D23514EABD260090D75E /* FocusEvent.h in Headers */,
     32325                                AADEFE4525AF4FD60040DD67 /* FocusOptions.h in Headers */,
    3232032326                                B2C3DA650D006CD600EF6F26 /* Font.h in Headers */,
    3232132327                                1AC2D89D1B1E291F00D52E87 /* FontAntialiasingStateSaver.h in Headers */,
  • trunk/Source/WebCore/dom/Element.cpp

    r274746 r274812  
    30413041}
    30423042
    3043 void Element::focus(SelectionRestorationMode restorationMode, FocusDirection direction)
     3043void Element::focus(const FocusOptions& options)
    30443044{
    30453045    if (!isConnected())
     
    30853085        // If a focus event handler changes the focus to a different node it
    30863086        // does not make sense to continue and update appearence.
    3087         if (!page->focusController().setFocusedElement(newTarget.get(), *document->frame(), direction))
     3087        if (!page->focusController().setFocusedElement(newTarget.get(), *document->frame(), options.direction))
    30883088            return;
    30893089    }
    30903090
    3091     newTarget->revealFocusedElement(restorationMode);
     3091    if (!options.preventScroll)
     3092        newTarget->revealFocusedElement(options.selectionRestorationMode);
    30923093}
    30933094
  • trunk/Source/WebCore/dom/Element.h

    r274173 r274812  
    2828#include "Document.h"
    2929#include "ElementData.h"
     30#include "FocusOptions.h"
    3031#include "HTMLNames.h"
    3132#include "ScrollTypes.h"
     
    402403
    403404    static AXTextStateChangeIntent defaultFocusTextStateChangeIntent() { return AXTextStateChangeIntent(AXTextStateChangeTypeSelectionMove, AXTextSelection { AXTextSelectionDirectionDiscontiguous, AXTextSelectionGranularityUnknown, true }); }
    404     virtual void focus(SelectionRestorationMode = SelectionRestorationMode::RestoreOrSelectAll, FocusDirection = FocusDirection::None);
     405    virtual void focus(const FocusOptions& = { });
    405406    void revealFocusedElement(SelectionRestorationMode);
    406407    virtual RefPtr<Element> focusAppearanceUpdateTarget();
  • trunk/Source/WebCore/dom/FocusOptions.h

    r274810 r274812  
    11/*
    2  * Copyright (C) 2019 Igalia S.L. All rights reserved.
     2 * Copyright (C) 2020 Igalia S.L. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 // https://html.spec.whatwg.org/multipage/dom.html#htmlorsvgelement
    27 // FIXME: update above link when this change has been implemented:
    28 // https://github.com/whatwg/html/issues/4702
    29 interface mixin HTMLOrForeignElement {
    30     [SameObject] readonly attribute DOMStringMap dataset;
    31     // FIXME: Implement 'nonce'.
    32     // attribute DOMString nonce; // intentionally no [CEReactions]
     26#pragma once
    3327
    34     // FIXME: Implement 'autofocus'.
    35     // [CEReactions] attribute boolean autofocus;
    36     [CEReactions, ImplementedAs=tabIndexForBindings] attribute long tabIndex;
    37     // FIMXE: focus() is specified to take an optional FocusOptions. Implement that.
    38     undefined focus();
    39     undefined blur();
     28#include "FocusDirection.h"
     29
     30namespace WebCore {
     31
     32struct FocusOptions {
     33    SelectionRestorationMode selectionRestorationMode { SelectionRestorationMode::RestoreOrSelectAll };
     34    FocusDirection direction { FocusDirection::None };
     35    bool preventScroll { false };
    4036};
     37
     38} // namespace WebCore
  • trunk/Source/WebCore/dom/FocusOptions.idl

    r274810 r274812  
    11/*
    2  * Copyright (C) 2019 Igalia S.L. All rights reserved.
     2 * Copyright (C) 2020 Igalia S.L. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 // https://html.spec.whatwg.org/multipage/dom.html#htmlorsvgelement
    27 // FIXME: update above link when this change has been implemented:
    28 // https://github.com/whatwg/html/issues/4702
    29 interface mixin HTMLOrForeignElement {
    30     [SameObject] readonly attribute DOMStringMap dataset;
    31     // FIXME: Implement 'nonce'.
    32     // attribute DOMString nonce; // intentionally no [CEReactions]
    33 
    34     // FIXME: Implement 'autofocus'.
    35     // [CEReactions] attribute boolean autofocus;
    36     [CEReactions, ImplementedAs=tabIndexForBindings] attribute long tabIndex;
    37     // FIMXE: focus() is specified to take an optional FocusOptions. Implement that.
    38     undefined focus();
    39     undefined blur();
     26dictionary FocusOptions {
     27   boolean preventScroll = false;
    4028};
  • trunk/Source/WebCore/html/HTMLFormControlElement.cpp

    r274029 r274812  
    255255        if (frameView && frameView->layoutContext().isInLayout()) {
    256256            frameView->queuePostLayoutCallback([element] {
    257                 element->focus(SelectionRestorationMode::PlaceCaretAtStart);
     257                element->focus({ SelectionRestorationMode::PlaceCaretAtStart });
    258258            });
    259259        } else {
    260260            Style::queuePostResolutionCallback([element] {
    261                 element->focus(SelectionRestorationMode::PlaceCaretAtStart);
     261                element->focus({ SelectionRestorationMode::PlaceCaretAtStart });
    262262            });
    263263        }
  • trunk/Source/WebCore/html/HTMLLabelElement.cpp

    r271930 r274812  
    173173}
    174174
    175 void HTMLLabelElement::focus(SelectionRestorationMode restorationMode, FocusDirection direction)
     175void HTMLLabelElement::focus(const FocusOptions& options)
    176176{
    177177    Ref<HTMLLabelElement> protectedThis(*this);
     
    180180        if (isFocusable()) {
    181181            // The value of restorationMode is not used for label elements as it doesn't override updateFocusAppearance.
    182             Element::focus(restorationMode, direction);
     182            Element::focus(options);
    183183            return;
    184184        }
     
    187187    // To match other browsers, always restore previous selection.
    188188    if (auto element = control())
    189         element->focus(SelectionRestorationMode::RestoreOrSelectAll, direction);
     189        element->focus({ SelectionRestorationMode::RestoreOrSelectAll, options.direction });
    190190}
    191191
  • trunk/Source/WebCore/html/HTMLLabelElement.h

    r271930 r274812  
    5252    void defaultEventHandler(Event&) final;
    5353
    54     void focus(SelectionRestorationMode, FocusDirection) final;
     54    void focus(const FocusOptions&) final;
    5555
    5656    bool isInteractiveContent() const final { return true; }
  • trunk/Source/WebCore/html/HTMLLegendElement.cpp

    r269587 r274812  
    5858}
    5959
    60 void HTMLLegendElement::focus(SelectionRestorationMode restorationMode, FocusDirection direction)
     60void HTMLLegendElement::focus(const FocusOptions& options)
    6161{
    6262    if (document().haveStylesheetsLoaded()) {
    6363        document().updateLayoutIgnorePendingStylesheets();
    6464        if (isFocusable()) {
    65             Element::focus(restorationMode, direction);
     65            Element::focus({ options.selectionRestorationMode, options.direction });
    6666            return;
    6767        }
     
    7070    // To match other browsers' behavior, never restore previous selection.
    7171    if (auto control = associatedControl())
    72         control->focus(SelectionRestorationMode::SelectAll, direction);
     72        control->focus({ SelectionRestorationMode::SelectAll, options.direction });
    7373}
    7474
  • trunk/Source/WebCore/html/HTMLLegendElement.h

    r269587 r274812  
    4444
    4545    bool accessKeyAction(bool sendMouseEvents) final;
    46     void focus(SelectionRestorationMode, FocusDirection) final;
     46    void focus(const FocusOptions&) final;
    4747};
    4848
  • trunk/Source/WebCore/html/HTMLOrForeignElement.idl

    r267953 r274812  
    3535    // [CEReactions] attribute boolean autofocus;
    3636    [CEReactions, ImplementedAs=tabIndexForBindings] attribute long tabIndex;
    37     // FIMXE: focus() is specified to take an optional FocusOptions. Implement that.
    38     undefined focus();
     37    undefined focus(optional FocusOptions options);
    3938    undefined blur();
    4039};
     40
  • trunk/Source/WebCore/html/InputType.cpp

    r272180 r274812  
    639639{
    640640    ASSERT(element());
    641     element()->focus(SelectionRestorationMode::SelectAll);
     641    element()->focus({ SelectionRestorationMode::SelectAll });
    642642    return false;
    643643}
  • trunk/Source/WebCore/page/FocusController.cpp

    r273812 r274812  
    535535
    536536    element->setHasFocusVisible(true);
    537     element->focus(SelectionRestorationMode::SelectAll, direction);
     537    element->focus({ SelectionRestorationMode::SelectAll, direction });
    538538    return true;
    539539}
     
    11091109    ASSERT(element);
    11101110
    1111     element->focus(SelectionRestorationMode::SelectAll, direction);
     1111    element->focus({ SelectionRestorationMode::SelectAll, direction });
    11121112    return true;
    11131113}
Note: See TracChangeset for help on using the changeset viewer.