Bug 737786 - 1/5 - Show/hide placeholder based on display lists instead of CSS class. r=bz

This commit is contained in:
Mounir Lamouri 2012-11-09 10:22:29 +00:00
Родитель 32446fd81f
Коммит 8edfbaf7e4
9 изменённых файлов: 92 добавлений и 38 удалений

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

@ -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;