Changeset 260826 in webkit


Ignore:
Timestamp:
Apr 28, 2020 7:54:52 AM (4 years ago)
Author:
commit-queue@webkit.org
Message:

[iOS] Marked text editor state only needs to be set when layout is up-to-date
https://bugs.webkit.org/show_bug.cgi?id=211087

Patch by Daniel Bates <dabates@apple.com> on 2020-04-28
Reviewed by Darin Adler.

Organize the code to reflect reality: editor state only has marked text rects if layout is
up-to-date. So, move these fields to from EditorState to EditorState::PostLayoutData.

While I am in this area of the code I also moved the editor state originIdentifierForPasteboard
to the top of the struct as it is aesthetically more pleasing to me to have the post layout
data last. It likely also produces better bit packing though this wasn't my primary motivation.

  • Shared/EditorState.cpp:

(WebKit::EditorState::encode const):
(WebKit::EditorState::decode):
(WebKit::EditorState::PostLayoutData::encode const):
(WebKit::EditorState::PostLayoutData::decode):
Move encoding and decoding of marked test fields from EditorState to EditorState::PostLayoutData.

(WebKit::operator<<): Fix up code now that marked text fields are in PostLayoutData.

  • Shared/EditorState.h:
  • UIProcess/ios/WKContentViewInteraction.mm:

(-[WKContentView textFirstRect]): Update code now that this data is in the post layout data struct.
(-[WKContentView textLastRect]): Ditto.
(-[WKContentView _updateChangedSelection:]): Ditto.

  • WebProcess/WebPage/ios/WebPageIOS.mm:

(WebKit::convertContentToRootViewSelectionRects): Added.
(WebKit::WebPage::getPlatformEditorState const): Update now that marked text fields are in the
post layout data struct. Simplify the early return as well: only continue if we're not missing post
layout data. If we're missing post layout data then we either do not have a frame view or layout is
not up-to-data. Either way we don't want to do anything. I also stored the FrameView in a Ref<> to
future proof the code should future code cause view detachment and destruction. Note that layout
could cause this, but the code currently covers this case. So, taking a Ref<> is about future proofing.
(WebKit::WebPage::getRectsForGranularityWithSelectionOffset): Update to use convertContentToRootViewSelectionRects().
(WebKit::WebPage::getRectsAtSelectionOffsetWithText): Ditto.
(WebKit::WebPage::requestAutocorrectionData): Use Vector::map() to convert the selection rects to
from content to root view FloatRects.
(WebKit::WebPage::convertSelectionRectsToRootView): Deleted.

