Backed out changeset 0e94014166b3 (bug 1658302) for causing bug 1662483

This commit is contained in:
Andreea Pavel 2020-09-02 00:44:18 +03:00
Родитель e30a2f5c84
Коммит b976f57ba6
6 изменённых файлов: 31 добавлений и 139 удалений

Просмотреть файл

@ -18,7 +18,6 @@
#include "mozilla/dom/HTMLFormSubmission.h"
#include "mozilla/dom/InputType.h"
#include "mozilla/dom/UserActivation.h"
#include "mozilla/dom/MutationEventBinding.h"
#include "mozilla/dom/WheelEventBinding.h"
#include "mozilla/PresShell.h"
#include "mozilla/StaticPrefs_dom.h"
@ -1283,11 +1282,6 @@ nsresult HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
// Clear the cached @autocomplete attribute and autocompleteInfo state.
mAutocompleteAttrState = nsContentUtils::eAutocompleteAttrState_Unknown;
mAutocompleteInfoState = nsContentUtils::eAutocompleteAttrState_Unknown;
} else if (aName == nsGkAtoms::placeholder) {
// Full addition / removals of the attribute reconstruct right now.
if (nsTextControlFrame* f = do_QueryFrame(GetPrimaryFrame())) {
f->PlaceholderChanged(aOldValue, aValue);
}
}
if (CreatesDateTimeWidget()) {
@ -5130,47 +5124,24 @@ nsChangeHint HTMLInputElement::GetAttributeChangeHint(const nsAtom* aAttribute,
nsChangeHint retval =
nsGenericHTMLFormElementWithState::GetAttributeChangeHint(aAttribute,
aModType);
const bool isAdditionOrRemoval =
aModType == MutationEvent_Binding::ADDITION ||
aModType == MutationEvent_Binding::REMOVAL;
const bool reconstruct = [&] {
if (aAttribute == nsGkAtoms::type) {
return true;
}
if (PlaceholderApplies() && aAttribute == nsGkAtoms::placeholder &&
isAdditionOrRemoval) {
// We need to re-create our placeholder text.
return true;
}
if (mType == NS_FORM_INPUT_FILE &&
(aAttribute == nsGkAtoms::allowdirs ||
aAttribute == nsGkAtoms::webkitdirectory)) {
if (aAttribute == nsGkAtoms::type ||
// The presence or absence of the 'directory' attribute determines what
// value we show in the file label when empty, via GetDisplayFileName.
return true;
}
if (mType == NS_FORM_INPUT_IMAGE && isAdditionOrRemoval &&
(aAttribute == nsGkAtoms::alt || aAttribute == nsGkAtoms::value)) {
// We might need to rebuild our alt text. Just go ahead and
// reconstruct our frame. This should be quite rare..
return true;
}
return false;
}();
if (reconstruct) {
// buttons we show for type=file.
aAttribute == nsGkAtoms::allowdirs ||
aAttribute == nsGkAtoms::webkitdirectory) {
retval |= nsChangeHint_ReconstructFrame;
} else if (mType == NS_FORM_INPUT_IMAGE &&
(aAttribute == nsGkAtoms::alt || aAttribute == nsGkAtoms::value)) {
// We might need to rebuild our alt text. Just go ahead and
// reconstruct our frame. This should be quite rare..
retval |= nsChangeHint_ReconstructFrame;
} else if (aAttribute == nsGkAtoms::value) {
retval |= NS_STYLE_HINT_REFLOW;
} else if (aAttribute == nsGkAtoms::size && IsSingleLineTextControl(false)) {
retval |= NS_STYLE_HINT_REFLOW;
} else if (PlaceholderApplies() && aAttribute == nsGkAtoms::placeholder) {
retval |= nsChangeHint_ReconstructFrame;
}
return retval;
}
@ -5906,7 +5877,8 @@ EventStates HTMLInputElement::IntrinsicState() const {
}
}
if (PlaceholderApplies() && HasAttr(nsGkAtoms::placeholder) &&
if (PlaceholderApplies() &&
HasAttr(kNameSpaceID_None, nsGkAtoms::placeholder) &&
ShouldShowPlaceholder()) {
state |= NS_EVENT_STATE_PLACEHOLDERSHOWN;
}

Просмотреть файл

@ -11,7 +11,6 @@
#include "mozilla/Attributes.h"
#include "mozilla/dom/HTMLFormSubmission.h"
#include "mozilla/dom/HTMLTextAreaElementBinding.h"
#include "mozilla/dom/MutationEventBinding.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/EventStates.h"
#include "mozilla/MappedDeclarations.h"
@ -40,7 +39,6 @@
#include "nsReadableUtils.h"
#include "nsStyleConsts.h"
#include "nsBaseCommandController.h"
#include "nsTextControlFrame.h"
#include "nsXULControllers.h"
NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(TextArea)
@ -434,16 +432,11 @@ nsChangeHint HTMLTextAreaElement::GetAttributeChangeHint(
nsChangeHint retval =
nsGenericHTMLFormElementWithState::GetAttributeChangeHint(aAttribute,
aModType);
const bool isAdditionOrRemoval =
aModType == MutationEvent_Binding::ADDITION ||
aModType == MutationEvent_Binding::REMOVAL;
if (aAttribute == nsGkAtoms::rows || aAttribute == nsGkAtoms::cols) {
retval |= NS_STYLE_HINT_REFLOW;
} else if (aAttribute == nsGkAtoms::wrap) {
retval |= nsChangeHint_ReconstructFrame;
} else if (aAttribute == nsGkAtoms::placeholder && isAdditionOrRemoval) {
} else if (aAttribute == nsGkAtoms::placeholder) {
retval |= nsChangeHint_ReconstructFrame;
}
return retval;
@ -823,7 +816,7 @@ EventStates HTMLTextAreaElement::IntrinsicState() const {
}
}
if (HasAttr(nsGkAtoms::placeholder) && IsValueEmpty()) {
if (HasAttr(kNameSpaceID_None, nsGkAtoms::placeholder) && IsValueEmpty()) {
state |= NS_EVENT_STATE_PLACEHOLDERSHOWN;
}
@ -933,10 +926,6 @@ nsresult HTMLTextAreaElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
UpdateTooLongValidityState();
} else if (aName == nsGkAtoms::minlength) {
UpdateTooShortValidityState();
} else if (aName == nsGkAtoms::placeholder) {
if (nsTextControlFrame* f = do_QueryFrame(GetPrimaryFrame())) {
f->PlaceholderChanged(aOldValue, aValue);
}
}
}

Просмотреть файл

@ -361,11 +361,11 @@ already_AddRefed<Element> nsTextControlFrame::MakeAnonElement(
already_AddRefed<Element> nsTextControlFrame::MakeAnonDivWithTextNode(
PseudoStyleType aPseudoType) const {
RefPtr<Element> div = MakeAnonElement(aPseudoType);
RefPtr<Element> divElement = MakeAnonElement(aPseudoType);
// Create the text node for the anonymous <div> element.
nsNodeInfoManager* nim = div->OwnerDoc()->NodeInfoManager();
RefPtr<nsTextNode> textNode = new (nim) nsTextNode(nim);
RefPtr<nsTextNode> textNode = new (divElement->OwnerDoc()->NodeInfoManager())
nsTextNode(divElement->OwnerDoc()->NodeInfoManager());
// If the anonymous div element is not for the placeholder, we should
// mark the text node as "maybe modified frequently" for avoiding ASCII
// range checks at every input.
@ -377,8 +377,8 @@ already_AddRefed<Element> nsTextControlFrame::MakeAnonDivWithTextNode(
textNode->MarkAsMaybeMasked();
}
}
div->AppendChildTo(textNode, false);
return div.forget();
divElement->AppendChildTo(textNode, false);
return divElement.forget();
}
nsresult nsTextControlFrame::CreateAnonymousContent(
@ -476,38 +476,21 @@ void nsTextControlFrame::CreatePlaceholderIfNeeded() {
MOZ_ASSERT(!mPlaceholderDiv);
// Do we need a placeholder node?
nsAutoString placeholder;
if (!mContent->AsElement()->GetAttr(nsGkAtoms::placeholder, placeholder)) {
nsAutoString placeholderTxt;
mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::placeholder,
placeholderTxt);
if (IsTextArea()) { // <textarea>s preserve newlines...
nsContentUtils::PlatformToDOMLineBreaks(placeholderTxt);
} else { // ...<input>s don't
nsContentUtils::RemoveNewlines(placeholderTxt);
}
if (placeholderTxt.IsEmpty()) {
return;
}
mPlaceholderDiv = MakeAnonDivWithTextNode(PseudoStyleType::placeholder);
UpdatePlaceholderText(placeholder, false);
}
void nsTextControlFrame::PlaceholderChanged(const nsAttrValue* aOld,
const nsAttrValue* aNew) {
if (!aOld || !aNew) {
return; // This should be handled by GetAttributeChangeHint.
}
nsAutoString placeholder;
aNew->ToString(placeholder);
UpdatePlaceholderText(placeholder, true);
}
void nsTextControlFrame::UpdatePlaceholderText(nsString& aPlaceholder,
bool aNotify) {
MOZ_ASSERT(mPlaceholderDiv);
MOZ_ASSERT(mPlaceholderDiv->GetFirstChild());
if (IsTextArea()) { // <textarea>s preserve newlines...
nsContentUtils::PlatformToDOMLineBreaks(aPlaceholder);
} else { // ...<input>s don't
nsContentUtils::RemoveNewlines(aPlaceholder);
}
mPlaceholderDiv->GetFirstChild()->AsText()->SetText(aPlaceholder, aNotify);
mPlaceholderDiv->GetFirstChild()->AsText()->SetText(placeholderTxt, false);
}
void nsTextControlFrame::CreatePreviewIfNeeded() {

Просмотреть файл

@ -155,8 +155,6 @@ class nsTextControlFrame : public nsContainerFrame,
nsISelectionController** aSelCon) override;
nsFrameSelection* GetOwnedFrameSelection() override;
void PlaceholderChanged(const nsAttrValue* aOld, const nsAttrValue* aNew);
/**
* Ensure mEditor is initialized with the proper flags and the default value.
* @throws NS_ERROR_NOT_INITIALIZED if mEditor has not been created
@ -331,7 +329,6 @@ class nsTextControlFrame : public nsContainerFrame,
nsresult CreateRootNode();
void CreatePlaceholderIfNeeded();
void UpdatePlaceholderText(nsString&, bool aNotify);
void CreatePreviewIfNeeded();
already_AddRefed<Element> MakeAnonElement(
mozilla::PseudoStyleType, Element* aParent = nullptr,

Просмотреть файл

@ -315,7 +315,6 @@ skip-if = (verify && debug && (os == 'linux'))
support-files = redundant_font_download.sjs
[test_reframe_cb.html]
[test_reframe_image_loading.html]
[test_reframe_input.html]
[test_reframe_pseudo_element.html]
[test_rem_unit.html]
[test_restyle_table_wrapper.html]

Просмотреть файл

@ -1,48 +0,0 @@
<!doctype html>
<meta charset="utf-8">
<title>Test for bug 1658302: We don't reframe for placeholder attribute value changes.</title>
<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<input id="input">
<textarea id="textarea"></textarea>
<script>
SimpleTest.waitForExplicitFinish();
const utils = SpecialPowers.DOMWindowUtils;
function expectReframe(shouldHaveReframed, callback) {
document.documentElement.offsetTop;
const previousConstructCount = utils.framesConstructed;
const previousReflowCount = utils.framesReflowed;
callback();
document.documentElement.offsetTop;
isnot(previousReflowCount, utils.framesReflowed, "We should have reflowed");
(shouldHaveReframed ? isnot : is)(previousConstructCount,
utils.framesConstructed,
`We should ${shouldHaveReframed ? "" : "not"} have reframed`);
}
for (const control of document.querySelectorAll("input, textarea")) {
// Creating the placeholder attribute reframes right now.
//
// TODO: Could be avoided with some more work.
expectReframe(true, () => {
control.placeholder = "foo";
});
// Incrementally changing it should not reframe, just reflow.
expectReframe(false, () => {
control.placeholder = "bar";
});
// Removing the placeholder attribute reframes right now.
//
// TODO: Could maybe be avoided with some more work.
expectReframe(true, () => {
control.removeAttribute("placeholder");
});
}
SimpleTest.finish();
</script>