/* -*- 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/. */
void HTMLRadioButtonAccessible::DOMAttributeChanged(
int32_t aNameSpaceID, nsAtom* aAttribute, int32_t aModType, const nsAttrValue* aOldValue, uint64_t aOldState) { if (aAttribute == nsGkAtoms::name) { // If our name changed, it's possible our MEMBER_OF relation // also changed. Push a cache update for Relations.
mDoc->QueueCacheUpdate(this, CacheDomain::Relations);
} else { // Otherwise, handle this attribute change the way our parent // class wants us to handle it.
RadioButtonAccessible::DOMAttributeChanged(aNameSpaceID, aAttribute,
aModType, aOldValue, aOldState);
}
}
uint64_t HTMLButtonAccessible::NativeState() const {
uint64_t state = HyperTextAccessible::NativeState();
dom::Element* elm = Elm(); if (auto* popover = elm->GetEffectivePopoverTargetElement()) {
LocalAccessible* popoverAcc = mDoc->GetAccessible(popover); if (!popoverAcc || !popoverAcc->IsAncestorOf(this)) { if (popover->IsPopoverOpen()) {
state |= states::EXPANDED;
} else {
state |= states::COLLAPSED;
}
}
}
ElementState elmState = mContent->AsElement()->State(); if (elmState.HasState(ElementState::DEFAULT)) state |= states::DEFAULT;
return state;
}
role HTMLButtonAccessible::NativeRole() const { return roles::PUSHBUTTON; }
ENameValueFlag HTMLButtonAccessible::NativeName(nsString& aName) const { // No need to check @value attribute for buttons since this attribute results // in native anonymous text node and the name is calculated from subtree. // The same magic works for @alt and @value attributes in case of type="image" // element that has no valid @src (note if input@type="image" has an image // then neither @alt nor @value attributes are used to generate a visual label // and thus we need to obtain the accessible name directly from attribute // value). Also the same algorithm works in case of default labels for // type="submit"/"reset"/"image" elements.
// Expose type for text input elements as it gives some useful context, // especially for mobile. if (const nsAttrValue* attr =
mContent->AsElement()->GetParsedAttr(nsGkAtoms::type)) {
RefPtr<nsAtom> inputType = attr->GetAsAtom(); if (inputType) { if (!ARIARoleMap() && inputType == nsGkAtoms::search) {
attributes->SetAttribute(nsGkAtoms::xmlroles, nsGkAtoms::searchbox);
}
attributes->SetAttribute(nsGkAtoms::textInputType, inputType);
}
} // If this element has the placeholder attribute set, // and if that is not identical to the name, expose it as an object attribute.
nsString placeholderText; if (mContent->AsElement()->GetAttr(nsGkAtoms::placeholder, placeholderText)) {
nsAutoString name;
Name(name); if (!name.Equals(placeholderText)) {
attributes->SetAttribute(nsGkAtoms::placeholder,
std::move(placeholderText));
}
}
HTMLInputElement* input = HTMLInputElement::FromNode(mContent); if (input) { // Pass NonSystem as the caller type, to be safe. We don't expect to have a // file input here.
input->GetValue(aValue, CallerType::NonSystem);
if (NativeState() & states::PROTECTED) { // Don't return password text! const char16_t mask = TextEditor::PasswordMask(); for (size_t i = 0; i < aValue.Length(); i++) {
aValue.SetCharAt(mask, i);
}
}
}
}
uint64_t HTMLTextFieldAccessible::NativeState() const {
uint64_t state = HyperTextAccessible::NativeState();
// Text fields are always editable, even if they are also read only or // disabled.
state |= states::EDITABLE;
// can be focusable, focused, protected. readonly, unavailable, selected if (mContent->IsHTMLElement(nsGkAtoms::input) &&
mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
nsGkAtoms::password, eIgnoreCase)) {
state |= states::PROTECTED;
}
if (mContent->AsElement()->HasAttr(nsGkAtoms::readonly)) {
state |= states::READONLY;
}
// Is it an <input> or a <textarea> ?
HTMLInputElement* input = HTMLInputElement::FromNode(mContent);
state |= input && input->IsSingleLineTextControl() ? states::SINGLE_LINE
: states::MULTI_LINE;
// Expose autocomplete state if it has associated autocomplete list. if (mContent->AsElement()->HasAttr(nsGkAtoms::list_)) { return state | states::SUPPORTS_AUTOCOMPLETION | states::HASPOPUP;
}
if (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 // we're talking here is based on what the user types, where a popup of // possible choices comes up.
nsAutoString autocomplete;
mContent->AsElement()->GetAttr(nsGkAtoms::autocomplete, autocomplete);
if (!autocomplete.LowerCaseEqualsLiteral("off")) {
Element* formElement = input->GetForm(); if (formElement) {
formElement->GetAttr(nsGkAtoms::autocomplete, autocomplete);
}
if (!formElement || !autocomplete.LowerCaseEqualsLiteral("off")) {
state |= states::SUPPORTS_AUTOCOMPLETION;
}
}
}
bool HTMLTextFieldAccessible::DoAction(uint8_t aIndex) const { if (aIndex != 0) returnfalse;
if (FocusMgr()->IsFocused(this)) { // This already has focus, so TakeFocus()will do nothing. However, the user // might be activating this element because they dismissed a touch keyboard // and want to bring it back.
DoCommand();
} else {
TakeFocus();
} returntrue;
}
role HTMLFileInputAccessible::NativeRole() const { return roles::PUSHBUTTON; }
bool HTMLFileInputAccessible::IsAcceptableChild(nsIContent* aEl) const { // File inputs are rendered using native anonymous children. However, we // want to expose this as a button Accessible so that clients can pick up the // name and description from the button they activate, rather than a // container. We still expose the text leaf descendants so we can get the // name of the Browse button and the file name. return aEl->IsText();
}
ENameValueFlag HTMLFileInputAccessible::Name(nsString& aName) const {
ENameValueFlag flag = HyperTextAccessible::Name(aName); if (flag == eNameFromSubtree) { // The author didn't provide a name. We'll compute the name from our subtree // below.
aName.Truncate();
} else { // The author provided a name. We do use that, but we also append our // subtree text so the user knows this is a file chooser button and what // file has been chosen. if (aName.IsEmpty()) { // Name computation is recursing, perhaps due to a wrapping <label>. Don't // append the subtree text. Return " " to prevent // nsTextEquivUtils::AppendFromAccessible walking the subtree itself.
aName += ' '; return flag;
}
} // Unfortunately, GetNameFromSubtree doesn't separate the button text from the // file name text. Compute the text ourselves.
uint32_t count = ChildCount(); for (uint32_t c = 0; c < count; ++c) {
TextLeafAccessible* leaf = LocalChildAt(c)->AsTextLeaf();
MOZ_ASSERT(leaf); if (!aName.IsEmpty()) {
aName += ' ';
}
aName += leaf->Text();
} return flag;
}
role HTMLSpinnerAccessible::NativeRole() const { return roles::SPINBUTTON; }
void HTMLSpinnerAccessible::Value(nsString& aValue) const {
HTMLTextFieldAccessible::Value(aValue); if (!aValue.IsEmpty()) return;
// Pass NonSystem as the caller type, to be safe. We don't expect to have a // file input here.
HTMLInputElement::FromNode(mContent)->GetValue(aValue, CallerType::NonSystem);
}
double HTMLSpinnerAccessible::MaxValue() const { double value = HTMLTextFieldAccessible::MaxValue(); if (!std::isnan(value)) return value;
void HTMLRangeAccessible::Value(nsString& aValue) const {
LeafAccessible::Value(aValue); if (!aValue.IsEmpty()) return;
// Pass NonSystem as the caller type, to be safe. We don't expect to have a // file input here.
HTMLInputElement::FromNode(mContent)->GetValue(aValue, CallerType::NonSystem);
}
double HTMLRangeAccessible::MaxValue() const { double value = LeafAccessible::MaxValue(); if (!std::isnan(value)) return value;
Relation HTMLGroupboxAccessible::RelationByType(RelationType aType) const {
Relation rel = HyperTextAccessible::RelationByType(aType); // No override for label, so use <legend> for this <fieldset> if (aType == RelationType::LABELLED_BY) rel.AppendTarget(mDoc, GetLegend());
role HTMLProgressAccessible::NativeRole() const { return roles::PROGRESSBAR; }
uint64_t HTMLProgressAccessible::NativeState() const {
uint64_t state = LeafAccessible::NativeState(); // Progress bars are always readonly.
state |= states::READONLY;
// An undetermined progressbar (i.e. without a value) has a mixed state.
nsAutoString attrValue;
mContent->AsElement()->GetAttr(nsGkAtoms::value, attrValue); if (attrValue.IsEmpty()) {
state |= states::MIXED;
}
double HTMLProgressAccessible::MaxValue() const { double value = LeafAccessible::MaxValue(); if (!std::isnan(value)) { return value;
}
nsAutoString strValue; if (mContent->AsElement()->GetAttr(nsGkAtoms::max, strValue)) {
nsresult result = NS_OK;
value = strValue.ToDouble(&result); if (NS_SUCCEEDED(result)) { return value;
}
}
// If we did not get a value from the above LeafAccessible call, // we should check to see if the meter has inner text. // If it does, we'll use that as our value.
nsTextEquivUtils::AppendFromDOMChildren(mContent, &aValue);
aValue.CompressWhitespace(); if (!aValue.IsEmpty()) { return;
}
// If no inner text is found, use curValue double curValue = CurValue(); if (std::isnan(curValue)) { return;
}
aValue.AppendFloat(curValue);
}
double HTMLMeterAccessible::MaxValue() const { double max = LeafAccessible::MaxValue(); double min = MinValue();
if (!std::isnan(max)) { return max > min ? max : min;
}
// If we didn't find a max value, check for the max attribute
nsAutoString strValue; if (mContent->AsElement()->GetAttr(nsGkAtoms::max, strValue)) {
nsresult result = NS_OK;
max = strValue.ToDouble(&result); if (NS_SUCCEEDED(result)) { return max > min ? max : min;
}
}
return 1 > min ? 1 : min;
}
double HTMLMeterAccessible::MinValue() const { double min = LeafAccessible::MinValue(); if (!std::isnan(min)) { return min;
}
nsAutoString strValue; if (mContent->AsElement()->GetAttr(nsGkAtoms::min, strValue)) {
nsresult result = NS_OK;
min = strValue.ToDouble(&result); if (NS_SUCCEEDED(result)) { return min;
}
}
if (std::isnan(value)) { /* If we didn't find a value from the LeafAccessible call above, check
* for a value attribute */
nsAutoString attrValue; if (!mContent->AsElement()->GetAttr(nsGkAtoms::value, attrValue)) { return minValue;
}
// If we find a value attribute, attempt to convert it to a double
nsresult error = NS_OK;
value = attrValue.ToDouble(&error); if (NS_FAILED(error)) { return minValue;
}
}
/* If we end up with a defined value, verify it falls between
* our established min/max. Otherwise, snap it to the nearest boundary. */ double maxValue = MaxValue(); if (value > maxValue) {
value = maxValue;
} elseif (value < minValue) {
value = minValue;
}
return value;
}
bool HTMLMeterAccessible::SetCurValue(double aValue) { returnfalse; // meters are readonly.
}
int32_t HTMLMeterAccessible::ValueRegion() const {
dom::HTMLMeterElement* elm = dom::HTMLMeterElement::FromNode(mContent); if (!elm) { return -1;
} double high = elm->High(); double low = elm->Low(); double optimum = elm->Optimum(); double value = elm->Value(); // For more information on how these regions are defined, see // "UA requirements for regions of the gauge" // https://html.spec.whatwg.org/multipage/form-elements.html#the-meter-element if (optimum > high) { if (value > high) { return 1;
} return value > low ? 0 : -1;
} if (optimum < low) { if (value < low) { return 1;
} return value < high ? 0 : -1;
} // optimum is between low and high, inclusive if (value >= low && value <= high) { return 1;
} // Both upper and lower regions are considered equally // non-optimal. return 0;
}
if (aAttribute == nsGkAtoms::value) {
mDoc->FireDelayedEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, this);
}
if (aAttribute == nsGkAtoms::high || aAttribute == nsGkAtoms::low ||
aAttribute == nsGkAtoms::optimum) { // Our meter's value region may have changed, queue an update for // the value domain.
mDoc->QueueCacheUpdate(this, CacheDomain::Value); return;
}
}
¤ Dauer der Verarbeitung: 0.18 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.