1. Nachrichten
  2. Forum
    1. Unerledigte Themen
    2. Forenregeln
  3. Spenden
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. camp-firefox.de
  2. Sören Hentzschel

Beiträge von Sören Hentzschel

  • extras_config_menu.uc.js in Fx 139 keine Funktion mehr

    • Sören Hentzschel
    • 3. April 2025 um 15:48

    Ich denke, das Thema hat sich erledigt, da Mozilla für Nutzer von Scripts eine Ausnahme implementiert:

    1958232 - Allow eval in browser.xhtml for users with userChromeJs
    ASSIGNED (tschuster) in Core - DOM: Security. Last updated 2025-04-03.
    bugzilla.mozilla.org
  • extras_config_menu.uc.js in Fx 139 keine Funktion mehr

    • Sören Hentzschel
    • 3. April 2025 um 11:51

    Die Schwierigkeit sehe ich hier gar nicht als das große Problem. Es ist bei diesem Script aber so, dass dort viel mit Funktionen gearbeitet wird, die dann das jeweilige Script weitergeben. Man wird da Dinge etwas anders aufbauen müssen. Es reicht hier nicht, nur die eine Stelle mit dem nicht mehr erlaubten Aufruf anzupassen. Und damit wird das zu einem Aufwands-Thema. Mir fehlt dafür aktuell leider die Zeit.

  • extras_config_menu.uc.js in Fx 139 keine Funktion mehr

    • Sören Hentzschel
    • 3. April 2025 um 11:32

    Function() ist im Endeffekt genau das Gleiche wie eval(). Das JavaScript muss direkt integriert werden statt in Strings verpackt zu werden, die dann als Variablen genutzt werden.

  • Der Glückwunsch-Thread

    • Sören Hentzschel
    • 3. April 2025 um 10:58

    Alles Gute!

  • Toolbox Button.uc.js funktioniert nur teilweise in Fx 139

    • Sören Hentzschel
    • 3. April 2025 um 10:13
    Zitat von 2002Andreas

    Naja, ich sehe schon einen riesen Unterschied zwischen einem unsicheren Betriebssystem, einer alten Firefox Version, oder einem Skript für Firefox.

    Bei dem obigen Skript, oder auch bei meinem anderen Skript extras_config_menu.uc.js sehe ich als Laie zumindest keine Sicherheitsbedenken.

    Gefahrlos ist das nicht. Das Script überschreibt eine interne Firefox-Funktion. Wenn in dieser Funktion eine Sicherheitslücke steckt, die Mozilla mit dem nächsten Update behebt, hast du weiter die Sicherheitslücke, bis du das Script an den neuen Firefox-Code anpasst - wovon du aber wahrscheinlich gar nichts mitbekommst, weil du nach jedem Update den Code abgleichen müsstest, um Unterschiede festzustellen.

    Sicherheit durch Eigenverantwortung ist kein funktionierendes Konzept. ;)

  • Desktop Ansicht

    • Sören Hentzschel
    • 3. April 2025 um 09:50

    Alles gut. ;) Sobald du Firefox 137 hast: Menü → Einstellungen → Website-Einstellungen → Desktop-Website immer anfordern.

  • Toolbox Button.uc.js funktioniert nur teilweise in Fx 139

    • Sören Hentzschel
    • 3. April 2025 um 00:06

    „Sollte jetzt selbst entscheiden können“ ist genau das, was auch Nutzer von Windows 7 sagen. ;)

    PS: Ich hatte mich schon gefragt, wieso dieses Script eine vergleichsweise hohe Code-Qualität mit ausführlicher Code-Dokumentation und ordentlicher Einrückung besitzt. Das Script stammt von einem Mozilla-Mitarbeiter. Das erklärt es wohl. Und erhöht vielleicht auch die Chance, dass es eine Lösung direkt vom Erzeuger des Scripts geben wird. ;)


    Nachtrag: Ich hab's jetzt einfach selbst angepasst:

    JavaScript
    // ==UserScript==
    // @name           Toolbox Button
    // @version        1.4.0
    // @author         aminomancer
    // @homepageURL    https://github.com/aminomancer/uc.css.js
    // @long-description
    // @description
    /*
    Adds a new toolbar button that 1) opens the content toolbox on left click; 2) opens the browser toolbox on right click; 3) toggles "Popup Auto-Hide" on middle click. Left click will open the toolbox for the active tab, or close it if it's already open. Right click will open the elevated browser toolbox if it's not already open. If it is already open, then instead of trying to start a new process and spawning an irritating dialog, it'll just show a brief notification saying the toolbox is already open. The button also shows a badge while a toolbox window is open. Middle click will toggle the preference for popup auto-hide: `ui.popup.disable_autohide`. This does the same thing as the "Disable Popup Auto-Hide" option in the menu at the top right of the browser toolbox, prevents popups from closing so you can debug them.
    
    If you want to change which mouse buttons execute which functions, search for `userChrome.toolboxButton.mouseConfig` in <about:config>. Change the 0, 1, and 2 values. 0 = left click, 1 = middle, and 2 = right. By default, when you open a browser toolbox window, the script will disable popup auto-hide, and then re-enable it when you close the toolbox. I find that I usually want popup auto-hide disabled when I'm using the toolbox, and never want it disabled when I'm not using the toolbox, so I made it automatic, instead of having to right click and then immediately middle click every time. If you don't like this automatic feature, you can turn it off by setting `userChrome.toolboxButton.popupAutohide.toggle-on-toolbox-launch` to false in about:config.
    
    You can force the browser toolbox to open in multiprocess mode by holding Shift and Accel (Ctrl/Cmd) when you right click (or whatever mouse button you set `browserToolbox` to for `userChrome.toolboxButton.mouseConfig`) the button.
    
    When you middle click, the button will show a notification telling you the current status of popup auto-hide, e.g. "Holding popups open." This is just so that people who use the feature a lot won't lose track of whether it's on or off, and won't need to open a popup and try to close it to test it. The toolbar button also changes appearance while popup auto-hide is disabled. It becomes blue like the downloads button and the icon changes into a popup icon. This change is animated, as long as the user doesn't have reduced motion enabled. All of these notifications use the native confirmation hint custom element, since it looks nice. That's the one that appears when you save a bookmark, `#confirmation-hint`. So you can customize them with that selector.
    */
    // @downloadURL    https://cdn.jsdelivr.net/gh/aminomancer/uc.css.js@master/JS/atoolboxButton.uc.js
    // @updateURL      https://cdn.jsdelivr.net/gh/aminomancer/uc.css.js@master/JS/atoolboxButton.uc.js
    // @license        This Source Code Form is subject to the terms of the Creative Commons Attribution-NonCommercial-ShareAlike International License, v. 4.0. If a copy of the CC BY-NC-SA 4.0 was not distributed with this file, You can obtain one at http://creativecommons.org/licenses/by-nc-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
    // ==/UserScript==
    
    
    (() => {
      // Modify these strings for easy localization. I tried to use built-in strings
      // for this so it would automatically localize itself, but I found that every
      // reference to the "Browser Toolbox" throughout the entire firefox UI is
      // derived from a single message in a single localization file, which doesn't
      // follow the standard format. It can only be parsed by the devtools' own
      // special l10n module, which itself can only be imported by a CJS module.
      // Requiring CJS just for a button seems ridiculous, plus there really aren't
      // any localized strings that work for these confirmation messages anyway, or
      // even the tooltip. So if your UI language isn't English you can modify all the
      // strings created by this script in the following object:
      const l10n = {
        // Confirmation hint. You receive this message when you right click the
        // toolbox button, but a toolbox process for the window is already open. You
        // can only have one toolbox open per-window. So if I have 3 windows open, and
        // I right-click the toolbox button in window 1, then it'll launch a browser
        // toolbox for window 1. If I then right-click the toolbox button in window 2,
        // it'll launch a browser toolbox for window 2. But if I go back to window 1
        // and right-click the toolbox button a second time, it will do nothing except
        // show a brief confirmation hint to explain the lack of action.
        alreadyOpenMsg: "Browser Werkzeuge sind bereits geöffnet.",
        // Confirmation hint. This appears when you first middle-click the toolbox
        // button. It signifies that popups are being kept open. That is, "popup
        // auto-hide" has been temporarily disabled.
        holdingOpenMsg: "Popups werden offen gehalten.",
        // Confirmation hint. This appears when you middle-click the toolbox button a
        // second time, toggling "popup auto-hide" back on, thereby allowing popups to
        // close on their own.
        lettingCloseMsg: "Popups werden automatisch geschlossen.",
    
    
        bundles: {},
        strings: new Map(),
        getString(name, where) {
          let string = this.strings.get(name);
          if (string) return string;
          string = this.bundles[where].GetStringFromName(name);
          this.strings.set(name, string);
          return string;
        },
        getFluentValue(id, args) {
          return this.fluentStrings.formatValueSync(id, args);
        },
        get defaultLabel() {
          return this.getString("toolbox.label", "toolbox");
        },
        get defaultTooltip() {
          return this.defaultLabel;
        },
      };
      ChromeUtils.defineLazyGetter(l10n.bundles, "menu", () =>
        Services.strings.createBundle("chrome://devtools/locale/menus.properties")
      );
      ChromeUtils.defineLazyGetter(l10n.bundles, "toolbox", () =>
        Services.strings.createBundle("chrome://devtools/locale/toolbox.properties")
      );
      ChromeUtils.defineLazyGetter(
        l10n,
        "fluentStrings",
        () => new Localization(["devtools/client/toolbox.ftl"], true)
      );
    
      if (
        /^chrome:\/\/browser\/content\/browser.(xul||xhtml)$/i.test(location) &&
        !CustomizableUI.getPlacementOfWidget("toolbox-button", true)
      ) {
        const { loader } = ChromeUtils.importESModule(
          "resource://devtools/shared/loader/Loader.sys.mjs"
        );
        const lazy = {};
        ChromeUtils.defineESModuleGetters(lazy, {
          BrowserToolboxLauncher:
            "resource://devtools/client/framework/browser-toolbox/Launcher.sys.mjs",
        });
        for (const [key, val] of Object.entries({
          gDevToolsBrowser:
            "resource://devtools/client/framework/devtools-browser.js",
          Actor: "resource://devtools/shared/protocol/Actor.js",
          dumpn: "resource://devtools/shared/DevToolsUtils.js",
        })) {
          loader.lazyRequireGetter(lazy, key, val, true);
        }
    
        if (location.href !== 'chrome://browser/content/browser.xhtml') return;
    
    
        CustomizableUI.createWidget({
          id: "toolbox-button",
          type: "custom",
          defaultArea: CustomizableUI.AREA_NAVBAR,
          label: l10n.defaultLabel,
          removable: true,
          overflows: true,
          tooltiptext: l10n.defaultTooltip,
          onBuild(aDoc) {
            let CustomHint = {
              ...aDoc.ownerGlobal.ConfirmationHint,
    
              /**
               * Shows a transient, non-interactive confirmation hint anchored to an
               * element, usually used in response to a user action to reaffirm that
               * it was successful and potentially provide extra context.
               *
               * @param  anchor (DOM node, required)
               *         The anchor for the panel. A value of null will anchor to the
               *         viewpoint (see options.x below)
               * @param  message (string, required)
               *         The message to be shown.
               * @param  options (object, optional)
               *         An object with any number of the following optional properties:
               *         - event (DOM event): The event that triggered the feedback.
               *         - hideArrow (boolean): Optionally hide the arrow.
               *         - hideCheck (boolean): Optionally hide the checkmark.
               *         - description (string): If provided, show a more detailed
               *                                 description/subtitle with the passed text.
               *         - duration (numeric): How long the hint should stick around, in
               *                               milliseconds. Default is 1500 — 1.5 seconds.
               *         - position (string): One of a number of strings representing how the anchor point of the popup
               *                              is aligned relative to the anchor point of the anchor node.
               *                              Possible values for position are:
               *                                  before_start, before_end, after_start, after_end,
               *                                  start_before, start_after, end_before, end_after,
               *                                  overlap, after_pointer
               *                              For example, after_start means the anchor node's bottom left corner will
               *                              be aligned with the popup node's top left corner. overlap means their
               *                              top left corners will be lined up exactly, so they will overlap.
               *         - x (number): Horizontal offset in pixels, relative to the anchor.
               *                       If no anchor is provided, relative to the viewport.
               *         - y (number): Vertical offset in pixels, relative to the anchor. Negative
               *                       values may also be used to move to the left and upwards respectively.
               *                       Unanchored popups may be created by supplying null as the
               *                       anchor node. An unanchored popup appears at the position
               *                       specified by x and y, relative to the viewport of the document
               *                       containing the popup node. (ignoring the anchor parameter)
               *
               */
              show(anchor, message, options = {}) {
                this._reset();
    
                this._message.removeAttribute("data-l10n-id");
                this._message.textContent = message;
    
                if (options.description) {
                  this._description.removeAttribute("data-l10n-id");
                  this._description.textContent = options.description;
                  this._description.hidden = false;
                  this._panel.classList.add("with-description");
                } else {
                  this._description.hidden = true;
                  this._panel.classList.remove("with-description");
                }
    
                if (options.hideArrow) {
                  this._panel.setAttribute("hidearrow", "true");
                }
    
                if (options.hideCheck) {
                  this._animationBox.setAttribute("hidden", "true");
                  this._panel.setAttribute("data-message-id", "hideCheckHint");
                } else {
                  this._animationBox.removeAttribute("hidden");
                  this._panel.setAttribute("data-message-id", "checkmarkHint");
                }
    
                const DURATION = options.duration || 1500;
                this._panel.addEventListener(
                  "popupshown",
                  () => {
                    this._animationBox.setAttribute("animate", "true");
                    this._timerID = setTimeout(
                      () => this._panel.hidePopup(true),
                      DURATION + 120
                    );
                  },
                  { once: true }
                );
    
                this._panel.addEventListener("popuphidden", () => this._reset(), {
                  once: true,
                });
    
                let { position, x, y } = options;
                this._panel.openPopup(null, {
                  position,
                  triggerEvent: options.event,
                });
                this._panel.moveToAnchor(anchor, position, x, y);
              },
    
              _reset() {
                if (this._timerID) {
                  clearTimeout(this._timerID);
                  this._timerID = null;
                  this._animationBox.removeAttribute("hidden");
                }
                if (this.__panel) {
                  this._panel.removeAttribute("hidearrow");
                  this._animationBox.removeAttribute("animate");
                  this._panel.removeAttribute("data-message-id");
                  this._panel.hidePopup();
                }
              },
    
              _ensurePanel() {
                if (!this.__panel) {
                  // hook into the built-in confirmation hint element
                  let wrapper = document.getElementById(
                    "confirmation-hint-wrapper"
                  );
                  wrapper?.replaceWith(wrapper.content);
                  this.__panel = ConfirmationHint.__panel =
                    document.getElementById("confirmation-hint");
                }
              },
            };
    
            let toolbarbutton = aDoc.createXULElement("toolbarbutton");
            let badgeStack = aDoc.createXULElement("stack");
            let icon = aDoc.createXULElement("image");
            let label = aDoc.createXULElement("label");
            let badgeLabel = aDoc.createElement("label");
            for (const [key, val] of Object.entries({
              class: "toolbarbutton-1 chromeclass-toolbar-additional",
              badged: true,
              label: l10n.defaultLabel,
              id: "toolbox-button",
              role: "button",
              icon: "toolbox",
              removable: true,
              overflows: true,
              tooltiptext: l10n.defaultTooltip,
            })) {
              toolbarbutton.setAttribute(key, val);
            }
    
            toolbarbutton.appendChild(badgeStack);
            badgeStack.after(label);
            badgeStack.appendChild(icon);
            icon.after(badgeLabel);
            badgeStack.setAttribute("class", "toolbarbutton-badge-stack");
            icon.setAttribute("class", "toolbarbutton-icon");
            badgeLabel.setAttribute("class", "toolbarbutton-badge");
            for (const [key, val] of Object.entries({
              class: "toolbarbutton-text",
              crop: "right",
              flex: "1",
              value: l10n.defaultLabel,
            })) {
              label.setAttribute(key, val);
            }
    
            let prefSvc = Services.prefs;
            let defaultPrefs = prefSvc.getDefaultBranch("");
            let obSvc = Services.obs;
            let toolboxBranch = "userChrome.toolboxButton";
            let autoHide = "ui.popup.disable_autohide";
            let autoTogglePopups =
              "userChrome.toolboxButton.popupAutohide.toggle-on-toolbox-launch";
            let mouseConfig = "userChrome.toolboxButton.mouseConfig";
    
            let onClick = function (e) {
              let { button } = e;
              let accel = e.getModifierState("Accel");
              let shift = e.getModifierState("Shift");
              if (accel) {
                if (button == 2 && !shift) {
                  return;
                }
                if (button == 0 && AppConstants.platform == "macosx") {
                  button = 2;
                  accel = false;
                }
              }
              switch (button) {
                case this.mouseConfig.contentToolbox:
                  // toggle the content toolbox
                  lazy.gDevToolsBrowser.toggleToolboxCommand(
                    aDoc.ownerGlobal.gBrowser
                  );
                  break;
                case this.mouseConfig.browserToolbox:
                  if (lazy.BrowserToolboxLauncher.getBrowserToolboxSessionState()) {
                    // check if a browser toolbox window is already open. if so,
                    // just show a hint that it's already open.
                    CustomHint.show(toolbarbutton, l10n.alreadyOpenMsg, {
                      event: e,
                      hideCheck: true,
                    });
                  } else {
                    // if not, launch a new one.
                    lazy.BrowserToolboxLauncher.init({
                      forceMultiprocess: accel && shift,
                    });
                  }
                  break;
                case this.mouseConfig.popupHide:
                  CustomHint.show(
                    toolbarbutton,
                    l10n[this.popupAutoHide ? "lettingCloseMsg" : "holdingOpenMsg"],
                    { event: e, hideCheck: this.popupAutoHide }
                  );
                  // toggle the pref
                  prefSvc.setBoolPref(autoHide, !this.popupAutoHide);
                  // animate the icon transformation
                  this.triggerAnimation();
                  break;
                default:
                  return;
              }
              e.preventDefault();
            };
    
            if (AppConstants.platform === "macosx") {
              toolbarbutton.onmousedown = onClick;
              toolbarbutton.onclick = e => {
                if (e.getModifierState("Accel")) return;
                e.preventDefault();
              };
            } else {
              toolbarbutton.onclick = onClick;
            }
    
            toolbarbutton.triggerAnimation = function () {
              this.addEventListener(
                "animationend",
                () => this.removeAttribute("animate"),
                { once: true }
              );
              this.setAttribute("animate", "true");
            };
    
            function getPref(root, pref) {
              switch (root.getPrefType(pref)) {
                case root.PREF_BOOL:
                  return root.getBoolPref(pref);
                case root.PREF_INT:
                  return root.getIntPref(pref);
                case root.PREF_STRING:
                  return root.getStringPref(pref);
                default:
                  return null;
              }
            }
    
            function prefObserver(sub, _top, pref) {
              let value = getPref(sub, pref);
              switch (pref) {
                case autoHide:
                  if (value === null) value = false;
                  toolbarbutton.popupAutoHide = value;
                  if (value) {
                    // change icon src to popup icon
                    toolbarbutton.setAttribute("icon", "autohide");
                    // highlight color
                    icon.style.fill = "var(--toolbarbutton-icon-fill-attention)";
                  } else {
                    // change icon src to toolbox icon
                    toolbarbutton.setAttribute("icon", "toolbox");
                    // un-highlight color
                    icon.style.removeProperty("fill");
                  }
                  break;
                case autoTogglePopups:
                  if (value === null) value = true;
                  toolbarbutton.autoTogglePopups = value;
                  break;
                case mouseConfig:
                  if (value === null) {
                    value = {
                      contentToolbox: 0,
                      browserToolbox: 2,
                      popupHide: 1,
                    };
                  }
                  toolbarbutton.mouseConfig = JSON.parse(value);
                  toolbarbutton.setStrings();
                  break;
              }
            }
    
            // listen for toolboxes opening and closing
            function toolboxObserver(sub, top, _data) {
              // whether a toolbox is open
              let state =
                lazy.BrowserToolboxLauncher.getBrowserToolboxSessionState();
              // set toolbar button's badge content
              badgeLabel.textContent = state ? 1 : "";
              // if toolbox is open and autohide is not already enabled, enable it
              switch (top) {
                case "initial-load":
                  return;
                // when a thread is created, set up its destroy method so it will
                // call the observer when it's destroyed. this ensures that if a
                // toolbox is closed while a content toolbox is inspecting the
                // system principal (such as on about:preferences), we will still
                // get notified that the toolbox has closed. otherwise, we wouldn't
                // get notified until the content toolbox also closes.
                case "devtools-thread-ready": {
                  let threadActor = sub?.wrappedJSObject;
                  if (threadActor) {
                    if (threadActor.destroy.name !== "destroyThreadActor") {
                      const STATES = {
                        DETACHED: "detached",
                        EXITED: "exited",
                        RUNNING: "running",
                        PAUSED: "paused",
                      };
    
                      threadActor.destroy = function destroyThreadActor() {
                        lazy.dumpn("in ThreadActor.prototype.destroy");
                        if (this._state == STATES.PAUSED) {
                          this.doResume();
                        }
    
                        this.removeAllWatchpoints();
                        this._xhrBreakpoints = [];
                        this._updateNetworkObserver();
    
                        this._activeEventBreakpoints = new Set();
                        this._debuggerNotificationObserver.removeListener(
                          this._eventBreakpointListener
                        );
    
                        for (const global of this.dbg.getDebuggees()) {
                          try {
                            this._debuggerNotificationObserver.disconnect(
                              global.unsafeDereference()
                            );
                          } catch (e) {
                          }
                        }
    
                        this.targetActor.off("window-ready", this._onWindowReady);
                        this.targetActor.off("will-navigate", this._onWillNavigate);
                        this.targetActor.off("navigate", this._onNavigate);
    
                        this.sourcesManager.off("newSource", this.onNewSourceEvent);
                        this.clearDebuggees();
                        this._threadLifetimePool.destroy();
                        this._threadLifetimePool = null;
                        this._dbg = null;
                        this._state = STATES.EXITED;
    
                        lazy.Actor.prototype.destroy.call(this);
                        // this leads back to toolboxObserver in 200ms
                        setTimeout(() => Services.obs.notifyObservers(null, "devtools-thread-destroyed"), 200);
                      }
                    }
                  }
                  break;
                }
                default:
                  break;
              }
              if (!toolbarbutton.autoTogglePopups) return;
              if (state && !toolbarbutton.popupAutoHide) {
                prefSvc.setBoolPref(autoHide, true);
              }
              // if toolbox just closed and autohide is not already disabled, disable it
              else if (!state && toolbarbutton.popupAutoHide) {
                prefSvc.setBoolPref(autoHide, false);
              }
            }
    
            toolbarbutton.setStrings = function () {
              let hotkey, labelString;
              for (const [key, val] of Object.entries(toolbarbutton.mouseConfig)) {
                if (val === 0) {
                  switch (key) {
                    case "contentToolbox":
                      labelString = l10n.getString("toolbox.label", "toolbox");
                      hotkey = aDoc.getElementById("key_toggleToolbox");
                      break;
                    case "browserToolbox":
                      labelString = l10n.getString(
                        "browserToolboxMenu.label",
                        "menu"
                      );
                      hotkey = aDoc.getElementById("key_browserToolbox");
                      break;
                    case "popupHide":
                      labelString = l10n.getFluentValue(
                        "toolbox-meatball-menu-noautohide-label"
                      );
                      break;
                  }
                }
              }
              let shortcut = hotkey
                ? ` (${ShortcutUtils.prettifyShortcut(hotkey)})`
                : "";
              toolbarbutton.label = labelString;
              label.value = labelString;
              toolbarbutton.tooltipText = labelString + shortcut;
            };
    
            // remove this window's observers when the window closes, since observers are global
            function uninit() {
              prefSvc.removeObserver(autoHide, prefObserver);
              prefSvc.removeObserver(toolboxBranch, prefObserver);
              for (const topic of [
                "devtools-thread-ready",
                "devtools-thread-destroyed",
                "devtools:loader:destroy",
              ]) {
                obSvc.removeObserver(toolboxObserver, topic);
              }
              window.removeEventListener("unload", uninit);
            }
    
            function toolboxInit() {
              prefObserver(prefSvc, null, autoHide);
              prefObserver(prefSvc, null, autoTogglePopups);
              prefObserver(prefSvc, null, mouseConfig);
              toolboxObserver(null, "initial-load");
            }
    
            defaultPrefs.setBoolPref(autoTogglePopups, true);
            defaultPrefs.setStringPref(
              mouseConfig,
              `{"contentToolbox": 0, "browserToolbox": 2, "popupHide": 1}`
            );
            window.addEventListener("unload", uninit);
            prefSvc.addObserver(autoHide, prefObserver);
            prefSvc.addObserver(toolboxBranch, prefObserver);
            for (const topic of [
              "devtools-thread-ready",
              "devtools-thread-destroyed",
              "devtools:loader:destroy",
            ]) {
              obSvc.addObserver(toolboxObserver, topic);
            }
            if (gBrowserInit.delayedStartupFinished) {
              toolboxInit();
            } else {
              let delayedListener2 = (subject, topic) => {
                if (
                  topic == "browser-delayed-startup-finished" &&
                  subject == window
                ) {
                  obSvc.removeObserver(delayedListener2, topic);
                  toolboxInit();
                }
              };
              obSvc.addObserver(
                delayedListener2,
                "browser-delayed-startup-finished"
              );
            }
            return toolbarbutton;
          },
        });
      }
    
      let styleSvc = Cc["@mozilla.org/content/style-sheet-service;1"].getService(
        Ci.nsIStyleSheetService
      );
      let toolboxCSS = /* css */ `
      .toolbarbutton-1#toolbox-button {
        --uc-toolbox-button: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAdUlEQVQokZVSwRHAIAgLPYfoXs7RCTpG53Avt7APrhaFU8gLMEEJAkEQgFbc7IxkVjt0r6Sp7VIVITumBpKt00FA2ThmjXzkfMMWO8EZFSj8LrUyjsG9b9DaJXq+qAIVxEUxtLHpaXE95dj1NcK2rmbwaGJ4Af0tIg00j/6iAAAAAElFTkSuQmCC');
        --uc-autohide-button: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAATCAYAAABlcqYFAAABeUlEQVQ4ja3UMSiEcRjH8Z8jKWU8q03JYEAhZ7PcZDFYrMpOWaTEgsEom4RFBmEjcSaEU0onFN0Rd9dFzr3er+Ut7vV/eS/vU7/l3/s8n/f/PvVKrkKKIm0hJZEoIUmkTaQO90w3MFniYK8MewHRgACQLKRmE7IRIALSkglJBYzcmhDPhrtwGJ6fIZeDTOYrwF5ri2dfSchBZxumOpoY5+mXvpKQ7NzID+Dl4Z6TitCvn8w3kpbIJS5dxBv7TbV/7sU3chOuAssqIqzMOfGZUV5W1yAWIzE4+D9kp6vLGf0KWLjrIx9nO9L4T6SmhrWePs7GI2A/FgHvJ/PEqwNaPBLHPZEi4HB6ipugdoJEQeJqZRYAO59kt7+B1B+AF+L5101UCgppwOYwWmceWubk6+zChKx7IamVXk6XxzgtD/Hh4wZOFkxIO5LtfjgrsdVdRjzkPdAA55HqfyAONIRU8Pmm2ObzPNKAEfgGNSMtIl37xZxcIy2YbvAJBGtcN/WRF/UAAAAASUVORK5CYII');
        list-style-image: var(--uc-toolbox-button);
        align-items: center;
      }
      .toolbarbutton-1#toolbox-button[icon="autohide"] {
        list-style-image: var(--uc-autohide-button);
      }
      .toolbarbutton-1#toolbox-button .toolbarbutton-badge-stack {
        justify-items: center;
      }
      .toolbarbutton-1#toolbox-button .toolbarbutton-icon {
        height: 16px;
        width: 16px;
        transition: fill 50ms ease-in-out 0s;
        background-image: var(--uc-toolbox-button), var(--uc-autohide-button);
        background-size: 0, 0;
      }
      @media (prefers-reduced-motion: no-preference) {
        .toolbarbutton-1#toolbox-button[animate] .toolbarbutton-icon {
          animation-name: toolboxButtonPulse;
          animation-duration: 200ms;
          animation-iteration-count: 1;
          animation-timing-function: ease-in-out;
        }
      }
      @keyframes toolboxButtonPulse {
        from {
          transform: scale(1);
        }
        40% {
          transform: scale(0.7);
        }
        to {
          transform: scale(1);
        }
      }
      #confirmation-hint[data-message-id="hideCheckHint"] #confirmation-hint-message {
        margin-inline: 0;
      }`;
    
      if (location.href !== 'chrome://browser/content/browser.xhtml') return;
    
      let styleURI = makeURI(
        `data:text/css;charset=UTF=8,${encodeURIComponent(toolboxCSS)}`
      );
      if (!styleSvc.sheetRegistered(styleURI, styleSvc.AUTHOR_SHEET)) {
        styleSvc.loadAndRegisterSheet(styleURI, styleSvc.AUTHOR_SHEET);
      }
    
      let observer = new MutationObserver(() => {
        if (document.getElementById("key_toggleToolbox")) {
          CustomizableUI.getWidget("toolbox-button")
            .forWindow(window)
            .node.setStrings();
          observer.disconnect();
          observer = null;
        }
      });
      observer.observe(document.body, { childList: true });
    })();
    Alles anzeigen
  • Toolbox Button.uc.js funktioniert nur teilweise in Fx 139

    • Sören Hentzschel
    • 2. April 2025 um 22:10
    Zitat von 2002Andreas

    security.browser_xhtml_csp.enabled

    auf:

    false

    funktioniert die Funktion zumindest erstmal wieder.

    Alternative dazu:

    security.browser_xhtml_csp.enabled => true
    security.browser_xhtml_csp.report-only => true

    Der Unterschied ist, dass der Code dann weiterhin ausgeführt wird, aber Mozilla über die Telemetrie-Funktion Daten darüber erhält, dass ansonsten etwas blockiert wird.

    So oder so wird diese Lösung nicht von Dauer sein.

  • Mozilla veröffentlicht Firefox 137 mit Tab-Gruppen und verbesserter Adressleiste

    • Sören Hentzschel
    • 2. April 2025 um 18:34

    Die meisten der in dem Abschnitt behandelten Neuerungen kannst du in der Zwischenzeit auch manuell aktivieren, indem du über about:config den Schalter browser.urlbar.scotchBonnet.enableOverride auf true setzt. Das ist eine Sammel-Option für mehrere Features.

  • Bookmarks Organizer - Probleme

    • Sören Hentzschel
    • 2. April 2025 um 14:16
    Zitat von Kakoje

    Sobald man jedoch über eine gewisse Anzahl hinauskommt fehlt bei den Ergebnissen die Möglichkeit die URLs selektiv zu bearbeiten. Man kann entweder nur alle oder nur jeden einzelnen bearbeiten.

    Bei der Überprüfung fehlerhafter Lesezeichen hast du wie gesagt überall unterschiedliche URLs. Und dann ist es selten sinnvoll, mehrere Lesezeichen auf einmal zu bearbeiten, zumal man ja auch jedes Ergebnis einzeln prüfen sollte, weil keine Erweiterung auf der ganzen Welt dazu in der Lage ist, eine Garantie abzugeben. Dafür gibt es zu viele Fälle, bei denen die Website eine Überprüfung verhindert.

    Zitat von Kakoje

    Und das obwohl ich teilweise 20 - 30 auf einmal bearbeiten könnte weil sie einer gewissen Logik folgen, beispielsweise zu einer gemeinsamen Domäne gehören.

    Ich verstehe den Gedanken, aber in der Praxis ist das dann doch nicht so einfach. Wenn du 20 „defekte“ Lesezeichen einer Domain hast, ist ja nicht gesagt, dass für alle gilt, dass sich einfach nur die Domain geändert hat. Manche der Lesezeichen können ja auch wirklich nicht mehr gültig sein. Dann müsste man die alle manuell auswählen, nachdem man diese alle einzeln überprüft hat, und aufpassen, dass man die richtigen zum Bearbeiten auswählt. Ob man dann wirklich noch so viel schneller ist, da bin ich mir nicht sicher.

    Zitat von Kakoje

    Wenn du dir ein ähnliches Tool wie beispielsweise Lesezeichenduplikate von Martin Väth anschaust so hat dies zwar weniger Grundfunktionalitäten, man kann jedoch die Ergebnisse sowohl einzeln markieren als auch nach bestimmten Vorgaben wie "alle außer den Gruppenjüngsten markieren". Die Löschung der Markierten erfolgt dann zu jedem beliebigen Zeitpunkt. So kann man Schritt für Schritt seine Favoriten verbessern.

    Doch auch Lesezeichenduplikate hat längst nicht alle Nachbearbeitungs-Funktionalitäten die ich mir wünschen würde. Nahezu optimal wird dies in dem Tool Alldup (kein FF Add-on, gibt es auch portable zum mal schnell schauen, was gemeint ist) gelöst. Dort kann man die Ergebnisse beispielsweise nach bestimmten Strings durchsuchen und dann alle gefundenen Ergebnisse markieren und danach löschen. So ist es einfach möglich auch alle Ergebnisse eines bestimmten Unterordners zu finden und gemeinsam zu löschen. Das fehlt mir beim Bookmark Organizer total.

    Die Erkennung von Duplikaten ist ein Feature, welches im Bookmarks Organizer eher unter „das kann es auch“ läuft. Da liefert die Erweiterung wirklich nur eine minimale Form der Unterstützung. Die Stärke vom Bookmarks Organizer - mit den grundsätzlichen Einschränkungen dieser Kategorie von Erweiterung - ist die Überprüfung auf fehlerhafte Lesezeichen. Wenn du viel mit Duplikaten zu tun hast, würde auch ich dir empfehlen, besser eine andere Erweiterung zu verwenden.

    Bei allem musst du auch eines bedenken: Von so mancher möglichen Verbesserung profitiert man natürlich umso stärker, je mehr Lesezeichen man hat. Wenn du 20.000 Lesezeichen hast, ist das ein Extrem-Fall. Basierend auf Zahlen aus dem Jahr 2021, weil ich gerade keine aktuelleren Zahlen habe, nutzen mehr als 93 Prozent der Firefox-Nutzer jeweils weniger als 100 (!) Lesezeichen. Wenn wir auf maximal 275 Lesezeichen gehen, dann sind wir bereits bei 97,5 Prozent der Nutzer. Wende ich diese Prozentzahl auf die Anzahl der Nutzer vom Bookmarks Organizer an (weil ich keine eigene Telemetrie in meinen Erweiterungen habe), sprechen wir von nicht einmal 370 Nutzern der Erweiterung mit mehr als 275 Lesezeichen. Auf der anderen Seite bräuchten gerade die Verbesserungen, von denen vor allem die Nutzer mit vielen Lesezeichen profitieren, wirklich viele Stunden an zusätzlicher Entwicklungszeit. Und das bei einer Erweiterung, die so gut wie keine Spenden-Einnahmen bringt und durch oft wirklich nicht faire Nutzer-Bewertungen auch nicht dazu motiviert, die Freizeit dafür zu verwenden. Da passt dann das Verhältnis einfach auf keiner Ebene, zumal ich ja auch nicht unendlich viel Zeit habe und entsprechend priorisieren muss.

    Zitat von Kakoje

    Es wurde nach Beispielen gefragt wo der Bookmark Organizer fehlerhaft meldet. Bei mir wurden alle Instagram Favoriten und alle Favoriten von Google als Fehler ausgewiesen.

    Danke, das werde ich prüfen und ggf. auch auf die Liste setzen.

    Zitat von Kakoje

    Wie schön wäre es gewesen alle diese Favoriten nach einer Textsuche gemeinsam zu Whitelisten?

    Definitiv. Für diesen Fall sowie zum Löschen fände ich eine Mehrfachauswahl auch schön (im Gegensatz zum Bearbeiten, wo ich den Anwendungsfall weniger sehe). Und dafür, das zu implementieren, bin ich auch grundsätzlich offen. Nur wird das realistisch gesehen nicht auf absehbare Zeit durch mich geschehen, da will ich ehrlich sein. Aber einen entsprechenden Community-Beitrag würde ich mit großem Dank annehmen. ;)

    Zitat von Kakoje

    Da du ja auch weiteres konstruktives Feedback haben wolltest: ich hätte mir gewünscht wenn die Fehler weiter aufgesplittet gewesen wären. Also echte 404er, Sicherheitsrisiko und sonstige Gründe. Denn 404er und Sicherheitsrisiko lösche ich unbesehen.

    Das ist leider nicht so einfach, schon damit angefangen, dass ganz viele Websites für eine 404-Seite gar keinen 404-Status senden. Es gibt auch noch andere Gründe, wieso ein Link nicht funktionieren kann, oder wieso der Bookmarks Organizer den Status nicht abfragen kann. Und den exakten Grund sieht die Erweiterung in den meisten Fällen gar nicht. Aus Sicht der Erweiterung gibt es in der Regel nur die Information: Das Lesezeichen funktioniert nicht.

    Zitat von Kakoje

    Daraus ergibt sich auch die durchschnittliche Bewertung von 3,7.

    Teilweise, aber insgesamt wäre das zu einfach betrachtet. Von denen, die konstruktives Feedback haben, erhalte ich tatsächlich oft positive Bewertungen und wenn keine guten Bewertungen, dann zumindest nicht ganz schlecht. Die schlechtesten Bewertungen kommen meistens wirklich von den Nutzern, die glauben, eine solche Erweiterung dürfte keine falschen Ergebnisse liefern. Ein angeblich defektes Lesezeichen funktioniert in Wahrheit doch? Dafür ist der Entwickler mit einem Stern abzustrafen. Das kommt gar nicht so selten vor. Oder wenn es mal einen Fehler gibt, wird auch sofort mit nur einem Stern bewertet, statt den Fehler zu melden und dem Entwickler die Chance auf Behebung zu geben. Das ist eine Verhaltensweise, die ich nicht nachvollziehen kann.

    Meine Erweiterung Keep or Delete Bookmarks hat im Übrigen exakt die identische Funktion zur Überprüfung auf defekte Lesezeichen und insgesamt weniger Features. Würde man strukturiert Ordnung in seine Lesezeichen bringen wollen, wäre die Erweiterung sogar weniger geeignet. Die Erweiterung hat einfach nur ein anderes Bedien-Konzept. Dort geht es über einen spielerischen Weg mit einer zufälligen Lesezeichen-Auswahl. Und die Erweiterung hat wie gesagt einen Bewertungsdurchschnitt von 4,8. Daran sieht man auch, dass es nicht alleine an den Features und der Qualität der Überprüfung liegen kann.

  • Bookmarks Organizer - Probleme

    • Sören Hentzschel
    • 2. April 2025 um 12:12

    Die ARD-Mediathek sendet einen Cross-Origin-Resource-Policy-Header, der externe Aufrufe wie durch den Bookmarks Organizer blockiert. Ich werde mir ansehen, ob ich da eine Möglichkeit habe, ansonsten werde ich die Domain auf die interne Liste der nicht zu prüfenden Domains setzen.

  • Problem nach Anpassung einiger sicherheitsrelevanter Einstellungen

    • Sören Hentzschel
    • 2. April 2025 um 08:21
    Zitat von f2a7b8i

    Die Seite habe ich kurz darauf wieder gefunden, nur deshalb konnte ich mich an diese Einstellung erinnern. Was man von der jetzt halten mag überlasse ich mal euch.

    Wie befürchtet: Die Seite gibt absolut fragwürdige Tipps, die sogar die Sicherheit der Nutzer gefährden. Dass privacy.resistFingerprinting auch nicht die Privatsphäre in dem Sinne verbessert, wie man meinen könnte, habe ich ja schon erklärt. Die Erklärung dieser Seite zu dieser Option ist als Schulnote ausgedrückt eine 6, ungenügend. Der ganze Artikel ist von vorne bis hinten schlecht. Da fehlen ja wirklich beinahe überall relevante Informationen. In der Form ist der Artikel irreführend und erzeugt auf diese Weise Nutzer-Ängste, die völlig unbegründet sind und einen dazu verführen, Änderungen vorzunehmen, für die es gar keinen Grund gibt und die man teilweise sogar unbedingt sein lassen sollte.

    Zitat von f2a7b8i

    Das war eher technisch gemeint. Warum es dies bei der PDF verursacht verstehe ich noch, aber beim Terminal nicht unbedingt. Da hilft mir leider auch die Firefox Support Seite nicht wirklich weiter.

    Die Support-Seite zeigt zumindest, dass dieses Symptom von dieser Option kommt. Wieso das nun ausgerechnet dort auftritt, wird sich nicht sagen lassen, ohne sich das genauer ansehen zu können. Und da es sich dabei um keine öffentliche Website handelt, ist das leider schwierig.

  • Mozilla veröffentlicht Firefox 137 mit Tab-Gruppen und verbesserter Adressleiste

    • Sören Hentzschel
    • 1. April 2025 um 22:53

    Ein neuer Artikel wurde veröffentlicht:

    Zitat
    Mozilla hat Firefox 137 für Windows, Apple macOS und Linux veröffentlicht. Dieser Artikel fasst die wichtigsten Neuerungen zusammen – wie immer auf diesem Blog weit ausführlicher als auf anderen Websites.

    Artikel lesen: „Mozilla veröffentlicht Firefox 137 mit Tab-Gruppen und verbesserter Adressleiste“

  • Firefox schließt sich zufällig – JSON-Datei taucht immer wieder auf

    • Sören Hentzschel
    • 1. April 2025 um 22:24

    Für den Inhalt dieser policies.json-Datei gibt es nur eine einzige Erklärung: Du hast Malware auf deinem System. Diese Konfiguration schaltet unter anderem Sicherheits-Updates, Absturzberichte (was erklärt, wieso es keine neueren Absturzberichte gibt), Telemetrie und das Feature zum Zurücksetzen des Profils ab. Außerdem wird eine Erweiterung in deinem Browser installiert, die nicht deaktiviert werden kann und von der niemand weiß, was sie macht. Möglicherweise ein Keylogger, der deine Passwörter abgreift und irgendwo hin versendet. Wenn nicht das, dann was anderes, was du nicht möchtest. Ich würde bei solch starken Alarmzeichen in jedem Fall vom Schlimmsten ausgehen.

  • FF 137 blockiert Hardware Video Dekodierung in Linux

    • Sören Hentzschel
    • 1. April 2025 um 20:23

    Du könntest mittels mozregression ermitteln, welche Änderung in Firefox 137 den Unterschied für dich verursacht hat:

    mozregression

    Wüsste man das, könnte man vielleicht mehr dazu sagen.

  • Eigener E-Mail-Dienst und KI-Assistent von Thunderbird angekündigt

    • Sören Hentzschel
    • 1. April 2025 um 19:38

    Das Formular sieht gleich aus. Nach dem Absenden erschien vorher aber nur eine 404-Seite. Jetzt funktioniert die Anmeldung und man erhält dann auch eine E-Mail, die man bestätigen muss.

  • Eigener E-Mail-Dienst und KI-Assistent von Thunderbird angekündigt

    • Sören Hentzschel
    • 1. April 2025 um 19:25
    Zitat von .DeJaVu

    Kann sich ja jeder vorab eintragen:
    https://thundermail.com/
    bzw.
    https://tb.pro/

    Die Warteliste wurde mittlerweile repariert. Man kann sich jetzt also eintragen.

  • FF 137 blockiert Hardware Video Dekodierung in Linux

    • Sören Hentzschel
    • 1. April 2025 um 19:16

    Das ist bereits seit Firefox 113 der Fall und der Grund dafür sind Darstellungsprobleme bei der Wiedergabe von Videos.

    1824307 - VAAPI: Small H264 videos in Firefox and Gnome Video are corrupted on AMD RS880
    RESOLVED (stransky) in Core - Audio/Video: Playback. Last updated 2023-03-28.
    bugzilla.mozilla.org
  • Firefox schließt sich zufällig – JSON-Datei taucht immer wieder auf

    • Sören Hentzschel
    • 1. April 2025 um 19:14

    Hallo,

    Zitat von Astros

    oder abstürzt

    Rufe bitte about:crashes auf und verlinke hier die letzten paar Absturzberichte.

    Zitat von Astros

    aber nach einer scheinbar zufälligen Zeit wird sie automatisch wieder erstellt.

    Teile bitte den Inhalt dieser Datei.

  • Code wird doppelt eingetragen in den Browser-Werkzeugen

    • Sören Hentzschel
    • 1. April 2025 um 16:57

    Sätze, die es von einem MacBook-Nutzer niemals geben würde. ;)

Unterstütze uns!

Jährlich (2025)

107,3 %

107,3% (697,41 von 650 EUR)

Jetzt spenden
  1. Kontakt
  2. Datenschutz
  3. Impressum
Community-Software: WoltLab Suite™
Mastodon