mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-09 05:14:24 +00:00
Bug 737786 - 1/5 - Show/hide placeholder based on display lists instead of CSS class. r=bz
This commit is contained in:
parent
32446fd81f
commit
8edfbaf7e4
@ -18,8 +18,8 @@ class nsTextControlFrame;
|
||||
|
||||
// IID for the nsITextControl interface
|
||||
#define NS_ITEXTCONTROLELEMENT_IID \
|
||||
{ 0xe0a05008, 0xef02, 0x4fa2, \
|
||||
{ 0x93, 0xf2, 0x78, 0xe1, 0xec, 0xf7, 0x5b, 0x79 } }
|
||||
{ 0x669bd7ca, 0x42af, 0x4f1e, \
|
||||
{ 0xa6, 0xe2, 0x86, 0xc4, 0x0a, 0x14, 0x73, 0x4e } }
|
||||
|
||||
/**
|
||||
* This interface is used for the text control frame to get the editor and
|
||||
@ -153,7 +153,12 @@ public:
|
||||
/**
|
||||
* Show/hide the placeholder for the control.
|
||||
*/
|
||||
NS_IMETHOD_(void) SetPlaceholderClass(bool aVisible, bool aNotify) = 0;
|
||||
NS_IMETHOD_(void) SetPlaceholderVisibility(bool aVisible, bool aNotify) = 0;
|
||||
|
||||
/**
|
||||
* Returns the current expected placeholder visibility state.
|
||||
*/
|
||||
NS_IMETHOD_(bool) GetPlaceholderVisibility() = 0;
|
||||
|
||||
/**
|
||||
* Callback called whenever the value is changed.
|
||||
|
@ -1474,14 +1474,25 @@ nsHTMLInputElement::GetPlaceholderNode()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
nsHTMLInputElement::SetPlaceholderClass(bool aVisible, bool aNotify)
|
||||
nsHTMLInputElement::SetPlaceholderVisibility(bool aVisible, bool aNotify)
|
||||
{
|
||||
nsTextEditorState *state = GetEditorState();
|
||||
if (state) {
|
||||
state->SetPlaceholderClass(aVisible, aNotify);
|
||||
state->SetPlaceholderVisibility(aVisible, aNotify);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
nsHTMLInputElement::GetPlaceholderVisibility()
|
||||
{
|
||||
nsTextEditorState* state = GetEditorState();
|
||||
if (!state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return state->GetPlaceholderVisibility();
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLInputElement::GetDisplayFileName(nsAString& aValue) const
|
||||
{
|
||||
|
@ -150,7 +150,8 @@ public:
|
||||
NS_IMETHOD_(nsIContent*) GetRootEditorNode();
|
||||
NS_IMETHOD_(nsIContent*) CreatePlaceholderNode();
|
||||
NS_IMETHOD_(nsIContent*) GetPlaceholderNode();
|
||||
NS_IMETHOD_(void) SetPlaceholderClass(bool aVisible, bool aNotify);
|
||||
NS_IMETHOD_(void) SetPlaceholderVisibility(bool aVisible, bool aNotify);
|
||||
NS_IMETHOD_(bool) GetPlaceholderVisibility();
|
||||
NS_IMETHOD_(void) InitializeKeyboardEventListeners();
|
||||
NS_IMETHOD_(void) OnValueChanged(bool aNotify);
|
||||
NS_IMETHOD_(bool) HasCachedSelection();
|
||||
|
@ -122,7 +122,8 @@ public:
|
||||
NS_IMETHOD_(nsIContent*) GetRootEditorNode();
|
||||
NS_IMETHOD_(nsIContent*) CreatePlaceholderNode();
|
||||
NS_IMETHOD_(nsIContent*) GetPlaceholderNode();
|
||||
NS_IMETHOD_(void) SetPlaceholderClass(bool aVisible, bool aNotify);
|
||||
NS_IMETHOD_(void) SetPlaceholderVisibility(bool aVisible, bool aNotify);
|
||||
NS_IMETHOD_(bool) GetPlaceholderVisibility();
|
||||
NS_IMETHOD_(void) InitializeKeyboardEventListeners();
|
||||
NS_IMETHOD_(void) OnValueChanged(bool aNotify);
|
||||
NS_IMETHOD_(bool) HasCachedSelection();
|
||||
@ -513,9 +514,15 @@ nsHTMLTextAreaElement::GetPlaceholderNode()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
nsHTMLTextAreaElement::SetPlaceholderClass(bool aVisible, bool aNotify)
|
||||
nsHTMLTextAreaElement::SetPlaceholderVisibility(bool aVisible, bool aNotify)
|
||||
{
|
||||
mState.SetPlaceholderClass(aVisible, aNotify);
|
||||
mState.SetPlaceholderVisibility(aVisible, aNotify);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
nsHTMLTextAreaElement::GetPlaceholderVisibility()
|
||||
{
|
||||
return mState.GetPlaceholderVisibility();
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -933,7 +933,8 @@ nsTextEditorState::nsTextEditorState(nsITextControlElement* aOwningElement)
|
||||
mInitializing(false),
|
||||
mValueTransferInProgress(false),
|
||||
mSelectionCached(true),
|
||||
mSelectionRestoreEagerInit(false)
|
||||
mSelectionRestoreEagerInit(false),
|
||||
mPlaceholderVisibility(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsTextEditorState);
|
||||
}
|
||||
@ -1660,6 +1661,10 @@ be called if @placeholder is the empty string when trimmed from line breaks");
|
||||
rv = mPlaceholderDiv->AppendChildTo(placeholderText, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mPlaceholderDiv->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
|
||||
NS_LITERAL_STRING("anonymous-div placeholder"),
|
||||
false);
|
||||
|
||||
// initialize the text
|
||||
UpdatePlaceholderText(false);
|
||||
|
||||
@ -1969,7 +1974,7 @@ nsTextEditorState::ValueWasChanged(bool aNotify)
|
||||
|
||||
nsAutoString valueString;
|
||||
GetValue(valueString, true);
|
||||
SetPlaceholderClass(valueString.IsEmpty(), aNotify);
|
||||
SetPlaceholderVisibility(valueString.IsEmpty(), aNotify);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1993,28 +1998,17 @@ nsTextEditorState::UpdatePlaceholderText(bool aNotify)
|
||||
}
|
||||
|
||||
void
|
||||
nsTextEditorState::SetPlaceholderClass(bool aVisible,
|
||||
bool aNotify)
|
||||
nsTextEditorState::SetPlaceholderVisibility(bool aVisible,
|
||||
bool aNotify)
|
||||
{
|
||||
NS_ASSERTION(mPlaceholderDiv, "This function should not be called if "
|
||||
"mPlaceholderDiv isn't set");
|
||||
|
||||
// No need to do anything if we don't have a frame yet
|
||||
if (!mBoundFrame)
|
||||
return;
|
||||
mPlaceholderVisibility = aVisible;
|
||||
|
||||
nsAutoString classValue;
|
||||
|
||||
classValue.Assign(NS_LITERAL_STRING("anonymous-div placeholder"));
|
||||
|
||||
if (!aVisible)
|
||||
classValue.AppendLiteral(" hidden");
|
||||
|
||||
nsIContent* placeholderDiv = GetPlaceholderNode();
|
||||
NS_ENSURE_TRUE_VOID(placeholderDiv);
|
||||
|
||||
placeholderDiv->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
|
||||
classValue, aNotify);
|
||||
if (mBoundFrame && aNotify) {
|
||||
mBoundFrame->InvalidateFrame();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -174,7 +174,10 @@ public:
|
||||
}
|
||||
|
||||
// placeholder methods
|
||||
void SetPlaceholderClass(bool aVisible, bool aNotify);
|
||||
void SetPlaceholderVisibility(bool aVisible, bool aNotify);
|
||||
bool GetPlaceholderVisibility() {
|
||||
return mPlaceholderVisibility;
|
||||
}
|
||||
void UpdatePlaceholderText(bool aNotify);
|
||||
|
||||
/**
|
||||
@ -278,6 +281,7 @@ private:
|
||||
bool mSelectionCached; // Whether mSelectionProperties is valid
|
||||
mutable bool mSelectionRestoreEagerInit; // Whether we're eager initing because of selection restore
|
||||
SelectionProperties mSelectionProperties;
|
||||
bool mPlaceholderVisibility;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1307,7 +1307,7 @@ nsTextControlFrame::SetValueChanged(bool aValueChanged)
|
||||
GetTextLength(&textLength);
|
||||
|
||||
nsWeakFrame weakFrame(this);
|
||||
txtCtrl->SetPlaceholderClass(!textLength, true);
|
||||
txtCtrl->SetPlaceholderVisibility(!textLength, true);
|
||||
if (!weakFrame.IsAlive()) {
|
||||
return;
|
||||
}
|
||||
@ -1365,7 +1365,7 @@ nsTextControlFrame::UpdateValueDisplay(bool aNotify,
|
||||
if (mUsePlaceholder && !aBeforeEditorInit)
|
||||
{
|
||||
nsWeakFrame weakFrame(this);
|
||||
txtCtrl->SetPlaceholderClass(value.IsEmpty(), aNotify);
|
||||
txtCtrl->SetPlaceholderVisibility(value.IsEmpty(), aNotify);
|
||||
NS_ENSURE_STATE(weakFrame.IsAlive());
|
||||
}
|
||||
|
||||
@ -1455,3 +1455,38 @@ nsTextControlFrame::PeekOffset(nsPeekOffsetStruct *aPos)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const nsRect& aDirtyRect,
|
||||
const nsDisplayListSet& aLists)
|
||||
{
|
||||
/*
|
||||
* The implementation of this method is equivalent as:
|
||||
* nsContainerFrame::BuildDisplayList()
|
||||
* with the difference that we filter-out the placeholder frame when it
|
||||
* should not be visible.
|
||||
*/
|
||||
DO_GLOBAL_REFLOW_COUNT_DSP("nsTextControlFrame");
|
||||
|
||||
nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent());
|
||||
NS_ASSERTION(txtCtrl, "Content not a text control element!");
|
||||
|
||||
nsresult rv = DisplayBorderBackgroundOutline(aBuilder, aLists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsIFrame* kid = mFrames.FirstChild();
|
||||
nsDisplayListSet set(aLists, aLists.Content());
|
||||
|
||||
while (kid) {
|
||||
// If the frame is the placeholder frame, we should only show it if the
|
||||
// placeholder has to be visible.
|
||||
if (kid->GetContent() != txtCtrl->GetPlaceholderNode() ||
|
||||
txtCtrl->GetPlaceholderVisibility()) {
|
||||
nsresult rv = BuildDisplayListForChild(aBuilder, kid, aDirtyRect, set, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
kid = kid->GetNextSibling();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -67,8 +67,6 @@ public:
|
||||
virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState);
|
||||
virtual bool IsCollapsed();
|
||||
|
||||
DECL_DO_GLOBAL_REFLOW_COUNT_DSP(nsTextControlFrame, nsContainerFrame)
|
||||
|
||||
virtual bool IsLeaf() const;
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
@ -101,6 +99,10 @@ public:
|
||||
NS_IMETHOD SetInitialChildList(ChildListID aListID,
|
||||
nsFrameList& aChildList) MOZ_OVERRIDE;
|
||||
|
||||
NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const nsRect& aDirtyRect,
|
||||
const nsDisplayListSet& aLists);
|
||||
|
||||
//==== BEGIN NSIFORMCONTROLFRAME
|
||||
virtual void SetFocus(bool aOn , bool aRepaint);
|
||||
virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue);
|
||||
|
@ -161,11 +161,6 @@ textarea > .placeholder {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
input > .placeholder.hidden,
|
||||
textarea > .placeholder.hidden {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
input:-moz-read-write,
|
||||
textarea:-moz-read-write {
|
||||
-moz-user-modify: read-write !important;
|
||||
|
Loading…
Reference in New Issue
Block a user