Modified: trunk/Source/WebCore/ChangeLog (225854 => 225855)
--- trunk/Source/WebCore/ChangeLog 2017-12-13 18:36:26 UTC (rev 225854)
+++ trunk/Source/WebCore/ChangeLog 2017-12-13 18:43:05 UTC (rev 225855)
@@ -1,3 +1,29 @@
+2017-12-13 Zalan Bujtas <[email protected]>
+
+ 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):
+
2017-12-13 Ryan Haddad <[email protected]>
Unreviewed, rolling out r225836.
Modified: trunk/Source/WebCore/accessibility/AXObjectCache.cpp (225854 => 225855)
--- trunk/Source/WebCore/accessibility/AXObjectCache.cpp 2017-12-13 18:36:26 UTC (rev 225854)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.cpp 2017-12-13 18:43:05 UTC (rev 225855)
@@ -721,6 +721,7 @@
if (is<Element>(node)) {
m_deferredRecomputeIsIgnoredList.remove(downcast<Element>(&node));
m_deferredSelectedChildredChangedList.remove(downcast<Element>(&node));
+ m_deferredTextFormControlValue.remove(downcast<Element>(&node));
}
m_deferredTextChangedList.remove(&node);
removeNodeForUse(node);
@@ -2725,8 +2726,19 @@
return result;
}
+template<typename T, typename U>
+static void filterMapForRemoval(const HashMap<T, U>& list, const Document& document, HashSet<Node*>& nodesToRemove)
+{
+ for (auto& entry : list) {
+ auto* node = entry.key;
+ if (node->isConnected() && &node->document() != &document)
+ continue;
+ nodesToRemove.add(node);
+ }
+}
+
template<typename T>
-static void filterForRemoval(const ListHashSet<T>& list, const Document& document, HashSet<Node*>& nodesToRemove)
+static void filterListForRemoval(const ListHashSet<T>& list, const Document& document, HashSet<Node*>& nodesToRemove)
{
for (auto* node : list) {
if (node->isConnected() && &node->document() != &document)
@@ -2738,11 +2750,12 @@
void AXObjectCache::prepareForDocumentDestruction(const Document& document)
{
HashSet<Node*> nodesToRemove;
- filterForRemoval(m_textMarkerNodes, document, nodesToRemove);
- filterForRemoval(m_modalNodesSet, document, nodesToRemove);
- filterForRemoval(m_deferredRecomputeIsIgnoredList, document, nodesToRemove);
- filterForRemoval(m_deferredTextChangedList, document, nodesToRemove);
- filterForRemoval(m_deferredSelectedChildredChangedList, document, nodesToRemove);
+ filterListForRemoval(m_textMarkerNodes, document, nodesToRemove);
+ filterListForRemoval(m_modalNodesSet, document, nodesToRemove);
+ filterListForRemoval(m_deferredRecomputeIsIgnoredList, document, nodesToRemove);
+ filterListForRemoval(m_deferredTextChangedList, document, nodesToRemove);
+ filterListForRemoval(m_deferredSelectedChildredChangedList, document, nodesToRemove);
+ filterMapForRemoval(m_deferredTextFormControlValue, document, nodesToRemove);
for (auto* node : nodesToRemove)
remove(*node);
@@ -2776,6 +2789,12 @@
for (auto* selectElement : m_deferredSelectedChildredChangedList)
selectedChildrenChanged(selectElement);
m_deferredSelectedChildredChangedList.clear();
+
+ for (auto& deferredFormControlContext : m_deferredTextFormControlValue) {
+ auto& textFormControlElement = downcast<HTMLTextFormControlElement>(*deferredFormControlContext.key);
+ postTextReplacementNotificationForTextControl(textFormControlElement, deferredFormControlContext.value, textFormControlElement.innerTextValue());
+ }
+ m_deferredTextFormControlValue.clear();
}
static bool rendererNeedsDeferredUpdate(RenderObject& renderer)
@@ -2841,6 +2860,14 @@
selectedChildrenChanged(&selectElement);
}
+void AXObjectCache::deferTextReplacementNotificationForTextControl(HTMLTextFormControlElement& formControlElement, const String& previousValue)
+{
+ auto* renderer = formControlElement.renderer();
+ if (!renderer)
+ return;
+ m_deferredTextFormControlValue.add(&formControlElement, previousValue);
+}
+
bool isNodeAriaVisible(Node* node)
{
if (!node)
Modified: trunk/Source/WebCore/accessibility/AXObjectCache.h (225854 => 225855)
--- trunk/Source/WebCore/accessibility/AXObjectCache.h 2017-12-13 18:36:26 UTC (rev 225854)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.h 2017-12-13 18:43:05 UTC (rev 225855)
@@ -337,7 +337,8 @@
void deferTextChangedIfNeeded(Node*);
void deferSelectedChildrenChangedIfNeeded(Element&);
void performDeferredCacheUpdate();
-
+ void deferTextReplacementNotificationForTextControl(HTMLTextFormControlElement&, const String& previousValue);
+
RefPtr<Range> rangeMatchesTextNearRange(RefPtr<Range>, const String&);
@@ -444,6 +445,7 @@
ListHashSet<Element*> m_deferredRecomputeIsIgnoredList;
ListHashSet<Node*> m_deferredTextChangedList;
ListHashSet<Element*> m_deferredSelectedChildredChangedList;
+ HashMap<Element*, String> m_deferredTextFormControlValue;
bool m_isSynchronizingSelection { false };
bool m_performingDeferredCacheUpdate { false };
};
@@ -496,6 +498,7 @@
inline void AXObjectCache::deferRecomputeIsIgnored(Element*) { }
inline void AXObjectCache::deferTextChangedIfNeeded(Node*) { }
inline void AXObjectCache::deferSelectedChildrenChangedIfNeeded(Element&) { }
+inline void AXObjectCache::deferTextReplacementNotificationForTextControl(HTMLTextFormControlElement&, const String&) { }
inline void AXObjectCache::detachWrapper(AccessibilityObject*, AccessibilityDetachmentType) { }
inline void AXObjectCache::focusModalNodeTimerFired() { }
inline void AXObjectCache::frameLoadingEventNotification(Frame*, AXLoadingEvent) { }
Modified: trunk/Source/WebCore/html/HTMLTextFormControlElement.cpp (225854 => 225855)
--- trunk/Source/WebCore/html/HTMLTextFormControlElement.cpp 2017-12-13 18:36:26 UTC (rev 225854)
+++ trunk/Source/WebCore/html/HTMLTextFormControlElement.cpp 2017-12-13 18:43:05 UTC (rev 225855)
@@ -576,7 +576,7 @@
#if HAVE(ACCESSIBILITY) && PLATFORM(COCOA)
if (textIsChanged && renderer()) {
if (AXObjectCache* cache = document().existingAXObjectCache())
- cache->postTextReplacementNotificationForTextControl(*this, previousValue, value);
+ cache->deferTextReplacementNotificationForTextControl(*this, previousValue);
}
#endif
}