зеркало из https://github.com/mozilla/pjs.git
Bug 457800 - Implement placeholder attribute for text input fields; r=ehsan,bzbarsky,bolter sr=roc ui-r=faaborg
--HG-- extra : rebase_source : 2e2f3a73553d720b32812603b0ce96c89b9a6261
This commit is contained in:
Родитель
f97f263c28
Коммит
b04de541c5
|
@ -52,7 +52,11 @@
|
|||
children: [
|
||||
{
|
||||
role: ROLE_ENTRY,
|
||||
children: []
|
||||
children: [
|
||||
{
|
||||
role: ROLE_TEXT_LEAF // HTML 5 placeholder attribute value
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
role: ROLE_COMBOBOX_LIST, // context menu
|
||||
|
@ -114,7 +118,11 @@
|
|||
},
|
||||
{
|
||||
role: ROLE_ENTRY,
|
||||
children: [ ]
|
||||
children: [
|
||||
{
|
||||
role: ROLE_TEXT_LEAF // HTML 5 placeholder attribute value
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
role: ROLE_COMBOBOX_LIST, // context menu popup
|
||||
|
|
|
@ -723,6 +723,7 @@ GK_ATOM(ping, "ping")
|
|||
#ifdef MOZ_MEDIA
|
||||
GK_ATOM(pixelratio, "pixelratio")
|
||||
#endif
|
||||
GK_ATOM(placeholder, "placeholder")
|
||||
GK_ATOM(plaintext, "plaintext")
|
||||
#ifdef MOZ_MEDIA
|
||||
GK_ATOM(playbackrate, "playbackrate")
|
||||
|
|
|
@ -764,6 +764,7 @@ NS_IMPL_STRING_ATTR(nsHTMLInputElement, UseMap, usemap)
|
|||
//NS_IMPL_STRING_ATTR(nsHTMLInputElement, Value, value)
|
||||
//NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLInputElement, Size, size, 0)
|
||||
//NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLInputElement, Type, type, "text")
|
||||
NS_IMPL_STRING_ATTR(nsHTMLInputElement, Placeholder, placeholder)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLInputElement::GetDefaultValue(nsAString& aValue)
|
||||
|
|
|
@ -379,6 +379,7 @@ NS_IMPL_BOOL_ATTR(nsHTMLTextAreaElement, ReadOnly, readonly)
|
|||
NS_IMPL_INT_ATTR(nsHTMLTextAreaElement, Rows, rows)
|
||||
NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLTextAreaElement, TabIndex, tabindex, 0)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLTextAreaElement, Wrap, wrap)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLTextAreaElement, Placeholder, placeholder)
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -154,6 +154,7 @@ _TEST_FILES = test_bug589.html \
|
|||
test_bug529859.html \
|
||||
test_bug535043.html \
|
||||
test_bug547850.html \
|
||||
test_bug457800.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=457800
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 457800</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=457800">Mozilla Bug 457800</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<input type="text" id="inputtext"/><br/>
|
||||
<input type="password"id="inputpassword"/><br/>
|
||||
<textarea id="textarea"></textarea>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 457800 **/
|
||||
|
||||
function testPlaceholderForElement(element)
|
||||
{
|
||||
// init
|
||||
element.value = ''
|
||||
|
||||
// check if {g,s}etAttribute are working
|
||||
element.setAttribute('placeholder', 'placeholder');
|
||||
is(element.getAttribute('placeholder'), 'placeholder', "element has no placeholder attribute");
|
||||
|
||||
// check if placeholder is working through DOM interface
|
||||
is(element.placeholder, 'placeholder', "can't read placeholder in DOM interface");
|
||||
element.placeholder = 'ph';
|
||||
is(element.placeholder, 'ph', "can't write placeholder in DOM interface");
|
||||
|
||||
// check placeholder and value are not interfering
|
||||
is(element.value, '', "value has changed when placeholder has changed");
|
||||
element.value = 'value';
|
||||
is(element.placeholder, 'ph', "placeholder in DOM interface has changed when value has changed");
|
||||
is(element.getAttribute('placeholder'), 'ph', "placeholder attribute has changed when value has changed");
|
||||
}
|
||||
|
||||
testPlaceholderForElement(document.getElementById('inputtext'));
|
||||
testPlaceholderForElement(document.getElementById('inputpassword'));
|
||||
testPlaceholderForElement(document.getElementById('textarea'));
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -42,7 +42,7 @@
|
|||
interface nsIControllers;
|
||||
interface nsIDOMFileList;
|
||||
|
||||
[scriptable, uuid(2cb61f32-b21f-4b87-904c-8876d8bb5f33)]
|
||||
[scriptable, uuid(e79806b8-7788-4229-ac69-debe395cb0e1)]
|
||||
interface nsIDOMNSHTMLInputElement : nsISupports
|
||||
{
|
||||
readonly attribute nsIControllers controllers;
|
||||
|
@ -58,6 +58,8 @@ interface nsIDOMNSHTMLInputElement : nsISupports
|
|||
|
||||
attribute boolean multiple;
|
||||
|
||||
attribute DOMString placeholder;
|
||||
|
||||
void mozGetFileNameArray([optional] out unsigned long aLength,
|
||||
[array,size_is(aLength), retval] out wstring aFileNames);
|
||||
void mozSetFileNameArray([array,size_is(aLength)] in wstring aFileNames,
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
|
||||
interface nsIControllers;
|
||||
|
||||
[scriptable, uuid(901ad7a9-1cd2-401e-9655-65f56c3dc5d4)]
|
||||
[scriptable, uuid(dd9f7df2-c06c-4c2d-b33a-90124e5ddea1)]
|
||||
interface nsIDOMNSHTMLTextAreaElement : nsISupports
|
||||
{
|
||||
readonly attribute nsIControllers controllers;
|
||||
|
@ -50,6 +50,7 @@ interface nsIDOMNSHTMLTextAreaElement : nsISupports
|
|||
attribute long selectionStart;
|
||||
attribute long selectionEnd;
|
||||
attribute long maxLength;
|
||||
attribute DOMString placeholder;
|
||||
|
||||
/**
|
||||
* Reflects the wrap content attribute. Possible values are "soft, "hard" and
|
||||
|
|
|
@ -1099,10 +1099,11 @@ nsTextControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
|||
if (!mDidPreDestroy) {
|
||||
PreDestroy();
|
||||
}
|
||||
if (mAnonymousDiv && mMutationObserver) {
|
||||
mAnonymousDiv->RemoveMutationObserver(mMutationObserver);
|
||||
if (mValueDiv && mMutationObserver) {
|
||||
mValueDiv->RemoveMutationObserver(mMutationObserver);
|
||||
}
|
||||
nsContentUtils::DestroyAnonymousContent(&mAnonymousDiv);
|
||||
nsContentUtils::DestroyAnonymousContent(&mValueDiv);
|
||||
nsContentUtils::DestroyAnonymousContent(&mPlaceholderDiv);
|
||||
nsBoxFrame::DestroyFrom(aDestructRoot);
|
||||
}
|
||||
|
||||
|
@ -1262,14 +1263,14 @@ nsTextControlFrame::CalcIntrinsicSize(nsIRenderingContext* aRenderingContext,
|
|||
aIntrinsicSize.width += 1;
|
||||
}
|
||||
|
||||
// Also add in the padding of our anonymous div child. Note that it hasn't
|
||||
// Also add in the padding of our value div child. Note that it hasn't
|
||||
// been reflowed yet, so we can't get its used padding, but it shouldn't be
|
||||
// using percentage padding anyway.
|
||||
nsMargin childPadding;
|
||||
if (GetFirstChild(nsnull)->GetStylePadding()->GetPadding(childPadding)) {
|
||||
aIntrinsicSize.width += childPadding.LeftRight();
|
||||
} else {
|
||||
NS_ERROR("Percentage padding on anonymous div?");
|
||||
NS_ERROR("Percentage padding on value div?");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1416,7 +1417,7 @@ nsTextControlFrame::InitEditor()
|
|||
if (!domdoc)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
rv = mEditor->Init(domdoc, shell, mAnonymousDiv, mSelCon, editorFlags);
|
||||
rv = mEditor->Init(domdoc, shell, mValueDiv, mSelCon, editorFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Initialize the controller for the editor
|
||||
|
@ -1586,7 +1587,7 @@ nsTextControlFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
|
|||
kNameSpaceID_XHTML);
|
||||
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = NS_NewHTMLElement(getter_AddRefs(mAnonymousDiv), nodeInfo, PR_FALSE);
|
||||
nsresult rv = NS_NewHTMLElement(getter_AddRefs(mValueDiv), nodeInfo, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Set the necessary classes on the text control. We use class values
|
||||
|
@ -1611,13 +1612,13 @@ nsTextControlFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
|
|||
|
||||
mMutationObserver = new nsAnonDivObserver(this);
|
||||
NS_ENSURE_TRUE(mMutationObserver, NS_ERROR_OUT_OF_MEMORY);
|
||||
mAnonymousDiv->AddMutationObserver(mMutationObserver);
|
||||
mValueDiv->AddMutationObserver(mMutationObserver);
|
||||
}
|
||||
rv = mAnonymousDiv->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
|
||||
classValue, PR_FALSE);
|
||||
rv = mValueDiv->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
|
||||
classValue, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!aElements.AppendElement(mAnonymousDiv))
|
||||
if (!aElements.AppendElement(mValueDiv))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// Create selection
|
||||
|
@ -1629,7 +1630,7 @@ nsTextControlFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
|
|||
// Create a SelectionController
|
||||
|
||||
mSelCon = new nsTextInputSelectionImpl(mFrameSel, shell,
|
||||
mAnonymousDiv);
|
||||
mValueDiv);
|
||||
if (!mSelCon)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
mTextListener = new nsTextInputListener();
|
||||
|
@ -1667,13 +1668,18 @@ nsTextControlFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
|
|||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// Now create the placeholder anonymous content
|
||||
rv = CreatePlaceholderDiv(aElements, doc->NodeInfoManager());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsTextControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements)
|
||||
{
|
||||
aElements.MaybeAppendElement(mAnonymousDiv);
|
||||
aElements.MaybeAppendElement(mValueDiv);
|
||||
aElements.MaybeAppendElement(mPlaceholderDiv);
|
||||
}
|
||||
|
||||
nscoord
|
||||
|
@ -1827,6 +1833,18 @@ nsTextControlFrame::IsLeaf() const
|
|||
void nsTextControlFrame::SetFocus(PRBool aOn, PRBool aRepaint)
|
||||
{
|
||||
if (!aOn) {
|
||||
nsWeakFrame weakFrame(this);
|
||||
|
||||
nsAutoString valueString;
|
||||
GetValue(valueString, PR_TRUE);
|
||||
if (valueString.IsEmpty())
|
||||
ShowPlaceholder();
|
||||
|
||||
if (!weakFrame.IsAlive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MaybeEndSecureKeyboardInput();
|
||||
return;
|
||||
}
|
||||
|
@ -1834,6 +1852,15 @@ void nsTextControlFrame::SetFocus(PRBool aOn, PRBool aRepaint)
|
|||
if (!mSelCon)
|
||||
return;
|
||||
|
||||
nsWeakFrame weakFrame(this);
|
||||
|
||||
HidePlaceholder();
|
||||
|
||||
if (!weakFrame.IsAlive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(InitFocusedValue()))
|
||||
MaybeBeginSecureKeyboardInput();
|
||||
|
||||
|
@ -2405,6 +2432,12 @@ nsTextControlFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
|||
}
|
||||
mEditor->SetFlags(flags);
|
||||
}
|
||||
else if (nsGkAtoms::placeholder == aAttribute)
|
||||
{
|
||||
nsWeakFrame weakFrame(this);
|
||||
UpdatePlaceholderText(PR_TRUE);
|
||||
NS_ENSURE_STATE(weakFrame.IsAlive());
|
||||
}
|
||||
// Allow the base class to handle common attributes supported
|
||||
// by all form elements...
|
||||
else {
|
||||
|
@ -2718,6 +2751,15 @@ nsTextControlFrame::SetValue(const nsAString& aValue)
|
|||
editor->SetFlags(savedFlags);
|
||||
if (selPriv)
|
||||
selPriv->EndBatchChanges();
|
||||
|
||||
if (newValue.IsEmpty())
|
||||
{
|
||||
if (!IsFocusedContent(mContent))
|
||||
ShowPlaceholder();
|
||||
// else it's already hidden
|
||||
}
|
||||
else
|
||||
HidePlaceholder();
|
||||
}
|
||||
|
||||
NS_ENSURE_STATE(weakFrame.IsAlive());
|
||||
|
@ -2808,6 +2850,88 @@ nsTextControlFrame::ShutDown()
|
|||
NS_IF_RELEASE(sNativeInputBindings);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextControlFrame::CreatePlaceholderDiv(nsTArray<nsIContent*>& aElements,
|
||||
nsNodeInfoManager* pNodeInfoManager)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIContent> placeholderText;
|
||||
|
||||
// Create a DIV for the placeholder
|
||||
// and add it to the anonymous content child list
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo;
|
||||
nodeInfo = pNodeInfoManager->GetNodeInfo(nsGkAtoms::div, nsnull,
|
||||
kNameSpaceID_XHTML);
|
||||
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = NS_NewHTMLElement(getter_AddRefs(mPlaceholderDiv), nodeInfo, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Create the text node for the placeholder text before doing anything else
|
||||
rv = NS_NewTextNode(getter_AddRefs(placeholderText), pNodeInfoManager);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mPlaceholderDiv->AppendChildTo(placeholderText, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Set the necessary classes on the text control. We use class values
|
||||
// instead of a 'style' attribute so that the style comes from a user-agent
|
||||
// style sheet and is still applied even if author styles are disabled.
|
||||
SetPlaceholderClass(PR_TRUE, PR_FALSE);
|
||||
|
||||
if (!aElements.AppendElement(mPlaceholderDiv))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// initialise the text
|
||||
UpdatePlaceholderText(PR_FALSE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextControlFrame::ShowPlaceholder()
|
||||
{
|
||||
return SetPlaceholderClass(PR_TRUE, PR_TRUE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextControlFrame::HidePlaceholder()
|
||||
{
|
||||
return SetPlaceholderClass(PR_FALSE, PR_TRUE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextControlFrame::SetPlaceholderClass(PRBool aVisible,
|
||||
PRBool aNotify)
|
||||
{
|
||||
nsresult rv;
|
||||
nsAutoString classValue;
|
||||
|
||||
classValue.Assign(NS_LITERAL_STRING("anonymous-div placeholder"));
|
||||
|
||||
if (!aVisible)
|
||||
classValue.AppendLiteral(" hidden");
|
||||
|
||||
rv = mPlaceholderDiv->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
|
||||
classValue, aNotify);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextControlFrame::UpdatePlaceholderText(PRBool aNotify)
|
||||
{
|
||||
nsAutoString placeholderValue;
|
||||
|
||||
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::placeholder, placeholderValue);
|
||||
RemoveNewlines(placeholderValue);
|
||||
NS_ASSERTION(mPlaceholderDiv->GetChildAt(0), "placeholder div has no child");
|
||||
mPlaceholderDiv->GetChildAt(0)->SetText(placeholderValue, aNotify);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsAnonDivObserver, nsIMutationObserver)
|
||||
|
||||
void
|
||||
|
|
|
@ -335,8 +335,16 @@ private:
|
|||
nsresult SelectAllOrCollapseToEndOfText(PRBool aSelect);
|
||||
nsresult SetSelectionEndPoints(PRInt32 aSelStart, PRInt32 aSelEnd);
|
||||
|
||||
// placeholder methods
|
||||
nsresult CreatePlaceholderDiv(nsTArray<nsIContent*>& aElements, nsNodeInfoManager* pNodeInfoManager);
|
||||
nsresult ShowPlaceholder();
|
||||
nsresult HidePlaceholder();
|
||||
nsresult SetPlaceholderClass(PRBool aVisible, PRBool aNotify);
|
||||
nsresult UpdatePlaceholderText(PRBool aNotify);
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIContent> mAnonymousDiv;
|
||||
nsCOMPtr<nsIContent> mValueDiv;
|
||||
nsCOMPtr<nsIContent> mPlaceholderDiv;
|
||||
|
||||
nsCOMPtr<nsIEditor> mEditor;
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Test: placeholder should be used by input password elements -->
|
||||
<body>
|
||||
<input type="password" value="" placeholder="my placeholder">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Test: placeholder should be used by input text elements -->
|
||||
<body>
|
||||
<input type="text" value="" placeholder="my placeholder">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Test: placeholder should be used by textarea elements -->
|
||||
<body>
|
||||
<textarea placeholder="my placeholder"></textarea>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: when unfocused, if value='', newest placeholder should be shown -->
|
||||
<script type="text/javascript">
|
||||
function focusPlaceholder()
|
||||
{
|
||||
document.getElementById('p1').focus();
|
||||
}
|
||||
function setPlaceholder()
|
||||
{
|
||||
document.getElementById('p1').placeholder = 'my placeholder';
|
||||
}
|
||||
function unFocusPlaceholder()
|
||||
{
|
||||
document.getElementById('p1').blur();
|
||||
}
|
||||
function disableReftestWait()
|
||||
{
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
|
||||
<body onload="focusPlaceholder(); setPlaceholder(); unFocusPlaceholder(); disableReftestWait();">
|
||||
<input type="text" id="p1" value="" placeholder="old placeholder">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: placeholder has to be used if set via javascript -->
|
||||
<script type="text/javascript">
|
||||
function setPlaceholder()
|
||||
{
|
||||
document.getElementById('p1').placeholder = "my placeholder";
|
||||
}
|
||||
function disableReftestWait()
|
||||
{
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
|
||||
<body onload="setPlaceholder(); disableReftestWait();">
|
||||
<input type="text" id="p1" value="" placeholder="">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Test: value has to be shown when not null -->
|
||||
<body>
|
||||
<input type="text" value="my value" placeholder="my placeholder">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: value has to be shown if set via javascript -->
|
||||
<script type="text/javascript">
|
||||
function setValue()
|
||||
{
|
||||
document.getElementById('p1').value = "my value";
|
||||
}
|
||||
function disableReftestWait()
|
||||
{
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
|
||||
<body onload="setValue(); disableReftestWait();">
|
||||
<input type="text" id="p1" value="" placeholder="my placeholder">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: placeholder has to be shown if value is reseted via javascript -->
|
||||
<script type="text/javascript">
|
||||
function setValue()
|
||||
{
|
||||
document.getElementById('p1').value = "";
|
||||
}
|
||||
function disableReftestWait()
|
||||
{
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
|
||||
<body onload="setValue(); disableReftestWait();">
|
||||
<input type="text" id="p1" value="my value" placeholder="my placeholder">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Test placeholder behavior when textarea is too small -->
|
||||
<body>
|
||||
<textarea cols="5" placeholder="my placeholder"></textarea>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Test placeholder behavior when input is too small -->
|
||||
<body>
|
||||
<input type="text" size="5" value="" placeholder="my placeholder">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: when focused, element should show placeholder
|
||||
Using a readonly input text to disable caret -->
|
||||
<script type="text/javascript">
|
||||
function focusPlaceholder()
|
||||
{
|
||||
document.getElementById('p1').focus();
|
||||
}
|
||||
function disableReftestWait()
|
||||
{
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
|
||||
<body onload="focusPlaceholder(); disableReftestWait();">
|
||||
<input type="text" id="p1" value="" placeholder="my placeholder" readonly>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: when focused, placeholder update shouldn't show placeholder
|
||||
Using a readonly input text to disable caret -->
|
||||
<script type="text/javascript">
|
||||
function focusPlaceholder()
|
||||
{
|
||||
document.getElementById('p1').focus();
|
||||
}
|
||||
function setPlaceholder()
|
||||
{
|
||||
document.getElementById('p1').placeholder = 'new placeholder';
|
||||
}
|
||||
function disableReftestWait()
|
||||
{
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
|
||||
<body onload="focusPlaceholder(); setPlaceholder(); disableReftestWait();">
|
||||
<input type="text" id="p1" value="" placeholder="my placeholder" readonly>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: when focused, value reset shouldn't show placeholder
|
||||
Using a readonly input text to disable caret -->
|
||||
<script type="text/javascript">
|
||||
function focusPlaceholder()
|
||||
{
|
||||
document.getElementById('p1').focus();
|
||||
}
|
||||
function resetValue()
|
||||
{
|
||||
document.getElementById('p1').value = '';
|
||||
}
|
||||
function disableReftestWait()
|
||||
{
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
|
||||
<body onload="focusPlaceholder(); resetValue(); disableReftestWait();">
|
||||
<input type="text" id="p1" value="my value" placeholder="my placeholder" readonly>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Using a readonly input text to disable caret -->
|
||||
<script type="text/javascript">
|
||||
function focusInput()
|
||||
{
|
||||
document.getElementById('t1').focus();
|
||||
}
|
||||
function disableReftestWait()
|
||||
{
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload="focusInput(); disableReftestWait();">
|
||||
<input id='t1' type="text" readonly>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
This test 'emulate' the placeholder by setting a style
|
||||
to the value of an input text.
|
||||
This test may break if placeholder default style is changed.
|
||||
-->
|
||||
<link rel='stylesheet' type='text/css' href='placeholder-style.css'>
|
||||
|
||||
<body>
|
||||
<input type="text" class="placeholder" size="5" value="my placeholder">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
This test 'emulate' the placeholder by setting a style
|
||||
to the value of a textarea.
|
||||
This test may break if placeholder default style is changed.
|
||||
-->
|
||||
<link rel='stylesheet' type='text/css' href='placeholder-style.css'>
|
||||
|
||||
<body>
|
||||
<textarea class="placeholder" cols="5">my placeholder</textarea>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<input type="text" value="my value">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,4 @@
|
|||
textarea.placeholder,
|
||||
input.placeholder {
|
||||
color: GrayText;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
This test 'emulate' the placeholder by setting a style
|
||||
to the value of an input text.
|
||||
This test may break if placeholder default style is changed.
|
||||
-->
|
||||
<link rel='stylesheet' type='text/css' href='placeholder-style.css'>
|
||||
|
||||
<body>
|
||||
<input type="text" class="placeholder" value="my placeholder">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
This test 'emulate' the placeholder by setting a style
|
||||
to the value of a textarea.
|
||||
This test may break if placeholder default style is changed.
|
||||
-->
|
||||
<link rel='stylesheet' type='text/css' href='placeholder-style.css'>
|
||||
|
||||
<body>
|
||||
<textarea class="placeholder">my placeholder</textarea>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
== placeholder-1-text.html placeholder-visible-ref.html
|
||||
== placeholder-1-password.html placeholder-visible-ref.html
|
||||
== placeholder-1-textarea.html placeholder-visible-textarea-ref.html
|
||||
== placeholder-2.html placeholder-visible-ref.html
|
||||
== placeholder-3.html placeholder-overridden-ref.html
|
||||
== placeholder-4.html placeholder-overridden-ref.html
|
||||
== placeholder-5.html placeholder-visible-ref.html
|
||||
== placeholder-6.html placeholder-overflow-ref.html
|
||||
== placeholder-6-textarea.html placeholder-overflow-textarea-ref.html
|
||||
== placeholder-7.html placeholder-focus-ref.html
|
||||
== placeholder-8.html placeholder-focus-ref.html
|
||||
== placeholder-9.html placeholder-focus-ref.html
|
||||
== placeholder-10.html placeholder-visible-ref.html
|
|
@ -33,3 +33,6 @@ HTTP(..) == text-control-baseline-1.html text-control-baseline-1-ref.html
|
|||
!= checkbox-checked-native-notref.html about:blank
|
||||
!= radio-checked-native.html about:blank
|
||||
!= radio-checked-native-notref.html about:blank
|
||||
|
||||
# placeholder
|
||||
include placeholder/reftest.list
|
||||
|
|
|
@ -162,6 +162,21 @@ input > .anonymous-div.inherit-overflow {
|
|||
overflow: inherit;
|
||||
}
|
||||
|
||||
input > .placeholder,
|
||||
textarea > .placeholder {
|
||||
color: GrayText;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче