mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-20 17:20:54 +00:00
Bug 787858 - XUL textbox context menu inaccessible, r=tbsaunde
This commit is contained in:
parent
7dbc4de777
commit
e18f2c52b6
@ -1310,7 +1310,7 @@ nsAccessibilityService::CreateAccessibleByType(nsIContent* aContent,
|
||||
accessible = new XULLabelAccessible(aContent, aDoc);
|
||||
|
||||
} else if (role.EqualsLiteral("xul:textbox")) {
|
||||
accessible = new XULTextFieldAccessible(aContent, aDoc);
|
||||
accessible = new EnumRoleAccessible(aContent, aDoc, roles::SECTION);
|
||||
|
||||
} else if (role.EqualsLiteral("xul:thumb")) {
|
||||
accessible = new XULThumbAccessible(aContent, aDoc);
|
||||
|
@ -1052,56 +1052,37 @@ Accessible::TakeFocus()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ENameValueFlag
|
||||
Accessible::GetHTMLName(nsString& aLabel)
|
||||
void
|
||||
Accessible::XULElmName(DocAccessible* aDocument,
|
||||
nsIContent* aElm, nsString& aName)
|
||||
{
|
||||
Accessible* labelAcc = nullptr;
|
||||
HTMLLabelIterator iter(Document(), this);
|
||||
while ((labelAcc = iter.Next())) {
|
||||
nsTextEquivUtils::AppendTextEquivFromContent(this, labelAcc->GetContent(),
|
||||
&aLabel);
|
||||
aLabel.CompressWhitespace();
|
||||
}
|
||||
/**
|
||||
* 3 main cases for XUL Controls to be labeled
|
||||
* 1 - control contains label="foo"
|
||||
* 2 - control has, as a child, a label element
|
||||
* - label has either value="foo" or children
|
||||
* 3 - non-child label contains control="controlID"
|
||||
* - label has either value="foo" or children
|
||||
* Once a label is found, the search is discontinued, so a control
|
||||
* that has a label child as well as having a label external to
|
||||
* the control that uses the control="controlID" syntax will use
|
||||
* the child label for its Name.
|
||||
*/
|
||||
|
||||
if (!aLabel.IsEmpty())
|
||||
return eNameOK;
|
||||
|
||||
nsTextEquivUtils::GetNameFromSubtree(this, aLabel);
|
||||
return aLabel.IsEmpty() ? eNameOK : eNameFromSubtree;
|
||||
}
|
||||
|
||||
/**
|
||||
* 3 main cases for XUL Controls to be labeled
|
||||
* 1 - control contains label="foo"
|
||||
* 2 - control has, as a child, a label element
|
||||
* - label has either value="foo" or children
|
||||
* 3 - non-child label contains control="controlID"
|
||||
* - label has either value="foo" or children
|
||||
* Once a label is found, the search is discontinued, so a control
|
||||
* that has a label child as well as having a label external to
|
||||
* the control that uses the control="controlID" syntax will use
|
||||
* the child label for its Name.
|
||||
*/
|
||||
ENameValueFlag
|
||||
Accessible::GetXULName(nsString& aName)
|
||||
{
|
||||
// CASE #1 (via label attribute) -- great majority of the cases
|
||||
nsCOMPtr<nsIDOMXULLabeledControlElement> labeledEl =
|
||||
do_QueryInterface(mContent);
|
||||
nsCOMPtr<nsIDOMXULLabeledControlElement> labeledEl = do_QueryInterface(aElm);
|
||||
if (labeledEl) {
|
||||
labeledEl->GetLabel(aName);
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMXULSelectControlItemElement> itemEl =
|
||||
do_QueryInterface(mContent);
|
||||
nsCOMPtr<nsIDOMXULSelectControlItemElement> itemEl = do_QueryInterface(aElm);
|
||||
if (itemEl) {
|
||||
itemEl->GetLabel(aName);
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMXULSelectControlElement> select =
|
||||
do_QueryInterface(mContent);
|
||||
nsCOMPtr<nsIDOMXULSelectControlElement> select = do_QueryInterface(aElm);
|
||||
// Use label if this is not a select control element which
|
||||
// uses label attribute to indicate which option is selected
|
||||
if (!select) {
|
||||
nsCOMPtr<nsIDOMXULElement> xulEl(do_QueryInterface(mContent));
|
||||
nsCOMPtr<nsIDOMXULElement> xulEl(do_QueryInterface(aElm));
|
||||
if (xulEl)
|
||||
xulEl->GetAttribute(NS_LITERAL_STRING("label"), aName);
|
||||
}
|
||||
@ -1111,7 +1092,7 @@ Accessible::GetXULName(nsString& aName)
|
||||
// CASES #2 and #3 ------ label as a child or <label control="id" ... > </label>
|
||||
if (aName.IsEmpty()) {
|
||||
Accessible* labelAcc = nullptr;
|
||||
XULLabelIterator iter(Document(), mContent);
|
||||
XULLabelIterator iter(aDocument, aElm);
|
||||
while ((labelAcc = iter.Next())) {
|
||||
nsCOMPtr<nsIDOMXULLabelElement> xulLabel =
|
||||
do_QueryInterface(labelAcc->GetContent());
|
||||
@ -1120,30 +1101,27 @@ Accessible::GetXULName(nsString& aName)
|
||||
// If no value attribute, a non-empty label must contain
|
||||
// children that define its text -- possibly using HTML
|
||||
nsTextEquivUtils::
|
||||
AppendTextEquivFromContent(this, labelAcc->GetContent(), &aName);
|
||||
AppendTextEquivFromContent(labelAcc, labelAcc->GetContent(), &aName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aName.CompressWhitespace();
|
||||
if (!aName.IsEmpty())
|
||||
return eNameOK;
|
||||
return;
|
||||
|
||||
// Can get text from title of <toolbaritem> if we're a child of a <toolbaritem>
|
||||
nsIContent *bindingParent = mContent->GetBindingParent();
|
||||
nsIContent *parent = bindingParent? bindingParent->GetParent() :
|
||||
mContent->GetParent();
|
||||
nsIContent *bindingParent = aElm->GetBindingParent();
|
||||
nsIContent* parent =
|
||||
bindingParent? bindingParent->GetParent() : aElm->GetParent();
|
||||
while (parent) {
|
||||
if (parent->Tag() == nsGkAtoms::toolbaritem &&
|
||||
parent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, aName)) {
|
||||
aName.CompressWhitespace();
|
||||
return eNameOK;
|
||||
return;
|
||||
}
|
||||
parent = parent->GetParent();
|
||||
}
|
||||
|
||||
nsTextEquivUtils::GetNameFromSubtree(this, aName);
|
||||
return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -2478,11 +2456,30 @@ Accessible::ARIAName(nsString& aName)
|
||||
ENameValueFlag
|
||||
Accessible::NativeName(nsString& aName)
|
||||
{
|
||||
if (mContent->IsHTML())
|
||||
return GetHTMLName(aName);
|
||||
if (mContent->IsHTML()) {
|
||||
Accessible* label = nullptr;
|
||||
HTMLLabelIterator iter(Document(), this);
|
||||
while ((label = iter.Next())) {
|
||||
nsTextEquivUtils::AppendTextEquivFromContent(this, label->GetContent(),
|
||||
&aName);
|
||||
aName.CompressWhitespace();
|
||||
}
|
||||
|
||||
if (mContent->IsXUL())
|
||||
return GetXULName(aName);
|
||||
if (!aName.IsEmpty())
|
||||
return eNameOK;
|
||||
|
||||
nsTextEquivUtils::GetNameFromSubtree(this, aName);
|
||||
return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
|
||||
}
|
||||
|
||||
if (mContent->IsXUL()) {
|
||||
XULElmName(mDoc, mContent, aName);
|
||||
if (!aName.IsEmpty())
|
||||
return eNameOK;
|
||||
|
||||
nsTextEquivUtils::GetNameFromSubtree(this, aName);
|
||||
return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
|
||||
}
|
||||
|
||||
if (mContent->IsSVG()) {
|
||||
// If user agents need to choose among multiple ‘desc’ or ‘title’ elements
|
||||
|
@ -879,10 +879,10 @@ protected:
|
||||
void ARIAName(nsString& aName);
|
||||
|
||||
/**
|
||||
* Compute the name of HTML/XUL node.
|
||||
* Return the name for XUL element.
|
||||
*/
|
||||
mozilla::a11y::ENameValueFlag GetHTMLName(nsString& aName);
|
||||
mozilla::a11y::ENameValueFlag GetXULName(nsString& aName);
|
||||
static void XULElmName(DocAccessible* aDocument,
|
||||
nsIContent* aElm, nsString& aName);
|
||||
|
||||
// helper method to verify frames
|
||||
static nsresult GetFullKeyName(const nsAString& aModifierName, const nsAString& aKeyName, nsAString& aStringOut);
|
||||
|
@ -328,16 +328,10 @@ HTMLTextFieldAccessible::NativeName(nsString& aName)
|
||||
if (!aName.IsEmpty())
|
||||
return nameFlag;
|
||||
|
||||
if (mContent->GetBindingParent()) {
|
||||
// XXX: bug 459640
|
||||
// There's a binding parent.
|
||||
// This means we're part of another control, so use parent accessible for name.
|
||||
// This ensures that a textbox inside of a XUL widget gets
|
||||
// an accessible name.
|
||||
Accessible* parent = Parent();
|
||||
if (parent)
|
||||
parent->GetName(aName);
|
||||
}
|
||||
// If part of compound of XUL widget then grab a name from XUL widget element.
|
||||
nsIContent* widgetElm = XULWidgetElm();
|
||||
if (widgetElm)
|
||||
XULElmName(mDoc, widgetElm, aName);
|
||||
|
||||
if (!aName.IsEmpty())
|
||||
return eNameOK;
|
||||
@ -369,8 +363,13 @@ void
|
||||
HTMLTextFieldAccessible::ApplyARIAState(uint64_t* aState) const
|
||||
{
|
||||
HyperTextAccessibleWrap::ApplyARIAState(aState);
|
||||
|
||||
aria::MapToState(aria::eARIAAutoComplete, mContent->AsElement(), aState);
|
||||
|
||||
// If part of compound of XUL widget then pick up ARIA stuff from XUL widget
|
||||
// element.
|
||||
nsIContent* widgetElm = XULWidgetElm();
|
||||
if (widgetElm)
|
||||
aria::MapToState(aria::eARIAAutoComplete, widgetElm->AsElement(), aState);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
@ -408,9 +407,8 @@ HTMLTextFieldAccessible::NativeState()
|
||||
if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::list))
|
||||
return state | states::SUPPORTS_AUTOCOMPLETION | states::HASPOPUP;
|
||||
|
||||
// No parent can mean a fake widget created for XUL textbox. If accessible
|
||||
// is unattached from tree then we don't care.
|
||||
if (mParent && Preferences::GetBool("browser.formfill.enable")) {
|
||||
// Ordinal XUL textboxes don't support autocomplete.
|
||||
if (!XULWidgetElm() && Preferences::GetBool("browser.formfill.enable")) {
|
||||
// Check to see if autocompletion is allowed on this input. We don't expose
|
||||
// it for password fields even though the entire password can be remembered
|
||||
// for a page if the user asks it to be. However, the kind of autocomplete
|
||||
|
@ -143,6 +143,11 @@ public:
|
||||
protected:
|
||||
// Accessible
|
||||
virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Return a XUL widget element this input is part of.
|
||||
*/
|
||||
nsIContent* XULWidgetElm() const { return mContent->GetBindingParent(); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -636,192 +636,3 @@ XULToolbarSeparatorAccessible::NativeState()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// XULTextFieldAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
XULTextFieldAccessible::
|
||||
XULTextFieldAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
HyperTextAccessibleWrap(aContent, aDoc)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED2(XULTextFieldAccessible,
|
||||
Accessible,
|
||||
nsIAccessibleText,
|
||||
nsIAccessibleEditableText)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// XULTextFieldAccessible: nsIAccessible
|
||||
|
||||
void
|
||||
XULTextFieldAccessible::Value(nsString& aValue)
|
||||
{
|
||||
aValue.Truncate();
|
||||
if (NativeRole() == roles::PASSWORD_TEXT) // Don't return password text!
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDOMXULTextBoxElement> textBox(do_QueryInterface(mContent));
|
||||
if (textBox) {
|
||||
textBox->GetValue(aValue);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mContent));
|
||||
if (menuList)
|
||||
menuList->GetLabel(aValue);
|
||||
}
|
||||
|
||||
void
|
||||
XULTextFieldAccessible::ApplyARIAState(uint64_t* aState) const
|
||||
{
|
||||
HyperTextAccessibleWrap::ApplyARIAState(aState);
|
||||
|
||||
aria::MapToState(aria::eARIAAutoComplete, mContent->AsElement(), aState);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
XULTextFieldAccessible::NativeState()
|
||||
{
|
||||
uint64_t state = HyperTextAccessibleWrap::NativeState();
|
||||
|
||||
nsCOMPtr<nsIContent> inputField(GetInputField());
|
||||
NS_ENSURE_TRUE(inputField, state);
|
||||
|
||||
// Create a temporary accessible from the HTML text field to get
|
||||
// the accessible state from. Doesn't add to cache into document cache.
|
||||
nsRefPtr<HTMLTextFieldAccessible> tempAccessible =
|
||||
new HTMLTextFieldAccessible(inputField, mDoc);
|
||||
if (tempAccessible)
|
||||
return state | tempAccessible->NativeState();
|
||||
return state;
|
||||
}
|
||||
|
||||
role
|
||||
XULTextFieldAccessible::NativeRole()
|
||||
{
|
||||
if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
|
||||
nsGkAtoms::password, eIgnoreCase))
|
||||
return roles::PASSWORD_TEXT;
|
||||
|
||||
return roles::ENTRY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only one actions available
|
||||
*/
|
||||
uint8_t
|
||||
XULTextFieldAccessible::ActionCount()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of our only action
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
XULTextFieldAccessible::GetActionName(uint8_t aIndex, nsAString& aName)
|
||||
{
|
||||
if (aIndex == eAction_Click) {
|
||||
aName.AssignLiteral("activate");
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the button to do its action
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
XULTextFieldAccessible::DoAction(uint8_t index)
|
||||
{
|
||||
if (index == 0) {
|
||||
nsCOMPtr<nsIDOMXULElement> element(do_QueryInterface(mContent));
|
||||
if (element)
|
||||
{
|
||||
element->Focus();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
bool
|
||||
XULTextFieldAccessible::CanHaveAnonChildren()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
XULTextFieldAccessible::IsAcceptableChild(Accessible* aPossibleChild) const
|
||||
{
|
||||
// XXX: entry shouldn't contain anything but text leafs. Currently it may
|
||||
// contain a trailing fake HTML br element added for layout needs. We don't
|
||||
// need to expose it since it'd be confusing for AT.
|
||||
return aPossibleChild->IsTextLeaf();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIEditor>
|
||||
XULTextFieldAccessible::GetEditor() const
|
||||
{
|
||||
nsCOMPtr<nsIContent> inputField = GetInputField();
|
||||
nsCOMPtr<nsIDOMNSEditableElement> editableElt(do_QueryInterface(inputField));
|
||||
if (!editableElt)
|
||||
return nullptr;
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
editableElt->GetEditor(getter_AddRefs(editor));
|
||||
return editor.forget();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// XULTextFieldAccessible: Accessible protected
|
||||
|
||||
void
|
||||
XULTextFieldAccessible::CacheChildren()
|
||||
{
|
||||
NS_ENSURE_TRUE_VOID(mDoc);
|
||||
// Create child accessibles for native anonymous content of underlying HTML
|
||||
// input element.
|
||||
nsCOMPtr<nsIContent> inputContent(GetInputField());
|
||||
if (!inputContent)
|
||||
return;
|
||||
|
||||
TreeWalker walker(this, inputContent);
|
||||
while (Accessible* child = walker.NextChild())
|
||||
AppendChild(child);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// XULTextFieldAccessible: HyperTextAccessible protected
|
||||
|
||||
already_AddRefed<nsFrameSelection>
|
||||
XULTextFieldAccessible::FrameSelection() const
|
||||
{
|
||||
nsCOMPtr<nsIContent> inputContent(GetInputField());
|
||||
NS_ASSERTION(inputContent, "No input content");
|
||||
if (!inputContent)
|
||||
return nullptr;
|
||||
|
||||
nsIFrame* frame = inputContent->GetPrimaryFrame();
|
||||
return frame ? frame->GetFrameSelection() : nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// XULTextFieldAccessible protected
|
||||
|
||||
already_AddRefed<nsIContent>
|
||||
XULTextFieldAccessible::GetInputField() const
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> inputFieldDOMNode;
|
||||
nsCOMPtr<nsIDOMXULTextBoxElement> textBox = do_QueryInterface(mContent);
|
||||
if (textBox)
|
||||
textBox->GetInputField(getter_AddRefs(inputFieldDOMNode));
|
||||
|
||||
NS_ASSERTION(inputFieldDOMNode, "No input field for XULTextFieldAccessible");
|
||||
|
||||
nsCOMPtr<nsIContent> inputField = do_QueryInterface(inputFieldDOMNode);
|
||||
return inputField.forget();
|
||||
}
|
||||
|
@ -215,47 +215,6 @@ public:
|
||||
virtual uint64_t NativeState();
|
||||
};
|
||||
|
||||
/**
|
||||
* Used for XUL textbox element.
|
||||
*/
|
||||
class XULTextFieldAccessible : public HyperTextAccessibleWrap
|
||||
{
|
||||
public:
|
||||
enum { eAction_Click = 0 };
|
||||
|
||||
XULTextFieldAccessible(nsIContent* aContent, DocAccessible* aDoc);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName);
|
||||
NS_IMETHOD DoAction(uint8_t index);
|
||||
|
||||
// HyperTextAccessible
|
||||
virtual already_AddRefed<nsIEditor> GetEditor() const;
|
||||
|
||||
// Accessible
|
||||
virtual void Value(nsString& aValue);
|
||||
virtual void ApplyARIAState(uint64_t* aState) const;
|
||||
virtual mozilla::a11y::role NativeRole();
|
||||
virtual uint64_t NativeState();
|
||||
virtual bool CanHaveAnonChildren();
|
||||
virtual bool IsAcceptableChild(Accessible* aPossibleChild) const MOZ_OVERRIDE;
|
||||
|
||||
// ActionAccessible
|
||||
virtual uint8_t ActionCount();
|
||||
|
||||
protected:
|
||||
// Accessible
|
||||
virtual void CacheChildren();
|
||||
|
||||
// HyperTextAccessible
|
||||
virtual already_AddRefed<nsFrameSelection> FrameSelection() const;
|
||||
|
||||
// nsXULTextFieldAccessible
|
||||
already_AddRefed<nsIContent> GetInputField() const;
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -635,7 +635,7 @@ XULListitemAccessible::NativeName(nsString& aName)
|
||||
}
|
||||
}
|
||||
|
||||
return GetXULName(aName);
|
||||
return Accessible::NativeName(aName);
|
||||
}
|
||||
|
||||
role
|
||||
|
@ -21,7 +21,6 @@ support-files =
|
||||
states.js
|
||||
table.js
|
||||
value.js
|
||||
testTextboxes.js
|
||||
text.js
|
||||
treeview.css
|
||||
treeview.js
|
||||
@ -32,5 +31,3 @@ support-files =
|
||||
[test_nsIAccessibleDocument.html]
|
||||
[test_nsIAccessibleImage.html]
|
||||
[test_OuterDocAccessible.html]
|
||||
[test_textboxes.html]
|
||||
[test_textboxes.xul]
|
||||
|
@ -91,6 +91,23 @@ function testActions(aArray)
|
||||
gActionsQueue.invoke();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test action names and descriptions.
|
||||
*/
|
||||
function testActionNames(aID, aActions)
|
||||
{
|
||||
var actions = (typeof aActions == "string") ?
|
||||
[ aActions ] : (aActions || []);
|
||||
|
||||
var acc = getAccessible(aID);
|
||||
is(acc.actionCount, actions.length, "Wong number of actions.");
|
||||
for (var i = 0; i < actions.length; i++ ) {
|
||||
is(acc.getActionName(i), actions[i], "Wrong action name at " + i + " index.");
|
||||
is(acc.getActionDescription(0), gActionDescrMap[actions[i]],
|
||||
"Wrong action description at " + i + "index.");
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Private
|
||||
|
||||
@ -151,3 +168,20 @@ function checkerOfActionInvoker(aType, aTarget, aActionObj)
|
||||
aActionObj.checkOnClickEvent(aEvent);
|
||||
}
|
||||
}
|
||||
|
||||
var gActionDescrMap =
|
||||
{
|
||||
jump: "Jump",
|
||||
press: "Press",
|
||||
check: "Check",
|
||||
uncheck: "Uncheck",
|
||||
select: "Select",
|
||||
open: "Open",
|
||||
close: "Close",
|
||||
switch: "Switch",
|
||||
click: "Click",
|
||||
collapse: "Collapse",
|
||||
expand: "Expand",
|
||||
activate: "Activate",
|
||||
cycle: "Cycle"
|
||||
};
|
||||
|
@ -328,6 +328,14 @@ function getApplicationAccessible()
|
||||
QueryInterface(nsIAccessibleApplication);
|
||||
}
|
||||
|
||||
/**
|
||||
* A version of accessible tree testing, doesn't fail if tree is not complete.
|
||||
*/
|
||||
function testElm(aID, aTreeObj)
|
||||
{
|
||||
testAccessibleTree(aID, aTreeObj, kSkipTreeFullCheck);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flags used for testAccessibleTree
|
||||
*/
|
||||
@ -370,11 +378,7 @@ function testAccessibleTree(aAccOrElmOrID, aAccTree, aFlags)
|
||||
|
||||
switch (prop) {
|
||||
case "actions": {
|
||||
var actions = (typeof accTree.actions == "string") ?
|
||||
[ accTree.actions ] : (accTree.actions || []);
|
||||
is(acc.actionCount, actions.length, "Wong number of actions.");
|
||||
for (var i = 0; i < actions.length; i++ )
|
||||
is(acc.getActionName(i), actions[i], "Wrong action name at " + i + " index.");
|
||||
testActionNames(acc, accTree.actions);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../actions.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
@ -22,11 +24,6 @@
|
||||
src="../name.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function testElm(aID, aTreeObj)
|
||||
{
|
||||
testAccessibleTree(aID, aTreeObj, kSkipTreeFullCheck);
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -28,7 +28,6 @@
|
||||
|
||||
function doTests()
|
||||
{
|
||||
|
||||
if (MAC) {
|
||||
todo(false, "Make these tests pass on OSX (bug 650294)");
|
||||
SimpleTest.finish();
|
||||
@ -38,10 +37,11 @@
|
||||
gQueue = new eventQueue(EVENT_TEXT_CARET_MOVED);
|
||||
|
||||
var id = "textbox";
|
||||
gQueue.push(new synthFocus(id, new caretMoveChecker(5, id)));
|
||||
gQueue.push(new synthSelectAll(id, new caretMoveChecker(5, id)));
|
||||
gQueue.push(new synthHomeKey(id, new caretMoveChecker(0, id)));
|
||||
gQueue.push(new synthRightKey(id, new caretMoveChecker(1, id)));
|
||||
var input = getNode(id).inputField;
|
||||
gQueue.push(new synthFocus(id, new caretMoveChecker(5, input)));
|
||||
gQueue.push(new synthSelectAll(id, new caretMoveChecker(5, input)));
|
||||
gQueue.push(new synthHomeKey(id, new caretMoveChecker(0, input)));
|
||||
gQueue.push(new synthRightKey(id, new caretMoveChecker(1, input)));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
@ -38,8 +38,10 @@
|
||||
// Test focus events.
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new synthFocus("textbox"));
|
||||
gQueue.push(new synthFocus("textbox_multiline"));
|
||||
gQueue.push(new synthFocus("textbox",
|
||||
new focusChecker(getNode("textbox").inputField)));
|
||||
gQueue.push(new synthFocus("textbox_multiline",
|
||||
new focusChecker(getNode("textbox_multiline").inputField)));
|
||||
gQueue.push(new synthFocus("scale"));
|
||||
gQueue.push(new synthFocusOnFrame("editabledoc"));
|
||||
gQueue.push(new synthFocus("radioclothes",
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
<script type="application/javascript">
|
||||
//gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true; // debug stuff
|
||||
gA11yEventDumpToConsole = true; // debug stuff
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
|
@ -36,10 +36,11 @@
|
||||
// Test focus events.
|
||||
gQueue = new eventQueue();
|
||||
|
||||
var textbox = getNode("textbox").inputField;
|
||||
gQueue.push(new synthClick("tab1", new focusChecker("tab1")));
|
||||
gQueue.push(new synthTab("tab1", new focusChecker("checkbox1")));
|
||||
gQueue.push(new synthKey("tab1", "VK_TAB", { ctrlKey: true },
|
||||
new focusChecker("textbox")));
|
||||
new focusChecker(textbox)));
|
||||
gQueue.push(new synthKey("tab2", "VK_TAB", { ctrlKey: true },
|
||||
new focusChecker("tab3")));
|
||||
gQueue.push(new synthKey("tab3", "VK_TAB", { ctrlKey: true },
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// aria-labelledby
|
||||
|
||||
|
||||
// Single relation. The value of 'aria-labelledby' contains the ID of
|
||||
// an element. Gets the name from text node of that element.
|
||||
testName("btn_labelledby_text", "text");
|
||||
|
@ -18,11 +18,16 @@
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
function getInput(aID)
|
||||
{
|
||||
return getNode(aID).inputField;
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ordinary textbox
|
||||
testStates("textbox",
|
||||
testStates(getInput("textbox"),
|
||||
STATE_FOCUSABLE,
|
||||
EXT_STATE_EDITABLE,
|
||||
STATE_PROTECTED | STATE_UNAVAILABLE,
|
||||
@ -31,7 +36,7 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Password textbox
|
||||
testStates("password",
|
||||
testStates(getInput("password"),
|
||||
STATE_FOCUSABLE | STATE_PROTECTED,
|
||||
EXT_STATE_EDITABLE,
|
||||
STATE_UNAVAILABLE,
|
||||
@ -40,7 +45,7 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Textarea
|
||||
testStates("textarea",
|
||||
testStates(getInput("textarea"),
|
||||
STATE_FOCUSABLE,
|
||||
EXT_STATE_EDITABLE | EXT_STATE_MULTI_LINE,
|
||||
STATE_PROTECTED | STATE_UNAVAILABLE,
|
||||
@ -49,7 +54,7 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Readonly textbox
|
||||
testStates("readonly_textbox",
|
||||
testStates(getInput("readonly_textbox"),
|
||||
STATE_FOCUSABLE | STATE_READONLY,
|
||||
EXT_STATE_EDITABLE,
|
||||
STATE_PROTECTED | STATE_UNAVAILABLE,
|
||||
@ -58,7 +63,7 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Disabled textbox
|
||||
testStates("disabled_textbox",
|
||||
testStates(getInput("disabled_textbox"),
|
||||
STATE_UNAVAILABLE,
|
||||
EXT_STATE_EDITABLE,
|
||||
STATE_FOCUSABLE | STATE_PROTECTED,
|
||||
@ -67,7 +72,7 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Readonly textarea
|
||||
testStates("readonly_textarea",
|
||||
testStates(getInput("readonly_textarea"),
|
||||
STATE_FOCUSABLE | STATE_READONLY,
|
||||
EXT_STATE_EDITABLE | EXT_STATE_MULTI_LINE,
|
||||
STATE_PROTECTED | STATE_UNAVAILABLE,
|
||||
@ -76,7 +81,7 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Disabled textarea
|
||||
testStates("disabled_textarea",
|
||||
testStates(getInput("disabled_textarea"),
|
||||
STATE_UNAVAILABLE,
|
||||
EXT_STATE_EDITABLE| EXT_STATE_MULTI_LINE,
|
||||
STATE_PROTECTED | STATE_FOCUSABLE,
|
||||
@ -86,7 +91,7 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Search textbox without search button, searches as you type and filters
|
||||
// a separate control.
|
||||
testStates("searchbox",
|
||||
testStates(getInput("searchbox"),
|
||||
STATE_FOCUSABLE,
|
||||
EXT_STATE_EDITABLE | EXT_STATE_SUPPORTS_AUTOCOMPLETION,
|
||||
STATE_PROTECTED | STATE_UNAVAILABLE,
|
||||
@ -95,7 +100,7 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Search textbox with search button, does not support autoCompletion.
|
||||
testStates("searchfield",
|
||||
testStates(getInput("searchfield"),
|
||||
STATE_FOCUSABLE,
|
||||
EXT_STATE_EDITABLE,
|
||||
STATE_PROTECTED | STATE_UNAVAILABLE,
|
||||
|
@ -1,33 +0,0 @@
|
||||
function testValue(aID, aAcc, aValue, aRole)
|
||||
{
|
||||
is(aAcc.value, aValue, "Wrong value for " + aID + "!");
|
||||
}
|
||||
|
||||
function testAction(aID, aAcc, aActionCount, aActionName, aActionDescription)
|
||||
{
|
||||
var actionCount = aAcc.actionCount;
|
||||
is(actionCount, aActionCount, "Wrong number of actions for " + aID + "!");
|
||||
|
||||
if (actionCount != 0) {
|
||||
// Test first action. Normally only 1 should be present.
|
||||
is(aAcc.getActionName(0), aActionName,
|
||||
"Wrong name of action for " + aID + "!");
|
||||
is(aAcc.getActionDescription(0), aActionDescription,
|
||||
"Wrong description of action for " + aID + "!");
|
||||
}
|
||||
}
|
||||
|
||||
function testThis(aID, aName, aValue, aDescription, aRole,
|
||||
aActionCount, aActionName, aActionDescription)
|
||||
{
|
||||
var acc = getAccessible(aID);
|
||||
if (!acc)
|
||||
return;
|
||||
|
||||
is(acc.name, aName, "Wrong name for " + aID + "!");
|
||||
testValue(aID, acc, aValue, aRole);
|
||||
is(acc.description, aDescription, "Wrong description for " + aID + "!");
|
||||
testRole(aID, aRole);
|
||||
|
||||
testAction(aID, acc, aActionCount, aActionName, aActionDescription);
|
||||
}
|
@ -1,164 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=442648
|
||||
-->
|
||||
<head>
|
||||
<title>nsIAccessible textboxes chrome tests</title>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="states.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="testTextboxes.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// normal textbox without content and with no proper label
|
||||
testThis("unlabelled_Textbox", // ID
|
||||
null, // name
|
||||
"", // value
|
||||
"", // description
|
||||
ROLE_ENTRY, // role
|
||||
1, // actionCount
|
||||
"activate", // ActionName
|
||||
"Activate"); // ActionDescription
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// normal textbox without content and with a proper label
|
||||
testThis("labelled_textbox", // ID
|
||||
"Second textbox:", // name
|
||||
"", // value
|
||||
"", // description
|
||||
ROLE_ENTRY, // role
|
||||
1, // actionCount
|
||||
"activate", // ActionName
|
||||
"Activate"); // ActionDescription
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// normal textbox with content and with a proper label
|
||||
testThis("prefilled_textbox", // ID
|
||||
"Textbox with predefined value:", // name
|
||||
"I have some text", // value
|
||||
"", // description
|
||||
ROLE_ENTRY, // role
|
||||
1, // actionCount
|
||||
"activate", // ActionName
|
||||
"Activate"); // ActionDescription
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// password textbox with a proper label
|
||||
testThis("password_textbox", // ID
|
||||
"Enter some password here:", // name
|
||||
"", // value
|
||||
"", // description
|
||||
ROLE_PASSWORD_TEXT, // role
|
||||
1, // actionCount
|
||||
"activate", // ActionName
|
||||
"Activate"); // ActionDescription
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// textarea without content and label
|
||||
testThis("unlabelled_Textarea", // ID
|
||||
null, // name
|
||||
"", // value
|
||||
"", // description
|
||||
ROLE_ENTRY, // role
|
||||
1, // actionCount
|
||||
"activate", // ActionName
|
||||
"Activate"); // ActionDescription
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// textarea without content and with proper label
|
||||
testThis("labelled_textarea", // ID
|
||||
"Labelled textarea:", // name
|
||||
"", // value
|
||||
"", // description
|
||||
ROLE_ENTRY, // role
|
||||
1, // actionCount
|
||||
"activate", // ActionName
|
||||
"Activate"); // ActionDescription
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// textarea with content and with proper label
|
||||
testThis("prefilled_textarea", // ID
|
||||
"Pre-filled textarea:", // name
|
||||
" I also have some text.\n ", // value
|
||||
"", // description
|
||||
ROLE_ENTRY, // role
|
||||
1, // actionCount
|
||||
"activate", // ActionName
|
||||
"Activate"); // ActionDescription
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// readonly textbox with content and with proper label
|
||||
testThis("readonly_textbox", // ID
|
||||
"The following is a read-only textbox:", // name
|
||||
"You cannot change me.", // value
|
||||
"", // description
|
||||
ROLE_ENTRY, // role
|
||||
1, // actionCount
|
||||
"activate", // ActionName
|
||||
"Activate"); // ActionDescription
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// readonly textarea with content and with proper label
|
||||
testThis("readonly_textarea", // ID
|
||||
"This textarea is readonly, too:", // name
|
||||
" You cannot change me, either.\n ", // value
|
||||
"", // description
|
||||
ROLE_ENTRY, // role
|
||||
1, // actionCount
|
||||
"activate", // ActionName
|
||||
"Activate"); // ActionDescription
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=442648">Mozilla Bug 442648</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<form action="test.php" method="post">
|
||||
Text before input without labelling it:
|
||||
<input type="text" name="unlabelled_Textbox" id="unlabelled_Textbox" size="50"/>
|
||||
<br><label for="labelled_textbox">Second textbox:</label>
|
||||
<input type="text" name="labelled_Textbox" id="labelled_textbox"/>
|
||||
<br><label for="prefilled_textbox">Textbox with predefined value:</label>
|
||||
<input type="text" name="prefilled_Textbox" id="prefilled_textbox" value="I have some text" size="80"/>
|
||||
<br><label for="password_textbox">Enter some password here:</label>
|
||||
<input type="password" name="password_Textbox" id="password_textbox"/>
|
||||
<br>Textarea without label:<br>
|
||||
<textarea id="unlabelled_Textarea" name="unlabelled_Textarea" cols="80" rows="5"></textarea>
|
||||
<br><label for="labelled_textarea">Labelled textarea:</label><br>
|
||||
<textarea id="labelled_textarea" name="labelled_Textarea" cols="80" rows="5"></textarea>
|
||||
<br><label for="prefilled_textarea">Pre-filled textarea:</label><br>
|
||||
<textarea id="prefilled_textarea" name="prefilled_Textarea" cols="80" rows="5">
|
||||
I also have some text.
|
||||
</textarea>
|
||||
<br><label for="readonly_textbox">The following is a read-only textbox:</label>
|
||||
<input type="text" readonly="true" name="readonly_Textbox" id="readonly_textbox" value="You cannot change me."/>
|
||||
<br><label for="readonly_textarea">This textarea is readonly, too:</label><br>
|
||||
<textarea name="readonly_Textarea" id="readonly_textarea" readonly="true" cols="80" rows="5">
|
||||
You cannot change me, either.
|
||||
</textarea>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -1,217 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="nsIAccessible XUL textboxes chrome tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="common.js" />
|
||||
<script type="application/javascript"
|
||||
src="role.js" />
|
||||
<script type="application/javascript"
|
||||
src="states.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="testTextboxes.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
function doTest()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// normal textbox without content and with no proper label
|
||||
testThis("unlabelled_Textbox", // ID
|
||||
null, // name
|
||||
"", // value
|
||||
"", // description
|
||||
ROLE_ENTRY, // role
|
||||
1, // actionCount
|
||||
"activate", // ActionName
|
||||
"Activate"); // ActionDescription
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// normal textbox without content and with a proper label
|
||||
testThis("labelled_textbox", // ID
|
||||
"Second textbox:", // name
|
||||
"", // value
|
||||
"", // description
|
||||
ROLE_ENTRY, // role
|
||||
1, // actionCount
|
||||
"activate", // ActionName
|
||||
"Activate"); // ActionDescription
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// normal textbox with content and with a proper label
|
||||
testThis("prefilled_textbox", // ID
|
||||
"Textbox with predefined value:", // name
|
||||
"I have some text", // value
|
||||
"", // description
|
||||
ROLE_ENTRY, // role
|
||||
1, // actionCount
|
||||
"activate", // ActionName
|
||||
"Activate"); // ActionDescription
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// password textbox with a proper label
|
||||
testThis("password_textbox", // ID
|
||||
"Enter some password here:", // name
|
||||
"", // value
|
||||
"", // description
|
||||
ROLE_PASSWORD_TEXT, // role
|
||||
1, // actionCount
|
||||
"activate", // ActionName
|
||||
"Activate"); // ActionDescription
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// textarea without content and label
|
||||
testThis("unlabelled_Textarea", // ID
|
||||
null, // name
|
||||
"", // value
|
||||
"", // description
|
||||
ROLE_ENTRY, // role
|
||||
1, // actionCount
|
||||
"activate", // ActionName
|
||||
"Activate"); // ActionDescription
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// textarea without content and with proper label
|
||||
testThis("labelled_textarea", // ID
|
||||
"Labelled textarea:", // name
|
||||
"", // value
|
||||
"", // description
|
||||
ROLE_ENTRY, // role
|
||||
1, // actionCount
|
||||
"activate", // ActionName
|
||||
"Activate"); // ActionDescription
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// textarea with content and with proper label
|
||||
testThis("prefilled_textarea", // ID
|
||||
"Pre-filled textarea:", // name
|
||||
"I also have some text.", // value
|
||||
"", // description
|
||||
ROLE_ENTRY, // role
|
||||
1, // actionCount
|
||||
"activate", // ActionName
|
||||
"Activate"); // ActionDescription
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// readonly textbox with content and with proper label
|
||||
testThis("readonly_textbox", // ID
|
||||
"The following is a read-only textbox:", // name
|
||||
"You cannot change me.", // value
|
||||
"", // description
|
||||
ROLE_ENTRY, // role
|
||||
1, // actionCount
|
||||
"activate", // ActionName
|
||||
"Activate"); // ActionDescription
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// readonly textarea with content and with proper label
|
||||
testThis("readonly_textarea", // ID
|
||||
"This textarea is readonly, too:", // name
|
||||
"You cannot change me, either.", // value
|
||||
"", // description
|
||||
ROLE_ENTRY, // role
|
||||
1, // actionCount
|
||||
"activate", // ActionName
|
||||
"Activate"); // ActionDescription
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Search textbox without search button, searches as you type and filters
|
||||
// a separate control.
|
||||
testThis("search-box", // ID
|
||||
"Search History:", // name
|
||||
"", // value
|
||||
"", // description
|
||||
ROLE_ENTRY, // role
|
||||
1, // actionCount
|
||||
"activate", // ActionName
|
||||
"Activate"); // ActionDescription
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Search textbox with search button, does not support autoCompletion.
|
||||
testThis("searchfield", // ID
|
||||
"Search all add-ons", // name
|
||||
"", // value
|
||||
"", // description
|
||||
ROLE_ENTRY, // role
|
||||
1, // actionCount
|
||||
"activate", // ActionName
|
||||
"Activate"); // ActionDescription
|
||||
testStates("searchfield", 0, 0, 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=442648">
|
||||
Mozilla Bug 442648
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox>
|
||||
<hbox>
|
||||
<label value="Text before input without labelling it:"/>
|
||||
<textbox id="unlabelled_Textbox" size="50"/>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<label control="labelled_textbox">Second textbox:</label>
|
||||
<textbox id="labelled_textbox"/>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<label control="prefilled_textbox">Textbox with predefined value:</label>
|
||||
<textbox id="prefilled_textbox" value="I have some text" size="80"/>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<label control="password_textbox">Enter some password here:</label>
|
||||
<textbox type="password" id="password_textbox"/>
|
||||
</hbox>
|
||||
<vbox>
|
||||
<label value="Textarea without label:"/>
|
||||
<textbox multiline="true" id="unlabelled_Textarea" cols="80" rows="5"/>
|
||||
</vbox>
|
||||
<vbox>
|
||||
<label control="labelled_textarea">Labelled textarea:</label>
|
||||
<textbox multiline="true" id="labelled_textarea" cols="80" rows="5"/>
|
||||
</vbox>
|
||||
<vbox>
|
||||
<label control="prefilled_textarea">Pre-filled textarea:</label>
|
||||
<textbox multiline="true" id="prefilled_textarea" cols="80" rows="5"
|
||||
value="I also have some text."/>
|
||||
</vbox>
|
||||
<hbox>
|
||||
<label control="readonly_textbox">The following is a read-only textbox:</label>
|
||||
<textbox readonly="true" id="readonly_textbox"
|
||||
value="You cannot change me."/>
|
||||
</hbox>
|
||||
<vbox>
|
||||
<label control="readonly_textarea">This textarea is readonly, too:</label>
|
||||
<textbox multiline="true" id="readonly_textarea" readonly="true" cols="80"
|
||||
rows="5" value="You cannot change me, either."/>
|
||||
</vbox>
|
||||
<hbox>
|
||||
<label value="Search History:" accesskey="S"
|
||||
control="search-box"/>
|
||||
<textbox id="search-box" flex="1" type="search"
|
||||
results="historyTree"/>
|
||||
</hbox>
|
||||
<textbox id="searchfield" placeholder="Search all add-ons"
|
||||
type="search" searchbutton="true"/>
|
||||
</vbox>
|
||||
</window>
|
@ -43,7 +43,7 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// XUL textbox
|
||||
|
||||
testTextAtOffset([ "tbox1" ], BOUNDARY_LINE_START,
|
||||
testTextAtOffset([ getNode("tbox1").inputField ], BOUNDARY_LINE_START,
|
||||
[ [ 0, 4, "test", 0, 4 ] ]);
|
||||
|
||||
SimpleTest.finish();
|
||||
|
@ -23,64 +23,68 @@
|
||||
|
||||
function doTest()
|
||||
{
|
||||
////////////////////
|
||||
// textbox
|
||||
////////////////////
|
||||
var accTree = {
|
||||
role: ROLE_ENTRY,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_TEXT_LEAF,
|
||||
children: []
|
||||
}
|
||||
]
|
||||
};
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// textboxes
|
||||
|
||||
var accTree =
|
||||
{ SECTION: [
|
||||
{ ENTRY: [ { TEXT_LEAF: [] } ] },
|
||||
{ MENUPOPUP: [] }
|
||||
] };
|
||||
|
||||
// default textbox
|
||||
testAccessibleTree("txc1", accTree);
|
||||
testAccessibleTree("txc", accTree);
|
||||
|
||||
// number textbox
|
||||
testAccessibleTree("txc2", accTree);
|
||||
// multiline
|
||||
testAccessibleTree("txc_multiline", accTree);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// search textbox
|
||||
testAccessibleTree("txc3", accTree);
|
||||
|
||||
// timed textbox
|
||||
testAccessibleTree("txc4_deprecated", accTree);
|
||||
if (MAC) {
|
||||
accTree =
|
||||
{ SECTION: [
|
||||
{ ENTRY: [ { TEXT_LEAF: [] } ] },
|
||||
{ MENUPOPUP: [] }
|
||||
] };
|
||||
} else {
|
||||
accTree =
|
||||
{ SECTION: [
|
||||
{ ENTRY: [ { TEXT_LEAF: [] } ] },
|
||||
{ PUSHBUTTON: [] },
|
||||
{ MENUPOPUP: [] }
|
||||
] };
|
||||
}
|
||||
|
||||
////////////////////
|
||||
testAccessibleTree("txc_search", accTree);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// number textbox
|
||||
|
||||
accTree =
|
||||
{ SECTION: [
|
||||
{ ENTRY: [ { TEXT_LEAF: [] } ] },
|
||||
{ MENUPOPUP: [] },
|
||||
{ PUSHBUTTON: [] },
|
||||
{ PUSHBUTTON: [] }
|
||||
] };
|
||||
|
||||
testAccessibleTree("txc_number", accTree);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// password textbox
|
||||
////////////////////
|
||||
accTree = {
|
||||
role: ROLE_PASSWORD_TEXT,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_TEXT_LEAF,
|
||||
children: []
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
testAccessibleTree("txc5", accTree);
|
||||
accTree =
|
||||
{ SECTION: [
|
||||
{ PASSWORD_TEXT: [ { TEXT_LEAF: [] } ] },
|
||||
{ MENUPOPUP: [] }
|
||||
] };
|
||||
|
||||
////////////////////
|
||||
// multiline textbox
|
||||
////////////////////
|
||||
accTree = {
|
||||
role: ROLE_ENTRY,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_TEXT_LEAF,
|
||||
children: []
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree("txc_password", accTree);
|
||||
|
||||
testAccessibleTree("txc6", accTree);
|
||||
|
||||
////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// autocomplete textbox
|
||||
////////////////////
|
||||
|
||||
accTree = {
|
||||
// textbox
|
||||
role: ROLE_AUTOCOMPLETE,
|
||||
@ -104,14 +108,14 @@
|
||||
]
|
||||
};
|
||||
|
||||
function test_txc7() {
|
||||
testAccessibleTree("txc7", accTree);
|
||||
function test_AutocompleteControl() {
|
||||
testAccessibleTree("txc_autocomplete", accTree);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
// XPFE and Toolkit autocomplete widgets differ.
|
||||
var txc7 = document.getElementById("txc7");
|
||||
if ("clearResults" in txc7) {
|
||||
var txc = document.getElementById("txc_autocomplete");
|
||||
if ("clearResults" in txc) {
|
||||
SimpleTest.ok(true, "Testing (Old) XPFE autocomplete widget.");
|
||||
|
||||
// Popup is always created. (See code below.)
|
||||
@ -141,14 +145,14 @@
|
||||
]
|
||||
}
|
||||
);
|
||||
test_txc7();
|
||||
test_AutocompleteControl();
|
||||
|
||||
} else {
|
||||
SimpleTest.ok(true, "Testing (New) Toolkit autocomplete widget.");
|
||||
|
||||
// Dumb access to trigger popup lazy creation.
|
||||
waitForEvent(EVENT_REORDER, txc7, test_txc7);
|
||||
txc7.popup;
|
||||
waitForEvent(EVENT_REORDER, txc, test_AutocompleteControl);
|
||||
txc.popup;
|
||||
|
||||
accTree.children.push(
|
||||
{
|
||||
@ -189,15 +193,12 @@
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<textbox id="txc1" value="hello"/>
|
||||
<textbox id="txc2" type="number" value="44"/>
|
||||
<textbox id="txc3" type="search" value="hello"/>
|
||||
<!-- This textbox triggers "Warning: Timed textboxes are deprecated. Consider using type="search" instead.".
|
||||
Yet let's test it too as long as it's (still) supported. -->
|
||||
<textbox id="txc4_deprecated" type="timed" value="hello"/>
|
||||
<textbox id="txc5" type="password" value="hello"/>
|
||||
<textbox id="txc6" multiline="true" value="hello"/>
|
||||
<textbox id="txc7" type="autocomplete" value="hello"/>
|
||||
<textbox id="txc" value="hello"/>
|
||||
<textbox id="txc_search" type="search" value="hello"/>
|
||||
<textbox id="txc_number" type="number" value="44"/>
|
||||
<textbox id="txc_password" type="password" value="hello"/>
|
||||
<textbox id="txc_multiline" multiline="true" value="hello"/>
|
||||
<textbox id="txc_autocomplete" type="autocomplete" value="hello"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user