Changeset 225855 in webkit


Ignore:
Timestamp:
Dec 13, 2017 10:43:05 AM (6 years ago)
Author:
Alan Bujtas
Message:

ASSERT(LayoutDisallowedScope::isLayoutAllowed()) whenever hitting Enter in Web Inspector console
https://bugs.webkit.org/show_bug.cgi?id=180690

Reviewed by Simon Fraser.

Defer text replacement notification until after layout is done to avoid unexpected forced layouts.

Covered by existing tests.

  • accessibility/AXObjectCache.cpp:

(WebCore::AXObjectCache::disableAccessibility):
(WebCore::AXObjectCache::remove):
(WebCore::filterMapForRemoval):
(WebCore::filterListForRemoval):
(WebCore::AXObjectCache::prepareForDocumentDestruction):
(WebCore::AXObjectCache::performDeferredCacheUpdate):
(WebCore::AXObjectCache::deferTextReplacementNotificationForTextControl):
(WebCore::filterForRemoval): Deleted.

  • accessibility/AXObjectCache.h: Need to use the base (Element) class since

we can't call is<HTMLTextFormControlElement> in Node d'tor.
(WebCore::AXObjectCache::deferTextReplacementNotificationForTextControl):

  • html/HTMLTextFormControlElement.cpp:

(WebCore::HTMLTextFormControlElement::setInnerTextValue):

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r225854 r225855  
     12017-12-13  Zalan Bujtas  <zalan@apple.com>
     2
     3        ASSERT(LayoutDisallowedScope::isLayoutAllowed()) whenever hitting Enter in Web Inspector console
     4        https://bugs.webkit.org/show_bug.cgi?id=180690
     5
     6        Reviewed by Simon Fraser.
     7
     8        Defer text replacement notification until after layout is done to avoid unexpected forced layouts.
     9
     10        Covered by existing tests.
     11
     12        * accessibility/AXObjectCache.cpp:
     13        (WebCore::AXObjectCache::disableAccessibility):
     14        (WebCore::AXObjectCache::remove):
     15        (WebCore::filterMapForRemoval):
     16        (WebCore::filterListForRemoval):
     17        (WebCore::AXObjectCache::prepareForDocumentDestruction):
     18        (WebCore::AXObjectCache::performDeferredCacheUpdate):
     19        (WebCore::AXObjectCache::deferTextReplacementNotificationForTextControl):
     20        (WebCore::filterForRemoval): Deleted.
     21        * accessibility/AXObjectCache.h: Need to use the base (Element) class since
     22        we can't call is<HTMLTextFormControlElement> in Node d'tor.
     23        (WebCore::AXObjectCache::deferTextReplacementNotificationForTextControl):
     24        * html/HTMLTextFormControlElement.cpp:
     25        (WebCore::HTMLTextFormControlElement::setInnerTextValue):
     26
    1272017-12-13  Ryan Haddad  <ryanhaddad@apple.com>
    228
  • trunk/Source/WebCore/accessibility/AXObjectCache.cpp

    r225613 r225855  
    722722        m_deferredRecomputeIsIgnoredList.remove(downcast<Element>(&node));
    723723        m_deferredSelectedChildredChangedList.remove(downcast<Element>(&node));
     724        m_deferredTextFormControlValue.remove(downcast<Element>(&node));
    724725    }
    725726    m_deferredTextChangedList.remove(&node);
     
    27262727}
    27272728
     2729template<typename T, typename U>
     2730static void filterMapForRemoval(const HashMap<T, U>& list, const Document& document, HashSet<Node*>& nodesToRemove)
     2731{
     2732    for (auto& entry : list) {
     2733        auto* node = entry.key;
     2734        if (node->isConnected() && &node->document() != &document)
     2735            continue;
     2736        nodesToRemove.add(node);
     2737    }
     2738}
     2739
    27282740template<typename T>
    2729 static void filterForRemoval(const ListHashSet<T>& list, const Document& document, HashSet<Node*>& nodesToRemove)
     2741static void filterListForRemoval(const ListHashSet<T>& list, const Document& document, HashSet<Node*>& nodesToRemove)
    27302742{
    27312743    for (auto* node : list) {
     
    27392751{
    27402752    HashSet<Node*> nodesToRemove;
    2741     filterForRemoval(m_textMarkerNodes, document, nodesToRemove);
    2742     filterForRemoval(m_modalNodesSet, document, nodesToRemove);
    2743     filterForRemoval(m_deferredRecomputeIsIgnoredList, document, nodesToRemove);
    2744     filterForRemoval(m_deferredTextChangedList, document, nodesToRemove);
    2745     filterForRemoval(m_deferredSelectedChildredChangedList, document, nodesToRemove);
     2753    filterListForRemoval(m_textMarkerNodes, document, nodesToRemove);
     2754    filterListForRemoval(m_modalNodesSet, document, nodesToRemove);
     2755    filterListForRemoval(m_deferredRecomputeIsIgnoredList, document, nodesToRemove);
     2756    filterListForRemoval(m_deferredTextChangedList, document, nodesToRemove);
     2757    filterListForRemoval(m_deferredSelectedChildredChangedList, document, nodesToRemove);
     2758    filterMapForRemoval(m_deferredTextFormControlValue, document, nodesToRemove);
    27462759
    27472760    for (auto* node : nodesToRemove)
     
    27772790        selectedChildrenChanged(selectElement);
    27782791    m_deferredSelectedChildredChangedList.clear();
     2792
     2793    for (auto& deferredFormControlContext : m_deferredTextFormControlValue) {
     2794        auto& textFormControlElement = downcast<HTMLTextFormControlElement>(*deferredFormControlContext.key);
     2795        postTextReplacementNotificationForTextControl(textFormControlElement, deferredFormControlContext.value, textFormControlElement.innerTextValue());
     2796    }
     2797    m_deferredTextFormControlValue.clear();
    27792798}
    27802799
     
    28402859    }
    28412860    selectedChildrenChanged(&selectElement);
     2861}
     2862
     2863void AXObjectCache::deferTextReplacementNotificationForTextControl(HTMLTextFormControlElement& formControlElement, const String& previousValue)
     2864{
     2865    auto* renderer = formControlElement.renderer();
     2866    if (!renderer)
     2867        return;
     2868    m_deferredTextFormControlValue.add(&formControlElement, previousValue);
    28422869}
    28432870
  • trunk/Source/WebCore/accessibility/AXObjectCache.h

    r225613 r225855  
    338338    void deferSelectedChildrenChangedIfNeeded(Element&);
    339339    void performDeferredCacheUpdate();
    340    
     340    void deferTextReplacementNotificationForTextControl(HTMLTextFormControlElement&, const String& previousValue);
     341
    341342    RefPtr<Range> rangeMatchesTextNearRange(RefPtr<Range>, const String&);
    342343   
     
    445446    ListHashSet<Node*> m_deferredTextChangedList;
    446447    ListHashSet<Element*> m_deferredSelectedChildredChangedList;
     448    HashMap<Element*, String> m_deferredTextFormControlValue;
    447449    bool m_isSynchronizingSelection { false };
    448450    bool m_performingDeferredCacheUpdate { false };
     
    497499inline void AXObjectCache::deferTextChangedIfNeeded(Node*) { }
    498500inline void AXObjectCache::deferSelectedChildrenChangedIfNeeded(Element&) { }
     501inline void AXObjectCache::deferTextReplacementNotificationForTextControl(HTMLTextFormControlElement&, const String&) { }
    499502inline void AXObjectCache::detachWrapper(AccessibilityObject*, AccessibilityDetachmentType) { }
    500503inline void AXObjectCache::focusModalNodeTimerFired() { }
  • trunk/Source/WebCore/html/HTMLTextFormControlElement.cpp

    r225837 r225855  
    577577        if (textIsChanged && renderer()) {
    578578            if (AXObjectCache* cache = document().existingAXObjectCache())
    579                 cache->postTextReplacementNotificationForTextControl(*this, previousValue, value);
     579                cache->deferTextReplacementNotificationForTextControl(*this, previousValue);
    580580        }
    581581#endif
Note: See TracChangeset for help on using the changeset viewer.