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:
James Teh 2020-02-21 01:23:37 +00:00
Родитель 3e660d9274
Коммит c604c6018c
4 изменённых файлов: 104 добавлений и 38 удалений

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

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