Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/browser/components/tabbrowser/content/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 9 kB image not shown  

Quelle  tabnote-menu.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 chrome windows with the subscript loader. Wrap in
// a block to prevent accidentally leaking globals onto `window`.
{
  const { TabNotes } = ChromeUtils.importESModule(
    "moz-src:///browser/components/tabnotes/TabNotes.sys.mjs"
  );

  const OVERFLOW_WARNING_THRESHOLD = 980;
  const OVERFLOW_MAX_THRESHOLD = 1000;

  const OverflowState = {
    NONE: "none",
    WARN: "warn",
    OVERFLOW: "overflow",
  };

  class MozTabbrowserTabNoteMenu extends MozXULElement {
    static markup = /*html*/ `
    <panel
        id="tabNotePanel"
        type="arrow"
        titlebar="normal"
        class="tab-note-editor-panel panel-no-padding"
        orient="vertical"
        role="dialog"
        ignorekeys="true"
        norolluponanchor="true"
        consumeoutsideclicks="false">

        <html:div class="panel-header" id="tab-note-editor-header" >
          <html:h1
            id="tab-note-editor-title">
          </html:h1>
        </html:div>

        <toolbarseparator id="tab-note-editor-separator" />

        <html:div
          class="panel-subview-body
          tab-note-editor-name">
          <html:textarea
            id="tab-note-text"
            name="tab-note-text"
            rows="3"
            value=""
            data-l10n-id="tab-note-editor-text-field"
          ></html:textarea>
        </html:div>

        <html:div
          class="panel-action-row panel-footer">
          <html:moz-button
              id="tab-note-editor-button-delete"
              type="icon ghost"
              data-l10n-id="tab-note-editor-button-delete">
          </html:moz-button>
          <html:div
            id="tab-note-overflow-indicator">
          </html:div>
          <html:moz-button-group
              id="tab-note-default-actions">
              <html:moz-button
                  id="tab-note-editor-button-cancel"
                  data-l10n-id="tab-note-editor-button-cancel">
              </html:moz-button>
              <html:moz-button
                  type="primary"
                  id="tab-note-editor-button-save"
                  data-l10n-id="tab-note-editor-button-save">
              </html:moz-button>
          </html:moz-button-group>
        </html:div>

    </panel>
       `;

    #initialized = false;
    #panel;
    #noteField;
    #headerEl;
    #separatorEl;
    #titleNode;
    /** @type {MozTabbrowserTab} */
    #currentTab = null;
    /** @type {boolean|null} */
    #createMode = null;
    #cancelButton;
    #saveButton;
    #deleteButton;
    #overflowIndicator;
    /** @type {TabNoteTelemetrySource|null} */
    #telemetrySource = null;

    connectedCallback() {
      if (this.#initialized) {
        return;
      }

      this.textContent = "";
      this.appendChild(this.constructor.fragment);
      this.initializeAttributeInheritance();

      this.#panel = this.querySelector("panel");
      this.#noteField = document.getElementById("tab-note-text");
      this.#headerEl = this.querySelector("#tab-note-editor-header");
      this.#separatorEl = this.querySelector("#tab-note-editor-separator");
      this.#titleNode = this.querySelector("#tab-note-editor-title");
      this.#cancelButton = this.querySelector("#tab-note-editor-button-cancel");
      this.#saveButton = this.querySelector("#tab-note-editor-button-save");
      this.#deleteButton = this.querySelector("#tab-note-editor-button-delete");
      this.#overflowIndicator = this.querySelector(
        "#tab-note-overflow-indicator"
      );

      this.#cancelButton.addEventListener("click", () => {
        this.#panel.hidePopup();
      });
      this.#saveButton.addEventListener("click", () => {
        this.saveNote();
      });
      this.#deleteButton.addEventListener("click", () => {
        this.#deleteNote();
      });
      this.#panel.addEventListener("keypress"this);
      this.#panel.addEventListener("popuphidden"this);
      this.#noteField.addEventListener("input"this);

      this.#initialized = true;
    }

    on_keypress(event) {
      if (event.defaultPrevented) {
        // The event has already been consumed inside of the panel.
        return;
      }

      switch (event.keyCode) {
        case KeyEvent.DOM_VK_ESCAPE:
          this.#panel.hidePopup();
          break;
        case KeyEvent.DOM_VK_RETURN:
          if (!event.shiftKey && event.target === this.#noteField) {
            this.saveNote();
          }
          break;
      }
    }

    on_input() {
      this.#updatePanel();
    }

    on_popuphidden() {
      this.#currentTab = null;
      this.#noteField.value = "";
      this.#telemetrySource = null;
    }

    get createMode() {
      return this.#createMode;
    }

    set createMode(createModeEnabled) {
      if (this.#createMode == createModeEnabled) {
        return;
      }
      let headerL10nId = createModeEnabled
        ? "tab-note-editor-title-create"
        : "tab-note-editor-title-edit";
      this.#titleNode.innerText =
        gBrowser.tabLocalization.formatValueSync(headerL10nId);
      this.#headerEl.hidden = !createModeEnabled;
      this.#separatorEl.hidden = !createModeEnabled;
      this.#deleteButton.hidden = createModeEnabled;
      this.#panel.setAttribute(
        "aria-label",
        gBrowser.tabLocalization.formatValueSync(headerL10nId)
      );

      this.#createMode = createModeEnabled;
    }

    get #panelPosition() {
      if (gBrowser.tabContainer.verticalMode) {
        return SidebarController._positionStart
          ? "topleft topright"
          : "topright topleft";
      }
      return "bottomleft topleft";
    }

    #updatePanel() {
      const inputLength = this.#noteField.value.length;
      const trimmedLength = this.#noteField.value.trim().length;

      let overflow;
      if (inputLength > OVERFLOW_MAX_THRESHOLD) {
        overflow = OverflowState.OVERFLOW;
      } else if (inputLength > OVERFLOW_WARNING_THRESHOLD) {
        overflow = OverflowState.WARN;
      } else {
        overflow = OverflowState.NONE;
      }

      this.#saveButton.disabled =
        overflow == OverflowState.OVERFLOW || trimmedLength === 0;

      if (overflow != OverflowState.NONE) {
        this.#panel.setAttribute("overflow", overflow);
        this.#overflowIndicator.innerText =
          gBrowser.tabLocalization.formatValueSync(
            "tab-note-editor-character-limit",
            {
              totalCharacters: inputLength,
              maxAllowedCharacters: OVERFLOW_MAX_THRESHOLD,
            }
          );
      } else {
        this.#panel.removeAttribute("overflow");
      }

      // Manually adjust panel height and scroll behaviour to compensate for input size
      // CSS has a `field-sizing` attribute that does this automatically,
      // but it is not yet supported.
      // TODO bug2006439: Replace this with `field-sizing` after the implementation of bug1832409
      this.#noteField.style.height = "auto"// Reset height so previous manual adjustments do not affect calculations
      let computedStyle = getComputedStyle(this.#noteField);
      let contentHeight =
        this.#noteField.scrollHeight -
        parseFloat(computedStyle.paddingTop) -
        parseFloat(computedStyle.paddingBottom);
      this.#noteField.style.height = `${contentHeight}px`;
    }

    /**
     * @param {MozTabbrowserTab} tab
     *   The tab whose note this panel will control.
     * @param {object} [options]
     * @param {TabNoteTelemetrySource} [options.telemetrySource]
     *   The UI surface that requested to open this panel.
     */

    openPanel(tab, options = {}) {
      if (!TabNotes.isEligible(tab)) {
        return;
      }
      // Lazily set the icon to avoid loading it at startup
      if (!this.#deleteButton.iconSrc) {
        this.#deleteButton.iconSrc = "chrome://global/skin/icons/delete.svg";
      }
      this.#currentTab = tab;
      this.#telemetrySource = options.telemetrySource;

      TabNotes.get(tab).then(note => {
        if (note) {
          this.createMode = false;
          this.#noteField.value = note.text;
        } else {
          this.createMode = true;
        }

        this.#panel.addEventListener(
          "popupshown",
          () => {
            this.#noteField.focus();
          },
          {
            once: true,
          }
        );
        this.#panel.openPopup(tab, {
          position: this.#panelPosition,
        });

        this.#updatePanel();
      });
    }

    saveNote() {
      let note = this.#noteField.value;

      if (
        TabNotes.isEligible(this.#currentTab) &&
        note.trim().length &&
        note.length <= OVERFLOW_MAX_THRESHOLD
      ) {
        TabNotes.set(this.#currentTab, note, {
          telemetrySource: this.#telemetrySource,
        });
      }

      this.#panel.hidePopup();
    }

    #deleteNote() {
      if (TabNotes.isEligible(this.#currentTab)) {
        TabNotes.delete(this.#currentTab, {
          telemetrySource: this.#telemetrySource,
        });
      }
      this.#panel.hidePopup();
    }
  }

  customElements.define("tabnote-menu", MozTabbrowserTabNoteMenu);
}

Messung V0.5 in Prozent
C=95 H=98 G=96

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

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.