WebKit Bugzilla
Attachment 346785 Details for
Bug 188410
: InputType should not interact with an HTMLInputElement is no longer associated with
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-188410-20180808130154.patch (text/plain), 135.24 KB, created by
Chris Dumez
on 2018-08-08 13:01:54 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Chris Dumez
Created:
2018-08-08 13:01:54 PDT
Size:
135.24 KB
patch
obsolete
>Subversion Revision: 234638 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 0c9ea71d8117106efdd24d081ea048283897029f..86e991c2a7068a4be592733fe7aa28d0aefb8a92 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,266 @@ >+2018-08-08 Chris Dumez <cdumez@apple.com> >+ >+ InputType does not need to be RefCounted and probably shouldn't be >+ https://bugs.webkit.org/show_bug.cgi?id=188410 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ InputType used to be owned by HTMLInputElement via a unique_ptr. We recently >+ made InputType RefCounted to try and adress some use-after-free crashes. This >+ led to issues because InputType had a raw pointer to its element and the >+ InputType can now outlive its element due to being refcounted. To address this >+ issue, InputType's m_element was updated to be a WeakPtr instead of a raw pointer >+ (C++ reference). However, this approach has several issues: >+ - It is now unclear when we can expect the element to be alive. We have code null-checking >+ it in a few instances, but most of the time we merely assert it is not null. >+ - An HTMLInputElement can change InputType during its lifetime. As a result, InputType::m_element >+ can be alive (non-null) even though the InputType in question is no longer associated >+ with this HTMLInputElement. This can cause an InputType to do operations on an input >+ element is is no longer associated with, which is bad. >+ >+ My proposal is as follows: >+ 1. Have the HTMLInputElement own the InputType again via unique_ptr. >+ 2. Make InputType::m_element be a C++ reference again since it cannot >+ be null. >+ >+ Now, the issue is still that whenever the InputType runs script in the middle of a method >+ (e.g. via firing an event), it may cause the InputType to get destroyed (e.g. if the >+ script changes the input element's type). There are several ways to deal with this: >+ 1. Use a EventQueueScope to dealy the firing of events, which we already do in a few places >+ 2. Use a weakThis local variable (which is a WeakPtr to |this|) and make sure it is non-null >+ after running script. >+ >+ I have audited the code and added weakThis checks after all InputType operations that could >+ run script. I have also added a few ScriptDisallowedScope assertions to make sure we do >+ not run script in a few places where it would not be safe. >+ >+ * html/BaseButtonInputType.cpp: >+ (WebCore::BaseButtonInputType::createInputRenderer): >+ (WebCore::BaseButtonInputType::setValue): >+ * html/BaseCheckableInputType.cpp: >+ (WebCore::BaseCheckableInputType::saveFormControlState const): >+ (WebCore::BaseCheckableInputType::restoreFormControlState): >+ (WebCore::BaseCheckableInputType::appendFormData const): >+ (WebCore::BaseCheckableInputType::handleKeydownEvent): >+ (WebCore::BaseCheckableInputType::accessKeyAction): >+ (WebCore::BaseCheckableInputType::setValue): >+ * html/BaseChooserOnlyDateAndTimeInputType.cpp: >+ (WebCore::BaseChooserOnlyDateAndTimeInputType::handleDOMActivateEvent): >+ (WebCore::BaseChooserOnlyDateAndTimeInputType::createShadowSubtree): >+ (WebCore::BaseChooserOnlyDateAndTimeInputType::updateInnerTextValue): >+ (WebCore::BaseChooserOnlyDateAndTimeInputType::setValue): >+ (WebCore::BaseChooserOnlyDateAndTimeInputType::didChooseValue): >+ (WebCore::BaseChooserOnlyDateAndTimeInputType::handleKeydownEvent): >+ (WebCore::BaseChooserOnlyDateAndTimeInputType::handleKeypressEvent): >+ (WebCore::BaseChooserOnlyDateAndTimeInputType::accessKeyAction): >+ (WebCore::BaseChooserOnlyDateAndTimeInputType::isMouseFocusable const): >+ (WebCore::BaseChooserOnlyDateAndTimeInputType::attributeChanged): >+ * html/BaseClickableWithKeyInputType.cpp: >+ (WebCore::BaseClickableWithKeyInputType::handleKeydownEvent): >+ (WebCore::BaseClickableWithKeyInputType::handleKeypressEvent): >+ (WebCore::BaseClickableWithKeyInputType::accessKeyAction): >+ * html/BaseClickableWithKeyInputType.h: >+ * html/BaseDateAndTimeInputType.cpp: >+ (WebCore::BaseDateAndTimeInputType::setValueAsDate const): >+ (WebCore::BaseDateAndTimeInputType::valueAsDouble const): >+ (WebCore::BaseDateAndTimeInputType::setValueAsDecimal const): >+ (WebCore::BaseDateAndTimeInputType::typeMismatch const): >+ (WebCore::BaseDateAndTimeInputType::attributeChanged): >+ (WebCore::BaseDateAndTimeInputType::serializeWithComponents const): >+ (WebCore::BaseDateAndTimeInputType::localizeValue const): >+ (WebCore::BaseDateAndTimeInputType::visibleValue const): >+ (WebCore::BaseDateAndTimeInputType::valueMissing const): >+ (WebCore::BaseDateAndTimeInputType::isKeyboardFocusable const): >+ * html/BaseTextInputType.cpp: >+ (WebCore::BaseTextInputType::patternMismatch const): >+ * html/CheckboxInputType.cpp: >+ (WebCore::CheckboxInputType::valueMissing const): >+ (WebCore::CheckboxInputType::willDispatchClick): >+ (WebCore::CheckboxInputType::didDispatchClick): >+ (WebCore::CheckboxInputType::shouldAppearIndeterminate const): >+ * html/ColorInputType.cpp: >+ (WebCore::ColorInputType::isMouseFocusable const): >+ (WebCore::ColorInputType::isKeyboardFocusable const): >+ (WebCore::ColorInputType::valueAsColor const): >+ (WebCore::ColorInputType::createShadowSubtree): >+ (WebCore::ColorInputType::setValue): >+ (WebCore::ColorInputType::handleDOMActivateEvent): >+ (WebCore::ColorInputType::didChooseColor): >+ (WebCore::ColorInputType::updateColorSwatch): >+ (WebCore::ColorInputType::shadowColorSwatch const): >+ (WebCore::ColorInputType::elementRectRelativeToRootView const): >+ (WebCore::ColorInputType::shouldShowSuggestions const): >+ (WebCore::ColorInputType::suggestions const): >+ * html/DateInputType.cpp: >+ (WebCore::DateInputType::createStepRange const): >+ * html/DateTimeLocalInputType.cpp: >+ (WebCore::DateTimeLocalInputType::createStepRange const): >+ * html/EmailInputType.cpp: >+ (WebCore::EmailInputType::typeMismatchFor const): >+ (WebCore::EmailInputType::typeMismatch const): >+ (WebCore::EmailInputType::typeMismatchText const): >+ (WebCore::EmailInputType::sanitizeValue const): >+ * html/FileInputType.cpp: >+ (WebCore::FileInputType::appendFormData const): >+ (WebCore::FileInputType::valueMissing const): >+ (WebCore::FileInputType::valueMissingText const): >+ (WebCore::FileInputType::handleDOMActivateEvent): >+ (WebCore::FileInputType::createInputRenderer): >+ (WebCore::FileInputType::setValue): >+ (WebCore::FileInputType::createShadowSubtree): >+ (WebCore::FileInputType::disabledStateChanged): >+ (WebCore::FileInputType::attributeChanged): >+ (WebCore::FileInputType::allowsDirectories const): >+ (WebCore::FileInputType::setFiles): >+ (WebCore::FileInputType::iconLoaded): >+ (WebCore::FileInputType::receiveDroppedFiles): >+ (WebCore::FileInputType::defaultToolTip const): >+ * html/HTMLInputElement.cpp: >+ (WebCore::HTMLInputElement::didAddUserAgentShadowRoot): >+ (WebCore::HTMLInputElement::accessKeyAction): >+ (WebCore::HTMLInputElement::parseAttribute): >+ (WebCore::HTMLInputElement::appendFormData): >+ * html/HTMLInputElement.h: >+ * html/HiddenInputType.cpp: >+ (WebCore::HiddenInputType::saveFormControlState const): >+ (WebCore::HiddenInputType::restoreFormControlState): >+ (WebCore::HiddenInputType::setValue): >+ (WebCore::HiddenInputType::appendFormData const): >+ * html/ImageInputType.cpp: >+ (WebCore::ImageInputType::appendFormData const): >+ (WebCore::ImageInputType::handleDOMActivateEvent): >+ (WebCore::ImageInputType::createInputRenderer): >+ (WebCore::ImageInputType::attributeChanged): >+ (WebCore::ImageInputType::attach): >+ (WebCore::ImageInputType::height const): >+ (WebCore::ImageInputType::width const): >+ * html/InputType.cpp: >+ (WebCore::createInputType): >+ (WebCore::InputType::create): >+ (WebCore::InputType::createText): >+ (WebCore::InputType::saveFormControlState const): >+ (WebCore::InputType::restoreFormControlState): >+ (WebCore::InputType::isFormDataAppendable const): >+ (WebCore::InputType::appendFormData const): >+ (WebCore::InputType::sizeShouldIncludeDecoration const): >+ (WebCore::InputType::validationMessage const): >+ (WebCore::InputType::createInputRenderer): >+ (WebCore::InputType::blur): >+ (WebCore::InputType::destroyShadowSubtree): >+ (WebCore::InputType::dispatchSimulatedClickIfActive const): >+ (WebCore::InputType::chrome const): >+ (WebCore::InputType::isKeyboardFocusable const): >+ (WebCore::InputType::isMouseFocusable const): >+ (WebCore::InputType::accessKeyAction): >+ (WebCore::InputType::setValue): >+ (WebCore::InputType::visibleValue const): >+ (WebCore::InputType::applyStep): >+ (WebCore::InputType::stepUpFromRenderer): >+ * html/InputType.h: >+ (WebCore::InputType::InputType): >+ (WebCore::InputType::element const): >+ * html/MonthInputType.cpp: >+ (WebCore::MonthInputType::valueAsDate const): >+ (WebCore::MonthInputType::createStepRange const): >+ * html/NumberInputType.cpp: >+ (WebCore::NumberInputType::setValue): >+ (WebCore::NumberInputType::valueAsDouble const): >+ (WebCore::NumberInputType::setValueAsDouble const): >+ (WebCore::NumberInputType::setValueAsDecimal const): >+ (WebCore::NumberInputType::typeMismatch const): >+ (WebCore::NumberInputType::createStepRange const): >+ (WebCore::NumberInputType::sizeShouldIncludeDecoration const): >+ (WebCore::NumberInputType::decorationWidth const): >+ (WebCore::NumberInputType::handleKeydownEvent): >+ (WebCore::NumberInputType::localizeValue const): >+ (WebCore::NumberInputType::visibleValue const): >+ (WebCore::NumberInputType::convertFromVisibleValue const): >+ (WebCore::NumberInputType::hasBadInput const): >+ (WebCore::NumberInputType::attributeChanged): >+ * html/RadioInputType.cpp: >+ (WebCore::RadioInputType::valueMissing const): >+ (WebCore::RadioInputType::handleKeydownEvent): >+ (WebCore::RadioInputType::handleKeyupEvent): >+ (WebCore::RadioInputType::isKeyboardFocusable const): >+ (WebCore::RadioInputType::shouldSendChangeEventAfterCheckedChanged): >+ (WebCore::RadioInputType::willDispatchClick): >+ (WebCore::RadioInputType::didDispatchClick): >+ (WebCore::RadioInputType::matchesIndeterminatePseudoClass const): >+ * html/RangeInputType.cpp: >+ (WebCore::RangeInputType::valueAsDouble const): >+ (WebCore::RangeInputType::setValueAsDecimal const): >+ (WebCore::RangeInputType::createStepRange const): >+ (WebCore::RangeInputType::handleMouseDownEvent): >+ (WebCore::RangeInputType::handleTouchEvent): >+ (WebCore::RangeInputType::handleKeydownEvent): >+ (WebCore::RangeInputType::createShadowSubtree): >+ (WebCore::RangeInputType::sliderTrackElement const): >+ (WebCore::RangeInputType::createInputRenderer): >+ (WebCore::RangeInputType::accessKeyAction): >+ (WebCore::RangeInputType::attributeChanged): >+ (WebCore::RangeInputType::setValue): >+ (WebCore::RangeInputType::updateTickMarkValues): >+ * html/ResetInputType.cpp: >+ (WebCore::ResetInputType::handleDOMActivateEvent): >+ * html/SearchInputType.cpp: >+ (WebCore::SearchInputType::addSearchResult): >+ (WebCore::SearchInputType::attributeChanged): >+ (WebCore::SearchInputType::createInputRenderer): >+ (WebCore::SearchInputType::createShadowSubtree): >+ (WebCore::SearchInputType::handleKeydownEvent): >+ (WebCore::SearchInputType::startSearchEventTimer): >+ (WebCore::SearchInputType::searchEventTimerFired): >+ (WebCore::SearchInputType::searchEventsShouldBeDispatched const): >+ (WebCore::SearchInputType::didSetValueByUserEdit): >+ (WebCore::SearchInputType::sizeShouldIncludeDecoration const): >+ * html/SubmitInputType.cpp: >+ (WebCore::SubmitInputType::appendFormData const): >+ (WebCore::SubmitInputType::handleDOMActivateEvent): >+ * html/TextFieldInputType.cpp: >+ (WebCore::TextFieldInputType::isKeyboardFocusable const): >+ (WebCore::TextFieldInputType::isMouseFocusable const): >+ (WebCore::TextFieldInputType::valueMissing const): >+ (WebCore::TextFieldInputType::setValue): >+ (WebCore::TextFieldInputType::handleClickEvent): >+ (WebCore::TextFieldInputType::handleKeydownEvent): >+ (WebCore::TextFieldInputType::handleKeydownEventForSpinButton): >+ (WebCore::TextFieldInputType::forwardEvent): >+ (WebCore::TextFieldInputType::elementDidBlur): >+ (WebCore::TextFieldInputType::handleFocusEvent): >+ (WebCore::TextFieldInputType::handleBlurEvent): >+ (WebCore::TextFieldInputType::createInputRenderer): >+ (WebCore::TextFieldInputType::shouldHaveSpinButton const): >+ (WebCore::TextFieldInputType::shouldHaveCapsLockIndicator const): >+ (WebCore::TextFieldInputType::createShadowSubtree): >+ (WebCore::TextFieldInputType::attributeChanged): >+ (WebCore::TextFieldInputType::disabledStateChanged): >+ (WebCore::TextFieldInputType::readOnlyStateChanged): >+ (WebCore::TextFieldInputType::handleBeforeTextInsertedEvent): >+ (WebCore::TextFieldInputType::updatePlaceholderText): >+ (WebCore::TextFieldInputType::appendFormData const): >+ (WebCore::TextFieldInputType::subtreeHasChanged): >+ (WebCore::TextFieldInputType::didSetValueByUserEdit): >+ (WebCore::TextFieldInputType::updateInnerTextValue): >+ (WebCore::TextFieldInputType::focusAndSelectSpinButtonOwner): >+ (WebCore::TextFieldInputType::shouldSpinButtonRespondToMouseEvents): >+ (WebCore::TextFieldInputType::shouldSpinButtonRespondToWheelEvents): >+ (WebCore::TextFieldInputType::shouldDrawCapsLockIndicator const): >+ (WebCore::TextFieldInputType::shouldDrawAutoFillButton const): >+ (WebCore::TextFieldInputType::autoFillButtonElementWasClicked): >+ (WebCore::TextFieldInputType::createContainer): >+ (WebCore::TextFieldInputType::createAutoFillButton): >+ (WebCore::TextFieldInputType::updateAutoFillButton): >+ (WebCore::TextFieldInputType::elementRectInRootViewCoordinates const): >+ (WebCore::TextFieldInputType::suggestions const): >+ (WebCore::TextFieldInputType::didSelectDataListOption): >+ (WebCore::TextFieldInputType::displaySuggestions): >+ * html/TimeInputType.cpp: >+ (WebCore::TimeInputType::createStepRange const): >+ * html/URLInputType.cpp: >+ (WebCore::URLInputType::typeMismatch const): >+ * html/WeekInputType.cpp: >+ (WebCore::WeekInputType::createStepRange const): >+ > 2018-08-04 Ryosuke Niwa <rniwa@webkit.org> > > Add CEReactions=NotNeeded for reactions only needed for customized builtins >diff --git a/Source/WebCore/html/BaseButtonInputType.cpp b/Source/WebCore/html/BaseButtonInputType.cpp >index 2ddbaeb9a69a80c1b49c4926967e3ed304469f39..428e41a0fbcb1cfb0b99cb37a88b9dc0a4042963 100644 >--- a/Source/WebCore/html/BaseButtonInputType.cpp >+++ b/Source/WebCore/html/BaseButtonInputType.cpp >@@ -53,8 +53,7 @@ bool BaseButtonInputType::appendFormData(DOMFormData&, bool) const > > RenderPtr<RenderElement> BaseButtonInputType::createInputRenderer(RenderStyle&& style) > { >- ASSERT(element()); >- return createRenderer<RenderButton>(*element(), WTFMove(style)); >+ return createRenderer<RenderButton>(element(), WTFMove(style)); > } > > bool BaseButtonInputType::storesValueSeparateFromAttribute() >@@ -64,8 +63,7 @@ bool BaseButtonInputType::storesValueSeparateFromAttribute() > > void BaseButtonInputType::setValue(const String& sanitizedValue, bool, TextFieldEventBehavior) > { >- ASSERT(element()); >- element()->setAttributeWithoutSynchronization(valueAttr, sanitizedValue); >+ element().setAttributeWithoutSynchronization(valueAttr, sanitizedValue); > } > > } // namespace WebCore >diff --git a/Source/WebCore/html/BaseCheckableInputType.cpp b/Source/WebCore/html/BaseCheckableInputType.cpp >index bb1da0866bb69afad9d9a24a802a1ea757890c20..6361cd3de45bbfd63bbabb86b18f05450843ec80 100644 >--- a/Source/WebCore/html/BaseCheckableInputType.cpp >+++ b/Source/WebCore/html/BaseCheckableInputType.cpp >@@ -45,22 +45,19 @@ using namespace HTMLNames; > > FormControlState BaseCheckableInputType::saveFormControlState() const > { >- ASSERT(element()); >- return { element()->checked() ? "on"_s : "off"_s }; >+ return { element().checked() ? "on"_s : "off"_s }; > } > > void BaseCheckableInputType::restoreFormControlState(const FormControlState& state) > { >- ASSERT(element()); >- element()->setChecked(state[0] == "on"); >+ element().setChecked(state[0] == "on"); > } > > bool BaseCheckableInputType::appendFormData(DOMFormData& formData, bool) const > { >- ASSERT(element()); >- if (!element()->checked()) >+ if (!element().checked()) > return false; >- formData.append(element()->name(), element()->value()); >+ formData.append(element().name(), element().value()); > return true; > } > >@@ -68,8 +65,7 @@ void BaseCheckableInputType::handleKeydownEvent(KeyboardEvent& event) > { > const String& key = event.keyIdentifier(); > if (key == "U+0020") { >- ASSERT(element()); >- element()->setActive(true, true); >+ element().setActive(true, true); > // No setDefaultHandled(), because IE dispatches a keypress in this case > // and the caller will only dispatch a keypress if we don't call setDefaultHandled(). > } >@@ -91,10 +87,12 @@ bool BaseCheckableInputType::canSetStringValue() const > // FIXME: Could share this with BaseClickableWithKeyInputType and RangeInputType if we had a common base class. > void BaseCheckableInputType::accessKeyAction(bool sendMouseEvents) > { >+ auto weakThis = makeWeakPtr(*this); > InputType::accessKeyAction(sendMouseEvents); >+ if (!weakThis) >+ return; > >- ASSERT(element()); >- element()->dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents); >+ element().dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents); > } > > String BaseCheckableInputType::fallbackValue() const >@@ -110,8 +108,7 @@ bool BaseCheckableInputType::storesValueSeparateFromAttribute() > > void BaseCheckableInputType::setValue(const String& sanitizedValue, bool, TextFieldEventBehavior) > { >- ASSERT(element()); >- element()->setAttributeWithoutSynchronization(valueAttr, sanitizedValue); >+ element().setAttributeWithoutSynchronization(valueAttr, sanitizedValue); > } > > bool BaseCheckableInputType::isCheckable() >diff --git a/Source/WebCore/html/BaseChooserOnlyDateAndTimeInputType.cpp b/Source/WebCore/html/BaseChooserOnlyDateAndTimeInputType.cpp >index 21fede101fb9a1c13ece1d748092f97c524828ae..3ff4b673eb4524d4ffc88e54fd8c03a3e1d4dcd1 100644 >--- a/Source/WebCore/html/BaseChooserOnlyDateAndTimeInputType.cpp >+++ b/Source/WebCore/html/BaseChooserOnlyDateAndTimeInputType.cpp >@@ -46,34 +46,30 @@ BaseChooserOnlyDateAndTimeInputType::~BaseChooserOnlyDateAndTimeInputType() > > void BaseChooserOnlyDateAndTimeInputType::handleDOMActivateEvent(Event&) > { >- ASSERT(element()); >- if (element()->isDisabledOrReadOnly() || !element()->renderer() || !UserGestureIndicator::processingUserGesture()) >+ if (element().isDisabledOrReadOnly() || !element().renderer() || !UserGestureIndicator::processingUserGesture()) > return; > > if (m_dateTimeChooser) > return; >- if (!element()->document().page()) >+ if (!element().document().page()) > return; > DateTimeChooserParameters parameters; >- if (!element()->setupDateTimeChooserParameters(parameters)) >- return; >+ element().setupDateTimeChooserParameters(parameters); > } > > void BaseChooserOnlyDateAndTimeInputType::createShadowSubtree() > { > static NeverDestroyed<AtomicString> valueContainerPseudo("-webkit-date-and-time-value", AtomicString::ConstructFromLiteral); > >- ASSERT(element()); >- auto valueContainer = HTMLDivElement::create(element()->document()); >+ auto valueContainer = HTMLDivElement::create(element().document()); > valueContainer->setPseudo(valueContainerPseudo); >- element()->userAgentShadowRoot()->appendChild(valueContainer); >+ element().userAgentShadowRoot()->appendChild(valueContainer); > updateInnerTextValue(); > } > > void BaseChooserOnlyDateAndTimeInputType::updateInnerTextValue() > { >- ASSERT(element()); >- RefPtr<Node> node = element()->userAgentShadowRoot()->firstChild(); >+ RefPtr<Node> node = element().userAgentShadowRoot()->firstChild(); > if (!is<HTMLElement>(node)) > return; > String displayValue = visibleValue(); >@@ -86,7 +82,10 @@ void BaseChooserOnlyDateAndTimeInputType::updateInnerTextValue() > > void BaseChooserOnlyDateAndTimeInputType::setValue(const String& value, bool valueChanged, TextFieldEventBehavior eventBehavior) > { >+ auto weakThis = makeWeakPtr(*this); > BaseDateAndTimeInputType::setValue(value, valueChanged, eventBehavior); >+ if (!weakThis) >+ return; > if (valueChanged) > updateInnerTextValue(); > } >@@ -98,8 +97,7 @@ void BaseChooserOnlyDateAndTimeInputType::detach() > > void BaseChooserOnlyDateAndTimeInputType::didChooseValue(const String& value) > { >- ASSERT(element()); >- element()->setValue(value, DispatchInputAndChangeEvent); >+ element().setValue(value, DispatchInputAndChangeEvent); > } > > void BaseChooserOnlyDateAndTimeInputType::didEndChooser() >@@ -115,14 +113,12 @@ void BaseChooserOnlyDateAndTimeInputType::closeDateTimeChooser() > > void BaseChooserOnlyDateAndTimeInputType::handleKeydownEvent(KeyboardEvent& event) > { >- ASSERT(element()); >- BaseClickableWithKeyInputType::handleKeydownEvent(*element(), event); >+ BaseClickableWithKeyInputType::handleKeydownEvent(element(), event); > } > > void BaseChooserOnlyDateAndTimeInputType::handleKeypressEvent(KeyboardEvent& event) > { >- ASSERT(element()); >- BaseClickableWithKeyInputType::handleKeypressEvent(*element(), event); >+ BaseClickableWithKeyInputType::handleKeypressEvent(element(), event); > } > > void BaseChooserOnlyDateAndTimeInputType::handleKeyupEvent(KeyboardEvent& event) >@@ -132,23 +128,26 @@ void BaseChooserOnlyDateAndTimeInputType::handleKeyupEvent(KeyboardEvent& event) > > void BaseChooserOnlyDateAndTimeInputType::accessKeyAction(bool sendMouseEvents) > { >+ auto weakThis = makeWeakPtr(*this); > BaseDateAndTimeInputType::accessKeyAction(sendMouseEvents); >- ASSERT(element()); >- BaseClickableWithKeyInputType::accessKeyAction(*element(), sendMouseEvents); >+ if (!weakThis) >+ return; >+ BaseClickableWithKeyInputType::accessKeyAction(element(), sendMouseEvents); > } > > bool BaseChooserOnlyDateAndTimeInputType::isMouseFocusable() const > { >- ASSERT(element()); >- return element()->isTextFormControlFocusable(); >+ return element().isTextFormControlFocusable(); > } > > void BaseChooserOnlyDateAndTimeInputType::attributeChanged(const QualifiedName& name) > { > if (name == valueAttr) { >- if (auto* element = this->element()) { >- if (!element->hasDirtyValue()) >- updateInnerTextValue(); >+ if (!element().hasDirtyValue()) { >+ auto weakThis = makeWeakPtr(*this); >+ updateInnerTextValue(); >+ if (!weakThis) >+ return; > } > } > BaseDateAndTimeInputType::attributeChanged(name); >diff --git a/Source/WebCore/html/BaseClickableWithKeyInputType.cpp b/Source/WebCore/html/BaseClickableWithKeyInputType.cpp >index 2c4dd55e9b038056728739afaa1124d10e51ed71..9bef8ea043bff2bfe7c32eb56bc18d22dff725b1 100644 >--- a/Source/WebCore/html/BaseClickableWithKeyInputType.cpp >+++ b/Source/WebCore/html/BaseClickableWithKeyInputType.cpp >@@ -39,21 +39,21 @@ namespace WebCore { > > using namespace HTMLNames; > >-void BaseClickableWithKeyInputType::handleKeydownEvent(HTMLInputElement& element, KeyboardEvent& event) >+void BaseClickableWithKeyInputType::handleKeydownEvent(Ref<HTMLInputElement>&& element, KeyboardEvent& event) > { > const String& key = event.keyIdentifier(); > if (key == "U+0020") { >- element.setActive(true, true); >+ element->setActive(true, true); > // No setDefaultHandled(), because IE dispatches a keypress in this case > // and the caller will only dispatch a keypress if we don't call setDefaultHandled(). > } > } > >-void BaseClickableWithKeyInputType::handleKeypressEvent(HTMLInputElement& element, KeyboardEvent& event) >+void BaseClickableWithKeyInputType::handleKeypressEvent(Ref<HTMLInputElement>&& element, KeyboardEvent& event) > { > int charCode = event.charCode(); > if (charCode == '\r') { >- element.dispatchSimulatedClick(&event); >+ element->dispatchSimulatedClick(&event); > event.setDefaultHandled(); > return; > } >@@ -73,21 +73,19 @@ void BaseClickableWithKeyInputType::handleKeyupEvent(InputType& inputType, Keybo > } > > // FIXME: Could share this with BaseCheckableInputType and RangeInputType if we had a common base class. >-void BaseClickableWithKeyInputType::accessKeyAction(HTMLInputElement& element, bool sendMouseEvents) >+void BaseClickableWithKeyInputType::accessKeyAction(Ref<HTMLInputElement>&& element, bool sendMouseEvents) > { >- element.dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents); >+ element->dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents); > } > > void BaseClickableWithKeyInputType::handleKeydownEvent(KeyboardEvent& event) > { >- ASSERT(element()); >- handleKeydownEvent(*element(), event); >+ handleKeydownEvent(element(), event); > } > > void BaseClickableWithKeyInputType::handleKeypressEvent(KeyboardEvent& event) > { >- ASSERT(element()); >- handleKeypressEvent(*element(), event); >+ handleKeypressEvent(element(), event); > } > > void BaseClickableWithKeyInputType::handleKeyupEvent(KeyboardEvent& event) >@@ -97,9 +95,12 @@ void BaseClickableWithKeyInputType::handleKeyupEvent(KeyboardEvent& event) > > void BaseClickableWithKeyInputType::accessKeyAction(bool sendMouseEvents) > { >+ auto weakThis = makeWeakPtr(*this); > InputType::accessKeyAction(sendMouseEvents); >- ASSERT(element()); >- accessKeyAction(*element(), sendMouseEvents); >+ if (!weakThis) >+ return; >+ >+ accessKeyAction(element(), sendMouseEvents); > } > > } // namespace WebCore >diff --git a/Source/WebCore/html/BaseClickableWithKeyInputType.h b/Source/WebCore/html/BaseClickableWithKeyInputType.h >index cc5457190d4e4dd09aabe5d6649571d8b00560f8..d945f86760364fc99cd9b0f04ee19d8efc53c78f 100644 >--- a/Source/WebCore/html/BaseClickableWithKeyInputType.h >+++ b/Source/WebCore/html/BaseClickableWithKeyInputType.h >@@ -37,10 +37,10 @@ namespace WebCore { > // Base of input types that dispatches a simulated click on space/return key. > class BaseClickableWithKeyInputType : public InputType { > public: >- static void handleKeydownEvent(HTMLInputElement&, KeyboardEvent&); >- static void handleKeypressEvent(HTMLInputElement&, KeyboardEvent&); >+ static void handleKeydownEvent(Ref<HTMLInputElement>&&, KeyboardEvent&); >+ static void handleKeypressEvent(Ref<HTMLInputElement>&&, KeyboardEvent&); > static void handleKeyupEvent(InputType&, KeyboardEvent&); >- static void accessKeyAction(HTMLInputElement&, bool sendMouseEvents); >+ static void accessKeyAction(Ref<HTMLInputElement>&&, bool sendMouseEvents); > > protected: > explicit BaseClickableWithKeyInputType(HTMLInputElement& element) : InputType(element) { } >diff --git a/Source/WebCore/html/BaseDateAndTimeInputType.cpp b/Source/WebCore/html/BaseDateAndTimeInputType.cpp >index 9036e764676490118b89a84d9e862559b89a08cc..132c388f3c5ad18ef7b2296d589d741ecd602ddd 100644 >--- a/Source/WebCore/html/BaseDateAndTimeInputType.cpp >+++ b/Source/WebCore/html/BaseDateAndTimeInputType.cpp >@@ -57,22 +57,19 @@ double BaseDateAndTimeInputType::valueAsDate() const > > ExceptionOr<void> BaseDateAndTimeInputType::setValueAsDate(double value) const > { >- ASSERT(element()); >- element()->setValue(serializeWithMilliseconds(value)); >+ element().setValue(serializeWithMilliseconds(value)); > return { }; > } > > double BaseDateAndTimeInputType::valueAsDouble() const > { >- ASSERT(element()); >- const Decimal value = parseToNumber(element()->value(), Decimal::nan()); >+ const Decimal value = parseToNumber(element().value(), Decimal::nan()); > return value.isFinite() ? value.toDouble() : DateComponents::invalidMilliseconds(); > } > > ExceptionOr<void> BaseDateAndTimeInputType::setValueAsDecimal(const Decimal& newValue, TextFieldEventBehavior eventBehavior) const > { >- ASSERT(element()); >- element()->setValue(serialize(newValue), eventBehavior); >+ element().setValue(serialize(newValue), eventBehavior); > return { }; > } > >@@ -83,8 +80,7 @@ bool BaseDateAndTimeInputType::typeMismatchFor(const String& value) const > > bool BaseDateAndTimeInputType::typeMismatch() const > { >- ASSERT(element()); >- return typeMismatchFor(element()->value()); >+ return typeMismatchFor(element().value()); > } > > Decimal BaseDateAndTimeInputType::defaultValueForStepUp() const >@@ -101,10 +97,9 @@ bool BaseDateAndTimeInputType::isSteppable() const > > void BaseDateAndTimeInputType::attributeChanged(const QualifiedName& name) > { >- if (name == maxAttr || name == minAttr) { >- if (auto* element = this->element()) >- element->invalidateStyleForSubtree(); >- } >+ if (name == maxAttr || name == minAttr) >+ element().invalidateStyleForSubtree(); >+ > InputType::attributeChanged(name); > } > >@@ -140,9 +135,8 @@ String BaseDateAndTimeInputType::serialize(const Decimal& value) const > > String BaseDateAndTimeInputType::serializeWithComponents(const DateComponents& date) const > { >- ASSERT(element()); > Decimal step; >- if (!element()->getAllowedValueStep(&step)) >+ if (!element().getAllowedValueStep(&step)) > return date.toString(); > if (step.remainder(msecPerMinute).isZero()) > return date.toString(DateComponents::None); >@@ -162,15 +156,13 @@ String BaseDateAndTimeInputType::localizeValue(const String& proposedValue) cons > if (!parseToDateComponents(proposedValue, &date)) > return proposedValue; > >- ASSERT(element()); >- String localized = element()->locale().formatDateTime(date); >+ String localized = element().locale().formatDateTime(date); > return localized.isEmpty() ? proposedValue : localized; > } > > String BaseDateAndTimeInputType::visibleValue() const > { >- ASSERT(element()); >- return localizeValue(element()->value()); >+ return localizeValue(element().value()); > } > > String BaseDateAndTimeInputType::sanitizeValue(const String& proposedValue) const >@@ -190,15 +182,13 @@ bool BaseDateAndTimeInputType::shouldRespectListAttribute() > > bool BaseDateAndTimeInputType::valueMissing(const String& value) const > { >- ASSERT(element()); >- return element()->isRequired() && value.isEmpty(); >+ return element().isRequired() && value.isEmpty(); > } > > #if PLATFORM(IOS) > bool BaseDateAndTimeInputType::isKeyboardFocusable(KeyboardEvent*) const > { >- ASSERT(element()); >- return !element()->isReadOnly() && element()->isTextFormControlFocusable(); >+ return !element().isReadOnly() && element().isTextFormControlFocusable(); > } > #endif > >diff --git a/Source/WebCore/html/BaseTextInputType.cpp b/Source/WebCore/html/BaseTextInputType.cpp >index b3685b91a9973b8311b1ca9cc80035f5fcfe51e8..815b717759178a5830891474faa2663962751dd3 100644 >--- a/Source/WebCore/html/BaseTextInputType.cpp >+++ b/Source/WebCore/html/BaseTextInputType.cpp >@@ -40,10 +40,9 @@ bool BaseTextInputType::isTextType() const > > bool BaseTextInputType::patternMismatch(const String& value) const > { >- ASSERT(element()); > // FIXME: We should execute RegExp parser first to check validity instead of creating an actual RegularExpression. > // https://bugs.webkit.org/show_bug.cgi?id=183361 >- const AtomicString& rawPattern = element()->attributeWithoutSynchronization(patternAttr); >+ const AtomicString& rawPattern = element().attributeWithoutSynchronization(patternAttr); > if (rawPattern.isNull() || value.isEmpty() || !JSC::Yarr::RegularExpression(rawPattern, JSC::Yarr::TextCaseSensitive, JSC::Yarr::MultilineDisabled, JSC::Yarr::UnicodeAwareMode).isValid()) > return false; > String pattern = "^(?:" + rawPattern + ")$"; >diff --git a/Source/WebCore/html/CheckboxInputType.cpp b/Source/WebCore/html/CheckboxInputType.cpp >index 8937e5334dbdbd4cefb957b17ca040a4d4d9b320..aac4e1cdd1c042e8779f96f4e7a9c5c8d0bd0f71 100644 >--- a/Source/WebCore/html/CheckboxInputType.cpp >+++ b/Source/WebCore/html/CheckboxInputType.cpp >@@ -36,6 +36,7 @@ > #include "InputTypeNames.h" > #include "KeyboardEvent.h" > #include "LocalizedStrings.h" >+#include "ScriptDisallowedScope.h" > > namespace WebCore { > >@@ -46,8 +47,7 @@ const AtomicString& CheckboxInputType::formControlType() const > > bool CheckboxInputType::valueMissing(const String&) const > { >- ASSERT(element()); >- return element()->isRequired() && !element()->checked(); >+ return element().isRequired() && !element().checked(); > } > > String CheckboxInputType::valueMissingText() const >@@ -65,26 +65,27 @@ void CheckboxInputType::handleKeyupEvent(KeyboardEvent& event) > > void CheckboxInputType::willDispatchClick(InputElementClickState& state) > { >- ASSERT(element()); >- > // An event handler can use preventDefault or "return false" to reverse the checking we do here. > // The InputElementClickState object contains what we need to undo what we did here in didDispatchClick. > >- state.checked = element()->checked(); >- state.indeterminate = element()->indeterminate(); >+ { >+ ScriptDisallowedScope::InMainThread scriptDisallowedScope; >+ >+ state.checked = element().checked(); >+ state.indeterminate = element().indeterminate(); > >- if (state.indeterminate) >- element()->setIndeterminate(false); >+ if (state.indeterminate) >+ element().setIndeterminate(false); >+ } > >- element()->setChecked(!state.checked, DispatchChangeEvent); >+ element().setChecked(!state.checked, DispatchChangeEvent); > } > > void CheckboxInputType::didDispatchClick(Event& event, const InputElementClickState& state) > { > if (event.defaultPrevented() || event.defaultHandled()) { >- ASSERT(element()); >- element()->setIndeterminate(state.indeterminate); >- element()->setChecked(state.checked); >+ element().setIndeterminate(state.indeterminate); >+ element().setChecked(state.checked); > } > > // The work we did in willDispatchClick was default handling. >@@ -103,8 +104,7 @@ bool CheckboxInputType::matchesIndeterminatePseudoClass() const > > bool CheckboxInputType::shouldAppearIndeterminate() const > { >- ASSERT(element()); >- return element()->indeterminate(); >+ return element().indeterminate(); > } > > } // namespace WebCore >diff --git a/Source/WebCore/html/ColorInputType.cpp b/Source/WebCore/html/ColorInputType.cpp >index 2a135f977d2d520f0c0b727786e5acbed76a9c59..3555414adc66bb1f17c65e890d4fb8a230e896d1 100644 >--- a/Source/WebCore/html/ColorInputType.cpp >+++ b/Source/WebCore/html/ColorInputType.cpp >@@ -83,18 +83,16 @@ ColorInputType::~ColorInputType() > > bool ColorInputType::isMouseFocusable() const > { >- ASSERT(element()); >- return element()->isTextFormControlFocusable(); >+ return element().isTextFormControlFocusable(); > } > > bool ColorInputType::isKeyboardFocusable(KeyboardEvent*) const > { >- ASSERT(element()); > #if PLATFORM(IOS) >- if (element()->isReadOnly()) >+ if (element().isReadOnly()) > return false; > >- return element()->isTextFormControlFocusable(); >+ return element().isTextFormControlFocusable(); > #endif > return false; > } >@@ -129,29 +127,30 @@ String ColorInputType::sanitizeValue(const String& proposedValue) const > > Color ColorInputType::valueAsColor() const > { >- ASSERT(element()); >- return parseSimpleColorValue(element()->value()).value(); >+ return parseSimpleColorValue(element().value()).value(); > } > > void ColorInputType::createShadowSubtree() > { >- ASSERT(element()); >- ASSERT(element()->shadowRoot()); >+ ASSERT(element().shadowRoot()); > >- Document& document = element()->document(); >+ Document& document = element().document(); > auto wrapperElement = HTMLDivElement::create(document); > wrapperElement->setPseudo(AtomicString("-webkit-color-swatch-wrapper", AtomicString::ConstructFromLiteral)); > auto colorSwatch = HTMLDivElement::create(document); > colorSwatch->setPseudo(AtomicString("-webkit-color-swatch", AtomicString::ConstructFromLiteral)); > wrapperElement->appendChild(colorSwatch); >- element()->userAgentShadowRoot()->appendChild(wrapperElement); >+ element().userAgentShadowRoot()->appendChild(wrapperElement); > > updateColorSwatch(); > } > > void ColorInputType::setValue(const String& value, bool valueChanged, TextFieldEventBehavior eventBehavior) > { >+ auto weakThis = makeWeakPtr(*this); > InputType::setValue(value, valueChanged, eventBehavior); >+ if (!weakThis) >+ return; > > if (!valueChanged) > return; >@@ -163,8 +162,7 @@ void ColorInputType::setValue(const String& value, bool valueChanged, TextFieldE > > void ColorInputType::handleDOMActivateEvent(Event& event) > { >- ASSERT(element()); >- if (element()->isDisabledFormControl() || !element()->renderer()) >+ if (element().isDisabledFormControl() || !element().renderer()) > return; > > if (!UserGestureIndicator::processingUserGesture()) >@@ -202,13 +200,12 @@ bool ColorInputType::shouldResetOnDocumentActivation() > > void ColorInputType::didChooseColor(const Color& color) > { >- ASSERT(element()); >- if (element()->isDisabledFormControl() || color == valueAsColor()) >+ if (element().isDisabledFormControl() || color == valueAsColor()) > return; > EventQueueScope scope; >- element()->setValueFromRenderer(color.serialized()); >+ element().setValueFromRenderer(color.serialized()); > updateColorSwatch(); >- element()->dispatchFormControlChangeEvent(); >+ element().dispatchFormControlChangeEvent(); > } > > void ColorInputType::didEndChooser() >@@ -228,14 +225,12 @@ void ColorInputType::updateColorSwatch() > if (!colorSwatch) > return; > >- ASSERT(element()); >- colorSwatch->setInlineStyleProperty(CSSPropertyBackgroundColor, element()->value(), false); >+ colorSwatch->setInlineStyleProperty(CSSPropertyBackgroundColor, element().value(), false); > } > > HTMLElement* ColorInputType::shadowColorSwatch() const > { >- ASSERT(element()); >- RefPtr<ShadowRoot> shadow = element()->userAgentShadowRoot(); >+ RefPtr<ShadowRoot> shadow = element().userAgentShadowRoot(); > if (!shadow) > return nullptr; > >@@ -248,10 +243,9 @@ HTMLElement* ColorInputType::shadowColorSwatch() const > > IntRect ColorInputType::elementRectRelativeToRootView() const > { >- ASSERT(element()); >- if (!element()->renderer()) >+ if (!element().renderer()) > return IntRect(); >- return element()->document().view()->contentsToRootView(element()->renderer()->absoluteBoundingBoxRect()); >+ return element().document().view()->contentsToRootView(element().renderer()->absoluteBoundingBoxRect()); > } > > Color ColorInputType::currentColor() >@@ -262,8 +256,7 @@ Color ColorInputType::currentColor() > bool ColorInputType::shouldShowSuggestions() const > { > #if ENABLE(DATALIST_ELEMENT) >- ASSERT(element()); >- return element()->hasAttributeWithoutSynchronization(listAttr); >+ return element().hasAttributeWithoutSynchronization(listAttr); > #else > return false; > #endif >@@ -273,8 +266,7 @@ Vector<Color> ColorInputType::suggestions() const > { > Vector<Color> suggestions; > #if ENABLE(DATALIST_ELEMENT) >- ASSERT(element()); >- if (auto dataList = element()->dataList()) { >+ if (auto dataList = element().dataList()) { > Ref<HTMLCollection> options = dataList->options(); > unsigned length = options->length(); > suggestions.reserveInitialCapacity(length); >diff --git a/Source/WebCore/html/DateInputType.cpp b/Source/WebCore/html/DateInputType.cpp >index c848a87dc670a79bb9a78918d032036712cd669c..3b5483960554313e2e61a9f19e49b4697c921474 100644 >--- a/Source/WebCore/html/DateInputType.cpp >+++ b/Source/WebCore/html/DateInputType.cpp >@@ -62,11 +62,10 @@ DateComponents::Type DateInputType::dateType() const > > StepRange DateInputType::createStepRange(AnyStepHandling anyStepHandling) const > { >- ASSERT(element()); >- const Decimal stepBase = parseToNumber(element()->attributeWithoutSynchronization(minAttr), 0); >- const Decimal minimum = parseToNumber(element()->attributeWithoutSynchronization(minAttr), Decimal::fromDouble(DateComponents::minimumDate())); >- const Decimal maximum = parseToNumber(element()->attributeWithoutSynchronization(maxAttr), Decimal::fromDouble(DateComponents::maximumDate())); >- const Decimal step = StepRange::parseStep(anyStepHandling, dateStepDescription, element()->attributeWithoutSynchronization(stepAttr)); >+ const Decimal stepBase = parseToNumber(element().attributeWithoutSynchronization(minAttr), 0); >+ const Decimal minimum = parseToNumber(element().attributeWithoutSynchronization(minAttr), Decimal::fromDouble(DateComponents::minimumDate())); >+ const Decimal maximum = parseToNumber(element().attributeWithoutSynchronization(maxAttr), Decimal::fromDouble(DateComponents::maximumDate())); >+ const Decimal step = StepRange::parseStep(anyStepHandling, dateStepDescription, element().attributeWithoutSynchronization(stepAttr)); > return StepRange(stepBase, RangeLimitations::Valid, minimum, maximum, step, dateStepDescription); > } > >diff --git a/Source/WebCore/html/DateTimeLocalInputType.cpp b/Source/WebCore/html/DateTimeLocalInputType.cpp >index 7cac1d9cbd633b95419b8e1fbf21b9e21613c98d..f281f4a062de5b40f8056542e7d770478bc5694a 100644 >--- a/Source/WebCore/html/DateTimeLocalInputType.cpp >+++ b/Source/WebCore/html/DateTimeLocalInputType.cpp >@@ -70,11 +70,10 @@ ExceptionOr<void> DateTimeLocalInputType::setValueAsDate(double value) const > > StepRange DateTimeLocalInputType::createStepRange(AnyStepHandling anyStepHandling) const > { >- ASSERT(element()); >- const Decimal stepBase = parseToNumber(element()->attributeWithoutSynchronization(minAttr), 0); >- const Decimal minimum = parseToNumber(element()->attributeWithoutSynchronization(minAttr), Decimal::fromDouble(DateComponents::minimumDateTime())); >- const Decimal maximum = parseToNumber(element()->attributeWithoutSynchronization(maxAttr), Decimal::fromDouble(DateComponents::maximumDateTime())); >- const Decimal step = StepRange::parseStep(anyStepHandling, dateTimeLocalStepDescription, element()->attributeWithoutSynchronization(stepAttr)); >+ const Decimal stepBase = parseToNumber(element().attributeWithoutSynchronization(minAttr), 0); >+ const Decimal minimum = parseToNumber(element().attributeWithoutSynchronization(minAttr), Decimal::fromDouble(DateComponents::minimumDateTime())); >+ const Decimal maximum = parseToNumber(element().attributeWithoutSynchronization(maxAttr), Decimal::fromDouble(DateComponents::maximumDateTime())); >+ const Decimal step = StepRange::parseStep(anyStepHandling, dateTimeLocalStepDescription, element().attributeWithoutSynchronization(stepAttr)); > return StepRange(stepBase, RangeLimitations::Valid, minimum, maximum, step, dateTimeLocalStepDescription); > } > >diff --git a/Source/WebCore/html/EmailInputType.cpp b/Source/WebCore/html/EmailInputType.cpp >index 42553693988b93dd1b5903f321181df9921293ae..de320b3392b9e519ef94f3c2fabd04e680d0783b 100644 >--- a/Source/WebCore/html/EmailInputType.cpp >+++ b/Source/WebCore/html/EmailInputType.cpp >@@ -59,10 +59,9 @@ const AtomicString& EmailInputType::formControlType() const > > bool EmailInputType::typeMismatchFor(const String& value) const > { >- ASSERT(element()); > if (value.isEmpty()) > return false; >- if (!element()->multiple()) >+ if (!element().multiple()) > return !isValidEmailAddress(value); > for (auto& address : value.splitAllowingEmptyEntries(',')) { > if (!isValidEmailAddress(stripLeadingAndTrailingHTMLSpaces(address))) >@@ -73,14 +72,12 @@ bool EmailInputType::typeMismatchFor(const String& value) const > > bool EmailInputType::typeMismatch() const > { >- ASSERT(element()); >- return typeMismatchFor(element()->value()); >+ return typeMismatchFor(element().value()); > } > > String EmailInputType::typeMismatchText() const > { >- ASSERT(element()); >- return element()->multiple() ? validationMessageTypeMismatchForMultipleEmailText() : validationMessageTypeMismatchForEmailText(); >+ return element().multiple() ? validationMessageTypeMismatchForMultipleEmailText() : validationMessageTypeMismatchForEmailText(); > } > > bool EmailInputType::isEmailField() const >@@ -96,8 +93,7 @@ bool EmailInputType::supportsSelectionAPI() const > String EmailInputType::sanitizeValue(const String& proposedValue) const > { > String noLineBreakValue = proposedValue.removeCharacters(isHTMLLineBreak); >- ASSERT(element()); >- if (!element()->multiple()) >+ if (!element().multiple()) > return stripLeadingAndTrailingHTMLSpaces(noLineBreakValue); > Vector<String> addresses = noLineBreakValue.splitAllowingEmptyEntries(','); > StringBuilder strippedValue; >diff --git a/Source/WebCore/html/FileInputType.cpp b/Source/WebCore/html/FileInputType.cpp >index 03af3a963494faf0012e21a938f5191780308508..68c513445e0e5470c57715509549599cb3ae4438 100644 >--- a/Source/WebCore/html/FileInputType.cpp >+++ b/Source/WebCore/html/FileInputType.cpp >@@ -40,6 +40,7 @@ > #include "LocalizedStrings.h" > #include "RenderFileUploadControl.h" > #include "RuntimeEnabledFeatures.h" >+#include "ScriptDisallowedScope.h" > #include "Settings.h" > #include "ShadowRoot.h" > #include "UserGestureIndicator.h" >@@ -153,11 +154,10 @@ void FileInputType::restoreFormControlState(const FormControlState& state) > > bool FileInputType::appendFormData(DOMFormData& formData, bool multipart) const > { >- ASSERT(element()); >- auto fileList = makeRefPtr(element()->files()); >+ auto fileList = makeRefPtr(element().files()); > ASSERT(fileList); > >- auto name = element()->name(); >+ auto name = element().name(); > > if (!multipart) { > // Send only the basenames. >@@ -187,20 +187,17 @@ bool FileInputType::appendFormData(DOMFormData& formData, bool multipart) const > > bool FileInputType::valueMissing(const String& value) const > { >- ASSERT(element()); >- return element()->isRequired() && value.isEmpty(); >+ return element().isRequired() && value.isEmpty(); > } > > String FileInputType::valueMissingText() const > { >- ASSERT(element()); >- return element()->multiple() ? validationMessageValueMissingForMultipleFileText() : validationMessageValueMissingForFileText(); >+ return element().multiple() ? validationMessageValueMissingForMultipleFileText() : validationMessageValueMissingForFileText(); > } > > void FileInputType::handleDOMActivateEvent(Event& event) > { >- ASSERT(element()); >- auto& input = *element(); >+ auto& input = element(); > > if (input.isDisabledFormControl()) > return; >@@ -227,8 +224,7 @@ void FileInputType::handleDOMActivateEvent(Event& event) > > RenderPtr<RenderElement> FileInputType::createInputRenderer(RenderStyle&& style) > { >- ASSERT(element()); >- return createRenderer<RenderFileUploadControl>(*element(), WTFMove(style)); >+ return createRenderer<RenderFileUploadControl>(element(), WTFMove(style)); > } > > bool FileInputType::canSetStringValue() const >@@ -272,8 +268,7 @@ void FileInputType::setValue(const String&, bool, TextFieldEventBehavior) > // FIXME: Should we clear the file list, or replace it with a new empty one here? This is observable from JavaScript through custom properties. > m_fileList->clear(); > m_icon = nullptr; >- ASSERT(element()); >- element()->invalidateStyleForSubtree(); >+ element().invalidateStyleForSubtree(); > } > > bool FileInputType::isFileUpload() const >@@ -283,32 +278,32 @@ bool FileInputType::isFileUpload() const > > void FileInputType::createShadowSubtree() > { >- ASSERT(element()); >- ASSERT(element()->shadowRoot()); >- element()->userAgentShadowRoot()->appendChild(element()->multiple() ? UploadButtonElement::createForMultiple(element()->document()): UploadButtonElement::create(element()->document())); >+ ASSERT(element().shadowRoot()); >+ element().userAgentShadowRoot()->appendChild(element().multiple() ? UploadButtonElement::createForMultiple(element().document()): UploadButtonElement::create(element().document())); > } > > void FileInputType::disabledStateChanged() > { >- ASSERT(element()); >- ASSERT(element()->shadowRoot()); >+ ASSERT(element().shadowRoot()); > >- auto root = element()->userAgentShadowRoot(); >+ auto root = element().userAgentShadowRoot(); > if (!root) > return; > > if (auto button = makeRefPtr(childrenOfType<UploadButtonElement>(*root).first())) >- button->setBooleanAttribute(disabledAttr, element()->isDisabledFormControl()); >+ button->setBooleanAttribute(disabledAttr, element().isDisabledFormControl()); > } > > void FileInputType::attributeChanged(const QualifiedName& name) > { > if (name == multipleAttr) { >- if (auto* element = this->element()) { >- ASSERT(element->shadowRoot()); >- if (auto root = element->userAgentShadowRoot()) { >- if (auto button = makeRefPtr(childrenOfType<UploadButtonElement>(*root).first())) >- button->setValue(element->multiple() ? fileButtonChooseMultipleFilesLabel() : fileButtonChooseFileLabel()); >+ ASSERT(element().shadowRoot()); >+ if (auto root = element().userAgentShadowRoot()) { >+ if (auto button = makeRefPtr(childrenOfType<UploadButtonElement>(*root).first())) { >+ auto weakThis = makeWeakPtr(*this); >+ button->setValue(element().multiple() ? fileButtonChooseMultipleFilesLabel() : fileButtonChooseFileLabel()); >+ if (!weakThis) >+ return; > } > } > } >@@ -349,8 +344,7 @@ bool FileInputType::allowsDirectories() const > { > if (!RuntimeEnabledFeatures::sharedFeatures().directoryUploadEnabled()) > return false; >- ASSERT(element()); >- return element()->hasAttributeWithoutSynchronization(webkitdirectoryAttr); >+ return element().hasAttributeWithoutSynchronization(webkitdirectoryAttr); > } > > void FileInputType::setFiles(RefPtr<FileList>&& files) >@@ -363,45 +357,50 @@ void FileInputType::setFiles(RefPtr<FileList>&& files, RequestIcon shouldRequest > if (!files) > return; > >- ASSERT(element()); >- Ref<HTMLInputElement> protectedInputElement(*element()); >- >- unsigned length = files->length(); >- > bool pathsChanged = false; >- if (length != m_fileList->length()) >- pathsChanged = true; >- else { >- for (unsigned i = 0; i < length; ++i) { >- if (files->file(i).path() != m_fileList->file(i).path()) { >- pathsChanged = true; >- break; >+ { >+ ScriptDisallowedScope::InMainThread scriptDisallowedScope; >+ Ref<HTMLInputElement> protectedInputElement(element()); >+ >+ unsigned length = files->length(); >+ >+ if (length != m_fileList->length()) >+ pathsChanged = true; >+ else { >+ for (unsigned i = 0; i < length; ++i) { >+ if (files->file(i).path() != m_fileList->file(i).path()) { >+ pathsChanged = true; >+ break; >+ } > } > } >- } > >- m_fileList = files.releaseNonNull(); >+ m_fileList = files.releaseNonNull(); > >- protectedInputElement->setFormControlValueMatchesRenderer(true); >- protectedInputElement->updateValidity(); >+ protectedInputElement->setFormControlValueMatchesRenderer(true); >+ protectedInputElement->updateValidity(); > >- if (shouldRequestIcon == RequestIcon::Yes) { >- Vector<String> paths; >- paths.reserveInitialCapacity(length); >- for (auto& file : m_fileList->files()) >- paths.uncheckedAppend(file->path()); >- requestIcon(paths); >- } >+ if (shouldRequestIcon == RequestIcon::Yes) { >+ Vector<String> paths; >+ paths.reserveInitialCapacity(length); >+ for (auto& file : m_fileList->files()) >+ paths.uncheckedAppend(file->path()); >+ requestIcon(paths); >+ } > >- if (protectedInputElement->renderer()) >- protectedInputElement->renderer()->repaint(); >+ if (protectedInputElement->renderer()) >+ protectedInputElement->renderer()->repaint(); >+ } > > if (pathsChanged) { > // This call may cause destruction of this instance. > // input instance is safe since it is ref-counted. >- protectedInputElement->dispatchChangeEvent(); >+ auto weakThis = makeWeakPtr(*this); >+ element().dispatchChangeEvent(); >+ if (!weakThis) >+ return; > } >- protectedInputElement->setChangedSinceLastFormControlChangeEvent(false); >+ element().setChangedSinceLastFormControlChangeEvent(false); > } > > void FileInputType::filesChosen(const Vector<FileChooserFileInfo>& paths, const String& displayString, Icon* icon) >@@ -434,8 +433,7 @@ void FileInputType::iconLoaded(RefPtr<Icon>&& icon) > return; > > m_icon = WTFMove(icon); >- ASSERT(element()); >- if (auto* renderer = element()->renderer()) >+ if (auto* renderer = element().renderer()) > renderer->repaint(); > } > >@@ -446,8 +444,7 @@ bool FileInputType::receiveDroppedFiles(const DragData& dragData) > if (paths.isEmpty()) > return false; > >- ASSERT(element()); >- if (element()->hasAttributeWithoutSynchronization(multipleAttr)) { >+ if (element().hasAttributeWithoutSynchronization(multipleAttr)) { > Vector<FileChooserFileInfo> files; > files.reserveInitialCapacity(paths.size()); > for (auto& path : paths) >@@ -470,8 +467,7 @@ String FileInputType::defaultToolTip() const > { > unsigned listSize = m_fileList->length(); > if (!listSize) { >- ASSERT(element()); >- if (element()->multiple()) >+ if (element().multiple()) > return fileButtonNoFilesSelectedLabel(); > return fileButtonNoFileSelectedLabel(); > } >diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp >index b1ff12d96a59fdb4d13d01144245a32c8113cebb..8a07c03809a95a435e68b1f97cbd004e860f77c2 100644 >--- a/Source/WebCore/html/HTMLInputElement.cpp >+++ b/Source/WebCore/html/HTMLInputElement.cpp >@@ -153,8 +153,7 @@ HTMLImageLoader& HTMLInputElement::ensureImageLoader() > > void HTMLInputElement::didAddUserAgentShadowRoot(ShadowRoot&) > { >- Ref<InputType> protectedInputType(*m_inputType); >- protectedInputType->createShadowSubtree(); >+ m_inputType->createShadowSubtree(); > updateInnerTextElementEditability(); > } > >@@ -631,8 +630,7 @@ bool HTMLInputElement::canHaveSelection() const > > void HTMLInputElement::accessKeyAction(bool sendMouseEvents) > { >- Ref<InputType> protectedInputType(*m_inputType); >- protectedInputType->accessKeyAction(sendMouseEvents); >+ m_inputType->accessKeyAction(sendMouseEvents); > } > > bool HTMLInputElement::isPresentationAttribute(const QualifiedName& name) const >@@ -689,7 +687,6 @@ inline void HTMLInputElement::initializeInputType() > void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicString& value) > { > ASSERT(m_inputType); >- Ref<InputType> protectedInputType(*m_inputType); > > if (name == nameAttr) { > removeFromRadioButtonGroup(); >@@ -879,7 +876,6 @@ void HTMLInputElement::setActivatedSubmit(bool flag) > > bool HTMLInputElement::appendFormData(DOMFormData& formData, bool multipart) > { >- Ref<InputType> protectedInputType(*m_inputType); > return m_inputType->isFormDataAppendable() && m_inputType->appendFormData(formData, multipart); > } > >diff --git a/Source/WebCore/html/HTMLInputElement.h b/Source/WebCore/html/HTMLInputElement.h >index 3729b89e27d8ca2e939c00f2081f97a2b5036102..67019efa8c427f484af5e16b0096408a0175e2e2 100644 >--- a/Source/WebCore/html/HTMLInputElement.h >+++ b/Source/WebCore/html/HTMLInputElement.h >@@ -55,7 +55,7 @@ struct InputElementClickState { > RefPtr<HTMLInputElement> checkedRadioButton; > }; > >-class HTMLInputElement : public HTMLTextFormControlElement, public CanMakeWeakPtr<HTMLInputElement> { >+class HTMLInputElement : public HTMLTextFormControlElement { > WTF_MAKE_ISO_ALLOCATED(HTMLInputElement); > public: > static Ref<HTMLInputElement> create(const QualifiedName&, Document&, HTMLFormElement*, bool createdByParser); >@@ -475,7 +475,7 @@ private: > bool m_hasTouchEventHandler : 1; > #endif > bool m_isSpellcheckDisabledExceptTextReplacement : 1; >- RefPtr<InputType> m_inputType; >+ std::unique_ptr<InputType> m_inputType; > // The ImageLoader must be owned by this element because the loader code assumes > // that it lives as long as its owning element lives. If we move the loader into > // the ImageInput object we may delete the loader while this element lives on. >diff --git a/Source/WebCore/html/HiddenInputType.cpp b/Source/WebCore/html/HiddenInputType.cpp >index a882c8fc59394831ec804afa2c9c76b01e7bb766..69706e25a80d214241ca6cbd2fd66dada37ed7c2 100644 >--- a/Source/WebCore/html/HiddenInputType.cpp >+++ b/Source/WebCore/html/HiddenInputType.cpp >@@ -52,14 +52,12 @@ FormControlState HiddenInputType::saveFormControlState() const > { > // valueAttributeWasUpdatedAfterParsing() never be true for form controls create by createElement() or cloneNode(). > // It's OK for now because we restore values only to form controls created by parsing. >- ASSERT(element()); >- return element()->valueAttributeWasUpdatedAfterParsing() ? FormControlState { { element()->value() } } : FormControlState { }; >+ return element().valueAttributeWasUpdatedAfterParsing() ? FormControlState { { element().value() } } : FormControlState { }; > } > > void HiddenInputType::restoreFormControlState(const FormControlState& state) > { >- ASSERT(element()); >- element()->setAttributeWithoutSynchronization(valueAttr, state[0]); >+ element().setAttributeWithoutSynchronization(valueAttr, state[0]); > } > > bool HiddenInputType::supportsValidation() const >@@ -89,8 +87,7 @@ bool HiddenInputType::storesValueSeparateFromAttribute() > > void HiddenInputType::setValue(const String& sanitizedValue, bool, TextFieldEventBehavior) > { >- ASSERT(element()); >- element()->setAttributeWithoutSynchronization(valueAttr, sanitizedValue); >+ element().setAttributeWithoutSynchronization(valueAttr, sanitizedValue); > } > > bool HiddenInputType::isHiddenType() const >@@ -100,8 +97,7 @@ bool HiddenInputType::isHiddenType() const > > bool HiddenInputType::appendFormData(DOMFormData& formData, bool isMultipartForm) const > { >- ASSERT(element()); >- auto name = element()->name(); >+ auto name = element().name(); > > if (equalIgnoringASCIICase(name, "_charset_")) { > formData.append(name, String { formData.encoding().name() }); >diff --git a/Source/WebCore/html/ImageInputType.cpp b/Source/WebCore/html/ImageInputType.cpp >index 2b0f1ed66828f126a7e159a04b1cba8c08c5aaa0..2a2cdac589ed8ae69fb8d6f8d6ae46436dda45c3 100644 >--- a/Source/WebCore/html/ImageInputType.cpp >+++ b/Source/WebCore/html/ImageInputType.cpp >@@ -56,11 +56,10 @@ bool ImageInputType::isFormDataAppendable() const > > bool ImageInputType::appendFormData(DOMFormData& formData, bool) const > { >- ASSERT(element()); >- if (!element()->isActivatedSubmit()) >+ if (!element().isActivatedSubmit()) > return false; > >- auto& name = element()->name(); >+ auto& name = element().name(); > if (name.isEmpty()) { > formData.append("x"_s, String::number(m_clickLocation.x())); > formData.append("y"_s, String::number(m_clickLocation.y())); >@@ -70,7 +69,7 @@ bool ImageInputType::appendFormData(DOMFormData& formData, bool) const > formData.append(makeString(name, ".x"), String::number(m_clickLocation.x())); > formData.append(makeString(name, ".y"), String::number(m_clickLocation.y())); > >- auto value = element()->value(); >+ auto value = element().value(); > if (!value.isEmpty()) > formData.append(name, value); > >@@ -84,8 +83,7 @@ bool ImageInputType::supportsValidation() const > > void ImageInputType::handleDOMActivateEvent(Event& event) > { >- ASSERT(element()); >- Ref<HTMLInputElement> protectedElement(*element()); >+ Ref<HTMLInputElement> protectedElement(element()); > if (protectedElement->isDisabledFormControl() || !protectedElement->form()) > return; > >@@ -116,23 +114,18 @@ void ImageInputType::handleDOMActivateEvent(Event& event) > > RenderPtr<RenderElement> ImageInputType::createInputRenderer(RenderStyle&& style) > { >- ASSERT(element()); >- return createRenderer<RenderImage>(*element(), WTFMove(style)); >+ return createRenderer<RenderImage>(element(), WTFMove(style)); > } > > void ImageInputType::attributeChanged(const QualifiedName& name) > { > if (name == altAttr) { >- if (auto* element = this->element()) { >- auto* renderer = element->renderer(); >- if (is<RenderImage>(renderer)) >- downcast<RenderImage>(*renderer).updateAltText(); >- } >+ auto* renderer = element().renderer(); >+ if (is<RenderImage>(renderer)) >+ downcast<RenderImage>(*renderer).updateAltText(); > } else if (name == srcAttr) { >- if (auto* element = this->element()) { >- if (element->renderer()) >- element->ensureImageLoader().updateFromElementIgnoringPreviousError(); >- } >+ if (element().renderer()) >+ element().ensureImageLoader().updateFromElementIgnoringPreviousError(); > } > BaseButtonInputType::attributeChanged(name); > } >@@ -141,11 +134,10 @@ void ImageInputType::attach() > { > BaseButtonInputType::attach(); > >- ASSERT(element()); >- HTMLImageLoader& imageLoader = element()->ensureImageLoader(); >+ HTMLImageLoader& imageLoader = element().ensureImageLoader(); > imageLoader.updateFromElement(); > >- auto* renderer = downcast<RenderImage>(element()->renderer()); >+ auto* renderer = downcast<RenderImage>(element().renderer()); > if (!renderer) > return; > >@@ -188,8 +180,7 @@ bool ImageInputType::shouldRespectHeightAndWidthAttributes() > > unsigned ImageInputType::height() const > { >- ASSERT(element()); >- Ref<HTMLInputElement> element(*this->element()); >+ Ref<HTMLInputElement> element(this->element()); > > element->document().updateLayout(); > >@@ -210,8 +201,7 @@ unsigned ImageInputType::height() const > > unsigned ImageInputType::width() const > { >- ASSERT(element()); >- Ref<HTMLInputElement> element(*this->element()); >+ Ref<HTMLInputElement> element(this->element()); > > element->document().updateLayout(); > >diff --git a/Source/WebCore/html/InputType.cpp b/Source/WebCore/html/InputType.cpp >index 9167fe9d922c52a5f8526c0243ed6b8403c99b5b..a89c8cdea4f86b19ebd5427ed6504e7f5ee2ec88 100644 >--- a/Source/WebCore/html/InputType.cpp >+++ b/Source/WebCore/html/InputType.cpp >@@ -64,6 +64,7 @@ > #include "ResetInputType.h" > #include "RuntimeEnabledFeatures.h" > #include "ScopedEventQueue.h" >+#include "ScriptDisallowedScope.h" > #include "SearchInputType.h" > #include "ShadowRoot.h" > #include "SubmitInputType.h" >@@ -85,13 +86,13 @@ using namespace HTMLNames; > > typedef bool (RuntimeEnabledFeatures::*InputTypeConditionalFunction)() const; > typedef const AtomicString& (*InputTypeNameFunction)(); >-typedef Ref<InputType> (*InputTypeFactoryFunction)(HTMLInputElement&); >+typedef std::unique_ptr<InputType> (*InputTypeFactoryFunction)(HTMLInputElement&); > typedef HashMap<AtomicString, InputTypeFactoryFunction, ASCIICaseInsensitiveHash> InputTypeFactoryMap; > > template<class T> >-static Ref<InputType> createInputType(HTMLInputElement& element) >+static std::unique_ptr<InputType> createInputType(HTMLInputElement& element) > { >- return adoptRef(*new T(element)); >+ return std::make_unique<T>(element); > } > > static InputTypeFactoryMap createInputTypeFactoryMap() >@@ -149,19 +150,19 @@ static InputTypeFactoryMap createInputTypeFactoryMap() > return map; > } > >-Ref<InputType> InputType::create(HTMLInputElement& element, const AtomicString& typeName) >+std::unique_ptr<InputType> InputType::create(HTMLInputElement& element, const AtomicString& typeName) > { > if (!typeName.isEmpty()) { > static const auto factoryMap = makeNeverDestroyed(createInputTypeFactoryMap()); > if (auto factory = factoryMap.get().get(typeName)) > return factory(element); > } >- return adoptRef(*new TextInputType(element)); >+ return std::make_unique<TextInputType>(element); > } > >-Ref<InputType> InputType::createText(HTMLInputElement& element) >+std::unique_ptr<InputType> InputType::createText(HTMLInputElement& element) > { >- return adoptRef(*new TextInputType(element)); >+ return std::make_unique<TextInputType>(element); > } > > InputType::~InputType() = default; >@@ -193,31 +194,27 @@ bool InputType::shouldSaveAndRestoreFormControlState() const > > FormControlState InputType::saveFormControlState() const > { >- ASSERT(element()); >- auto currentValue = element()->value(); >- if (currentValue == element()->defaultValue()) >+ auto currentValue = element().value(); >+ if (currentValue == element().defaultValue()) > return { }; > return { { currentValue } }; > } > > void InputType::restoreFormControlState(const FormControlState& state) > { >- ASSERT(element()); >- element()->setValue(state[0]); >+ element().setValue(state[0]); > } > > bool InputType::isFormDataAppendable() const > { >- ASSERT(element()); > // There is no form data unless there's a name for non-image types. >- return !element()->name().isEmpty(); >+ return !element().name().isEmpty(); > } > > bool InputType::appendFormData(DOMFormData& formData, bool) const > { >- ASSERT(element()); > // Always successful. >- formData.append(element()->name(), element()->value()); >+ formData.append(element().name(), element().value()); > return true; > } > >@@ -323,8 +320,7 @@ double InputType::maximum() const > > bool InputType::sizeShouldIncludeDecoration(int, int& preferredSize) const > { >- ASSERT(element()); >- preferredSize = element()->size(); >+ preferredSize = element().size(); > return false; > } > >@@ -395,8 +391,7 @@ String InputType::valueMissingText() const > > String InputType::validationMessage() const > { >- ASSERT(element()); >- String value = element()->value(); >+ String value = element().value(); > > // The order of the following checks is meaningful. e.g. We'd like to show the > // badInput message even if the control has other validation errors. >@@ -412,11 +407,11 @@ String InputType::validationMessage() const > if (patternMismatch(value)) > return validationMessagePatternMismatchText(); > >- if (element()->tooShort()) >- return validationMessageTooShortText(numGraphemeClusters(value), element()->minLength()); >+ if (element().tooShort()) >+ return validationMessageTooShortText(numGraphemeClusters(value), element().minLength()); > >- if (element()->tooLong()) >- return validationMessageTooLongText(numGraphemeClusters(value), element()->effectiveMaxLength()); >+ if (element().tooLong()) >+ return validationMessageTooLongText(numGraphemeClusters(value), element().effectiveMaxLength()); > > if (!isSteppable()) > return emptyString(); >@@ -486,14 +481,12 @@ bool InputType::shouldSubmitImplicitly(Event& event) > > RenderPtr<RenderElement> InputType::createInputRenderer(RenderStyle&& style) > { >- ASSERT(element()); >- return RenderPtr<RenderElement>(RenderElement::createFor(*element(), WTFMove(style))); >+ return RenderPtr<RenderElement>(RenderElement::createFor(element(), WTFMove(style))); > } > > void InputType::blur() > { >- ASSERT(element()); >- element()->defaultBlur(); >+ element().defaultBlur(); > } > > void InputType::createShadowSubtree() >@@ -502,8 +495,7 @@ void InputType::createShadowSubtree() > > void InputType::destroyShadowSubtree() > { >- ASSERT(element()); >- RefPtr<ShadowRoot> root = element()->userAgentShadowRoot(); >+ RefPtr<ShadowRoot> root = element().userAgentShadowRoot(); > if (!root) > return; > >@@ -542,16 +534,14 @@ DateComponents::Type InputType::dateType() const > > void InputType::dispatchSimulatedClickIfActive(KeyboardEvent& event) const > { >- ASSERT(element()); >- if (element()->active()) >- element()->dispatchSimulatedClick(&event); >+ if (element().active()) >+ element().dispatchSimulatedClick(&event); > event.setDefaultHandled(); > } > > Chrome* InputType::chrome() const > { >- ASSERT(element()); >- if (Page* page = element()->document().page()) >+ if (Page* page = element().document().page()) > return &page->chrome(); > return nullptr; > } >@@ -568,14 +558,12 @@ bool InputType::hasCustomFocusLogic() const > > bool InputType::isKeyboardFocusable(KeyboardEvent* event) const > { >- ASSERT(element()); >- return !element()->isReadOnly() && element()->isTextFormControlKeyboardFocusable(event); >+ return !element().isReadOnly() && element().isTextFormControlKeyboardFocusable(event); > } > > bool InputType::isMouseFocusable() const > { >- ASSERT(element()); >- return element()->isTextFormControlMouseFocusable(); >+ return element().isTextFormControlMouseFocusable(); > } > > bool InputType::shouldUseInputMethod() const >@@ -593,8 +581,7 @@ void InputType::handleBlurEvent() > > void InputType::accessKeyAction(bool) > { >- ASSERT(element()); >- element()->focus(false); >+ element().focus(false); > } > > void InputType::addSearchResult() >@@ -665,21 +652,27 @@ bool InputType::storesValueSeparateFromAttribute() > > void InputType::setValue(const String& sanitizedValue, bool valueChanged, TextFieldEventBehavior eventBehavior) > { >- ASSERT(element()); >- element()->setValueInternal(sanitizedValue, eventBehavior); >- element()->invalidateStyleForSubtree(); >+ { >+ ScriptDisallowedScope::InMainThread scriptDisallowedScope; >+ element().setValueInternal(sanitizedValue, eventBehavior); >+ element().invalidateStyleForSubtree(); >+ } > if (!valueChanged) > return; > > switch (eventBehavior) { > case DispatchChangeEvent: >- element()->dispatchFormControlChangeEvent(); >+ element().dispatchFormControlChangeEvent(); > break; >- case DispatchInputAndChangeEvent: >- element()->dispatchFormControlInputEvent(); >- if (auto element = this->element()) >- element->dispatchFormControlChangeEvent(); >+ case DispatchInputAndChangeEvent: { >+ auto weakThis = makeWeakPtr(*this); >+ element().dispatchFormControlInputEvent(); >+ // Running script could have destroyed this object. >+ if (!weakThis) >+ return; >+ element().dispatchFormControlChangeEvent(); > break; >+ } > case DispatchNoEvent: > break; > } >@@ -705,8 +698,7 @@ String InputType::localizeValue(const String& proposedValue) const > > String InputType::visibleValue() const > { >- ASSERT(element()); >- return element()->value(); >+ return element().value(); > } > > bool InputType::isEmptyValue() const >@@ -962,8 +954,7 @@ ExceptionOr<void> InputType::applyStep(int count, AnyStepHandling anyStepHandlin > if (!stepRange.hasStep()) > return Exception { InvalidStateError }; > >- ASSERT(element()); >- const Decimal current = parseToNumberOrNaN(element()->value()); >+ const Decimal current = parseToNumberOrNaN(element().value()); > if (!current.isFinite()) > return Exception { InvalidStateError }; > Decimal newValue = current + stepRange.step() * count; >@@ -976,7 +967,7 @@ ExceptionOr<void> InputType::applyStep(int count, AnyStepHandling anyStepHandlin > if (newValue < stepRange.minimum()) > newValue = stepRange.minimum(); > >- if (!equalLettersIgnoringASCIICase(element()->attributeWithoutSynchronization(stepAttr), "any")) >+ if (!equalLettersIgnoringASCIICase(element().attributeWithoutSynchronization(stepAttr), "any")) > newValue = stepRange.alignValueForStep(current, newValue); > > if (newValue - stepRange.maximum() > acceptableErrorValue) >@@ -984,12 +975,13 @@ ExceptionOr<void> InputType::applyStep(int count, AnyStepHandling anyStepHandlin > if (newValue > stepRange.maximum()) > newValue = stepRange.maximum(); > >+ auto weakThis = makeWeakPtr(*this); > auto result = setValueAsDecimal(newValue, eventBehavior); >- if (result.hasException()) >+ if (result.hasException() || !weakThis) > return result; > >- if (AXObjectCache* cache = element()->document().existingAXObjectCache()) >- cache->postNotification(element(), AXObjectCache::AXValueChanged); >+ if (AXObjectCache* cache = element().document().existingAXObjectCache()) >+ cache->postNotification(&element(), AXObjectCache::AXValueChanged); > > return result; > } >@@ -1076,8 +1068,7 @@ void InputType::stepUpFromRenderer(int n) > else > sign = 0; > >- ASSERT(element()); >- String currentStringValue = element()->value(); >+ String currentStringValue = element().value(); > Decimal current = parseToNumberOrNaN(currentStringValue); > if (!current.isFinite()) { > current = defaultValueForStepUp(); >@@ -1091,7 +1082,7 @@ void InputType::stepUpFromRenderer(int n) > if ((sign > 0 && current < stepRange.minimum()) || (sign < 0 && current > stepRange.maximum())) > setValueAsDecimal(sign > 0 ? stepRange.minimum() : stepRange.maximum(), DispatchInputAndChangeEvent); > else { >- if (stepMismatch(element()->value())) { >+ if (stepMismatch(element().value())) { > ASSERT(!step.isZero()); > const Decimal base = stepRange.stepBase(); > Decimal newValue; >@@ -1107,7 +1098,10 @@ void InputType::stepUpFromRenderer(int n) > if (newValue > stepRange.maximum()) > newValue = stepRange.maximum(); > >+ auto weakThis = makeWeakPtr(*this); > setValueAsDecimal(newValue, n == 1 || n == -1 ? DispatchInputAndChangeEvent : DispatchNoEvent); >+ if (!weakThis) >+ return; > if (n > 1) > applyStep(n - 1, AnyIsDefaultStep, DispatchInputAndChangeEvent); > else if (n < -1) >diff --git a/Source/WebCore/html/InputType.h b/Source/WebCore/html/InputType.h >index c994cce523cc86b66ce9ea8023847063629b2e8d..fa2307ac22d782130e2169c173d12daa00b077ef 100644 >--- a/Source/WebCore/html/InputType.h >+++ b/Source/WebCore/html/InputType.h >@@ -69,12 +69,12 @@ struct InputElementClickState; > // An InputType object represents the type-specific part of an HTMLInputElement. > // Do not expose instances of InputType and classes derived from it to classes > // other than HTMLInputElement. >-class InputType : public RefCounted<InputType> { >+class InputType : public CanMakeWeakPtr<InputType> { > WTF_MAKE_FAST_ALLOCATED; > > public: >- static Ref<InputType> create(HTMLInputElement&, const AtomicString&); >- static Ref<InputType> createText(HTMLInputElement&); >+ static std::unique_ptr<InputType> create(HTMLInputElement&, const AtomicString&); >+ static std::unique_ptr<InputType> createText(HTMLInputElement&); > virtual ~InputType(); > > static bool themeSupportsDataListUI(InputType*); >@@ -305,8 +305,8 @@ public: > > protected: > explicit InputType(HTMLInputElement& element) >- : m_element(makeWeakPtr(element)) { } >- HTMLInputElement* element() const { return m_element.get(); } >+ : m_element(element) { } >+ HTMLInputElement& element() const { return m_element; } > Chrome* chrome() const; > Decimal parseToNumberOrNaN(const String&) const; > >@@ -314,8 +314,8 @@ private: > // Helper for stepUp()/stepDown(). Adds step value * count to the current value. > ExceptionOr<void> applyStep(int count, AnyStepHandling, TextFieldEventBehavior); > >- // Raw pointer because the HTMLInputElement object owns this InputType object. >- WeakPtr<HTMLInputElement> m_element; >+ // The HTMLInputElement object owns this InputType object. >+ HTMLInputElement& m_element; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/html/MonthInputType.cpp b/Source/WebCore/html/MonthInputType.cpp >index f92b35535a1d6ea23367a696052f18a23f1e24e1..6c6d4f84176ef56e9c06db8ac187d62d9353ff1a 100644 >--- a/Source/WebCore/html/MonthInputType.cpp >+++ b/Source/WebCore/html/MonthInputType.cpp >@@ -60,9 +60,8 @@ DateComponents::Type MonthInputType::dateType() const > > double MonthInputType::valueAsDate() const > { >- ASSERT(element()); > DateComponents date; >- if (!parseToDateComponents(element()->value(), &date)) >+ if (!parseToDateComponents(element().value(), &date)) > return DateComponents::invalidMilliseconds(); > double msec = date.millisecondsSinceEpoch(); > ASSERT(std::isfinite(msec)); >@@ -92,11 +91,10 @@ Decimal MonthInputType::defaultValueForStepUp() const > > StepRange MonthInputType::createStepRange(AnyStepHandling anyStepHandling) const > { >- ASSERT(element()); >- const Decimal stepBase = parseToNumber(element()->attributeWithoutSynchronization(minAttr), Decimal::fromDouble(monthDefaultStepBase)); >- const Decimal minimum = parseToNumber(element()->attributeWithoutSynchronization(minAttr), Decimal::fromDouble(DateComponents::minimumMonth())); >- const Decimal maximum = parseToNumber(element()->attributeWithoutSynchronization(maxAttr), Decimal::fromDouble(DateComponents::maximumMonth())); >- const Decimal step = StepRange::parseStep(anyStepHandling, monthStepDescription, element()->attributeWithoutSynchronization(stepAttr)); >+ const Decimal stepBase = parseToNumber(element().attributeWithoutSynchronization(minAttr), Decimal::fromDouble(monthDefaultStepBase)); >+ const Decimal minimum = parseToNumber(element().attributeWithoutSynchronization(minAttr), Decimal::fromDouble(DateComponents::minimumMonth())); >+ const Decimal maximum = parseToNumber(element().attributeWithoutSynchronization(maxAttr), Decimal::fromDouble(DateComponents::maximumMonth())); >+ const Decimal step = StepRange::parseStep(anyStepHandling, monthStepDescription, element().attributeWithoutSynchronization(stepAttr)); > return StepRange(stepBase, RangeLimitations::Valid, minimum, maximum, step, monthStepDescription); > } > >diff --git a/Source/WebCore/html/NumberInputType.cpp b/Source/WebCore/html/NumberInputType.cpp >index 3a92afc1ac82296cd5e4de3e76d067af2d44e4d4..795597dd2a718bbd7072e412d732940afa347e81 100644 >--- a/Source/WebCore/html/NumberInputType.cpp >+++ b/Source/WebCore/html/NumberInputType.cpp >@@ -93,16 +93,18 @@ const AtomicString& NumberInputType::formControlType() const > > void NumberInputType::setValue(const String& sanitizedValue, bool valueChanged, TextFieldEventBehavior eventBehavior) > { >- ASSERT(element()); >- if (!valueChanged && sanitizedValue.isEmpty() && !element()->innerTextValue().isEmpty()) >+ if (!valueChanged && sanitizedValue.isEmpty() && !element().innerTextValue().isEmpty()) { >+ auto weakThis = makeWeakPtr(*this); > updateInnerTextValue(); >+ if (!weakThis) >+ return; >+ } > TextFieldInputType::setValue(sanitizedValue, valueChanged, eventBehavior); > } > > double NumberInputType::valueAsDouble() const > { >- ASSERT(element()); >- return parseToDoubleForNumberType(element()->value()); >+ return parseToDoubleForNumberType(element().value()); > } > > ExceptionOr<void> NumberInputType::setValueAsDouble(double newValue, TextFieldEventBehavior eventBehavior) const >@@ -111,8 +113,7 @@ ExceptionOr<void> NumberInputType::setValueAsDouble(double newValue, TextFieldEv > const double floatMax = std::numeric_limits<float>::max(); > if (newValue < -floatMax || newValue > floatMax) > return Exception { InvalidStateError }; >- ASSERT(element()); >- element()->setValue(serializeForNumberType(newValue), eventBehavior); >+ element().setValue(serializeForNumberType(newValue), eventBehavior); > return { }; > } > >@@ -122,8 +123,7 @@ ExceptionOr<void> NumberInputType::setValueAsDecimal(const Decimal& newValue, Te > const Decimal floatMax = Decimal::fromDouble(std::numeric_limits<float>::max()); > if (newValue < -floatMax || newValue > floatMax) > return Exception { InvalidStateError }; >- ASSERT(element()); >- element()->setValue(serializeForNumberType(newValue), eventBehavior); >+ element().setValue(serializeForNumberType(newValue), eventBehavior); > return { }; > } > >@@ -134,8 +134,7 @@ bool NumberInputType::typeMismatchFor(const String& value) const > > bool NumberInputType::typeMismatch() const > { >- ASSERT(element()); >- ASSERT(!typeMismatchFor(element()->value())); >+ ASSERT(!typeMismatchFor(element().value())); > return false; > } > >@@ -143,11 +142,10 @@ StepRange NumberInputType::createStepRange(AnyStepHandling anyStepHandling) cons > { > static NeverDestroyed<const StepRange::StepDescription> stepDescription(numberDefaultStep, numberDefaultStepBase, numberStepScaleFactor); > >- ASSERT(element()); >- const Decimal stepBase = parseToDecimalForNumberType(element()->attributeWithoutSynchronization(minAttr), numberDefaultStepBase); >+ const Decimal stepBase = parseToDecimalForNumberType(element().attributeWithoutSynchronization(minAttr), numberDefaultStepBase); > // FIXME: We should use numeric_limits<double>::max for number input type. > const Decimal floatMax = Decimal::fromDouble(std::numeric_limits<float>::max()); >- const Element& element = *this->element(); >+ const Element& element = this->element(); > > RangeLimitations rangeLimitations = RangeLimitations::Invalid; > auto extractBound = [&] (const QualifiedName& attributeName, const Decimal& defaultValue) -> Decimal { >@@ -170,16 +168,15 @@ bool NumberInputType::sizeShouldIncludeDecoration(int defaultSize, int& preferre > { > preferredSize = defaultSize; > >- ASSERT(element()); >- auto& stepString = element()->attributeWithoutSynchronization(stepAttr); >+ auto& stepString = element().attributeWithoutSynchronization(stepAttr); > if (equalLettersIgnoringASCIICase(stepString, "any")) > return false; > >- const Decimal minimum = parseToDecimalForNumberType(element()->attributeWithoutSynchronization(minAttr)); >+ const Decimal minimum = parseToDecimalForNumberType(element().attributeWithoutSynchronization(minAttr)); > if (!minimum.isFinite()) > return false; > >- const Decimal maximum = parseToDecimalForNumberType(element()->attributeWithoutSynchronization(maxAttr)); >+ const Decimal maximum = parseToDecimalForNumberType(element().attributeWithoutSynchronization(maxAttr)); > if (!maximum.isFinite()) > return false; > >@@ -195,10 +192,8 @@ bool NumberInputType::sizeShouldIncludeDecoration(int defaultSize, int& preferre > > float NumberInputType::decorationWidth() const > { >- ASSERT(element()); >- > float width = 0; >- RefPtr<HTMLElement> spinButton = element()->innerSpinButtonElement(); >+ RefPtr<HTMLElement> spinButton = element().innerSpinButtonElement(); > if (RenderBox* spinRenderer = spinButton ? spinButton->renderBox() : 0) { > width += spinRenderer->borderAndPaddingLogicalWidth(); > // Since the width of spinRenderer is not calculated yet, spinRenderer->logicalWidth() returns 0. >@@ -215,7 +210,10 @@ bool NumberInputType::isSteppable() const > > void NumberInputType::handleKeydownEvent(KeyboardEvent& event) > { >+ auto weakThis = makeWeakPtr(*this); > handleKeydownEventForSpinButton(event); >+ if (!weakThis) >+ return; > if (!event.defaultHandled()) > TextFieldInputType::handleKeydownEvent(event); > } >@@ -244,14 +242,12 @@ String NumberInputType::localizeValue(const String& proposedValue) const > // We don't localize scientific notations. > if (proposedValue.find(isE) != notFound) > return proposedValue; >- ASSERT(element()); >- return element()->locale().convertToLocalizedNumber(proposedValue); >+ return element().locale().convertToLocalizedNumber(proposedValue); > } > > String NumberInputType::visibleValue() const > { >- ASSERT(element()); >- return localizeValue(element()->value()); >+ return localizeValue(element().value()); > } > > String NumberInputType::convertFromVisibleValue(const String& visibleValue) const >@@ -261,8 +257,7 @@ String NumberInputType::convertFromVisibleValue(const String& visibleValue) cons > // We don't localize scientific notations. > if (visibleValue.find(isE) != notFound) > return visibleValue; >- ASSERT(element()); >- return element()->locale().convertFromLocalizedNumber(visibleValue); >+ return element().locale().convertFromLocalizedNumber(visibleValue); > } > > String NumberInputType::sanitizeValue(const String& proposedValue) const >@@ -274,8 +269,7 @@ String NumberInputType::sanitizeValue(const String& proposedValue) const > > bool NumberInputType::hasBadInput() const > { >- ASSERT(element()); >- String standardValue = convertFromVisibleValue(element()->innerTextValue()); >+ String standardValue = convertFromVisibleValue(element().innerTextValue()); > return !standardValue.isEmpty() && !std::isfinite(parseToDoubleForNumberType(standardValue)); > } > >@@ -295,19 +289,14 @@ bool NumberInputType::isNumberField() const > } > > void NumberInputType::attributeChanged(const QualifiedName& name) >-{ >- ASSERT(element()); >+{; > if (name == maxAttr || name == minAttr) { >- if (auto* element = this->element()) { >- element->invalidateStyleForSubtree(); >- if (auto* renderer = element->renderer()) >- renderer->setNeedsLayoutAndPrefWidthsRecalc(); >- } >+ element().invalidateStyleForSubtree(); >+ if (auto* renderer = element().renderer()) >+ renderer->setNeedsLayoutAndPrefWidthsRecalc(); > } else if (name == stepAttr) { >- if (auto* element = this->element()) { >- if (auto* renderer = element->renderer()) >- renderer->setNeedsLayoutAndPrefWidthsRecalc(); >- } >+ if (auto* renderer = element().renderer()) >+ renderer->setNeedsLayoutAndPrefWidthsRecalc(); > } > TextFieldInputType::attributeChanged(name); > } >diff --git a/Source/WebCore/html/RadioInputType.cpp b/Source/WebCore/html/RadioInputType.cpp >index c11f6c956a1b553d397946e7e76299b5c69bbf60..c60d5cca435848f0c48afaa70eda014a6c96c20d 100644 >--- a/Source/WebCore/html/RadioInputType.cpp >+++ b/Source/WebCore/html/RadioInputType.cpp >@@ -44,8 +44,7 @@ const AtomicString& RadioInputType::formControlType() const > > bool RadioInputType::valueMissing(const String&) const > { >- ASSERT(element()); >- return element()->isInRequiredRadioButtonGroup() && !element()->checkedRadioButtonForGroup(); >+ return element().isInRequiredRadioButtonGroup() && !element().checkedRadioButtonForGroup(); > } > > String RadioInputType::valueMissingText() const >@@ -60,26 +59,28 @@ void RadioInputType::handleClickEvent(MouseEvent& event) > > void RadioInputType::handleKeydownEvent(KeyboardEvent& event) > { >+ auto weakThis = makeWeakPtr(*this); > BaseCheckableInputType::handleKeydownEvent(event); >+ if (!weakThis) >+ return; > if (event.defaultHandled()) > return; > const String& key = event.keyIdentifier(); > if (key != "Up" && key != "Down" && key != "Left" && key != "Right") > return; > >- ASSERT(element()); > // Left and up mean "previous radio button". > // Right and down mean "next radio button". > // Tested in WinIE, and even for RTL, left still means previous radio button (and so moves > // to the right). Seems strange, but we'll match it. > // However, when using Spatial Navigation, we need to be able to navigate without changing the selection. >- if (isSpatialNavigationEnabled(element()->document().frame())) >+ if (isSpatialNavigationEnabled(element().document().frame())) > return; > bool forward = (key == "Down" || key == "Right"); > > // We can only stay within the form's children if the form hasn't been demoted to a leaf because > // of malformed HTML. >- RefPtr<Node> node = element(); >+ RefPtr<Node> node = &element(); > while ((node = (forward ? NodeTraversal::next(*node) : NodeTraversal::previous(*node)))) { > // Once we encounter a form element, we know we're through. > if (is<HTMLFormElement>(*node)) >@@ -88,10 +89,12 @@ void RadioInputType::handleKeydownEvent(KeyboardEvent& event) > if (!is<HTMLInputElement>(*node)) > continue; > RefPtr<HTMLInputElement> inputElement = downcast<HTMLInputElement>(node.get()); >- if (inputElement->form() != element()->form()) >+ if (inputElement->form() != element().form()) > break; >- if (inputElement->isRadioButton() && inputElement->name() == element()->name() && inputElement->isFocusable()) { >- element()->document().setFocusedElement(inputElement.get()); >+ if (inputElement->isRadioButton() && inputElement->name() == element().name() && inputElement->isFocusable()) { >+ element().document().setFocusedElement(inputElement.get()); >+ if (!weakThis) >+ return; > inputElement->dispatchSimulatedClick(&event, SendNoEvents, DoNotShowPressedLook); > event.setDefaultHandled(); > return; >@@ -105,10 +108,9 @@ void RadioInputType::handleKeyupEvent(KeyboardEvent& event) > if (key != "U+0020") > return; > >- ASSERT(element()); > // If an unselected radio is tabbed into (because the entire group has nothing > // checked, or because of some explicit .focus() call), then allow space to check it. >- if (element()->checked()) >+ if (element().checked()) > return; > dispatchSimulatedClickIfActive(event); > } >@@ -118,35 +120,32 @@ bool RadioInputType::isKeyboardFocusable(KeyboardEvent* event) const > if (!InputType::isKeyboardFocusable(event)) > return false; > >- ASSERT(element()); > // When using Spatial Navigation, every radio button should be focusable. >- if (isSpatialNavigationEnabled(element()->document().frame())) >+ if (isSpatialNavigationEnabled(element().document().frame())) > return true; > > // Never allow keyboard tabbing to leave you in the same radio group. Always > // skip any other elements in the group. >- RefPtr<Element> currentFocusedNode = element()->document().focusedElement(); >+ RefPtr<Element> currentFocusedNode = element().document().focusedElement(); > if (is<HTMLInputElement>(currentFocusedNode)) { > HTMLInputElement& focusedInput = downcast<HTMLInputElement>(*currentFocusedNode); >- if (focusedInput.isRadioButton() && focusedInput.form() == element()->form() && focusedInput.name() == element()->name()) >+ if (focusedInput.isRadioButton() && focusedInput.form() == element().form() && focusedInput.name() == element().name()) > return false; > } > > // Allow keyboard focus if we're checked or if nothing in the group is checked. >- return element()->checked() || !element()->checkedRadioButtonForGroup(); >+ return element().checked() || !element().checkedRadioButtonForGroup(); > } > > bool RadioInputType::shouldSendChangeEventAfterCheckedChanged() > { > // Don't send a change event for a radio button that's getting unchecked. > // This was done to match the behavior of other browsers. >- ASSERT(element()); >- return element()->checked(); >+ return element().checked(); > } > > void RadioInputType::willDispatchClick(InputElementClickState& state) > { >- ASSERT(element()); > // An event handler can use preventDefault or "return false" to reverse the selection we do here. > // The InputElementClickState object contains what we need to undo what we did here in didDispatchClick. > >@@ -154,10 +153,10 @@ void RadioInputType::willDispatchClick(InputElementClickState& state) > // Therefore if nothing is currently selected, we won't allow the upcoming action to be "undone", since > // we want some object in the radio group to actually get selected. > >- state.checked = element()->checked(); >- state.checkedRadioButton = element()->checkedRadioButtonForGroup(); >+ state.checked = element().checked(); >+ state.checkedRadioButton = element().checkedRadioButtonForGroup(); > >- element()->setChecked(true, DispatchChangeEvent); >+ element().setChecked(true, DispatchChangeEvent); > } > > void RadioInputType::didDispatchClick(Event& event, const InputElementClickState& state) >@@ -166,8 +165,7 @@ void RadioInputType::didDispatchClick(Event& event, const InputElementClickState > // Restore the original selected radio button if possible. > // Make sure it is still a radio button and only do the restoration if it still belongs to our group. > auto& button = state.checkedRadioButton; >- ASSERT(element()); >- if (button && button->isRadioButton() && button->form() == element()->form() && button->name() == element()->name()) >+ if (button && button->isRadioButton() && button->form() == element().form() && button->name() == element().name()) > button->setChecked(true); > } > >@@ -182,8 +180,7 @@ bool RadioInputType::isRadioButton() const > > bool RadioInputType::matchesIndeterminatePseudoClass() const > { >- ASSERT(element()); >- const HTMLInputElement& element = *this->element(); >+ const HTMLInputElement& element = this->element(); > if (const RadioButtonGroups* radioButtonGroups = element.radioButtonGroups()) > return !radioButtonGroups->hasCheckedButton(&element); > return !element.checked(); >diff --git a/Source/WebCore/html/RangeInputType.cpp b/Source/WebCore/html/RangeInputType.cpp >index 4460d71982d67b6f3c80f419c83fbc31c9c87fa0..7defd267d3a4e9bd6110ba694dae78aaaa6330ef 100644 >--- a/Source/WebCore/html/RangeInputType.cpp >+++ b/Source/WebCore/html/RangeInputType.cpp >@@ -92,14 +92,12 @@ const AtomicString& RangeInputType::formControlType() const > > double RangeInputType::valueAsDouble() const > { >- ASSERT(element()); >- return parseToDoubleForNumberType(element()->value()); >+ return parseToDoubleForNumberType(element().value()); > } > > ExceptionOr<void> RangeInputType::setValueAsDecimal(const Decimal& newValue, TextFieldEventBehavior eventBehavior) const > { >- ASSERT(element()); >- element()->setValue(serialize(newValue), eventBehavior); >+ element().setValue(serialize(newValue), eventBehavior); > return { }; > } > >@@ -115,17 +113,16 @@ bool RangeInputType::supportsRequired() const > > StepRange RangeInputType::createStepRange(AnyStepHandling anyStepHandling) const > { >- ASSERT(element()); >- const Decimal minimum = parseToNumber(element()->attributeWithoutSynchronization(minAttr), rangeDefaultMinimum); >- const Decimal maximum = ensureMaximum(parseToNumber(element()->attributeWithoutSynchronization(maxAttr), rangeDefaultMaximum), minimum, rangeDefaultMaximum); >+ const Decimal minimum = parseToNumber(element().attributeWithoutSynchronization(minAttr), rangeDefaultMinimum); >+ const Decimal maximum = ensureMaximum(parseToNumber(element().attributeWithoutSynchronization(maxAttr), rangeDefaultMaximum), minimum, rangeDefaultMaximum); > >- const AtomicString& precisionValue = element()->attributeWithoutSynchronization(precisionAttr); >+ const AtomicString& precisionValue = element().attributeWithoutSynchronization(precisionAttr); > if (!precisionValue.isNull()) { > const Decimal step = equalLettersIgnoringASCIICase(precisionValue, "float") ? Decimal::nan() : 1; > return StepRange(minimum, RangeLimitations::Valid, minimum, maximum, step, rangeStepDescription); > } > >- const Decimal step = StepRange::parseStep(anyStepHandling, rangeStepDescription, element()->attributeWithoutSynchronization(stepAttr)); >+ const Decimal step = StepRange::parseStep(anyStepHandling, rangeStepDescription, element().attributeWithoutSynchronization(stepAttr)); > return StepRange(minimum, RangeLimitations::Valid, minimum, maximum, step, rangeStepDescription); > } > >@@ -138,15 +135,14 @@ bool RangeInputType::isSteppable() const > > void RangeInputType::handleMouseDownEvent(MouseEvent& event) > { >- ASSERT(element()); >- if (element()->isDisabledFormControl()) >+ if (element().isDisabledFormControl()) > return; > > if (event.button() != LeftButton || !is<Node>(event.target())) > return; >- ASSERT(element()->shadowRoot()); >+ ASSERT(element().shadowRoot()); > auto& targetNode = downcast<Node>(*event.target()); >- if (&targetNode != element() && !targetNode.isDescendantOf(element()->userAgentShadowRoot().get())) >+ if (&targetNode != &element() && !targetNode.isDescendantOf(element().userAgentShadowRoot().get())) > return; > auto& thumb = typedSliderThumbElement(); > if (&targetNode == &thumb) >@@ -160,10 +156,12 @@ void RangeInputType::handleMouseDownEvent(MouseEvent& event) > void RangeInputType::handleTouchEvent(TouchEvent& event) > { > #if PLATFORM(IOS) >+ auto weakThis = makeWeakPtr(*this); > typedSliderThumbElement().handleTouchEvent(event); >+ if (!weakThis) >+ return; > #elif ENABLE(TOUCH_SLIDER) >- ASSERT(element()); >- if (element()->isDisabledFormControl()) >+ if (element().isDisabledFormControl()) > return; > > if (event.type() == eventNames().touchendEvent) { >@@ -196,13 +194,12 @@ void RangeInputType::disabledStateChanged() > > void RangeInputType::handleKeydownEvent(KeyboardEvent& event) > { >- ASSERT(element()); >- if (element()->isDisabledFormControl()) >+ if (element().isDisabledFormControl()) > return; > > const String& key = event.keyIdentifier(); > >- const Decimal current = parseToNumberOrNaN(element()->value()); >+ const Decimal current = parseToNumberOrNaN(element().value()); > ASSERT(current.isFinite()); > > StepRange stepRange(createStepRange(RejectAny)); >@@ -210,11 +207,11 @@ void RangeInputType::handleKeydownEvent(KeyboardEvent& event) > > // FIXME: We can't use stepUp() for the step value "any". So, we increase > // or decrease the value by 1/100 of the value range. Is it reasonable? >- const Decimal step = equalLettersIgnoringASCIICase(element()->attributeWithoutSynchronization(stepAttr), "any") ? (stepRange.maximum() - stepRange.minimum()) / 100 : stepRange.step(); >+ const Decimal step = equalLettersIgnoringASCIICase(element().attributeWithoutSynchronization(stepAttr), "any") ? (stepRange.maximum() - stepRange.minimum()) / 100 : stepRange.step(); > const Decimal bigStep = std::max((stepRange.maximum() - stepRange.minimum()) / 10, step); > > bool isVertical = false; >- if (auto* renderer = element()->renderer()) { >+ if (auto* renderer = element().renderer()) { > ControlPart part = renderer->style().appearance(); > isVertical = part == SliderVerticalPart || part == MediaVolumeSliderPart; > } >@@ -245,8 +242,8 @@ void RangeInputType::handleKeydownEvent(KeyboardEvent& event) > EventQueueScope scope; > setValueAsDecimal(newValue, DispatchInputAndChangeEvent); > >- if (AXObjectCache* cache = element()->document().existingAXObjectCache()) >- cache->postNotification(element(), AXObjectCache::AXValueChanged); >+ if (AXObjectCache* cache = element().document().existingAXObjectCache()) >+ cache->postNotification(&element(), AXObjectCache::AXValueChanged); > } > > event.setDefaultHandled(); >@@ -254,27 +251,25 @@ void RangeInputType::handleKeydownEvent(KeyboardEvent& event) > > void RangeInputType::createShadowSubtree() > { >- ASSERT(element()); >- ASSERT(element()->userAgentShadowRoot()); >+ ASSERT(element().userAgentShadowRoot()); > >- Document& document = element()->document(); >+ Document& document = element().document(); > auto track = HTMLDivElement::create(document); > track->setPseudo(AtomicString("-webkit-slider-runnable-track", AtomicString::ConstructFromLiteral)); > track->appendChild(SliderThumbElement::create(document)); > auto container = SliderContainerElement::create(document); > container->appendChild(track); >- element()->userAgentShadowRoot()->appendChild(container); >+ element().userAgentShadowRoot()->appendChild(container); > } > > HTMLElement* RangeInputType::sliderTrackElement() const > { >- ASSERT(element()); >- ASSERT(element()->userAgentShadowRoot()); >- ASSERT(element()->userAgentShadowRoot()->firstChild()); // container >- ASSERT(element()->userAgentShadowRoot()->firstChild()->isHTMLElement()); >- ASSERT(element()->userAgentShadowRoot()->firstChild()->firstChild()); // track >+ ASSERT(element().userAgentShadowRoot()); >+ ASSERT(element().userAgentShadowRoot()->firstChild()); // container >+ ASSERT(element().userAgentShadowRoot()->firstChild()->isHTMLElement()); >+ ASSERT(element().userAgentShadowRoot()->firstChild()->firstChild()); // track > >- RefPtr<ShadowRoot> root = element()->userAgentShadowRoot(); >+ RefPtr<ShadowRoot> root = element().userAgentShadowRoot(); > if (!root) > return nullptr; > >@@ -300,8 +295,7 @@ HTMLElement* RangeInputType::sliderThumbElement() const > > RenderPtr<RenderElement> RangeInputType::createInputRenderer(RenderStyle&& style) > { >- ASSERT(element()); >- return createRenderer<RenderSlider>(*element(), WTFMove(style)); >+ return createRenderer<RenderSlider>(element(), WTFMove(style)); > } > > Decimal RangeInputType::parseToNumber(const String& src, const Decimal& defaultValue) const >@@ -319,10 +313,12 @@ String RangeInputType::serialize(const Decimal& value) const > // FIXME: Could share this with BaseClickableWithKeyInputType and BaseCheckableInputType if we had a common base class. > void RangeInputType::accessKeyAction(bool sendMouseEvents) > { >+ auto weakThis = makeWeakPtr(*this); > InputType::accessKeyAction(sendMouseEvents); >+ if (!weakThis) >+ return; > >- ASSERT(element()); >- element()->dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents); >+ element().dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents); > } > > void RangeInputType::attributeChanged(const QualifiedName& name) >@@ -330,9 +326,11 @@ void RangeInputType::attributeChanged(const QualifiedName& name) > // FIXME: Don't we need to do this work for precisionAttr too? > if (name == maxAttr || name == minAttr) { > // Sanitize the value. >- if (auto* element = this->element()) { >- if (element->hasDirtyValue()) >- element->setValue(element->value()); >+ if (element().hasDirtyValue()) { >+ auto weakThis = makeWeakPtr(*this); >+ element().setValue(element().value()); >+ if (!weakThis) >+ return; > } > typedSliderThumbElement().setPositionFromValue(); > } >@@ -341,15 +339,16 @@ void RangeInputType::attributeChanged(const QualifiedName& name) > > void RangeInputType::setValue(const String& value, bool valueChanged, TextFieldEventBehavior eventBehavior) > { >+ auto weakThis = makeWeakPtr(*this); > InputType::setValue(value, valueChanged, eventBehavior); >+ if (!weakThis) >+ return; > > if (!valueChanged) > return; > >- if (eventBehavior == DispatchNoEvent) { >- ASSERT(element()); >- element()->setTextAsOfLastFormControlChangeEvent(value); >- } >+ if (eventBehavior == DispatchNoEvent) >+ element().setTextAsOfLastFormControlChangeEvent(value); > > typedSliderThumbElement().setPositionFromValue(); > } >@@ -386,8 +385,7 @@ void RangeInputType::updateTickMarkValues() > return; > m_tickMarkValues.clear(); > m_tickMarkValuesDirty = false; >- ASSERT(element()); >- auto dataList = element()->dataList(); >+ auto dataList = element().dataList(); > if (!dataList) > return; > Ref<HTMLCollection> options = dataList->options(); >@@ -396,7 +394,7 @@ void RangeInputType::updateTickMarkValues() > RefPtr<Node> node = options->item(i); > HTMLOptionElement& optionElement = downcast<HTMLOptionElement>(*node); > String optionValue = optionElement.value(); >- if (!element()->isValidValue(optionValue)) >+ if (!element().isValidValue(optionValue)) > continue; > m_tickMarkValues.append(parseToNumber(optionValue, Decimal::nan())); > } >diff --git a/Source/WebCore/html/ResetInputType.cpp b/Source/WebCore/html/ResetInputType.cpp >index 405cb2cc594a3d331146a855dbfa195b3ab70915..016fe104bb26d323dcc4bb3457681308a97c08a2 100644 >--- a/Source/WebCore/html/ResetInputType.cpp >+++ b/Source/WebCore/html/ResetInputType.cpp >@@ -52,10 +52,9 @@ bool ResetInputType::supportsValidation() const > > void ResetInputType::handleDOMActivateEvent(Event& event) > { >- ASSERT(element()); >- if (element()->isDisabledFormControl() || !element()->form()) >+ if (element().isDisabledFormControl() || !element().form()) > return; >- element()->form()->reset(); >+ element().form()->reset(); > event.setDefaultHandled(); > } > >diff --git a/Source/WebCore/html/SearchInputType.cpp b/Source/WebCore/html/SearchInputType.cpp >index 7124391a3063ee5a2628e46d3fcac85c6168aeee..498231d26401d7ae29fee53a31efbdf0dce7f4e9 100644 >--- a/Source/WebCore/html/SearchInputType.cpp >+++ b/Source/WebCore/html/SearchInputType.cpp >@@ -56,9 +56,8 @@ void SearchInputType::addSearchResult() > // Normally we've got the correct renderer by the time we get here. However when the input type changes > // we don't update the associated renderers until after the next tree update, so we could actually end up here > // with a mismatched renderer (e.g. through form submission). >- ASSERT(element()); >- if (is<RenderSearchField>(element()->renderer())) >- downcast<RenderSearchField>(*element()->renderer()).addSearchResult(); >+ if (is<RenderSearchField>(element().renderer())) >+ downcast<RenderSearchField>(*element().renderer()).addSearchResult(); > #endif > } > >@@ -76,8 +75,10 @@ void SearchInputType::attributeChanged(const QualifiedName& name) > { > if (name == resultsAttr) { > if (m_resultsButton) { >- if (auto* element = this->element()) >- updateResultButtonPseudoType(*m_resultsButton, element->maxResults()); >+ auto weakThis = makeWeakPtr(*this); >+ updateResultButtonPseudoType(*m_resultsButton, element().maxResults()); >+ if (!weakThis) >+ return; > } > } > BaseTextInputType::attributeChanged(name); >@@ -85,8 +86,7 @@ void SearchInputType::attributeChanged(const QualifiedName& name) > > RenderPtr<RenderElement> SearchInputType::createInputRenderer(RenderStyle&& style) > { >- ASSERT(element()); >- return createRenderer<RenderSearchField>(*element(), WTFMove(style)); >+ return createRenderer<RenderSearchField>(element(), WTFMove(style)); > } > > const AtomicString& SearchInputType::formControlType() const >@@ -115,12 +115,11 @@ void SearchInputType::createShadowSubtree() > ASSERT(container); > ASSERT(textWrapper); > >- ASSERT(element()); >- m_resultsButton = SearchFieldResultsButtonElement::create(element()->document()); >- updateResultButtonPseudoType(*m_resultsButton, element()->maxResults()); >+ m_resultsButton = SearchFieldResultsButtonElement::create(element().document()); >+ updateResultButtonPseudoType(*m_resultsButton, element().maxResults()); > container->insertBefore(*m_resultsButton, textWrapper.get()); > >- m_cancelButton = SearchFieldCancelButtonElement::create(element()->document()); >+ m_cancelButton = SearchFieldCancelButtonElement::create(element().document()); > container->insertBefore(*m_cancelButton, textWrapper->nextSibling()); > } > >@@ -136,15 +135,14 @@ HTMLElement* SearchInputType::cancelButtonElement() const > > void SearchInputType::handleKeydownEvent(KeyboardEvent& event) > { >- ASSERT(element()); >- if (element()->isDisabledOrReadOnly()) { >+ if (element().isDisabledOrReadOnly()) { > TextFieldInputType::handleKeydownEvent(event); > return; > } > > const String& key = event.keyIdentifier(); > if (key == "U+001B") { >- Ref<HTMLInputElement> protectedInputElement(*element()); >+ Ref<HTMLInputElement> protectedInputElement(element()); > protectedInputElement->setValueForUser(emptyString()); > protectedInputElement->onSearch(); > event.setDefaultHandled(); >@@ -162,9 +160,8 @@ void SearchInputType::destroyShadowSubtree() > > void SearchInputType::startSearchEventTimer() > { >- ASSERT(element()); >- ASSERT(element()->renderer()); >- unsigned length = element()->innerTextValue().length(); >+ ASSERT(element().renderer()); >+ unsigned length = element().innerTextValue().length(); > > if (!length) { > m_searchEventTimer.startOneShot(0_ms); >@@ -183,21 +180,18 @@ void SearchInputType::stopSearchEventTimer() > > void SearchInputType::searchEventTimerFired() > { >- ASSERT(element()); >- element()->onSearch(); >+ element().onSearch(); > } > > bool SearchInputType::searchEventsShouldBeDispatched() const > { >- ASSERT(element()); >- return element()->hasAttributeWithoutSynchronization(incrementalAttr); >+ return element().hasAttributeWithoutSynchronization(incrementalAttr); > } > > void SearchInputType::didSetValueByUserEdit() > { >- ASSERT(element()); >- if (m_cancelButton && is<RenderSearchField>(element()->renderer())) >- downcast<RenderSearchField>(*element()->renderer()).updateCancelButtonVisibility(); >+ if (m_cancelButton && is<RenderSearchField>(element().renderer())) >+ downcast<RenderSearchField>(*element().renderer()).updateCancelButtonVisibility(); > // If the incremental attribute is set, then dispatch the search event > if (searchEventsShouldBeDispatched()) > startSearchEventTimer(); >@@ -207,8 +201,7 @@ void SearchInputType::didSetValueByUserEdit() > > bool SearchInputType::sizeShouldIncludeDecoration(int, int& preferredSize) const > { >- ASSERT(element()); >- preferredSize = element()->size(); >+ preferredSize = element().size(); > return true; > } > >diff --git a/Source/WebCore/html/SubmitInputType.cpp b/Source/WebCore/html/SubmitInputType.cpp >index 1b1ea080e3807ac6542c5ca2491845cc0c753c9c..3e5aac088056fd6b94d3e70a9ffff1797f6388ef 100644 >--- a/Source/WebCore/html/SubmitInputType.cpp >+++ b/Source/WebCore/html/SubmitInputType.cpp >@@ -48,10 +48,9 @@ const AtomicString& SubmitInputType::formControlType() const > > bool SubmitInputType::appendFormData(DOMFormData& formData, bool) const > { >- ASSERT(element()); >- if (!element()->isActivatedSubmit()) >+ if (!element().isActivatedSubmit()) > return false; >- formData.append(element()->name(), element()->valueWithDefault()); >+ formData.append(element().name(), element().valueWithDefault()); > return true; > } > >@@ -62,8 +61,7 @@ bool SubmitInputType::supportsRequired() const > > void SubmitInputType::handleDOMActivateEvent(Event& event) > { >- ASSERT(element()); >- Ref<HTMLInputElement> protectedElement(*element()); >+ Ref<HTMLInputElement> protectedElement(element()); > if (protectedElement->isDisabledFormControl() || !protectedElement->form()) > return; > >diff --git a/Source/WebCore/html/TextFieldInputType.cpp b/Source/WebCore/html/TextFieldInputType.cpp >index 6fefffdb9e8144e7337340290c85b995c69849fb..620933f86998e9635a6c1104aa5d2ec48e6bd8ab 100644 >--- a/Source/WebCore/html/TextFieldInputType.cpp >+++ b/Source/WebCore/html/TextFieldInputType.cpp >@@ -51,6 +51,7 @@ > #include "RenderLayer.h" > #include "RenderTextControlSingleLine.h" > #include "RenderTheme.h" >+#include "ScriptDisallowedScope.h" > #include "ShadowRoot.h" > #include "TextControlInnerElements.h" > #include "TextEvent.h" >@@ -83,18 +84,16 @@ TextFieldInputType::~TextFieldInputType() > > bool TextFieldInputType::isKeyboardFocusable(KeyboardEvent*) const > { >- ASSERT(element()); > #if PLATFORM(IOS) >- if (element()->isReadOnly()) >+ if (element().isReadOnly()) > return false; > #endif >- return element()->isTextFormControlFocusable(); >+ return element().isTextFormControlFocusable(); > } > > bool TextFieldInputType::isMouseFocusable() const > { >- ASSERT(element()); >- return element()->isTextFormControlFocusable(); >+ return element().isTextFormControlFocusable(); > } > > bool TextFieldInputType::isTextField() const >@@ -116,24 +115,28 @@ bool TextFieldInputType::isEmptyValue() const > > bool TextFieldInputType::valueMissing(const String& value) const > { >- ASSERT(element()); >- return element()->isRequired() && value.isEmpty(); >+ return element().isRequired() && value.isEmpty(); > } > > void TextFieldInputType::setValue(const String& sanitizedValue, bool valueChanged, TextFieldEventBehavior eventBehavior) > { >- ASSERT(element()); >- > // Grab this input element to keep reference even if JS event handler > // changes input type. >- Ref<HTMLInputElement> input(*element()); >+ Ref<HTMLInputElement> input(element()); > > // We don't ask InputType::setValue to dispatch events because > // TextFieldInputType dispatches events different way from InputType. >- InputType::setValue(sanitizedValue, valueChanged, DispatchNoEvent); >+ { >+ ScriptDisallowedScope::InMainThread scriptDisallowedScope; >+ InputType::setValue(sanitizedValue, valueChanged, DispatchNoEvent); >+ } > >- if (valueChanged) >+ auto weakThis = makeWeakPtr(*this); >+ if (valueChanged) { > updateInnerTextValue(); >+ if (!weakThis) >+ return; >+ } > > unsigned max = visibleValue().length(); > if (input->focused()) >@@ -141,6 +144,9 @@ void TextFieldInputType::setValue(const String& sanitizedValue, bool valueChange > else > input->cacheSelectionInResponseToSetValue(max); > >+ if (!weakThis) >+ return; >+ > if (!valueChanged) > return; > >@@ -152,11 +158,17 @@ void TextFieldInputType::setValue(const String& sanitizedValue, bool valueChange > input->dispatchFormControlInputEvent(); > else > input->dispatchFormControlChangeEvent(); >+ if (!weakThis) >+ return; > break; > > case DispatchInputAndChangeEvent: { > input->dispatchFormControlInputEvent(); >+ if (!weakThis) >+ return; > input->dispatchFormControlChangeEvent(); >+ if (!weakThis) >+ return; > break; > } > >@@ -172,15 +184,14 @@ void TextFieldInputType::setValue(const String& sanitizedValue, bool valueChange > #if ENABLE(DATALIST_ELEMENT) > void TextFieldInputType::handleClickEvent(MouseEvent&) > { >- if (element()->focused() && element()->list()) >+ if (element().focused() && element().list()) > displaySuggestions(DataListSuggestionActivationType::ControlClicked); > } > #endif > > void TextFieldInputType::handleKeydownEvent(KeyboardEvent& event) > { >- ASSERT(element()); >- if (!element()->focused()) >+ if (!element().focused()) > return; > #if ENABLE(DATALIST_ELEMENT) > const String& key = event.keyIdentifier(); >@@ -189,16 +200,15 @@ void TextFieldInputType::handleKeydownEvent(KeyboardEvent& event) > event.setDefaultHandled(); > } > #endif >- RefPtr<Frame> frame = element()->document().frame(); >- if (!frame || !frame->editor().doTextFieldCommandFromEvent(element(), &event)) >+ RefPtr<Frame> frame = element().document().frame(); >+ if (!frame || !frame->editor().doTextFieldCommandFromEvent(&element(), &event)) > return; > event.setDefaultHandled(); > } > > void TextFieldInputType::handleKeydownEventForSpinButton(KeyboardEvent& event) > { >- ASSERT(element()); >- if (element()->isDisabledOrReadOnly()) >+ if (element().isDisabledOrReadOnly()) > return; > #if ENABLE(DATALIST_ELEMENT) > if (m_suggestionPicker) >@@ -224,18 +234,19 @@ void TextFieldInputType::forwardEvent(Event& event) > > bool isFocusEvent = event.type() == eventNames().focusEvent; > bool isBlurEvent = event.type() == eventNames().blurEvent; >- if (isFocusEvent || isBlurEvent) >+ if (isFocusEvent || isBlurEvent) { >+ auto weakThis = makeWeakPtr(*this); > capsLockStateMayHaveChanged(); >- if (event.isMouseEvent() || isFocusEvent || isBlurEvent) { >- ASSERT(element()); >- element()->forwardEvent(event); >+ if (!weakThis) >+ return; > } >+ if (event.isMouseEvent() || isFocusEvent || isBlurEvent) >+ element().forwardEvent(event); > } > > void TextFieldInputType::elementDidBlur() > { >- ASSERT(element()); >- auto* renderer = element()->renderer(); >+ auto* renderer = element().renderer(); > if (!renderer) > return; > >@@ -258,17 +269,18 @@ void TextFieldInputType::elementDidBlur() > > void TextFieldInputType::handleFocusEvent(Node* oldFocusedNode, FocusDirection) > { >- ASSERT(element()); >- ASSERT_UNUSED(oldFocusedNode, oldFocusedNode != element()); >- if (RefPtr<Frame> frame = element()->document().frame()) >- frame->editor().textFieldDidBeginEditing(element()); >+ ASSERT_UNUSED(oldFocusedNode, oldFocusedNode != &element()); >+ if (RefPtr<Frame> frame = element().document().frame()) >+ frame->editor().textFieldDidBeginEditing(&element()); > } > > void TextFieldInputType::handleBlurEvent() > { >+ auto weakThis = makeWeakPtr(*this); > InputType::handleBlurEvent(); >- ASSERT(element()); >- element()->endEditing(); >+ if (!weakThis) >+ return; >+ element().endEditing(); > } > > bool TextFieldInputType::shouldSubmitImplicitly(Event& event) >@@ -279,8 +291,7 @@ bool TextFieldInputType::shouldSubmitImplicitly(Event& event) > > RenderPtr<RenderElement> TextFieldInputType::createInputRenderer(RenderStyle&& style) > { >- ASSERT(element()); >- return createRenderer<RenderTextControlSingleLine>(*element(), WTFMove(style)); >+ return createRenderer<RenderTextControlSingleLine>(element(), WTFMove(style)); > } > > bool TextFieldInputType::needsContainer() const >@@ -290,20 +301,17 @@ bool TextFieldInputType::needsContainer() const > > bool TextFieldInputType::shouldHaveSpinButton() const > { >- ASSERT(element()); >- return RenderTheme::singleton().shouldHaveSpinButton(*element()); >+ return RenderTheme::singleton().shouldHaveSpinButton(element()); > } > > bool TextFieldInputType::shouldHaveCapsLockIndicator() const > { >- ASSERT(element()); >- return RenderTheme::singleton().shouldHaveCapsLockIndicator(*element()); >+ return RenderTheme::singleton().shouldHaveCapsLockIndicator(element()); > } > > void TextFieldInputType::createShadowSubtree() > { >- ASSERT(element()); >- ASSERT(element()->shadowRoot()); >+ ASSERT(element().shadowRoot()); > > ASSERT(!m_innerText); > ASSERT(!m_innerBlock); >@@ -311,7 +319,7 @@ void TextFieldInputType::createShadowSubtree() > ASSERT(!m_capsLockIndicator); > ASSERT(!m_autoFillButton); > >- Document& document = element()->document(); >+ Document& document = element().document(); > bool shouldHaveSpinButton = this->shouldHaveSpinButton(); > bool shouldHaveCapsLockIndicator = this->shouldHaveCapsLockIndicator(); > bool createsContainer = shouldHaveSpinButton || shouldHaveCapsLockIndicator || needsContainer(); >@@ -319,7 +327,7 @@ void TextFieldInputType::createShadowSubtree() > m_innerText = TextControlInnerTextElement::create(document); > > if (!createsContainer) { >- element()->userAgentShadowRoot()->appendChild(*m_innerText); >+ element().userAgentShadowRoot()->appendChild(*m_innerText); > updatePlaceholderText(); > return; > } >@@ -398,25 +406,34 @@ void TextFieldInputType::destroyShadowSubtree() > void TextFieldInputType::attributeChanged(const QualifiedName& name) > { > if (name == valueAttr || name == placeholderAttr) { >- if (element()) >- updateInnerTextValue(); >+ auto weakThis = makeWeakPtr(*this); >+ updateInnerTextValue(); >+ if (!weakThis) >+ return; > } >+ > InputType::attributeChanged(name); > } > > void TextFieldInputType::disabledStateChanged() > { >+ auto weakThis = makeWeakPtr(*this); > if (m_innerSpinButton) > m_innerSpinButton->releaseCapture(); > capsLockStateMayHaveChanged(); >+ if (!weakThis) >+ return; > updateAutoFillButton(); > } > > void TextFieldInputType::readOnlyStateChanged() > { >+ auto weakThis = makeWeakPtr(*this); > if (m_innerSpinButton) > m_innerSpinButton->releaseCapture(); > capsLockStateMayHaveChanged(); >+ if (!weakThis) >+ return; > updateAutoFillButton(); > } > >@@ -517,13 +534,12 @@ String TextFieldInputType::sanitizeValue(const String& proposedValue) const > > void TextFieldInputType::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent& event) > { >- ASSERT(element()); > // Make sure that the text to be inserted will not violate the maxLength. > > // We use RenderTextControlSingleLine::text() instead of InputElement::value() > // because they can be mismatched by sanitizeValue() in > // HTMLInputElement::subtreeHasChanged() in some cases. >- String innerText = element()->innerTextValue(); >+ String innerText = element().innerTextValue(); > unsigned oldLength = numGraphemeClusters(innerText); > > // selectionLength represents the selection length of this text field to be >@@ -532,18 +548,18 @@ void TextFieldInputType::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent& > // selection length. The selection is the source of text drag-and-drop in > // that case, and nothing in the text field will be removed. > unsigned selectionLength = 0; >- if (element()->focused()) { >- ASSERT(enclosingTextFormControl(element()->document().frame()->selection().selection().start()) == element()); >- int selectionStart = element()->selectionStart(); >- ASSERT(selectionStart <= element()->selectionEnd()); >- int selectionCodeUnitCount = element()->selectionEnd() - selectionStart; >+ if (element().focused()) { >+ ASSERT(enclosingTextFormControl(element().document().frame()->selection().selection().start()) == &element()); >+ int selectionStart = element().selectionStart(); >+ ASSERT(selectionStart <= element().selectionEnd()); >+ int selectionCodeUnitCount = element().selectionEnd() - selectionStart; > selectionLength = selectionCodeUnitCount ? numGraphemeClusters(StringView(innerText).substring(selectionStart, selectionCodeUnitCount)) : 0; > } > ASSERT(oldLength >= selectionLength); > > // Selected characters will be removed by the next text event. > unsigned baseLength = oldLength - selectionLength; >- unsigned maxLength = isTextType() ? element()->effectiveMaxLength() : HTMLInputElement::maxEffectiveLength; >+ unsigned maxLength = isTextType() ? element().effectiveMaxLength() : HTMLInputElement::maxEffectiveLength; > unsigned appendableLength = maxLength > baseLength ? maxLength - baseLength : 0; > > // Truncate the inserted text to avoid violating the maxLength and other constraints. >@@ -571,8 +587,7 @@ void TextFieldInputType::updatePlaceholderText() > { > if (!supportsPlaceholder()) > return; >- ASSERT(element()); >- String placeholderText = element()->strippedPlaceholder(); >+ String placeholderText = element().strippedPlaceholder(); > if (placeholderText.isEmpty()) { > if (m_placeholder) { > m_placeholder->parentNode()->removeChild(*m_placeholder); >@@ -581,8 +596,8 @@ void TextFieldInputType::updatePlaceholderText() > return; > } > if (!m_placeholder) { >- m_placeholder = TextControlPlaceholderElement::create(element()->document()); >- element()->userAgentShadowRoot()->insertBefore(*m_placeholder, m_container ? m_container.get() : innerTextElement().get()); >+ m_placeholder = TextControlPlaceholderElement::create(element().document()); >+ element().userAgentShadowRoot()->insertBefore(*m_placeholder, m_container ? m_container.get() : innerTextElement().get()); > } > m_placeholder->setInnerText(placeholderText); > } >@@ -590,10 +605,9 @@ void TextFieldInputType::updatePlaceholderText() > bool TextFieldInputType::appendFormData(DOMFormData& formData, bool multipart) const > { > InputType::appendFormData(formData, multipart); >- ASSERT(element()); >- auto& dirnameAttrValue = element()->attributeWithoutSynchronization(dirnameAttr); >+ auto& dirnameAttrValue = element().attributeWithoutSynchronization(dirnameAttr); > if (!dirnameAttrValue.isNull()) >- formData.append(dirnameAttrValue, element()->directionForFormData()); >+ formData.append(dirnameAttrValue, element().directionForFormData()); > return true; > } > >@@ -604,8 +618,8 @@ String TextFieldInputType::convertFromVisibleValue(const String& visibleValue) c > > void TextFieldInputType::subtreeHasChanged() > { >- ASSERT(element()); >- element()->setChangedSinceLastFormControlChangeEvent(true); >+ auto weakThis = makeWeakPtr(*this); >+ element().setChangedSinceLastFormControlChangeEvent(true); > > // We don't need to call sanitizeUserInputValue() function here because > // HTMLInputElement::handleBeforeTextInsertedEvent() has already called >@@ -617,26 +631,29 @@ void TextFieldInputType::subtreeHasChanged() > // user input in order to retain parity between what's in the model and > // what's on the screen. Otherwise, we retain the sanitization process for > // backward compatibility. https://bugs.webkit.org/show_bug.cgi?id=150346 >- String innerText = convertFromVisibleValue(element()->innerTextValue()); >+ String innerText = convertFromVisibleValue(element().innerTextValue()); > if (!supportsSelectionAPI()) > innerText = sanitizeValue(innerText); >- element()->setValueFromRenderer(innerText); >- element()->updatePlaceholderVisibility(); >+ element().setValueFromRenderer(innerText); >+ if (!weakThis) >+ return; >+ element().updatePlaceholderVisibility(); >+ if (!weakThis) >+ return; > // Recalc for :invalid change. >- element()->invalidateStyleForSubtree(); >+ element().invalidateStyleForSubtree(); > > didSetValueByUserEdit(); > } > > void TextFieldInputType::didSetValueByUserEdit() > { >- ASSERT(element()); >- if (!element()->focused()) >+ if (!element().focused()) > return; >- if (RefPtr<Frame> frame = element()->document().frame()) >- frame->editor().textDidChangeInTextField(element()); >+ if (RefPtr<Frame> frame = element().document().frame()) >+ frame->editor().textDidChangeInTextField(&element()); > #if ENABLE(DATALIST_ELEMENT) >- if (element()->list()) >+ if (element().list()) > displaySuggestions(DataListSuggestionActivationType::TextChanged); > #endif > } >@@ -653,45 +670,43 @@ void TextFieldInputType::spinButtonStepUp() > > void TextFieldInputType::updateInnerTextValue() > { >- ASSERT(element()); >- if (!element()->formControlValueMatchesRenderer()) { >+ if (!element().formControlValueMatchesRenderer()) { >+ auto weakThis = makeWeakPtr(*this); > // Update the renderer value if the formControlValueMatchesRenderer() flag is false. > // It protects an unacceptable renderer value from being overwritten with the DOM value. >- element()->setInnerTextValue(visibleValue()); >- element()->updatePlaceholderVisibility(); >+ element().setInnerTextValue(visibleValue()); >+ if (!weakThis) >+ return; >+ element().updatePlaceholderVisibility(); > } > } > > void TextFieldInputType::focusAndSelectSpinButtonOwner() > { >- ASSERT(element()); >- Ref<HTMLInputElement> input(*element()); >+ Ref<HTMLInputElement> input(element()); > input->focus(); > input->select(); > } > > bool TextFieldInputType::shouldSpinButtonRespondToMouseEvents() > { >- ASSERT(element()); >- return !element()->isDisabledOrReadOnly(); >+ return !element().isDisabledOrReadOnly(); > } > > bool TextFieldInputType::shouldSpinButtonRespondToWheelEvents() > { >- ASSERT(element()); >- return shouldSpinButtonRespondToMouseEvents() && element()->focused(); >+ return shouldSpinButtonRespondToMouseEvents() && element().focused(); > } > > bool TextFieldInputType::shouldDrawCapsLockIndicator() const > { >- ASSERT(element()); >- if (element()->document().focusedElement() != element()) >+ if (element().document().focusedElement() != &element()) > return false; > >- if (element()->isDisabledOrReadOnly()) >+ if (element().isDisabledOrReadOnly()) > return false; > >- RefPtr<Frame> frame = element()->document().frame(); >+ RefPtr<Frame> frame = element().document().frame(); > if (!frame) > return false; > >@@ -712,33 +727,30 @@ void TextFieldInputType::capsLockStateMayHaveChanged() > > bool TextFieldInputType::shouldDrawAutoFillButton() const > { >- ASSERT(element()); >- return !element()->isDisabledOrReadOnly() && element()->autoFillButtonType() != AutoFillButtonType::None; >+ return !element().isDisabledOrReadOnly() && element().autoFillButtonType() != AutoFillButtonType::None; > } > > void TextFieldInputType::autoFillButtonElementWasClicked() > { >- ASSERT(element()); >- Page* page = element()->document().page(); >+ Page* page = element().document().page(); > if (!page) > return; > >- page->chrome().client().handleAutoFillButtonClick(*element()); >+ page->chrome().client().handleAutoFillButtonClick(element()); > } > > void TextFieldInputType::createContainer() > { > ASSERT(!m_container); >- ASSERT(element()); > >- m_container = TextControlInnerContainer::create(element()->document()); >+ m_container = TextControlInnerContainer::create(element().document()); > m_container->setPseudo(AtomicString("-webkit-textfield-decoration-container", AtomicString::ConstructFromLiteral)); > >- m_innerBlock = TextControlInnerElement::create(element()->document()); >+ m_innerBlock = TextControlInnerElement::create(element().document()); > m_innerBlock->appendChild(*m_innerText); > m_container->appendChild(*m_innerBlock); > >- element()->userAgentShadowRoot()->appendChild(*m_container); >+ element().userAgentShadowRoot()->appendChild(*m_container); > } > > void TextFieldInputType::createAutoFillButton(AutoFillButtonType autoFillButtonType) >@@ -748,8 +760,7 @@ void TextFieldInputType::createAutoFillButton(AutoFillButtonType autoFillButtonT > if (autoFillButtonType == AutoFillButtonType::None) > return; > >- ASSERT(element()); >- m_autoFillButton = AutoFillButtonElement::create(element()->document(), *this); >+ m_autoFillButton = AutoFillButtonElement::create(element().document(), *this); > m_autoFillButton->setPseudo(autoFillButtonTypeToAutoFillButtonPseudoClassName(autoFillButtonType)); > m_autoFillButton->setAttributeWithoutSynchronization(roleAttr, AtomicString("button", AtomicString::ConstructFromLiteral)); > m_autoFillButton->setAttributeWithoutSynchronization(aria_labelAttr, autoFillButtonTypeToAccessibilityLabel(autoFillButtonType)); >@@ -763,8 +774,7 @@ void TextFieldInputType::updateAutoFillButton() > if (!m_container) > createContainer(); > >- ASSERT(element()); >- AutoFillButtonType autoFillButtonType = element()->autoFillButtonType(); >+ AutoFillButtonType autoFillButtonType = element().autoFillButtonType(); > if (!m_autoFillButton) > createAutoFillButton(autoFillButtonType); > >@@ -787,23 +797,23 @@ void TextFieldInputType::updateAutoFillButton() > > IntRect TextFieldInputType::elementRectInRootViewCoordinates() const > { >- if (!element()->renderer()) >+ if (!element().renderer()) > return IntRect(); >- return element()->document().view()->contentsToRootView(element()->renderer()->absoluteBoundingBoxRect()); >+ return element().document().view()->contentsToRootView(element().renderer()->absoluteBoundingBoxRect()); > } > > Vector<String> TextFieldInputType::suggestions() const > { > Vector<String> suggestions; > >- if (auto dataList = element()->dataList()) { >+ if (auto dataList = elemen.dataList()) { > Ref<HTMLCollection> options = dataList->options(); > for (unsigned i = 0; auto* option = downcast<HTMLOptionElement>(options->item(i)); ++i) { >- if (!element()->isValidValue(option->value())) >+ if (!element().isValidValue(option->value())) > continue; > > String value = sanitizeValue(option->value()); >- if (!suggestions.contains(value) && (element()->value().isEmpty() || value.containsIgnoringASCIICase(element()->value()))) >+ if (!suggestions.contains(value) && (element().value().isEmpty() || value.containsIgnoringASCIICase(element().value()))) > suggestions.append(value); > } > } >@@ -813,7 +823,7 @@ Vector<String> TextFieldInputType::suggestions() const > > void TextFieldInputType::didSelectDataListOption(const String& selectedOption) > { >- element()->setValue(selectedOption, DispatchInputAndChangeEvent); >+ element().setValue(selectedOption, DispatchInputAndChangeEvent); > } > > void TextFieldInputType::didCloseSuggestions() >@@ -823,7 +833,7 @@ void TextFieldInputType::didCloseSuggestions() > > void TextFieldInputType::displaySuggestions(DataListSuggestionActivationType type) > { >- if (element()->isDisabledFormControl() || !element()->renderer()) >+ if (element().isDisabledFormControl() || !element().renderer()) > return; > > if (!UserGestureIndicator::processingUserGesture()) >diff --git a/Source/WebCore/html/TimeInputType.cpp b/Source/WebCore/html/TimeInputType.cpp >index 42c3911ede22bf127f9c2c9adaeed1de369e2577..edb44c2133dfa167fae3ba37e69dd61431aa3301 100644 >--- a/Source/WebCore/html/TimeInputType.cpp >+++ b/Source/WebCore/html/TimeInputType.cpp >@@ -77,11 +77,10 @@ Decimal TimeInputType::defaultValueForStepUp() const > > StepRange TimeInputType::createStepRange(AnyStepHandling anyStepHandling) const > { >- ASSERT(element()); >- const Decimal stepBase = parseToNumber(element()->attributeWithoutSynchronization(minAttr), 0); >- const Decimal minimum = parseToNumber(element()->attributeWithoutSynchronization(minAttr), Decimal::fromDouble(DateComponents::minimumTime())); >- const Decimal maximum = parseToNumber(element()->attributeWithoutSynchronization(maxAttr), Decimal::fromDouble(DateComponents::maximumTime())); >- const Decimal step = StepRange::parseStep(anyStepHandling, timeStepDescription, element()->attributeWithoutSynchronization(stepAttr)); >+ const Decimal stepBase = parseToNumber(element().attributeWithoutSynchronization(minAttr), 0); >+ const Decimal minimum = parseToNumber(element().attributeWithoutSynchronization(minAttr), Decimal::fromDouble(DateComponents::minimumTime())); >+ const Decimal maximum = parseToNumber(element().attributeWithoutSynchronization(maxAttr), Decimal::fromDouble(DateComponents::maximumTime())); >+ const Decimal step = StepRange::parseStep(anyStepHandling, timeStepDescription, element().attributeWithoutSynchronization(stepAttr)); > return StepRange(stepBase, RangeLimitations::Valid, minimum, maximum, step, timeStepDescription); > } > >diff --git a/Source/WebCore/html/URLInputType.cpp b/Source/WebCore/html/URLInputType.cpp >index 6ca0ac1a2013cf6d5d8dc5c0ea03b211792f195e..1824a181568483dc7076d59116f9d462664c66b4 100644 >--- a/Source/WebCore/html/URLInputType.cpp >+++ b/Source/WebCore/html/URLInputType.cpp >@@ -52,8 +52,7 @@ bool URLInputType::typeMismatchFor(const String& value) const > > bool URLInputType::typeMismatch() const > { >- ASSERT(element()); >- return typeMismatchFor(element()->value()); >+ return typeMismatchFor(element().value()); > } > > String URLInputType::typeMismatchText() const >diff --git a/Source/WebCore/html/WeekInputType.cpp b/Source/WebCore/html/WeekInputType.cpp >index bcb6af2caad5e5f3bea9454a5103eb951cd43d62..9aff4f6fbda77d69f8a498c75e1a1ad0958960ea 100644 >--- a/Source/WebCore/html/WeekInputType.cpp >+++ b/Source/WebCore/html/WeekInputType.cpp >@@ -57,11 +57,10 @@ DateComponents::Type WeekInputType::dateType() const > > StepRange WeekInputType::createStepRange(AnyStepHandling anyStepHandling) const > { >- ASSERT(element()); >- const Decimal stepBase = parseToNumber(element()->attributeWithoutSynchronization(minAttr), weekDefaultStepBase); >- const Decimal minimum = parseToNumber(element()->attributeWithoutSynchronization(minAttr), Decimal::fromDouble(DateComponents::minimumWeek())); >- const Decimal maximum = parseToNumber(element()->attributeWithoutSynchronization(maxAttr), Decimal::fromDouble(DateComponents::maximumWeek())); >- const Decimal step = StepRange::parseStep(anyStepHandling, weekStepDescription, element()->attributeWithoutSynchronization(stepAttr)); >+ const Decimal stepBase = parseToNumber(element().attributeWithoutSynchronization(minAttr), weekDefaultStepBase); >+ const Decimal minimum = parseToNumber(element().attributeWithoutSynchronization(minAttr), Decimal::fromDouble(DateComponents::minimumWeek())); >+ const Decimal maximum = parseToNumber(element().attributeWithoutSynchronization(maxAttr), Decimal::fromDouble(DateComponents::maximumWeek())); >+ const Decimal step = StepRange::parseStep(anyStepHandling, weekStepDescription, element().attributeWithoutSynchronization(stepAttr)); > return StepRange(stepBase, RangeLimitations::Valid, minimum, maximum, step, weekStepDescription); > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 188410
:
346785
|
346867
|
346869