зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1616078: Don't use HTMLListBulletAccessible for CSS ::marker content. r=eeejay,emilio,MarcoZ
::marker content gets handled like text from any other CSS pseudo-class. Therefore, using HTMLListBulletAccessible ends up duplicating the content already exposed in the a11y tree. Now, we only use HTMLListBulletAccessible for nsBulletFrames instead of all marker frames. As part of this, remove nsContainerFrame::GetSpokenMarkerContent, since we no longer need it to retrieve ::marker content. The bulk of its other work was done by nsBulletFrame::GetSpokenContent, which we now call directly. It also handled producing a default bullet character for list-style-image, but it makes sense for this to live in the a11y code. Differential Revision: https://phabricator.services.mozilla.com/D63443 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
3e660d9274
Коммит
c604c6018c
|
@ -11,7 +11,7 @@
|
||||||
#include "Role.h"
|
#include "Role.h"
|
||||||
#include "States.h"
|
#include "States.h"
|
||||||
|
|
||||||
#include "nsContainerFrame.h"
|
#include "nsBulletFrame.h"
|
||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
@ -38,14 +38,13 @@ HTMLLIAccessible::HTMLLIAccessible(nsIContent* aContent, DocAccessible* aDoc)
|
||||||
: HyperTextAccessibleWrap(aContent, aDoc), mBullet(nullptr) {
|
: HyperTextAccessibleWrap(aContent, aDoc), mBullet(nullptr) {
|
||||||
mType = eHTMLLiType;
|
mType = eHTMLLiType;
|
||||||
|
|
||||||
if (nsIFrame* bulletFrame = nsLayoutUtils::GetMarkerFrame(aContent)) {
|
if (nsBulletFrame* bulletFrame =
|
||||||
if (const nsStyleList* styleList = bulletFrame->StyleList()) {
|
do_QueryFrame(nsLayoutUtils::GetMarkerFrame(aContent))) {
|
||||||
if (styleList->GetListStyleImage() ||
|
const nsStyleList* styleList = bulletFrame->StyleList();
|
||||||
!styleList->mCounterStyle.IsNone()) {
|
if (styleList->GetListStyleImage() || !styleList->mCounterStyle.IsNone()) {
|
||||||
mBullet = new HTMLListBulletAccessible(mContent, mDoc);
|
mBullet = new HTMLListBulletAccessible(mContent, mDoc);
|
||||||
Document()->BindToDocument(mBullet, nullptr);
|
Document()->BindToDocument(mBullet, nullptr);
|
||||||
AppendChild(mBullet);
|
AppendChild(mBullet);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,10 +136,20 @@ ENameValueFlag HTMLListBulletAccessible::Name(nsString& aName) const {
|
||||||
aName.Truncate();
|
aName.Truncate();
|
||||||
|
|
||||||
// Native anonymous content, ARIA can't be used. Get list bullet text.
|
// Native anonymous content, ARIA can't be used. Get list bullet text.
|
||||||
if (nsContainerFrame* frame = do_QueryFrame(mContent->GetPrimaryFrame())) {
|
nsBulletFrame* frame = do_QueryFrame(GetFrame());
|
||||||
frame->GetSpokenMarkerText(aName);
|
if (!frame) {
|
||||||
|
return eNameOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (frame->StyleList()->GetListStyleImage()) {
|
||||||
|
// Bullet is an image, so use default bullet character.
|
||||||
|
const char16_t kDiscCharacter = 0x2022;
|
||||||
|
aName.Assign(kDiscCharacter);
|
||||||
|
aName.Append(' ');
|
||||||
|
return eNameOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame->GetSpokenText(aName);
|
||||||
return eNameOK;
|
return eNameOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -166,6 +166,63 @@
|
||||||
|
|
||||||
testAccessibleTree("list10", tree);
|
testAccessibleTree("list10", tree);
|
||||||
|
|
||||||
|
// list-style-image
|
||||||
|
testAccessibleTree("list11", discAccTree);
|
||||||
|
|
||||||
|
// list-style: none
|
||||||
|
tree =
|
||||||
|
{ LIST: [ // ul
|
||||||
|
{ LISTITEM: [ // li
|
||||||
|
{ TEXT_LEAF: [] },
|
||||||
|
] },
|
||||||
|
{ LISTITEM: [ // li
|
||||||
|
{ TEXT_LEAF: [] },
|
||||||
|
] },
|
||||||
|
] };
|
||||||
|
testAccessibleTree("list12", tree);
|
||||||
|
|
||||||
|
// ::marker with content
|
||||||
|
tree = { // ol
|
||||||
|
role: ROLE_LIST,
|
||||||
|
children: [
|
||||||
|
{ // li
|
||||||
|
role: ROLE_LISTITEM,
|
||||||
|
children: [
|
||||||
|
{ // ::marker content text
|
||||||
|
role: ROLE_STATICTEXT,
|
||||||
|
name: "foo",
|
||||||
|
},
|
||||||
|
{ // ::marker content counter
|
||||||
|
role: ROLE_STATICTEXT,
|
||||||
|
name: "1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: ROLE_TEXT_LEAF,
|
||||||
|
name: "Oranges",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{ // li
|
||||||
|
role: ROLE_LISTITEM,
|
||||||
|
children: [
|
||||||
|
{ // ::marker content text
|
||||||
|
role: ROLE_STATICTEXT,
|
||||||
|
name: "foo",
|
||||||
|
},
|
||||||
|
{ // ::marker content counter
|
||||||
|
role: ROLE_STATICTEXT,
|
||||||
|
name: "2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: ROLE_TEXT_LEAF,
|
||||||
|
name: "Apples",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
testAccessibleTree("list13", tree);
|
||||||
|
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,5 +323,32 @@
|
||||||
<div><dt>item2</td><dd>description</dd></div>
|
<div><dt>item2</td><dd>description</dd></div>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
<!-- list-style-image -->
|
||||||
|
<ul id="list11"
|
||||||
|
style="list-style-type: none; list-style-image: url('../moz.png');">
|
||||||
|
<li>Oranges</li>
|
||||||
|
<li>Apples</li>
|
||||||
|
<li>Bananas</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!-- list-style: none -->
|
||||||
|
<ul id="list12" style="list-style: none;">
|
||||||
|
<li>Oranges</li>
|
||||||
|
<li>Apples</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!-- ::marker with content -->
|
||||||
|
<style>
|
||||||
|
#list13 li {
|
||||||
|
counter-increment: list13counter;
|
||||||
|
}
|
||||||
|
#list13 li::marker {
|
||||||
|
content: 'foo' counter(list13counter);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<ol id="list13">
|
||||||
|
<li>Oranges</li>
|
||||||
|
<li>Apples</li>
|
||||||
|
</ol>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1722,26 +1722,6 @@ StyleAlignFlags nsContainerFrame::CSSAlignmentForAbsPosChild(
|
||||||
return StyleAlignFlags::START;
|
return StyleAlignFlags::START;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ACCESSIBILITY
|
|
||||||
void nsContainerFrame::GetSpokenMarkerText(nsAString& aText) const {
|
|
||||||
aText.Truncate();
|
|
||||||
const nsStyleList* myList = StyleList();
|
|
||||||
if (myList->GetListStyleImage()) {
|
|
||||||
char16_t kDiscCharacter = 0x2022;
|
|
||||||
aText.Assign(kDiscCharacter);
|
|
||||||
aText.Append(' ');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (nsIFrame* marker = nsLayoutUtils::GetMarkerFrame(GetContent())) {
|
|
||||||
if (nsBulletFrame* bullet = do_QueryFrame(marker)) {
|
|
||||||
bullet->GetSpokenText(aText);
|
|
||||||
} else {
|
|
||||||
marker->GetContent()->GetTextContent(aText, IgnoreErrors());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsOverflowContinuationTracker::nsOverflowContinuationTracker(
|
nsOverflowContinuationTracker::nsOverflowContinuationTracker(
|
||||||
nsContainerFrame* aFrame, bool aWalkOOFFrames,
|
nsContainerFrame* aFrame, bool aWalkOOFFrames,
|
||||||
bool aSkipOverflowContainerChildren)
|
bool aSkipOverflowContainerChildren)
|
||||||
|
|
|
@ -429,13 +429,6 @@ class nsContainerFrame : public nsSplittableFrame {
|
||||||
virtual mozilla::StyleAlignFlags CSSAlignmentForAbsPosChild(
|
virtual mozilla::StyleAlignFlags CSSAlignmentForAbsPosChild(
|
||||||
const ReflowInput& aChildRI, mozilla::LogicalAxis aLogicalAxis) const;
|
const ReflowInput& aChildRI, mozilla::LogicalAxis aLogicalAxis) const;
|
||||||
|
|
||||||
#ifdef ACCESSIBILITY
|
|
||||||
/**
|
|
||||||
* Return the ::marker text equivalent, without flushing.
|
|
||||||
*/
|
|
||||||
void GetSpokenMarkerText(nsAString& aText) const;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define NS_DECLARE_FRAME_PROPERTY_FRAMELIST(prop) \
|
#define NS_DECLARE_FRAME_PROPERTY_FRAMELIST(prop) \
|
||||||
NS_DECLARE_FRAME_PROPERTY_WITH_DTOR_NEVER_CALLED(prop, nsFrameList)
|
NS_DECLARE_FRAME_PROPERTY_WITH_DTOR_NEVER_CALLED(prop, nsFrameList)
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче