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


Quelle  DateTimePickerPanel.sys.mjs   Sprache: unbekannt

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

export var DateTimePickerPanel = class {
  constructor(element) {
    this.element = element;

    this.TIME_PICKER_WIDTH = "13em";
    this.TIME_PICKER_HEIGHT = "22em";
    this.DATE_PICKER_WIDTH = "24em";
    this.DATE_PICKER_HEIGHT = "27em";
  }

  get dateTimePopupFrame() {
    let frame = this.element.querySelector("#dateTimePopupFrame");
    if (!frame) {
      frame = this.element.ownerDocument.createXULElement("iframe");
      frame.id = "dateTimePopupFrame";
      this.element.appendChild(frame);
    }
    return frame;
  }

  openPicker(type, rect, detail) {
    if (type == "datetime-local") {
      type = "date";
    }
    this.type = type;
    this.pickerState = {};
    // TODO: Resize picker according to content zoom level
    this.element.style.fontSize = "10px";
    switch (type) {
      case "time": {
        this.detail = detail;
        this.dateTimePopupFrame.addEventListener("load", this, true);
        this.dateTimePopupFrame.setAttribute(
          "src",
          "chrome://global/content/timepicker.xhtml"
        );
        this.dateTimePopupFrame.style.width = this.TIME_PICKER_WIDTH;
        this.dateTimePopupFrame.style.height = this.TIME_PICKER_HEIGHT;
        break;
      }
      case "date": {
        this.detail = detail;
        this.dateTimePopupFrame.addEventListener("load", this, true);
        this.dateTimePopupFrame.setAttribute(
          "src",
          "chrome://global/content/datepicker.xhtml"
        );
        this.dateTimePopupFrame.style.width = this.DATE_PICKER_WIDTH;
        this.dateTimePopupFrame.style.height = this.DATE_PICKER_HEIGHT;
        break;
      }
    }
    this.element.openPopupAtScreenRect(
      "after_start",
      rect.left,
      rect.top,
      rect.width,
      rect.height,
      false,
      false
    );
  }

  closePicker(clear) {
    if (clear) {
      this.element.dispatchEvent(new CustomEvent("DateTimePickerValueCleared"));
    }
    this.pickerState = {};
    this.type = undefined;
    this.dateTimePopupFrame.removeEventListener("load", this, true);
    this.dateTimePopupFrame.contentDocument.removeEventListener(
      "message",
      this
    );
    this.dateTimePopupFrame.setAttribute("src", "");
    this.element.hidePopup();
  }

  setPopupValue(data) {
    switch (this.type) {
      case "time": {
        this.postMessageToPicker({
          name: "PickerSetValue",
          detail: data.value,
        });
        break;
      }
      case "date": {
        const { year, month, day } = data.value;
        this.postMessageToPicker({
          name: "PickerSetValue",
          detail: {
            year,
            // Month value from input box starts from 1 instead of 0
            month: month == undefined ? undefined : month - 1,
            day,
          },
        });
        break;
      }
    }
  }

  initPicker(detail) {
    let locale = new Services.intl.Locale(
      Services.locale.webExposedLocales[0],
      {
        calendar: "gregory",
      }
    ).toString();

    // Workaround for bug 1418061, while we wait for resolution of
    // http://bugs.icu-project.org/trac/ticket/13592: drop the PT region code,
    // because it results in "abbreviated" day names that are too long;
    // the region-less "pt" locale has shorter forms that are better here.
    locale = locale.replace(/^pt-PT/i, "pt");

    const dir = Services.locale.isAppLocaleRTL ? "rtl" : "ltr";

    switch (this.type) {
      case "time": {
        const { hour, minute } = detail.value;
        const format = detail.format || "12";

        this.postMessageToPicker({
          name: "PickerInit",
          detail: {
            hour,
            minute,
            format,
            locale,
            min: detail.min,
            max: detail.max,
            step: detail.step,
          },
        });
        break;
      }
      case "date": {
        const { year, month, day } = detail.value;
        const { firstDayOfWeek, weekends } = this.getCalendarInfo(locale);

        const monthDisplayNames = new Services.intl.DisplayNames(locale, {
          type: "month",
          style: "short",
          calendar: "gregory",
        });
        const monthStrings = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].map(
          month => monthDisplayNames.of(month)
        );

        const weekdayDisplayNames = new Services.intl.DisplayNames(locale, {
          type: "weekday",
          style: "abbreviated",
          calendar: "gregory",
        });
        const weekdayStrings = [
          // Weekdays starting Sunday (7) to Saturday (6).
          7, 1, 2, 3, 4, 5, 6,
        ].map(weekday => weekdayDisplayNames.of(weekday));

        this.postMessageToPicker({
          name: "PickerInit",
          detail: {
            year,
            // Month value from input box starts from 1 instead of 0
            month: month == undefined ? undefined : month - 1,
            day,
            firstDayOfWeek,
            weekends,
            monthStrings,
            weekdayStrings,
            locale,
            dir,
            min: detail.min,
            max: detail.max,
            step: detail.step,
            stepBase: detail.stepBase,
          },
        });
        break;
      }
    }
  }

  /**
   * @param {Boolean} passAllValues: Pass spinner values regardless if they've been set/changed or not
   */
  setInputBoxValue(passAllValues) {
    switch (this.type) {
      case "time": {
        const { hour, minute, isHourSet, isMinuteSet, isDayPeriodSet } =
          this.pickerState;
        const isAnyValueSet = isHourSet || isMinuteSet || isDayPeriodSet;
        if (passAllValues && isAnyValueSet) {
          this.sendPickerValueChanged({ hour, minute });
        } else {
          this.sendPickerValueChanged({
            hour: isHourSet || isDayPeriodSet ? hour : undefined,
            minute: isMinuteSet ? minute : undefined,
          });
        }
        break;
      }
      case "date": {
        this.sendPickerValueChanged(this.pickerState);
        break;
      }
    }
  }

  sendPickerValueChanged(value) {
    switch (this.type) {
      case "time": {
        this.element.dispatchEvent(
          new CustomEvent("DateTimePickerValueChanged", {
            detail: {
              hour: value.hour,
              minute: value.minute,
            },
          })
        );
        break;
      }
      case "date": {
        this.element.dispatchEvent(
          new CustomEvent("DateTimePickerValueChanged", {
            detail: {
              year: value.year,
              // Month value from input box starts from 1 instead of 0
              month: value.month == undefined ? undefined : value.month + 1,
              day: value.day,
            },
          })
        );
        break;
      }
    }
  }

  getCalendarInfo(locale) {
    const calendarInfo = Services.intl.getCalendarInfo(locale);

    // Day of week from calendarInfo starts from 1 as Monday to 7 as Sunday,
    // so they need to be mapped to JavaScript convention with 0 as Sunday
    // and 6 as Saturday
    function toDateWeekday(day) {
      return day === 7 ? 0 : day;
    }

    let firstDayOfWeek = toDateWeekday(calendarInfo.firstDayOfWeek),
      weekend = calendarInfo.weekend;

    let weekends = weekend.map(toDateWeekday);

    return {
      firstDayOfWeek,
      weekends,
    };
  }

  handleEvent(aEvent) {
    switch (aEvent.type) {
      case "load": {
        this.initPicker(this.detail);
        this.dateTimePopupFrame.contentWindow.addEventListener("message", this);
        break;
      }
      case "message": {
        this.handleMessage(aEvent);
        break;
      }
    }
  }

  handleMessage(aEvent) {
    if (
      !this.dateTimePopupFrame.contentDocument.nodePrincipal.isSystemPrincipal
    ) {
      return;
    }

    switch (aEvent.data.name) {
      case "PickerPopupChanged": {
        this.pickerState = aEvent.data.detail;
        this.setInputBoxValue();
        break;
      }
      case "ClosePopup": {
        this.closePicker(aEvent.data.detail);
        break;
      }
    }
  }

  postMessageToPicker(data) {
    if (
      this.dateTimePopupFrame.contentDocument.nodePrincipal.isSystemPrincipal
    ) {
      this.dateTimePopupFrame.contentWindow.postMessage(data, "*");
    }
  }
};

[ Dauer der Verarbeitung: 0.25 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