Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  mozActionElements.mm   Sprache: unbekannt

 
/* clang-format off */
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* clang-format on */
/* 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/. */

#import "mozActionElements.h"

#import "MacUtils.h"
#include "LocalAccessible-inl.h"
#include "DocAccessible.h"
#include "XULTabAccessible.h"
#include "HTMLFormControlAccessible.h"

#include "nsCocoaUtils.h"
#include "mozilla/FloatingPoint.h"

using namespace mozilla::a11y;

@implementation mozButtonAccessible

- (NSNumber*)moxHasPopup {
  return @([self stateWithMask:states::HASPOPUP] != 0);
}

- (NSString*)moxPopupValue {
  if ([self stateWithMask:states::HASPOPUP] != 0) {
    return utils::GetAccAttr(self, nsGkAtoms::aria_haspopup);
  }

  return nil;
}

@end

@implementation mozPopupButtonAccessible

- (NSString*)moxTitle {
  // Popup buttons don't have titles.
  return @"";
}

- (BOOL)moxBlockSelector:(SEL)selector {
  if (selector == @selector(moxHasPopup)) {
    return YES;
  }

  return [super moxBlockSelector:selector];
}

- (NSArray*)moxChildren {
  if ([self stateWithMask:states::EXPANDED] == 0) {
    // If the popup button is collapsed don't return its children.
    return @[];
  }

  return [super moxChildren];
}

- (void)stateChanged:(uint64_t)state isEnabled:(BOOL)enabled {
  [super stateChanged:state isEnabled:enabled];

  if (state == states::EXPANDED) {
    // If the EXPANDED state is updated, fire AXMenu events on the
    // popups child which is the actual menu.
    if (mozAccessible* popup = (mozAccessible*)[self childAt:0]) {
      [popup moxPostNotification:(enabled ? @"AXMenuOpened" : @"AXMenuClosed")];
    }
  }
}

@end

@implementation mozRadioButtonAccessible

- (NSArray*)moxLinkedUIElements {
  return [[self getRelationsByType:RelationType::MEMBER_OF]
      arrayByAddingObjectsFromArray:[super moxLinkedUIElements]];
}

@end

@implementation mozCheckboxAccessible

- (int)isChecked {
  // check if we're checked or in a mixed state
  uint64_t state =
      [self stateWithMask:(states::CHECKED | states::PRESSED | states::MIXED)];
  if (state & (states::CHECKED | states::PRESSED)) {
    return kChecked;
  }

  if (state & states::MIXED) {
    return kMixed;
  }

  return kUnchecked;
}

- (id)moxValue {
  NS_OBJC_BEGIN_TRY_BLOCK_RETURN;

  return [NSNumber numberWithInt:[self isChecked]];

  NS_OBJC_END_TRY_BLOCK_RETURN(nil);
}

- (void)stateChanged:(uint64_t)state isEnabled:(BOOL)enabled {
  [super stateChanged:state isEnabled:enabled];

  if (state & (states::CHECKED | states::PRESSED | states::MIXED)) {
    [self moxPostNotification:NSAccessibilityValueChangedNotification];
  }
}

@end

@implementation mozPaneAccessible

- (NSArray*)moxChildren {
  // By default, all tab panels are exposed in the a11y tree
  // even if the tab they represent isn't the active tab. To
  // prevent VoiceOver from navigating background tab content,
  // only expose the tab panel that is currently on screen.
  for (mozAccessible* child in [super moxChildren]) {
    if (!([child state] & states::OFFSCREEN)) {
      return [NSArray arrayWithObject:GetObjectOrRepresentedView(child)];
    }
  }
  MOZ_ASSERT_UNREACHABLE("We have no on screen tab content?");
  return @[];
}

@end

@implementation mozRangeAccessible

- (id)moxValue {
  return [NSNumber numberWithDouble:mGeckoAccessible->CurValue()];
}

- (id)moxMinValue {
  return [NSNumber numberWithDouble:mGeckoAccessible->MinValue()];
}