Location:
trunk/Source/WebKit
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r260820 r260826  
     12020-04-28  Daniel Bates  <dabates@apple.com>
     2
     3        [iOS] Marked text editor state only needs to be set when layout is up-to-date
     4        https://bugs.webkit.org/show_bug.cgi?id=211087
     5
     6        Reviewed by Darin Adler.
     7
     8        Organize the code to reflect reality: editor state only has marked text rects if layout is
     9        up-to-date. So, move these fields to from EditorState to EditorState::PostLayoutData.
     10
     11        While I am in this area of the code I also moved the editor state originIdentifierForPasteboard
     12        to the top of the struct as it is aesthetically more pleasing to me to have the post layout
     13        data last. It likely also produces better bit packing though this wasn't my primary motivation.
     14
     15        * Shared/EditorState.cpp:
     16        (WebKit::EditorState::encode const):
     17        (WebKit::EditorState::decode):
     18        (WebKit::EditorState::PostLayoutData::encode const):
     19        (WebKit::EditorState::PostLayoutData::decode):
     20        Move encoding and decoding of marked test fields from EditorState to EditorState::PostLayoutData.
     21
     22        (WebKit::operator<<): Fix up code now that marked text fields are in PostLayoutData.
     23        * Shared/EditorState.h:
     24        * UIProcess/ios/WKContentViewInteraction.mm:
     25        (-[WKContentView textFirstRect]): Update code now that this data is in the post layout data struct.
     26        (-[WKContentView textLastRect]): Ditto.
     27        (-[WKContentView _updateChangedSelection:]): Ditto.
     28        * WebProcess/WebPage/ios/WebPageIOS.mm:
     29        (WebKit::convertContentToRootViewSelectionRects): Added.
     30        (WebKit::WebPage::getPlatformEditorState const): Update now that marked text fields are in the
     31        post layout data struct. Simplify the early return as well: only continue if we're not missing post
     32        layout data. If we're missing post layout data then we either do not have a frame view or layout is
     33        not up-to-data. Either way we don't want to do anything. I also stored the FrameView in a Ref<> to
     34        future proof the code should future code cause view detachment and destruction. Note that layout
     35        could cause this, but the code currently covers this case. So, taking a Ref<> is about future proofing.
     36        (WebKit::WebPage::getRectsForGranularityWithSelectionOffset): Update to use convertContentToRootViewSelectionRects().
     37        (WebKit::WebPage::getRectsAtSelectionOffsetWithText): Ditto.
     38        (WebKit::WebPage::requestAutocorrectionData): Use Vector::map() to convert the selection rects to
     39        from content to root view FloatRects.
     40        (WebKit::WebPage::convertSelectionRectsToRootView): Deleted.
     41
    1422020-04-28  Per Arne Vollan  <pvollan@apple.com>
    243
  • trunk/Source/WebKit/Shared/EditorState.cpp

    r258131 r260826  
    11/*
    2  * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
     2 * Copyright (C) 2010-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3535void EditorState::encode(IPC::Encoder& encoder) const
    3636{
     37    encoder << originIdentifierForPasteboard;
    3738    encoder << shouldIgnoreSelectionChanges;
    3839    encoder << selectionIsNone;
     
    4445    encoder << hasComposition;
    4546    encoder << isMissingPostLayoutData;
    46 
    4747    if (!isMissingPostLayoutData)
    4848        m_postLayoutData.encode(encoder);
    49 
    50 #if PLATFORM(IOS_FAMILY)
    51     encoder << firstMarkedRect;
    52     encoder << lastMarkedRect;
    53     encoder << markedText;
    54 #endif
    55 
    56     encoder << originIdentifierForPasteboard;
    5749}
    5850
    5951bool EditorState::decode(IPC::Decoder& decoder, EditorState& result)
    6052{
     53    if (!decoder.decode(result.originIdentifierForPasteboard))
     54        return false;
     55
    6156    if (!decoder.decode(result.shouldIgnoreSelectionChanges))
    6257        return false;
     
    9085            return false;
    9186    }
    92 
    93 #if PLATFORM(IOS_FAMILY)
    94     if (!decoder.decode(result.firstMarkedRect))
    95         return false;
    96     if (!decoder.decode(result.lastMarkedRect))
    97         return false;
    98     if (!decoder.decode(result.markedText))
    99         return false;
    100 #endif
    101 
    102     if (!decoder.decode(result.originIdentifierForPasteboard))
    103         return false;
    10487
    10588    return true;
     
    137120    encoder << selectionStartIsAtParagraphBoundary;
    138121    encoder << selectionEndIsAtParagraphBoundary;
     122    encoder << firstMarkedRect;
     123    encoder << lastMarkedRect;
     124    encoder << markedText;
    139125#endif
    140126#if PLATFORM(MAC)
     
    209195    if (!decoder.decode(result.selectionEndIsAtParagraphBoundary))
    210196        return false;
     197    if (!decoder.decode(result.firstMarkedRect))
     198        return false;
     199    if (!decoder.decode(result.lastMarkedRect))
     200        return false;
     201    if (!decoder.decode(result.markedText))
     202        return false;
    211203#endif
    212204#if PLATFORM(MAC)
     
    248240TextStream& operator<<(TextStream& ts, const EditorState& editorState)
    249241{
    250 #if PLATFORM(IOS_FAMILY)
    251     if (editorState.firstMarkedRect != IntRect())
    252         ts.dumpProperty("firstMarkedRect", editorState.firstMarkedRect);
    253     if (editorState.lastMarkedRect != IntRect())
    254         ts.dumpProperty("lastMarkedRect", editorState.lastMarkedRect);
    255     if (editorState.markedText.length())
    256         ts.dumpProperty("markedText", editorState.markedText);
    257 #endif
    258 
    259242    if (editorState.shouldIgnoreSelectionChanges)
    260243        ts.dumpProperty("shouldIgnoreSelectionChanges", editorState.shouldIgnoreSelectionChanges);
     
    302285#endif // PLATFORM(COCOA)
    303286#if PLATFORM(IOS_FAMILY)
     287    if (editorState.postLayoutData().firstMarkedRect != IntRect())
     288        ts.dumpProperty("firstMarkedRect", editorState.postLayoutData().firstMarkedRect);
     289    if (editorState.postLayoutData().lastMarkedRect != IntRect())
     290        ts.dumpProperty("lastMarkedRect", editorState.postLayoutData().lastMarkedRect);
     291    if (editorState.postLayoutData().markedText.length())
     292        ts.dumpProperty("markedText", editorState.postLayoutData().markedText);
    304293    if (editorState.postLayoutData().caretRectAtEnd != IntRect())
    305294        ts.dumpProperty("caretRectAtEnd", editorState.postLayoutData().caretRectAtEnd);
  • trunk/Source/WebKit/Shared/EditorState.h

    r260025 r260826  
    11/*
    2  * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
     2 * Copyright (C) 2010-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6666
    6767struct EditorState {
     68    String originIdentifierForPasteboard;
    6869    bool shouldIgnoreSelectionChanges { false };
    69 
    7070    bool selectionIsNone { true }; // This will be false when there is a caret selection.
    7171    bool selectionIsRange { false };
     
    7676    bool hasComposition { false };
    7777    bool isMissingPostLayoutData { true };
    78 
    79 #if PLATFORM(IOS_FAMILY)
    80     WebCore::IntRect firstMarkedRect;
    81     WebCore::IntRect lastMarkedRect;
    82     String markedText;
    83 #endif
    84 
    85     String originIdentifierForPasteboard;
    8678
    8779    struct PostLayoutData {
     
    115107        bool selectionStartIsAtParagraphBoundary { false };
    116108        bool selectionEndIsAtParagraphBoundary { false };
     109        WebCore::IntRect firstMarkedRect;
     110        WebCore::IntRect lastMarkedRect;
     111        String markedText;
    117112#endif
    118113#if PLATFORM(MAC)
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

    r260764 r260826  
    41194119- (CGRect)textFirstRect
    41204120{
    4121     return (_page->editorState().hasComposition) ? _page->editorState().firstMarkedRect : _autocorrectionData.textFirstRect;
     4121    return _page->editorState().hasComposition ? _page->editorState().postLayoutData().firstMarkedRect : _autocorrectionData.textFirstRect;
    41224122}
    41234123
    41244124- (CGRect)textLastRect
    41254125{
    4126     return (_page->editorState().hasComposition) ? _page->editorState().lastMarkedRect : _autocorrectionData.textLastRect;
     4126    return _page->editorState().hasComposition ? _page->editorState().postLayoutData().lastMarkedRect : _autocorrectionData.textLastRect;
    41274127}
    41284128
     
    65236523- (void)_updateChangedSelection:(BOOL)force
    65246524{
    6525     auto& state = _page->editorState();
    6526     if (state.isMissingPostLayoutData)
    6527         return;
    6528 
    6529     auto& postLayoutData = state.postLayoutData();
    6530     WebKit::WKSelectionDrawingInfo selectionDrawingInfo(state);
     6525    auto& editorState = _page->editorState();
     6526    if (editorState.isMissingPostLayoutData)
     6527        return;
     6528
     6529    auto& postLayoutData = editorState.postLayoutData();
     6530    WebKit::WKSelectionDrawingInfo selectionDrawingInfo { editorState };
    65316531    if (force || selectionDrawingInfo != _lastSelectionDrawingInfo) {
    65326532        LOG_WITH_STREAM(Selection, stream << "_updateChangedSelection " << selectionDrawingInfo);
     
    65366536        // FIXME: We need to figure out what to do if the selection is changed by Javascript.
    65376537        if (_textInteractionAssistant) {
    6538             _markedText = (_page->editorState().hasComposition) ? _page->editorState().markedText : String();
     6538            _markedText = editorState.hasComposition ? postLayoutData.markedText : String { };
    65396539            [_textInteractionAssistant selectionChanged];
    65406540        }
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.h

    r260820 r260826  
    13541354    void updateViewportSizeForCSSViewportUnits();
    13551355
    1356     static void convertSelectionRectsToRootView(WebCore::FrameView*, Vector<WebCore::SelectionRect>&);
    1357 
    13581356    void getFocusedElementInformation(FocusedElementInformation&);
    13591357    void platformInitializeAccessibility();
  • trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm

    r260764 r260826  
    246246}
    247247
     248static void convertContentToRootViewSelectionRects(const FrameView& view, Vector<SelectionRect>& rects)
     249{
     250    for (auto& rect : rects)
     251        rect.setRect(view.contentsToRootView(rect.rect()));
     252}
     253
    248254void WebPage::getPlatformEditorState(Frame& frame, EditorState& result) const
    249255{
    250256    getPlatformEditorStateCommon(frame, result);
    251257
    252     FrameView* view = frame.view();
    253     if (!view) {
    254         result.isMissingPostLayoutData = true;
    255         return;
    256     }
     258    if (result.isMissingPostLayoutData)
     259        return;
     260    ASSERT(frame.view());
     261    auto& postLayoutData = result.postLayoutData();
     262    auto view = makeRef(*frame.view());
    257263
    258264    if (frame.editor().hasComposition()) {
    259         RefPtr<Range> compositionRange = frame.editor().compositionRange();
     265        auto compositionRange = frame.editor().compositionRange();
    260266        Vector<WebCore::SelectionRect> compositionRects;
    261267        if (compositionRange) {
    262268            compositionRange->collectSelectionRects(compositionRects);
    263269            if (compositionRects.size())
    264                 result.firstMarkedRect = view->contentsToRootView(compositionRects[0].rect());
     270                postLayoutData.firstMarkedRect = view->contentsToRootView(compositionRects[0].rect());
    265271            if (compositionRects.size() > 1)
    266                 result.lastMarkedRect = view->contentsToRootView(compositionRects.last().rect());
     272                postLayoutData.lastMarkedRect = view->contentsToRootView(compositionRects.last().rect());
    267273            else
    268                 result.lastMarkedRect = result.firstMarkedRect;
    269             result.markedText = plainTextForContext(compositionRange.get());
    270         }
    271     }
    272 
    273     // We only set the remaining EditorState entries if layout is done as a performance optimization
    274     // to avoid the need to force a synchronous layout here to compute these entries.
    275     if (view->needsLayout() || result.isMissingPostLayoutData)
    276         return;
    277 
    278     auto& postLayoutData = result.postLayoutData();
     274                postLayoutData.lastMarkedRect = postLayoutData.firstMarkedRect;
     275            postLayoutData.markedText = plainTextForContext(compositionRange.get());
     276        }
     277    }
     278
    279279    const auto& selection = frame.selection().selection();
    280280    postLayoutData.isStableStateUpdate = m_isInStableState;
     
    297297        if (selectedRange) {
    298298            createLiveRange(*selectedRange)->collectSelectionRects(postLayoutData.selectionRects);
    299             convertSelectionRectsToRootView(view, postLayoutData.selectionRects);
     299            convertContentToRootViewSelectionRects(view, postLayoutData.selectionRects);
    300300            selectedText = plainTextForDisplay(*selectedRange);
    301301            postLayoutData.selectedTextLength = selectedText.length();
     
    20052005    Vector<WebCore::SelectionRect> selectionRects;
    20062006    range->collectSelectionRectsWithoutUnionInteriorLines(selectionRects);
    2007     convertSelectionRectsToRootView(frame.view(), selectionRects);
     2007    convertContentToRootViewSelectionRects(*frame.view(), selectionRects);
    20082008    send(Messages::WebPageProxy::SelectionRectsCallback(selectionRects, callbackID));
    20092009}
     
    20632063    Vector<WebCore::SelectionRect> selectionRects;
    20642064    range->collectSelectionRectsWithoutUnionInteriorLines(selectionRects);
    2065     convertSelectionRectsToRootView(frame.view(), selectionRects);
     2065    convertContentToRootViewSelectionRects(*frame.view(), selectionRects);
    20662066    send(Messages::WebPageProxy::SelectionRectsCallback(selectionRects, callbackID));
    20672067}
     
    22582258}
    22592259
    2260 void WebPage::convertSelectionRectsToRootView(FrameView* view, Vector<SelectionRect>& selectionRects)
    2261 {
    2262     for (size_t i = 0; i < selectionRects.size(); ++i) {
    2263         SelectionRect& currentRect = selectionRects[i];
    2264         currentRect.setRect(view->contentsToRootView(currentRect.rect()));
    2265     }
    2266 }
    2267 
    22682260void WebPage::requestDictationContext(CallbackID callbackID)
    22692261{
     
    23782370        range->collectSelectionRects(selectionRects);
    23792371
    2380     Vector<FloatRect> rectsForText;
    2381     rectsForText.grow(selectionRects.size());
    2382 
    2383     convertSelectionRectsToRootView(frame.view(), selectionRects);
    2384     for (size_t i = 0; i < selectionRects.size(); i++)
    2385         rectsForText[i] = selectionRects[i].rect();
     2372    auto rootViewSelectionRects = selectionRects.map([&](const auto& selectionRect) -> FloatRect { return frame.view()->contentsToRootView(selectionRect.rect()); });
    23862373
    23872374    bool multipleFonts = false;
     
    23902377        font = coreFont->getCTFont();
    23912378
    2392     reply({ WTFMove(rectsForText), (__bridge UIFont *)font });
     2379    reply({ WTFMove(rootViewSelectionRects) , (__bridge UIFont *)font });
    23932380}
    23942381
Note: See TracChangeset for help on using the changeset viewer.