/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
CssAltContent::CssAltContent(nsIContent* aContent) {
nsIFrame* frame = aContent->GetPrimaryFrame(); if (!frame) { return;
} if (!frame->IsReplaced()) { return;
} // Check if this is for a pseudo-element. if (aContent->IsInNativeAnonymousSubtree()) {
nsIContent* parent = aContent->GetParent(); if (parent && (parent->IsGeneratedContentContainerForBefore() ||
parent->IsGeneratedContentContainerForAfter() ||
parent->IsGeneratedContentContainerForMarker())) {
mPseudoElement = parent->AsElement(); // We need the frame from the pseudo-element to get the content style.
frame = parent->GetPrimaryFrame(); if (!frame) { return;
} // We need the real element to get any attributes.
mRealElement = parent->GetParentElement(); if (!mRealElement) { return;
}
}
} if (!mRealElement) { if (aContent->IsElement()) {
mRealElement = aContent->AsElement();
} else { return;
}
}
mItems = frame->StyleContent()->AltContentItems();
}
void CssAltContent::AppendToString(nsAString& aOut) { // There can be multiple alt text items. for (constauto& item : mItems) { if (item.IsString()) {
aOut.Append(NS_ConvertUTF8toUTF16(item.AsString().AsString()));
} elseif (item.IsAttr()) { // This item gets its value from an attribute on the element or from // fallback text.
MOZ_ASSERT(mRealElement); constauto& attr = item.AsAttr();
RefPtr<nsAtom> name = attr.attribute.AsAtom();
int32_t nsId = kNameSpaceID_None;
RefPtr<nsAtom> ns = attr.namespace_url.AsAtom(); if (!ns->IsEmpty()) {
nsresult rv = nsNameSpaceManager::GetInstance()->RegisterNameSpace(
ns.forget(), nsId); if (NS_FAILED(rv)) { continue;
}
} if (mRealElement->IsHTMLElement() &&
mRealElement->OwnerDoc()->IsHTMLDocument()) {
ToLowerCaseASCII(name);
}
nsAutoString val; if (!mRealElement->GetAttr(nsId, name, val)) { if (RefPtr<nsAtom> fallback = attr.fallback.AsAtom()) {
fallback->ToString(val);
}
}
aOut.Append(val);
}
}
}
/* static */ bool CssAltContent::HandleAttributeChange(nsIContent* aContent,
int32_t aNameSpaceID,
nsAtom* aAttribute) { // Handle CSS content which replaces the content of aContent itself. if (CssAltContent(aContent).HandleAttributeChange(aNameSpaceID, aAttribute)) { returntrue;
} // Handle any pseudo-elements with CSS alt content. for (dom::Element* pseudo : {nsLayoutUtils::GetBeforePseudo(aContent),
nsLayoutUtils::GetAfterPseudo(aContent),
nsLayoutUtils::GetMarkerPseudo(aContent)}) { // CssAltContent wants a child of a pseudo-element.
nsIContent* child = pseudo ? pseudo->GetFirstChild() : nullptr; if (child &&
CssAltContent(child).HandleAttributeChange(aNameSpaceID, aAttribute)) { returntrue;
}
} returnfalse;
}
bool CssAltContent::HandleAttributeChange(int32_t aNameSpaceID,
nsAtom* aAttribute) { for (constauto& item : mItems) { if (!item.IsAttr()) { continue;
}
MOZ_ASSERT(mRealElement); constauto& attr = item.AsAttr();
RefPtr<nsAtom> name = attr.attribute.AsAtom(); if (mRealElement->IsHTMLElement() &&
mRealElement->OwnerDoc()->IsHTMLDocument()) {
ToLowerCaseASCII(name);
} if (name != aAttribute) { continue;
}
int32_t nsId = kNameSpaceID_None;
RefPtr<nsAtom> ns = attr.namespace_url.AsAtom(); if (!ns->IsEmpty()) {
nsresult rv = nsNameSpaceManager::GetInstance()->RegisterNameSpace(
ns.forget(), nsId); if (NS_FAILED(rv)) { continue;
}
} if (nsId != aNameSpaceID) { continue;
} // The CSS alt content references this attribute which has just changed.
DocAccessible* docAcc = GetExistingDocAccessible(mRealElement->OwnerDoc());
MOZ_ASSERT(docAcc); if (mPseudoElement) { // For simplicity, we just recreate the pseudo-element subtree. If this // becomes a performance problem, we can probably do better. For images, // we can just fire a name change event. Text is a bit more complicated, // as we need to update the text leaf with the new alt text and fire the // appropriate text change events. Mixed content gets even messier.
docAcc->RecreateAccessible(mPseudoElement);
} else { // This is CSS content replacing an element's content.
MOZ_ASSERT(mRealElement->GetPrimaryFrame());
MOZ_ASSERT(mRealElement->GetPrimaryFrame()->IsReplaced());
LocalAccessible* acc = docAcc->GetAccessible(mRealElement);
MOZ_ASSERT(acc);
docAcc->FireDelayedEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, acc);
} returntrue;
} returnfalse;
}
} // namespace mozilla::a11y
¤ Dauer der Verarbeitung: 0.20 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.