// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// @dart = 2.6
part of engine;

/// Renders [_label] and [_value] to the semantics DOM.
///
/// The rendering method is browser-dependent. There is no explicit ARIA
/// attribute to express "value". Instead, you are expected to render the
/// value as text content of HTML.
///
/// VoiceOver only supports "aria-label" for certain ARIA roles. For plain
/// text it expects that the label is part of the text content of the element.
/// The strategy for VoiceOver is to combine [_label] and [_value] and stamp
/// out a single child element that contains the value.
///
/// TalkBack supports the "aria-label" attribute. However, when present,
/// TalkBack ignores the text content. Therefore, we cannot split [_label]
/// and [_value] between "aria-label" and text content. The strategy for
/// TalkBack is to combine [_label] and [_value] into a single "aria-label".
///
/// The [_value] is not always rendered. Some semantics nodes correspond to
/// interactive controls, such as an `<input>` element. In such case the value
/// is reported via that element's `value` attribute rather than rendering it
/// separately.
///
/// Aria role image is not managed by this role manager. Img role and label
/// describes the visual are added in [ImageRoleManager].
class LabelAndValue extends RoleManager {
  LabelAndValue(SemanticsObject semanticsObject)
      : super(Role.labelAndValue, semanticsObject);

  /// Supplements the "aria-label" that renders the combination of [_label] and
  /// [_value] to semantics as text content.
  ///
  /// This extra element is needed for the following reasons:
  ///
  /// - VoiceOver on iOS Safari does not recognize standalone "aria-label". It
  ///   only works for specific roles.
  /// - TalkBack does support "aria-label". However, if an element has children
  ///   its label is not reachable via accessibility focus. This happens, for
  ///   example in popup dialogs, such as the alert dialog. The text of the
  ///   alert is supplied as a label on the parent node.
  html.Element _auxiliaryValueElement;

  @override
  void update() {
    final bool hasValue = semanticsObject.hasValue;
    final bool hasLabel = semanticsObject.hasLabel;

    // If the node is incrementable or a text field the value is reported to the
    // browser via the respective role managers. We do not need to also render
    // it again here.
    final bool shouldDisplayValue = hasValue &&
        !semanticsObject.isIncrementable &&
        !semanticsObject.isTextField;

    if (!hasLabel && !shouldDisplayValue) {
      _cleanUpDom();
      return;
    }

    final StringBuffer combinedValue = StringBuffer();
    if (hasLabel) {
      combinedValue.write(semanticsObject.label);
      if (shouldDisplayValue) {
        combinedValue.write(' ');
      }
    }

    if (shouldDisplayValue) {
      combinedValue.write(semanticsObject.value);
    }

    semanticsObject.element
        .setAttribute('aria-label', combinedValue.toString());

    if (semanticsObject.hasFlag(ui.SemanticsFlag.isHeader)) {
      semanticsObject.setAriaRole('heading', true);
    }

    if (_auxiliaryValueElement == null) {
      _auxiliaryValueElement = html.Element.tag('flt-semantics-value');
      // Absolute positioning and sizing of leaf text elements confuses
      // VoiceOver. So we let the browser size the value node. The node will
      // still have a bigger tap area. However, if the node is a parent to other
      // nodes, then VoiceOver behaves as expected with absolute positioning and
      // sizing.
      if (semanticsObject.hasChildren) {
        _auxiliaryValueElement.style
          ..position = 'absolute'
          ..top = '0'
          ..left = '0'
          ..width = '${semanticsObject.rect.width}px'
          ..height = '${semanticsObject.rect.height}px';
      }
      _auxiliaryValueElement.style.fontSize = '6px';
      semanticsObject.element.append(_auxiliaryValueElement);
    }
    _auxiliaryValueElement.text = combinedValue.toString();
  }

  void _cleanUpDom() {
    if (_auxiliaryValueElement != null) {
      _auxiliaryValueElement.remove();
      _auxiliaryValueElement = null;
    }
    semanticsObject.element.attributes.remove('aria-label');
    semanticsObject.setAriaRole('heading', false);
  }

  @override
  void dispose() {
    _cleanUpDom();
  }
}
