зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to autoland on a CLOSED TREE
This commit is contained in:
Коммит
2692897b74
|
@ -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>
|
Загрузка…
Ссылка в новой задаче