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


Quelle  radio.js   Sprache: JAVA

 
/* 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/. */


"use strict";

// This is loaded into all XUL windows. Wrap in a block to prevent
// leaking to window scope.
(() => {
  class MozRadiogroup extends MozElements.BaseControl {
    constructor() {
      super();

      this.addEventListener("mousedown", event => {
        if (this.disabled) {
          event.preventDefault();
        }
      });

      /**
       * keyboard navigation  Here's how keyboard navigation works in radio groups on Windows:
       * The group takes 'focus'
       * The user is then free to navigate around inside the group
       * using the arrow keys. Accessing previous or following radio buttons
       * is done solely through the arrow keys and not the tab button. Tab
       * takes you to the next widget in the tab order
       */

      this.addEventListener("keypress", event => {
        if (event.key != " " || event.originalTarget != this) {
          return;
        }
        this.selectedItem = this.focusedItem;
        this.selectedItem.doCommand();
        // Prevent page from scrolling on the space key.
        event.preventDefault();
      });

      this.addEventListener("keypress", event => {
        if (
          event.keyCode != KeyEvent.DOM_VK_UP ||
          event.originalTarget != this
        ) {
          return;
        }
        this.checkAdjacentElement(false);
        event.stopPropagation();
        event.preventDefault();
      });

      this.addEventListener("keypress", event => {
        if (
          event.keyCode != KeyEvent.DOM_VK_LEFT ||
          event.originalTarget != this
        ) {
          return;
        }
        // left arrow goes back when we are ltr, forward when we are rtl
        this.checkAdjacentElement(
          document.defaultView.getComputedStyle(this).direction == "rtl"
        );
        event.stopPropagation();
        event.preventDefault();
      });

      this.addEventListener("keypress", event => {
        if (
          event.keyCode != KeyEvent.DOM_VK_DOWN ||
          event.originalTarget != this
        ) {
          return;
        }
        this.checkAdjacentElement(true);
        event.stopPropagation();
        event.preventDefault();
      });

      this.addEventListener("keypress", event => {
        if (
          event.keyCode != KeyEvent.DOM_VK_RIGHT ||
          event.originalTarget != this
        ) {
          return;
        }
        // right arrow goes forward when we are ltr, back when we are rtl
        this.checkAdjacentElement(
          document.defaultView.getComputedStyle(this).direction == "ltr"
        );
        event.stopPropagation();
        event.preventDefault();
      });

      /**
       * set a focused attribute on the selected item when the group
       * receives focus so that we can style it as if it were focused even though
       * it is not (Windows platform behaviour is for the group to receive focus,
       * not the item
       */

      this.addEventListener("focus", event => {
        if (event.originalTarget != this) {
          return;
        }
        this.setAttribute("focused""true");
        if (this.focusedItem) {
          return;
        }

        var val = this.selectedItem;
        if (!val || val.disabled || val.hidden || val.collapsed) {
          var children = this._getRadioChildren();
          for (var i = 0; i < children.length; ++i) {
            if (
              !children[i].hidden &&
              !children[i].collapsed &&
              !children[i].disabled
            ) {
              val = children[i];
              break;
            }
          }
        }
        this.focusedItem = val;
      });

      this.addEventListener("blur", event => {
        if (event.originalTarget != this) {
          return;
        }
        this.removeAttribute("focused");
        this.focusedItem = null;
      });
    }

    connectedCallback() {
      if (this.delayConnectedCallback()) {
        return;
      }

      // When this is called via `connectedCallback` there are two main variations:
      //   1) The radiogroup and radio children are defined in markup.
      //   2) We are appending a DocumentFragment
      // In both cases, the <radiogroup> connectedCallback fires first. But in (2),
      // the children <radio>s won't be upgraded yet, so r.control will be undefined.
      // To avoid churn in this case where we would have to reinitialize the list as each
      // child radio gets upgraded as a result of init(), ignore the resulting calls
      // to radioAttached.
      this.ignoreRadioChildConstruction = true;
      this.init();
      this.ignoreRadioChildConstruction = false;
      if (!this.value) {
        this.selectedIndex = 0;
      }
    }

    init() {
      this._radioChildren = null;

      if (this.getAttribute("disabled") == "true") {
        this.disabled = true;
      }

      var children = this._getRadioChildren();
      var length = children.length;
      for (var i = 0; i < length; i++) {
        if (children[i].getAttribute("selected") == "true") {
          this.selectedIndex = i;
          return;
        }
      }

      var value = this.value;
      if (value) {
        this.value = value;
      }
    }

    /**
     * Called when a new <radio> gets added to an already connected radiogroup.
     * This can happen due to DOM getting appended after the <radiogroup> is created.
     * When this happens, reinitialize the UI if necessary to make sure the state is
     * consistent.
     *
     * @param {DOMNode} child
     *                  The <radio> element that got added
     */

    radioAttached(child) {
      if (this.ignoreRadioChildConstruction) {
        return;
      }
      if (!this._radioChildren || !this._radioChildren.includes(child)) {
        this.init();
      }
    }

    /**
     * Called when a new <radio> gets removed from a radio group.
     *
     * @param {DOMNode} child
     *                  The <radio> element that got removed
     */

    radioUnattached() {
      // Just invalidate the cache, next time it's fetched it'll get rebuilt.
      this._radioChildren = null;
    }

    set value(val) {
      this.setAttribute("value", val);
      var children = this._getRadioChildren();
      for (var i = 0; i < children.length; i++) {
        if (String(children[i].value) == String(val)) {
          this.selectedItem = children[i];
          break;
        }
      }
    }

    get value() {
      return this.getAttribute("value") || "";
    }

    set disabled(val) {
      if (val) {
        this.setAttribute("disabled""true");
      } else {
        this.removeAttribute("disabled");
      }
      var children = this._getRadioChildren();
      for (var i = 0; i < children.length; ++i) {
        children[i].disabled = val;
      }
    }

    get disabled() {
      if (this.getAttribute("disabled") == "true") {
        return true;
      }
      var children = this._getRadioChildren();
      for (var i = 0; i < children.length; ++i) {
        if (
          !children[i].hidden &&
          !children[i].collapsed &&
          !children[i].disabled
        ) {
          return false;
        }
      }
      return true;
    }

    get itemCount() {
      return this._getRadioChildren().length;
    }

    set selectedIndex(val) {
      this.selectedItem = this._getRadioChildren()[val];
    }

    get selectedIndex() {
      var children = this._getRadioChildren();
      for (var i = 0; i < children.length; ++i) {
        if (children[i].selected) {
          return i;
        }
      }
      return -1;
    }

    set selectedItem(val) {
      var focused = this.getAttribute("focused") == "true";
      var alreadySelected = false;

      if (val) {
        alreadySelected = val.getAttribute("selected") == "true";
        val.setAttribute("focused", focused);
        val.setAttribute("selected""true");
        this.setAttribute("value", val.value);
      } else {
        this.removeAttribute("value");
      }

      // uncheck all other group nodes
      var children = this._getRadioChildren();
      var previousItem = null;
      for (var i = 0; i < children.length; ++i) {
        if (children[i] != val) {
          if (children[i].getAttribute("selected") == "true") {
            previousItem = children[i];
          }

          children[i].removeAttribute("selected");
          children[i].removeAttribute("focused");
        }
      }

      var event = document.createEvent("Events");
      event.initEvent("select"falsetrue);
      this.dispatchEvent(event);

      if (focused) {
        if (alreadySelected) {
          // Notify accessibility that this item got focus.
          event = document.createEvent("Events");
          event.initEvent("DOMMenuItemActive"truetrue);
          val.dispatchEvent(event);
        } else {
          // Only report if actual change
          if (val) {
            // Accessibility will fire focus for this.
            event = document.createEvent("Events");
            event.initEvent("RadioStateChange"truetrue);
            val.dispatchEvent(event);
          }

          if (previousItem) {
            event = document.createEvent("Events");
            event.initEvent("RadioStateChange"truetrue);
            previousItem.dispatchEvent(event);
          }
        }
      }
    }

    get selectedItem() {
      var children = this._getRadioChildren();
      for (var i = 0; i < children.length; ++i) {
        if (children[i].selected) {
          return children[i];
        }
      }
      return null;
    }

    set focusedItem(val) {
      if (val) {
        val.setAttribute("focused""true");
        // Notify accessibility that this item got focus.
        let event = document.createEvent("Events");
        event.initEvent("DOMMenuItemActive"truetrue);
        val.dispatchEvent(event);
      }

      // unfocus all other group nodes
      var children = this._getRadioChildren();
      for (var i = 0; i < children.length; ++i) {
        if (children[i] != val) {
          children[i].removeAttribute("focused");
        }
      }
    }

    get focusedItem() {
      var children = this._getRadioChildren();
      for (var i = 0; i < children.length; ++i) {
        if (children[i].getAttribute("focused") == "true") {
          return children[i];
        }
      }
      return null;
    }

    checkAdjacentElement(aNextFlag) {
      var currentElement = this.focusedItem || this.selectedItem;
      var i;
      var children = this._getRadioChildren();
      for (i = 0; i < children.length; ++i) {
        if (children[i] == currentElement) {
          break;
        }
      }
      var index = i;

      if (aNextFlag) {
        do {
          if (++i == children.length) {
            i = 0;
          }
          if (i == index) {
            break;
          }
        } while (
          children[i].hidden ||
          children[i].collapsed ||
          children[i].disabled
        );
        // XXX check for display/visibility props too

        this.selectedItem = children[i];
        children[i].doCommand();
      } else {
        do {
          if (i == 0) {
            i = children.length;
          }
          if (--i == index) {
            break;
          }
        } while (
          children[i].hidden ||
          children[i].collapsed ||
          children[i].disabled
        );
        // XXX check for display/visibility props too

        this.selectedItem = children[i];
        children[i].doCommand();
      }
    }

    _getRadioChildren() {
      if (this._radioChildren) {
        return this._radioChildren;
      }

      let radioChildren = [];
      if (this.hasChildNodes()) {
        for (let radio of this.querySelectorAll("radio")) {
          customElements.upgrade(radio);
          if (radio.control == this) {
            radioChildren.push(radio);
          }
        }
      } else {
        const XUL_NS =
          "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
        for (let radio of this.ownerDocument.getElementsByAttribute(
          "group",
          this.id
        )) {
          if (radio.namespaceURI == XUL_NS && radio.localName == "radio") {
            customElements.upgrade(radio);
            radioChildren.push(radio);
          }
        }
      }

      return (this._radioChildren = radioChildren);
    }

    getIndexOfItem(item) {
      return this._getRadioChildren().indexOf(item);
    }

    getItemAtIndex(index) {
      var children = this._getRadioChildren();
      return index >= 0 && index < children.length ? children[index] : null;
    }

    appendItem(label, value) {
      var radio = document.createXULElement("radio");
      radio.setAttribute("label", label);
      radio.setAttribute("value", value);
      this.appendChild(radio);
      return radio;
    }
  }

  MozXULElement.implementCustomInterface(MozRadiogroup, [
    Ci.nsIDOMXULSelectControlElement,
    Ci.nsIDOMXULRadioGroupElement,
  ]);

  customElements.define("radiogroup", MozRadiogroup);

  class MozRadio extends MozElements.BaseText {
    static get markup() {
      return `
      <image class="radio-check"></image>
      <hbox class="radio-label-box" align="center" flex="1">
        <image class="radio-icon"></image>
        <label class="radio-label" flex="1"></label>
      </hbox>
      `;
    }

    static get inheritedAttributes() {
      return {
        ".radio-check""disabled,selected",
        ".radio-label""text=label,accesskey,crop",
        ".radio-icon""src",
      };
    }

    constructor() {
      super();
      this.addEventListener("click", () => {
        if (!this.disabled) {
          this.control.selectedItem = this;
        }
      });

      this.addEventListener("mousedown", () => {
        if (!this.disabled) {
          this.control.focusedItem = this;
        }
      });
    }

    connectedCallback() {
      if (this.delayConnectedCallback()) {
        return;
      }

      if (!this.connectedOnce) {
        this.connectedOnce = true;
        // If the caller didn't provide custom content then append the default:
        if (!this.firstElementChild) {
          this.appendChild(this.constructor.fragment);
          this.initializeAttributeInheritance();
        }
      }

      var control = (this._control = this.control);
      if (control) {
        control.radioAttached(this);
      }
    }

    disconnectedCallback() {
      if (this.control) {
        this.control.radioUnattached(this);
      }
      this._control = null;
    }

    set value(val) {
      this.setAttribute("value", val);
    }

    get value() {
      return this.getAttribute("value") || "";
    }

    get selected() {
      return this.hasAttribute("selected");
    }

    get radioGroup() {
      return this.control;
    }

    get control() {
      if (this._control) {
        return this._control;
      }

      var radiogroup = this.closest("radiogroup");
      if (radiogroup) {
        return radiogroup;
      }

      var group = this.getAttribute("group");
      if (!group) {
        return null;
      }

      var parent = this.ownerDocument.getElementById(group);
      if (!parent || parent.localName != "radiogroup") {
        parent = null;
      }
      return parent;
    }
  }

  MozXULElement.implementCustomInterface(MozRadio, [
    Ci.nsIDOMXULSelectControlItemElement,
  ]);
  customElements.define("radio", MozRadio);
})();

Messung V0.5
C=95 H=85 G=90

¤ Dauer der Verarbeitung: 0.18 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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 und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


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