- (id)moxMaxValue {
  return [NSNumber numberWithDouble:mGeckoAccessible->MaxValue()];
}

- (NSString*)moxOrientation {
  RefPtr<AccAttributes> attributes = mGeckoAccessible->Attributes();
  if (attributes) {
    nsAutoString result;
    attributes->GetAttribute(nsGkAtoms::aria_orientation, result);
    if (result.Equals(u"horizontal"_ns)) {
      return NSAccessibilityHorizontalOrientationValue;
    } else if (result.Equals(u"vertical"_ns)) {
      return NSAccessibilityVerticalOrientationValue;
    }
  }

  return NSAccessibilityUnknownOrientationValue;
}

- (void)handleAccessibleEvent:(uint32_t)eventType {
  switch (eventType) {
    case nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE:
    case nsIAccessibleEvent::EVENT_VALUE_CHANGE:
      [self moxPostNotification:NSAccessibilityValueChangedNotification];
      break;
    default:
      [super handleAccessibleEvent:eventType];
      break;
  }
}

@end

@implementation mozMeterAccessible

- (NSString*)moxValueDescription {
  nsAutoString valueDesc;
  mGeckoAccessible->Value(valueDesc);
  if (mGeckoAccessible->TagName() != nsGkAtoms::meter) {
    // We're dealing with an aria meter, which shouldn't get
    // a value region.
    return nsCocoaUtils::ToNSString(valueDesc);
  }

  if (!valueDesc.IsEmpty()) {
    // Append a comma to separate the existing value description
    // from the value region.
    valueDesc.Append(u", "_ns);
  }
  // We need to concat the given value description
  // with a description of the value as either optimal,
  // suboptimal, or critical.
  int32_t region;
  if (mGeckoAccessible->IsRemote()) {
    region = mGeckoAccessible->AsRemote()->ValueRegion();
  } else {
    HTMLMeterAccessible* localMeter =
        static_cast<HTMLMeterAccessible*>(mGeckoAccessible->AsLocal());
    region = localMeter->ValueRegion();
  }

  if (region == 1) {
    valueDesc.Append(u"Optimal value"_ns);
  } else if (region == 0) {
    valueDesc.Append(u"Suboptimal value"_ns);
  } else {
    MOZ_ASSERT(region == -1);
    valueDesc.Append(u"Critical value"_ns);
  }

  return nsCocoaUtils::ToNSString(valueDesc);
}

@end

@implementation mozIncrementableAccessible

- (NSString*)moxValueDescription {
  nsAutoString valueDesc;
  mGeckoAccessible->Value(valueDesc);
  return nsCocoaUtils::ToNSString(valueDesc);
}

- (void)moxSetValue:(id)value {
  [self setValue:([value doubleValue])];
}

- (void)moxPerformIncrement {
  [self changeValueBySteps:1];
}

- (void)moxPerformDecrement {
  [self changeValueBySteps:-1];
}

/*
 * Updates the accessible's current value by factor and step.
 *
 * factor: A signed integer representing the number of times to
 *    apply step to the current value. A positive value will increment,
 *    while a negative one will decrement.
 * step: An unsigned integer specified by the webauthor and indicating the
 *    amount by which to increment/decrement the current value.
 */
- (void)changeValueBySteps:(int)factor {
  MOZ_ASSERT(mGeckoAccessible, "mGeckoAccessible is null");

  double newValue =
      mGeckoAccessible->CurValue() + (mGeckoAccessible->Step() * factor);
  [self setValue:(newValue)];
}

/*
 * Updates the accessible's current value to the specified value
 */
- (void)setValue:(double)value {
  MOZ_ASSERT(mGeckoAccessible, "mGeckoAccessible is null");
  mGeckoAccessible->SetCurValue(value);
}

@end

@implementation mozDatePickerAccessible

- (NSString*)moxTitle {
  return utils::LocalizedString(u"dateField"_ns);
}

@end

[ Dauer der Verarbeitung: 0.18 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge