mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-10 01:08:21 +00:00
Bug 396166 - xul:label@value accessible should implement nsIAccessibleText, r=tbsaunde, roc
This commit is contained in:
parent
aa7f8f28f4
commit
68f9fb3d83
@ -52,6 +52,7 @@ enum AccType {
|
||||
eMenuPopupType,
|
||||
eProgressType,
|
||||
eRootType,
|
||||
eXULLabelType,
|
||||
eXULTabpanelsType,
|
||||
eXULTreeType,
|
||||
|
||||
|
@ -65,7 +65,7 @@ EnableLogging(const char* aModulesStr)
|
||||
size_t tokenLen = strcspn(token, ",");
|
||||
for (unsigned int idx = 0; idx < ArrayLength(sModuleMap); idx++) {
|
||||
if (strncmp(token, sModuleMap[idx].mStr, tokenLen) == 0) {
|
||||
#if !defined(MOZ_PROFILING) && (!defined(MOZ_DEBUG) || defined(MOZ_OPTIMIZE))
|
||||
#if !defined(MOZ_PROFILING) && (!defined(DEBUG) || defined(MOZ_OPTIMIZE))
|
||||
// Stack tracing on profiling enabled or debug not optimized builds.
|
||||
if (strncmp(token, "stack", tokenLen) == 0)
|
||||
break;
|
||||
|
@ -402,6 +402,24 @@ nsAccessibilityService::UpdateImageMap(nsImageFrame* aImageFrame)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsAccessibilityService::UpdateLabelValue(nsIPresShell* aPresShell,
|
||||
nsIContent* aLabelElm,
|
||||
const nsString& aNewValue)
|
||||
{
|
||||
DocAccessible* document = GetDocAccessible(aPresShell);
|
||||
if (document) {
|
||||
Accessible* accessible = document->GetAccessible(aLabelElm);
|
||||
if (accessible) {
|
||||
XULLabelAccessible* xulLabel = accessible->AsXULLabel();
|
||||
NS_ASSERTION(xulLabel,
|
||||
"UpdateLabelValue was called for wrong accessible!");
|
||||
if (xulLabel)
|
||||
xulLabel->UpdateLabelValue(aNewValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsAccessibilityService::PresShellActivated(nsIPresShell* aPresShell)
|
||||
{
|
||||
|
@ -104,6 +104,12 @@ public:
|
||||
*/
|
||||
void UpdateImageMap(nsImageFrame* aImageFrame);
|
||||
|
||||
/**
|
||||
* Update the label accessible tree when rendered @value is changed.
|
||||
*/
|
||||
void UpdateLabelValue(nsIPresShell* aPresShell, nsIContent* aLabelElm,
|
||||
const nsString& aNewValue);
|
||||
|
||||
/**
|
||||
* Notify accessibility that anchor jump has been accomplished to the given
|
||||
* target. Used by layout.
|
||||
|
@ -46,6 +46,7 @@ class Relation;
|
||||
class TableAccessible;
|
||||
class TableCellAccessible;
|
||||
class TextLeafAccessible;
|
||||
class XULLabelAccessible;
|
||||
class XULTreeAccessible;
|
||||
|
||||
/**
|
||||
@ -523,6 +524,9 @@ public:
|
||||
bool IsTextLeaf() const { return mType == eTextLeafType; }
|
||||
TextLeafAccessible* AsTextLeaf();
|
||||
|
||||
bool IsXULLabel() const { return mType == eXULLabelType; }
|
||||
XULLabelAccessible* AsXULLabel();
|
||||
|
||||
bool IsXULTabpanels() const { return mType == eXULTabpanelsType; }
|
||||
|
||||
bool IsXULTree() const { return mType == eXULTreeType; }
|
||||
@ -892,7 +896,7 @@ protected:
|
||||
|
||||
static const uint8_t kChildrenFlagsBits = 2;
|
||||
static const uint8_t kStateFlagsBits = 5;
|
||||
static const uint8_t kTypeBits = 5;
|
||||
static const uint8_t kTypeBits = 6;
|
||||
static const uint8_t kGenericTypesBits = 12;
|
||||
|
||||
/**
|
||||
|
@ -7,18 +7,25 @@
|
||||
|
||||
#include "Accessible-inl.h"
|
||||
#include "BaseAccessibles.h"
|
||||
#include "DocAccessible-inl.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "nsCoreUtils.h"
|
||||
#include "nsTextEquivUtils.h"
|
||||
#include "Relation.h"
|
||||
#include "Role.h"
|
||||
#include "States.h"
|
||||
#include "TextUpdater.h"
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
#include "Logging.h"
|
||||
#endif
|
||||
|
||||
#include "nsIAccessibleRelation.h"
|
||||
#include "nsIDOMXULDescriptionElement.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsString.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTextBoxFrame.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
@ -30,6 +37,31 @@ XULLabelAccessible::
|
||||
XULLabelAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
HyperTextAccessibleWrap(aContent, aDoc)
|
||||
{
|
||||
mType = eXULLabelType;
|
||||
|
||||
// If @value attribute is given then it's rendered instead text content. In
|
||||
// this case we need to create a text leaf accessible to make @value attribute
|
||||
// accessible.
|
||||
// XXX: text interface doesn't let you get the text by words.
|
||||
nsTextBoxFrame* textBoxFrame = do_QueryFrame(mContent->GetPrimaryFrame());
|
||||
if (textBoxFrame) {
|
||||
mValueTextLeaf = new XULLabelTextLeafAccessible(mContent, mDoc);
|
||||
if (mDoc->BindToDocument(mValueTextLeaf, nullptr)) {
|
||||
nsAutoString text;
|
||||
textBoxFrame->GetCroppedTitle(text);
|
||||
mValueTextLeaf->SetText(text);
|
||||
return;
|
||||
}
|
||||
|
||||
mValueTextLeaf = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XULLabelAccessible::Shutdown()
|
||||
{
|
||||
mValueTextLeaf = nullptr;
|
||||
HyperTextAccessibleWrap::Shutdown();
|
||||
}
|
||||
|
||||
ENameValueFlag
|
||||
@ -37,7 +69,9 @@ XULLabelAccessible::NativeName(nsString& aName)
|
||||
{
|
||||
// if the value attr doesn't exist, the screen reader must get the accessible text
|
||||
// from the accessible text interface or from the children
|
||||
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, aName);
|
||||
if (mValueTextLeaf)
|
||||
return mValueTextLeaf->Name(aName);
|
||||
|
||||
return eNameOK;
|
||||
}
|
||||
|
||||
@ -72,6 +106,53 @@ XULLabelAccessible::RelationByType(uint32_t aType)
|
||||
return rel;
|
||||
}
|
||||
|
||||
void
|
||||
XULLabelAccessible::UpdateLabelValue(const nsString& aValue)
|
||||
{
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eText)) {
|
||||
logging::MsgBegin("TEXT", "text may be changed (xul:label @value update)");
|
||||
logging::Node("container", mContent);
|
||||
logging::MsgEntry("old text '%s'",
|
||||
NS_ConvertUTF16toUTF8(mValueTextLeaf->Text()).get());
|
||||
logging::MsgEntry("new text: '%s'",
|
||||
NS_ConvertUTF16toUTF8(aValue).get());
|
||||
logging::MsgEnd();
|
||||
}
|
||||
#endif
|
||||
|
||||
TextUpdater::Run(mDoc, mValueTextLeaf, aValue);
|
||||
}
|
||||
|
||||
void
|
||||
XULLabelAccessible::CacheChildren()
|
||||
{
|
||||
if (mValueTextLeaf) {
|
||||
AppendChild(mValueTextLeaf);
|
||||
return;
|
||||
}
|
||||
|
||||
// Cache children from subtree.
|
||||
AccessibleWrap::CacheChildren();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// XULLabelTextLeafAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
role
|
||||
XULLabelTextLeafAccessible::NativeRole()
|
||||
{
|
||||
return roles::TEXT_LEAF;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
XULLabelTextLeafAccessible::NativeState()
|
||||
{
|
||||
return TextLeafAccessibleWrap::NativeState() | states::READONLY;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// XULTooltipAccessible
|
||||
|
@ -6,12 +6,14 @@
|
||||
#ifndef mozilla_a11y_XULElementAccessibles_h__
|
||||
#define mozilla_a11y_XULElementAccessibles_h__
|
||||
|
||||
#include "BaseAccessibles.h"
|
||||
#include "HyperTextAccessibleWrap.h"
|
||||
#include "TextLeafAccessibleWrap.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class XULLabelTextLeafAccessible;
|
||||
|
||||
/**
|
||||
* Used for XUL description and label elements.
|
||||
*/
|
||||
@ -21,15 +23,48 @@ public:
|
||||
XULLabelAccessible(nsIContent* aContent, DocAccessible* aDoc);
|
||||
|
||||
// Accessible
|
||||
virtual void Shutdown();
|
||||
virtual a11y::role NativeRole();
|
||||
virtual uint64_t NativeState();
|
||||
virtual Relation RelationByType(uint32_t aRelationType);
|
||||
|
||||
void UpdateLabelValue(const nsString& aValue);
|
||||
|
||||
protected:
|
||||
// Accessible
|
||||
virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
|
||||
virtual void CacheChildren() MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
nsRefPtr<XULLabelTextLeafAccessible> mValueTextLeaf;
|
||||
};
|
||||
|
||||
inline XULLabelAccessible*
|
||||
Accessible::AsXULLabel()
|
||||
{
|
||||
return IsXULLabel() ? static_cast<XULLabelAccessible*>(this) : nullptr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to implement text interface on XUL label accessible in case when text
|
||||
* is provided by @value attribute (no underlying text frame).
|
||||
*/
|
||||
class XULLabelTextLeafAccessible MOZ_FINAL : public TextLeafAccessibleWrap
|
||||
{
|
||||
public:
|
||||
XULLabelTextLeafAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
TextLeafAccessibleWrap(aContent, aDoc)
|
||||
{ mStateFlags |= eSharedNode; }
|
||||
|
||||
virtual ~XULLabelTextLeafAccessible() { }
|
||||
|
||||
// Accessible
|
||||
virtual a11y::role NativeRole() MOZ_OVERRIDE;
|
||||
virtual uint64_t NativeState() MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Used for XUL tooltip element.
|
||||
*/
|
||||
|
@ -582,13 +582,13 @@ function getTextFromClipboard()
|
||||
var clip = Components.classes["@mozilla.org/widget/clipboard;1"].
|
||||
getService(Components.interfaces.nsIClipboard);
|
||||
if (!clip)
|
||||
return;
|
||||
return "";
|
||||
|
||||
var trans = Components.classes["@mozilla.org/widget/transferable;1"].
|
||||
createInstance(Components.interfaces.nsITransferable);
|
||||
trans.init(getLoadContext());
|
||||
if (!trans)
|
||||
return;
|
||||
return "";
|
||||
|
||||
trans.addDataFlavor("text/unicode");
|
||||
clip.getData(trans, clip.kGlobalClipboard);
|
||||
|
@ -1548,16 +1548,21 @@ function textChangeChecker(aID, aStart, aEnd, aTextOrFunc, aIsInserted, aFromUse
|
||||
{
|
||||
this.target = getNode(aID);
|
||||
this.type = aIsInserted ? EVENT_TEXT_INSERTED : EVENT_TEXT_REMOVED;
|
||||
this.startOffset = aStart;
|
||||
this.endOffset = aEnd;
|
||||
this.textOrFunc = aTextOrFunc;
|
||||
|
||||
this.check = function textChangeChecker_check(aEvent)
|
||||
{
|
||||
aEvent.QueryInterface(nsIAccessibleTextChangeEvent);
|
||||
|
||||
var modifiedText = (typeof aTextOrFunc == "function") ?
|
||||
aTextOrFunc() : aTextOrFunc;
|
||||
var modifiedTextLen = (aEnd == -1) ? modifiedText.length : aEnd - aStart;
|
||||
var modifiedText = (typeof this.textOrFunc == "function") ?
|
||||
this.textOrFunc() : this.textOrFunc;
|
||||
var modifiedTextLen =
|
||||
(this.endOffset == -1) ? modifiedText.length : aEnd - aStart;
|
||||
|
||||
is(aEvent.start, aStart, "Wrong start offset for " + prettyName(aID));
|
||||
is(aEvent.start, this.startOffset,
|
||||
"Wrong start offset for " + prettyName(aID));
|
||||
is(aEvent.length, modifiedTextLen, "Wrong length for " + prettyName(aID));
|
||||
var changeInfo = (aIsInserted ? "inserted" : "removed");
|
||||
is(aEvent.isInserted(), aIsInserted,
|
||||
|
@ -46,6 +46,7 @@ MOCHITEST_A11Y_FILES =\
|
||||
test_focus_tabbox.xul \
|
||||
test_focus_tree.xul \
|
||||
test_fromUserInput.html \
|
||||
test_label.xul \
|
||||
test_menu.xul \
|
||||
test_mutation.html \
|
||||
test_mutation.xhtml \
|
||||
|
177
accessible/tests/mochitest/events/test_label.xul
Normal file
177
accessible/tests/mochitest/events/test_label.xul
Normal file
@ -0,0 +1,177 @@
|
||||
<?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="Tests: accessible XUL label/description events">
|
||||
|
||||
<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="../events.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
const kRecreated = 0;
|
||||
const kTextRemoved = 1;
|
||||
const kTextChanged = 2;
|
||||
|
||||
const kNoValue = 0;
|
||||
|
||||
/**
|
||||
* Set/remove @value attribute.
|
||||
*/
|
||||
function setValue(aID, aValue, aResult, aOldValue)
|
||||
{
|
||||
this.labelNode = getNode(aID);
|
||||
|
||||
this.eventSeq = [];
|
||||
|
||||
switch (aResult) {
|
||||
case kRecreated:
|
||||
this.eventSeq.push(new invokerChecker(EVENT_HIDE, this.labelNode));
|
||||
this.eventSeq.push(new invokerChecker(EVENT_SHOW, this.labelNode));
|
||||
break;
|
||||
case kTextRemoved:
|
||||
this.eventSeq.push(
|
||||
new textChangeChecker(this.labelNode, 0, aOldValue.length,
|
||||
aOldValue, false));
|
||||
break;
|
||||
case kTextChanged:
|
||||
this.eventSeq.push(
|
||||
new textChangeChecker(this.labelNode, 0, aOldValue.length,
|
||||
aOldValue, false));
|
||||
this.eventSeq.push(
|
||||
new textChangeChecker(this.labelNode, 0, aValue.length,
|
||||
aValue, true));
|
||||
break;
|
||||
}
|
||||
|
||||
this.invoke = function setValue_invoke()
|
||||
{
|
||||
if (aValue === kNoValue)
|
||||
this.labelNode.removeAttribute("value");
|
||||
else
|
||||
this.labelNode.setAttribute("value", aValue);
|
||||
}
|
||||
|
||||
this.finalCheck = function setValue_finalCheck()
|
||||
{
|
||||
var tree =
|
||||
{ LABEL: [
|
||||
{ TEXT_LEAF: [ ] }
|
||||
] };
|
||||
testAccessibleTree(aID, tree);
|
||||
}
|
||||
|
||||
this.getID = function setValue_getID()
|
||||
{
|
||||
return "set @value='" + aValue + "' for label " + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change @crop attribute.
|
||||
*/
|
||||
function setCrop(aID, aCropValue, aRemovedText, aInsertedText)
|
||||
{
|
||||
this.labelNode = getNode(aID);
|
||||
this.width = this.labelNode.boxObject.width;
|
||||
this.charWidth = this.width / this.labelNode.value.length;
|
||||
|
||||
this.eventSeq = [
|
||||
new textChangeChecker(this.labelNode, 0, -1, aRemovedText, false),
|
||||
new textChangeChecker(this.labelNode, 0, -1, aInsertedText, true)
|
||||
];
|
||||
|
||||
this.invoke = function setCrop_invoke()
|
||||
{
|
||||
if (!this.labelNode.hasAttribute("crop"))
|
||||
this.labelNode.width = Math.floor(this.width - 2 * this.charWidth);
|
||||
|
||||
this.labelNode.setAttribute("crop", aCropValue);
|
||||
}
|
||||
|
||||
this.getID = function setCrop_finalCheck()
|
||||
{
|
||||
return "set crop " + aCropValue;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
gA11yEventDumpToConsole = true;
|
||||
|
||||
var gQueue = null;
|
||||
function doTest()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new setValue("label", "shiroka strana", kRecreated));
|
||||
gQueue.push(new setValue("label", "?<>!+_", kTextChanged, "shiroka strana"));
|
||||
gQueue.push(new setValue("label", "", kTextRemoved, "?<>!+_"));
|
||||
gQueue.push(new setValue("label", kNoValue, kRecreated));
|
||||
|
||||
gQueue.push(new setValue("descr", "hello world", kRecreated));
|
||||
gQueue.push(new setValue("descr", "si_ya", kTextChanged, "hello world"));
|
||||
gQueue.push(new setValue("descr", "", kTextRemoved, "si_ya"));
|
||||
gQueue.push(new setValue("descr", kNoValue, kRecreated));
|
||||
|
||||
if (MAC) {
|
||||
// "valuetocro" -> "…etocro"
|
||||
gQueue.push(new setCrop("croplabel", "left", "valu", "…"));
|
||||
// "…etocro", "val…cro"
|
||||
gQueue.push(new setCrop("croplabel", "center", "…eto", "val…"));
|
||||
} else {
|
||||
// "valuetocro" -> "…uetocro"
|
||||
gQueue.push(new setCrop("croplabel", "left", "val", "…"));
|
||||
// "…uetocro" -> "valu…cro"
|
||||
gQueue.push(new setCrop("croplabel", "center", "…ueto", "valu…"));
|
||||
}
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=396166"
|
||||
title="xul:label@value accessible should implement nsIAccessibleText">
|
||||
Bug 396166
|
||||
</a>
|
||||
<br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<label id="label">hello</label>
|
||||
<description id="descr">hello</description>
|
||||
|
||||
<hbox>
|
||||
<label id="croplabel" value="valuetocro"
|
||||
style="font-family: monospace;"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
@ -15,6 +15,7 @@ MOCHITEST_A11Y_FILES = \
|
||||
doc.html \
|
||||
test_doc.html \
|
||||
test_hypertext.html \
|
||||
test_label.xul \
|
||||
test_passwords.html \
|
||||
test_selection.html \
|
||||
test_singleline.html \
|
||||
|
64
accessible/tests/mochitest/text/test_label.xul
Normal file
64
accessible/tests/mochitest/text/test_label.xul
Normal file
@ -0,0 +1,64 @@
|
||||
<?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="Tests: XUL label text interface">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../text.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Testing
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
var ids = ["label1", "label2"];
|
||||
|
||||
testCharacterCount(ids, 5);
|
||||
|
||||
testText(ids, 0, -1, "Hello");
|
||||
testText(ids, 0, 1, "H");
|
||||
|
||||
testCharAfterOffset(ids, 0, "e", 1, 2);
|
||||
testCharBeforeOffset(ids, 1, "H", 0, 1);
|
||||
testCharAtOffset(ids, 1, "e", 1, 2);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<vbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=396166"
|
||||
title="xul:label@value accessible should implement nsIAccessibleText">
|
||||
Bug 396166
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
<label id="label1" value="Hello"/>
|
||||
<label id="label2">Hello</label>
|
||||
</vbox>
|
||||
</window>
|
@ -21,20 +21,13 @@
|
||||
|
||||
function doTest()
|
||||
{
|
||||
var accTree = {
|
||||
role: ROLE_GROUPING,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_LABEL,
|
||||
children: [ ]
|
||||
},
|
||||
{
|
||||
role: ROLE_CHECKBUTTON,
|
||||
children: [ ]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
var accTree =
|
||||
{ GROUPING: [
|
||||
{ LABEL: [
|
||||
{ TEXT_LEAF: [ ] }
|
||||
] },
|
||||
{ CHECKBUTTON: [ ] }
|
||||
] };
|
||||
testAccessibleTree("groupbox", accTree);
|
||||
|
||||
SimpleTest.finish()
|
||||
|
@ -31,6 +31,10 @@
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
#include "nsAccessibilityService.h"
|
||||
#endif
|
||||
|
||||
#ifdef IBMBIDI
|
||||
#include "nsBidiUtils.h"
|
||||
#include "nsBidiPresUtils.h"
|
||||
@ -59,6 +63,9 @@ NS_NewTextBoxFrame (nsIPresShell* aPresShell, nsStyleContext* aContext)
|
||||
|
||||
NS_IMPL_FRAMEARENA_HELPERS(nsTextBoxFrame)
|
||||
|
||||
NS_QUERYFRAME_HEAD(nsTextBoxFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsTextBoxFrame)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsTextBoxFrameSuper)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextBoxFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||
@ -596,8 +603,10 @@ nsTextBoxFrame::CalculateTitleForWidth(nsPresContext* aPresContext,
|
||||
nsRenderingContext& aRenderingContext,
|
||||
nscoord aWidth)
|
||||
{
|
||||
if (mTitle.IsEmpty())
|
||||
if (mTitle.IsEmpty()) {
|
||||
mCroppedTitle.Truncate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsRefPtr<nsFontMetrics> fm;
|
||||
nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm));
|
||||
@ -993,6 +1002,17 @@ nsTextBoxFrame::CalcDrawRect(nsRenderingContext &aRenderingContext)
|
||||
// determine (cropped) title which fits in aRect.width and its width
|
||||
nscoord titleWidth =
|
||||
CalculateTitleForWidth(presContext, aRenderingContext, textRect.width);
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
// Make sure to update the accessible tree in case when cropped title is
|
||||
// changed.
|
||||
nsAccessibilityService* accService = GetAccService();
|
||||
if (accService) {
|
||||
accService->UpdateLabelValue(PresContext()->PresShell(), mContent,
|
||||
mCroppedTitle);
|
||||
}
|
||||
#endif
|
||||
|
||||
// determine if and at which position to put the underline
|
||||
UpdateAccessIndex();
|
||||
|
||||
|
@ -14,6 +14,8 @@ typedef nsLeafBoxFrame nsTextBoxFrameSuper;
|
||||
class nsTextBoxFrame : public nsTextBoxFrameSuper
|
||||
{
|
||||
public:
|
||||
NS_DECL_QUERYFRAME_TARGET(nsTextBoxFrame)
|
||||
NS_DECL_QUERYFRAME
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
|
||||
virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState);
|
||||
@ -59,6 +61,8 @@ public:
|
||||
|
||||
virtual bool ComputesOwnOverflowArea();
|
||||
|
||||
void GetCroppedTitle(nsString& aTitle) const { aTitle = mCroppedTitle; }
|
||||
|
||||
protected:
|
||||
friend class nsAsyncAccesskeyUpdate;
|
||||
friend class nsDisplayXULTextBox;
|
||||
|
Loading…
x
Reference in New Issue
Block a user