Modified: trunk/Source/WebCore/editing/Editor.cpp (294513 => 294514)
--- trunk/Source/WebCore/editing/Editor.cpp 2022-05-19 23:46:27 UTC (rev 294513)
+++ trunk/Source/WebCore/editing/Editor.cpp 2022-05-20 00:00:07 UTC (rev 294514)
@@ -138,6 +138,8 @@
namespace WebCore {
+constexpr auto textFieldDidBeginEditingClientNotificationDelay = 500_ms;
+
static bool dispatchBeforeInputEvent(Element& element, const AtomString& inputType, const String& data = { }, RefPtr<DataTransfer>&& dataTransfer = nullptr, const Vector<RefPtr<StaticRange>>& targetRanges = { }, Event::IsCancelable cancelable = Event::IsCancelable::Yes)
{
auto event = InputEvent::create(eventNames().beforeinputEvent, inputType, cancelable, element.document().windowProxy(), data, WTFMove(dataTransfer), targetRanges, 0);
@@ -1246,6 +1248,7 @@
#if ENABLE(TELEPHONE_NUMBER_DETECTION) && !PLATFORM(IOS_FAMILY)
, m_telephoneNumberDetectionUpdateTimer(*this, &Editor::scanSelectionForTelephoneNumbers, 0_s)
#endif
+ , m_textFieldDidBeginEditingTimer(*this, &Editor::textFieldDidBeginEditingTimerFired)
{
}
@@ -3462,43 +3465,95 @@
return computeAndSetTypingStyle(EditingStyle::create(&properties), editingAction);
}
-void Editor::textFieldDidBeginEditing(Element& e)
+bool Editor::stopTextFieldDidBeginEditingTimer()
{
- if (client())
- client()->textFieldDidBeginEditing(e);
+ if (m_textFieldDidBeginEditingTimer.isActive()) {
+ m_textFieldDidBeginEditingTimer.stop();
+ return true;
+ }
+ return false;
}
-void Editor::textFieldDidEndEditing(Element& e)
+void Editor::textFieldDidBeginEditingTimerFired()
{
+ auto* client = this->client();
+ if (!client)
+ return;
+
+ if (RefPtr element = m_document.activeElement())
+ client->textFieldDidBeginEditing(*element);
+}
+
+void Editor::textFieldDidBeginEditing(Element& element)
+{
+ auto* client = this->client();
+ if (!client)
+ return;
+
+ if (isInSubframeWithoutUserInteraction()) {
+ m_textFieldDidBeginEditingTimer.startOneShot(textFieldDidBeginEditingClientNotificationDelay);
+ return;
+ }
+
+ client->textFieldDidBeginEditing(element);
+}
+
+void Editor::textFieldDidEndEditing(Element& element)
+{
dismissCorrectionPanelAsIgnored();
- if (client())
- client()->textFieldDidEndEditing(e);
+
+ auto* client = this->client();
+ if (!client)
+ return;
+
+ if (stopTextFieldDidBeginEditingTimer())
+ return;
+
+ client->textFieldDidEndEditing(element);
}
-void Editor::textDidChangeInTextField(Element& e)
+void Editor::textDidChangeInTextField(Element& element)
{
- if (client())
- client()->textDidChangeInTextField(e);
+ auto* client = this->client();
+ if (!client)
+ return;
+
+ if (stopTextFieldDidBeginEditingTimer())
+ client->textFieldDidBeginEditing(element);
+ client->textDidChangeInTextField(element);
}
-bool Editor::doTextFieldCommandFromEvent(Element& e, KeyboardEvent* ke)
+bool Editor::doTextFieldCommandFromEvent(Element& element, KeyboardEvent* event)
{
- if (client())
- return client()->doTextFieldCommandFromEvent(e, ke);
+ auto* client = this->client();
+ if (!client)
+ return false;
- return false;
+ if (stopTextFieldDidBeginEditingTimer())
+ client->textFieldDidBeginEditing(element);
+ return client->doTextFieldCommandFromEvent(element, event);
}
void Editor::textWillBeDeletedInTextField(Element& input)
{
- if (client())
- client()->textWillBeDeletedInTextField(input);
+ auto* client = this->client();
+ if (!client)
+ return;
+
+ if (stopTextFieldDidBeginEditingTimer())
+ client->textFieldDidBeginEditing(input);
+ client->textWillBeDeletedInTextField(input);
}
-void Editor::textDidChangeInTextArea(Element& e)
+void Editor::textDidChangeInTextArea(Element& element)
{
- if (client())
- client()->textDidChangeInTextArea(e);
+ auto* client = this->client();
+ if (!client)
+ return;
+
+ if (stopTextFieldDidBeginEditingTimer())
+ client->textFieldDidBeginEditing(element);
+ client->textDidChangeInTextArea(element);
}
void Editor::applyEditingStyleToBodyElement() const
@@ -3686,6 +3741,11 @@
}
#endif
+bool Editor::isInSubframeWithoutUserInteraction() const
+{
+ return !m_hasHandledAnyEditing && !m_document.hasHadUserInteraction() && !m_document.isTopDocument();
+}
+
void Editor::respondToChangedSelection(const VisibleSelection&, OptionSet<FrameSelection::SetSelectionOption> options)
{
#if PLATFORM(IOS_FAMILY)
@@ -3705,7 +3765,7 @@
setStartNewKillRingSequence(true);
m_imageElementsToLoadBeforeRevealingSelection.clear();
- if (!m_hasHandledAnyEditing && !m_document.hasHadUserInteraction() && !m_document.isTopDocument())
+ if (isInSubframeWithoutUserInteraction())
return;
if (m_editorUIUpdateTimer.isActive())
Modified: trunk/Source/WebCore/editing/Editor.h (294513 => 294514)
--- trunk/Source/WebCore/editing/Editor.h 2022-05-19 23:46:27 UTC (rev 294513)
+++ trunk/Source/WebCore/editing/Editor.h 2022-05-20 00:00:07 UTC (rev 294514)
@@ -632,6 +632,8 @@
std::optional<SimpleRange> adjustedSelectionRange();
+ bool isInSubframeWithoutUserInteraction() const;
+
#if PLATFORM(COCOA)
RefPtr<SharedBuffer> selectionInWebArchiveFormat();
String selectionInHTMLFormat();
@@ -647,6 +649,9 @@
void notifyClientOfAttachmentUpdates();
#endif
+ bool stopTextFieldDidBeginEditingTimer();
+ void textFieldDidBeginEditingTimerFired();
+
String platformContentTypeForBlobType(const String& type) const;
void postTextStateChangeNotificationForCut(const String&, const VisibleSelection&);
@@ -690,6 +695,8 @@
Vector<SimpleRange> m_detectedTelephoneNumberRanges;
#endif
+ Timer m_textFieldDidBeginEditingTimer;
+
mutable std::unique_ptr<ScrollView::ProhibitScrollingWhenChangingContentSizeForScope> m_prohibitScrollingDueToContentSizeChangesWhileTyping;
bool m_isGettingDictionaryPopupInfo { false };