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. FuchsFan

Beiträge von FuchsFan

  • Selektor für kleinen Pfeil in CSS-Code zum extra-config-menü.uc.js ab v139

    • FuchsFan
    • 2. Mai 2025 um 15:40

    2002Andreas

    Nun habe ich doch noch einen Weg gefunden, so z.B. für Scripte.

    CSS
    #ExtraConfigMenu-popup:hover menu#submenu-ucjs::after {
      content: "" !important;
      background-image: url("..//icons/down2.png") !important;
      margin-right: 12px !important; 
      display: block !important;
      background-repeat: no-repeat !important;
      background-position: 0px 3px !important;
      background-size: 14px 14px !important;
    }

    Hast du noch eine Idee, wie man das auf die restlichen übertragen könnte (um nicht jedes einzeln aufzuführen)?

  • Selektor für kleinen Pfeil in CSS-Code zum extra-config-menü.uc.js ab v139

    • FuchsFan
    • 2. Mai 2025 um 15:04
    Zitat von milupo

    Meines Erachtens kannst du dir ein zusätzliches background-image sparen, denn mit content: kannst du das genauso ausdrücken. Eine Eigenschaft weniger und keine leere content-Eigenschaft.

    milupo

    Danke für den Hinweis, ich erinnere mich, das haben wir schon mal gemacht.

    Damals beim Einrichten der Seite von camp-firefox z.B.

    CSS
    h1.contentTitle::after {
        font-size: 36px !important;
        content: " F i r e f o x   " url("../icons/FuchsCamp2.png") "   F o r u m" !important;
        color: blue  !important;
        font-weight: 800 !important;
    	font-family: Times New Roman, Times, serif !important;
        font-style: italic !important;
        }
  • Selektor für kleinen Pfeil in CSS-Code zum extra-config-menü.uc.js ab v139

    • FuchsFan
    • 2. Mai 2025 um 14:59
    Zitat von Horstmann

    Unglaublich ....

    Tief Luft holen bringt den Puls wieder in Ordnung. Nun hör bitte auf damit, seid ihr alle unfehlbar?


    Zitat von Horstmann

    Oder mal sowas wie #ExtraConfigMenu-popup > menu:hover menu::after testen, mit oder ohne > ... 8)

    Bringt es auch nicht.:/

  • Selektor für kleinen Pfeil in CSS-Code zum extra-config-menü.uc.js ab v139

    • FuchsFan
    • 2. Mai 2025 um 14:43
    Zitat von Mira_Belle

    Wurdest Du nicht aufgefordert ganze Skripte zu posten?

    Nun fangt doch nicht schon wieder damit an, das nervt ja langsam. Aber du hast ja nicht ganz Unrecht, bitteschön.

    CSS
    // ==UserScript==
    // @name           extras_config_menu.uc.js
    // @compatibility  Firefox 6*.*
    // @include        main
    // @version        1.0.20190504
    // @edit           @aborix - Erweiterung mit Submenüs / 02.12.2022 
    // @edit           @FuchsFan - Erweiterung mit Ordner JS und Submenü Scripte
    // @edit 		   @BrokenHeart	1/25 - Anpass. wg. Änderung der Sicherheitsrichtlinien bei 'inlineEvents'
    // ==/UserScript==
    
    var uProfMenu = {
      // Beginn der Konfiguration
      // In der folgenden Zeile (11) den Pfad zum Texteditor eintragen (unter Ubuntu 10.04 z.B.: '/usr/bin/gedit'). Bei Fehleintrag wird view_source.editor.path ausgelesen:
      //TextOpenExe: 'C:\\Program Files (x86)\\Notepad++\\notepad++.exe',
      TextOpenExe: 'C:\\notepad++\\notepad++.exe',
      // Falls gewuenscht, in Zeile 15 einen Dateimanager eintragen (komplett leer lassen fuer Dateimanager des Systems) Beispiele:
      // vFileManager: 'E:\\Total Commander\\Totalcmd.exe',
      // vFileManager: 'C:\\Program Files (x86)\\FreeCommander\\FreeCommander.exe'
      vFileManager: '',
      // Falls die JavaScript-Scripte nicht im chrome-Verzeichnis, sondern einem Unterverzeichnis sind,
      // in der folgenden Zeile das Unterverzeichnis eintragen, sonst '':
      jsSubfolder: 'Scripte',
      // In der folgenden Zeile (19) 'menu' eintragen, damit es unter "Extras" als Menue erscheint, sonst die id des gewuenschten
      // Elements *nach* dem der Button erscheinen soll (z.B. 'urlbar', 'searchbar', 'undoclosetab-button','abp-toolbarbutton')
      // Bitte nicht so etwas wie die Menue- oder Navigationsleiste (sondern einen Menuepunkt oder einen Button mit id auf diesen Leisten) eintragen:
      warpmenuto: 'searchbar',
     // Unter Linux sollte/kann versucht werden, die userChromeJS-Skripte zu sortieren, unter Windows ist das evtl. nicht noetig (die Sortierung wird Gross- und Kleinschreibung *nicht* beruecksichtigen - dazu wird die sort()-Funktion entsprechend mit einer Vergleichsfunktion aufgerufen)
      sortScripts: 0,   // 1 zum Erzwingen der Sortierung
      // Einbindung GM-Skripte-Ordner (0: nein, 1: Greasemonkey [Profil-Verzeichnis], 2: UserScriptLoader [Chrome-Verzeichnis], 3: Scriptish [Profil-Verzeichnis]):
      gmOrdner: 0,
      // Einbindung CSS-Ordner (0: nein, 1: UserCSSLoader-Ordner im Chrome-Verzeichnis):
      cssOrdner: 0,
      // In Zeile 30 gueltige about:Adressen eintragen, die ebenfalls aufgerufen werden sollen.
      // - Zum Ausblenden: abouts: [],
      // - Damit die about:-Seiten nicht als Untermenue, sondern direkt als Menuepunkte aufgefuehrt werden, muss das erste Element '0' sein:
      // abouts: ['0','about:about','about:addons','about:cache','about:config','about:support'],
      abouts: ['about:about','about:addons','about:buildconfig','about:cache','about:certificate','about:compat','about:config','about:crashes','about:debugging',
               'about:logging','about:logins','about:loginsimportreport','about:memory','about:networking','about:performance','about:plugins','about:policies','about:preferences','about:privatebrowsing','about:profiles','about:processes','about:profiling',
               'about:protections','about:serviceworkers','about:support','about:telemetry','about:third-party','about:unloads','about:url-classifier','about:webrtc','about:welcome','about:welcomeback','about:windows-messages'],
      // Die normalen Firefox-Einstellungen auch zur Verfuegung stellen (0: nein, 1: ja):
      showNormalPrefs: 0,
      // Stellt "Skriptliste in Zwischenablage" zur Verfuegung (1: ja, 2: mit getrennter Nummerierung, 3: mit gemeinsamer Nummerierung) oder nicht (0):
      enableScriptsToClip: 1,
      // Um den Eintrag "Neustart" zu erzwingen (falls z.B. das andere Skript zu spaet eingebunden und nicht erkannt wird), auf 1 setzen:
      enableRestart: 1,
      // Ende der Konfiguration
      
      init: function() {
    	  
    	  if (location != 'chrome://browser/content/browser.xhtml') return;
    	  
        if (this.warpmenuto.toLowerCase() == 'menu') {
          // aufgrund des gewaehlten warpmenuto als Untermenue von Extras anlegen
          var zielmenu = document.getElementById('menu_ToolsPopup');
          if (zielmenu==null) {
            userChrome.log("extras_config_menu.uc.js findet Zielmenue nicht, evtl. weil ein anderes Fenster als das Hauptfenster " +
                           "geoeffnet wurde. Falls dieser Fehler auch im Hauptfenster auftritt, bitte die vorgehende Definition " +
                           "von 'zielmenu' kontrollieren.");
            return;
          }
          var menu = zielmenu.appendChild(this.createME("menu","Config Men\u00FC",0,0,"ExtraConfigMenu"));
          menu.setAttribute("class","menu-iconic");
          menu.setAttribute("ondblclick","openTrustedLinkIn('about:config', 'tab');");
         } else {
          // als Button nach dem per warpmenuto gewaehlten Element anlegen (s. Kommentar ueber warpmenuto im Konfigurationsabschnitt)
          /* var zielmenu = document.getElementById(this.warpmenuto);
          if (zielmenu==null) {
            userChrome.log("extras_config_menu.uc.js findet Zielpunkt '"+this.warpmenuto+"' nicht, evtl. weil ein anderes Fenster als das Hauptfenster " +
                           "geoeffnet wurde. Falls dieser Fehler auch im Hauptfenster auftritt, bitte die vorgehende Definition " +
                           "von 'warpmenuto' kontrollieren.");
            return;
          }
          var menu = zielmenu.parentNode.insertBefore(document.createXULElement('toolbarbutton'), zielmenu.nextSibling);
          menu.setAttribute("id", "ExtraConfigMenu-button");
          menu.setAttribute("class", "toolbarbutton-1");
          menu.setAttribute("type", "menu");
          menu.setAttribute("tooltiptext", "Extra Config Menü\nMittelklick \öffnet about:config");
          menu.setAttribute("onclick", "if (event.button===1 && event.target==this) openTrustedLinkIn('about:config','tab');");
        } */
    	
    	// als verschiebbaren Button anlegen
          if (window.__SSi == "window0") {
            CustomizableUI.createWidget({
              id: "ExtraConfigMenu-button",
              defaultArea: CustomizableUI.AREA_NAVBAR,
              label: "Extra Config Menü",
              tooltiptext: "Extra Config Menü\nRechtsklick \öffnet about:config"
            });
    		
          }
          var menu = document.getElementById("ExtraConfigMenu-button");
          menu.setAttribute("type", "menu");
    	  menu.addEventListener('click', function(event) {
    			if (event.button == 2 && !this.open) { 
    				openTrustedLinkIn("about:config", "tab");
    				event.preventDefault();
    			};
    	 },true);
    	  
        }
    	
    	//ab hier ist alles gleich, egal ob Button oder Menue
        var css = " \
          #ExtraConfigMenu, #ExtraConfigMenu-button { \
            list-style-image: url(file:///C:/FoxIcons/1206.png) !important; margin-right: 10px !important; margin-bottom: 2px !important; margin-top: 2px !important; \
          } \
          #ExtraConfigMenu-button > dropmarker, #ExtraConfigMenu-button > hbox > .toolbarbutton-menu-dropmarker { \
            display: none !important; \
          }";
        var sss = Cc['@mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
        var uri = makeURI('data:text/css;charset=UTF=8,' + encodeURIComponent(css));
        sss.loadAndRegisterSheet(uri,sss.AGENT_SHEET);
    	menu.addEventListener('popupshowing', function(event) {
    			uProfMenu.getScripts(0);
    			uProfMenu.getCss(3);
    			uProfMenu.getCss(4);
    			uProfMenu.getCss(5);
    			uProfMenu.getCss(6);
    	 },true);
    	
        var menupopup = menu.appendChild(this.createME("menupopup",0,0,0,"ExtraConfigMenu-popup"));
        // Anlegen von Untermenues fuer userChromeJS-Skripte und CSS-Dateien (befuellen spaeter)
        var submenu=menupopup.appendChild(this.createME("menu","Scripte",0,0,"submenu-ucjs"));
        var submenupopup = submenu.appendChild(this.createME("menupopup",0,0,0,"submenu-ucjs-items"));
    
        // var submenu = menupopup.appendChild(this.createME("menu","uc.xul",0,0,"submenu-ucxul"));
        // var submenupopup = submenu.appendChild(this.createME("menupopup",0,0,0,"submenu-ucxul-items"));
        var submenu = menupopup.appendChild(this.createME("menu","css",0,0,"submenu-css"));
        var submenupopup = submenu.appendChild(this.createME("menupopup",0,0,0,"submenu-css-items"));
        var submenu = menupopup.appendChild(this.createME("menu","cssweb",0,0,"submenu-cssweb"));
        var submenupopup = submenu.appendChild(this.createME("menupopup",0,0,0,"submenu-cssweb-items"));
        var submenu = menupopup.appendChild(this.createME("menu","cssabout",0,0,"submenu-cssabout"));
        var submenupopup = submenu.appendChild(this.createME("menupopup",0,0,0,"submenu-cssabout-items"));
    	var submenu = menupopup.appendChild(this.createME("menu","cssshadow",0,0,"submenu-cssshadow"));
        var submenupopup = submenu.appendChild(this.createME("menupopup",0,0,0,"submenu-cssshadow-items"));
        
    	if (this.enableScriptsToClip) menupopup.appendChild(this.createME("menuitem","Skriptliste in Zwischenablage","uProfMenu.getScripts(1)","uProfMenu_clipboard",0));
    	
        // Ende Anlegen von Untermenues
    	    
    	menupopup.appendChild(document.createXULElement('menuseparator'));
        
    	// Einbindung von Konfigdateien
        menupopup.appendChild(this.createME("menuitem","userChrome.css","uProfMenu.edit(7,'userChrome.css');","uProfMenu_edit",0));
        menupopup.appendChild(this.createME("menuitem","userContent.css","uProfMenu.edit(7,'userContent.css');","uProfMenu_edit",0));
        menupopup.appendChild(this.createME("menuitem","userChromeShadow.css","uProfMenu.edit(7,'userChromeShadow.css');","uProfMenu_edit",0));
        menupopup.appendChild(this.createME("menuitem","userChrome.js","uProfMenu.edit(7,'userChrome.js');","uProfMenu_edit",0));
        menupopup.appendChild(this.createME("menuitem","prefs.js","uProfMenu.edit(1,'prefs.js');","uProfMenu_edit",0));
        menupopup.appendChild(this.createME("menuitem","user.js","uProfMenu.edit(1,'user.js');","uProfMenu_edit"),0);
        menupopup.appendChild(this.createME("menuitem","policies.json","uProfMenu.edit(9,'policies.json');","uProfMenu_edit"),0);
        // Ende Einbindung von Konfigdateien
    	
    	// Einbindung von abouts
        if (this.abouts.length>0) {
          menupopup.appendChild(document.createXULElement('menuseparator'));
          // falls der erste Eintrag des Arrays = '0' ist, dann kein Untermenue anlegen, sondern direkt als Menuepunkte einbinden
          if (this.abouts[0]=='0') {
            for (var i = 1; i < this.abouts.length; i++) {
            menupopup.appendChild(this.createME("menuitem",this.abouts[i],"openTrustedLinkIn('"+this.abouts[i]+"','tab')","uProfMenu_about"),0);
            }
           } else {
            // der erste Eintrag des arrays ist ungleich '0', deshalb als Untermenue einrichten
            var submenu = menupopup.appendChild(this.createME("menu","uc.js",0,0,"submenu-about"));
            var submenupopup = submenu.appendChild(this.createME("menupopup",0,0,0,"submenu-about-items"));
            this.fillMenu("submenu-about","submenu-about-items", "about Funktionen",this.abouts,"uProfMenu_about",1);
          }
        }
        // Ende Einbindung von abouts
    	
    	// Einbindung von Menü Funktionen
        var submenu = menupopup.appendChild(this.createME("menu","Funktionen",0,0,"submenu-extra2"));
        var submenupopup = submenu.appendChild(this.createME("menupopup",0,0,0,"submenu-extra2-items"));
        this.fillMenu("submenu-extra2","submenu-extra2-items", "Funktionen",
          [
            {label:'Addon-Manager', command:"BrowserAddonUI.openAddonsMgr();"},
    		{label:'Einstellungen', command:"openPreferences();"},
    		{label:'about:config', command:"openTrustedLinkIn('about:config', gBrowser.selectedTab.isEmpty ? 'current' : 'tab');"},
    		{label:'about:support', command:"openTrustedLinkIn('about:support', gBrowser.selectedTab.isEmpty ? 'current' : 'tab');"},
    		{label:'Browser-Werkzeuge', command:"var { require } = ChromeUtils.importESModule('resource://devtools/shared/loader/Loader.sys.mjs', {});\
                          var { BrowserToolboxLauncher } = require('resource://devtools/client/framework/browser-toolbox/Launcher.sys.mjs');\
                          BrowserToolboxLauncher.init();",
    		},			  
    		{label:'Browser-Konsole', command:"var { require } = ChromeUtils.importESModule('resource://devtools/shared/loader/Loader.sys.mjs', {});\
                          var { BrowserConsoleManager } = require('resource://devtools/client/webconsole/browser-console-manager');\
                          BrowserConsoleManager.openBrowserConsoleOrFocus();",
            },
    		{label:'Entwickler-Werkzeuge', command:"var { require } = ChromeUtils.importESModule('resource://devtools/shared/loader/Loader.sys.mjs', {});\
                    var { gDevToolsBrowser } = require('devtools/client/framework/devtools-browser');\
                    gDevToolsBrowser.toggleToolboxCommand(window.gBrowser, Cu.now());",
            },
            {label:'Neustart im abgesicherten Modus', command:"safeModeRestart();"},		
    	  ],
          "extra2-directory",7);
        // Ende Einbindung von Menü Funktionen	  
    
        // Einbindung von Menü Verzeichnisse
        var submenu = menupopup.appendChild(this.createME("menu","Verzeichnisse",0,0,"submenu-extra"));
        var submenupopup = submenu.appendChild(this.createME("menupopup",0,0,0,"submenu-extra-items"));
        this.fillMenu("submenu-extra","submenu-extra-items", "Verzeichnisse",
          [
            {label:'Installationsordner', command:"uProfMenu.prefDirOpen('CurProcD')"},
    		{label:'Profilordner', command:"uProfMenu.prefDirOpen('ProfD')"},
            {label:'Icons', command:"uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm')+uProfMenu.getDirSep()+'Icons');"},
    		{label:'IconsMenü', command:"uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm')+uProfMenu.getDirSep()+'IconsMenü');"},
    		{label:'IconsHamburger', command:"uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm')+uProfMenu.getDirSep()+'IconsHamburger');"},
    		{label:'Bookmark-Backups', command:"uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfD')+uProfMenu.getDirSep()+'bookmarkbackups');"},
    		{label:'Addonordner', command:"uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfD')+uProfMenu.getDirSep()+'extensions');"},
    		{label:'Startup-Cacheordner', command:"uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfD')+uProfMenu.getDirSep()+'startupCache');"},
    		{label:'FoxIcons', command:"uProfMenu.dirOpen('C:\\FoxIcons');"}, 
    		{label:'FoxIcons2', command:"uProfMenu.dirOpen('C:\\FoxIcons2');"},
    		{label:'FoxBilder', command:"uProfMenu.dirOpen('C:\\FoxBilder');"},
    		{label:'Download Firefox', command:"uProfMenu.dirOpen('D:\\Download Firefox');"}
    	  ],
          "extra-directory",7);
    	// Ende Einbindung von Menü Verzeichnisse  
        
        menupopup.appendChild(document.createXULElement('menuseparator'));
    	
        // Einbindung von Ordnern
        switch (this.gmOrdner) {
          case 1:
            menupopup.appendChild(this.createME("menuitem","GM-skripty","uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfD')+uProfMenu.getDirSep()+'gm_scripts');","uProfMenu_folder"),0);
            break;
          case 2:
            menupopup.appendChild(this.createME("menuitem","USL-skripty","uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm')+uProfMenu.getDirSep()+'UserScriptLoader');","uProfMenu_folder"),0);
            break;
          case 3:
            menupopup.appendChild(this.createME("menuitem","Skripty Scriptish","uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfD')+uProfMenu.getDirSep()+'scriptish_scripts');","uProfMenu_folder"),0);
            break;
        }
        if (this.cssOrdner) {
          menupopup.appendChild(this.createME("menuitem","CSS-Ordner","uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm')+uProfMenu.getDirSep()+'CSS');","uProfMenu_folder"),0);
        }
        menupopup.appendChild(this.createME("menuitem","Ordner chrome","uProfMenu.prefDirOpen('UChrm');","uProfMenu_folder"),0);
        menupopup.appendChild(this.createME("menuitem","Ordner CSSWeb","uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm')+uProfMenu.getDirSep()+'CSSWeb');","uProfMenu_folder"),0);
        menupopup.appendChild(this.createME("menuitem","Ordner CSS","uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm')+uProfMenu.getDirSep()+'css');","uProfMenu_folder"),0);
    	
        //menupopup.appendChild(this.createME("menuitem","Profilordner","uProfMenu.prefDirOpen('ProfD');","uProfMenu_folder"),0);
        
    	//menupopup.appendChild(this.createME("menuitem","Installationsordner","uProfMenu.prefDirOpen('CurProcD');","uProfMenu_folder"),0);
        //menupopup.appendChild(this.createME("menuitem","Addonordner","uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfD')+uProfMenu.getDirSep()+'extensions');","uProfMenu_folder"),0);
        //menupopup.appendChild(this.createME("menuitem","Startup-Cacheordner","uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('ProfLD')+uProfMenu.getDirSep()+'startupCache');","uProfMenu_folder"),0);
    	
        menupopup.appendChild(this.createME("menuitem","Ordner CSSAbout","uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm')+uProfMenu.getDirSep()+'CSSAbout');","uProfMenu_folder"),0);
    	menupopup.appendChild(this.createME("menuitem","Ordner Scripte","uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm')+uProfMenu.getDirSep()+'Scripte');","uProfMenu_folder"),0);
    	menupopup.appendChild(this.createME("menuitem","Ordner CSSShadow","uProfMenu.dirOpen(uProfMenu.getPrefDirectoryPath('UChrm')+uProfMenu.getDirSep()+'CSSShadow');","uProfMenu_folder"),0);
    	
    	// Ende Einbindung von Ordnern
    	
        
    	
        // Separator, falls dieser nicht schon durch abouts generiert wurde und weitere Menuepunkte folgen werden
        if (this.abouts.length==0 && (this.showNormalPrefs || typeof(ToolRstartMod) != "undefined")) menupopup.appendChild(document.createXULElement('menuseparator'));
        
    	
    	  
    	  
        // Falls gewuenscht (s. Konfigurationsabschnitt), Zugriff auf die normalen Einstellungen
        if (this.showNormalPrefs) menupopup.appendChild(this.createME("menuitem","Einstellungen","try{openOptionsDialog();}catch(e){openPreferences();}","uProfMenu_prefs"),0);
        // Falls addRestartButton installiert ist, Neustart zur Verfuegung stellen (addRestartButton 1.0.20120105mod erforderlich)
        if(this.enableRestart) menupopup.appendChild(this.createME("menuitem","Neustart",
        "Services.appinfo.invalidateCachesOnRestart(); Services.startup.quit(Ci.nsIAppStartup.eRestart | Ci.nsIAppStartup.eAttemptQuit,0);"));
      },
    
      getDirSep:function() {
        // Betriebssystem nach https://developer.mozilla.org/en/Code_snippets/Miscellaneous ermitteln
        var osString = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULRuntime).OS;
        var dirsep = "/";
        switch(osString) {
          case "WINNT":
            dirsep = "\\";
            break;
          case "Linux":
            dirsep = "/";
            break;
          case "Darwin":
            dirsep = "/";
            break;
        }
        return dirsep;
      },
    
      edit:function(OpenMode,Filename){
        var Path = "";
        var dSep = this.getDirSep();  // die Trennzeichen zwischen Ordnern abhaengig vom Betriebssystem machen
        switch (OpenMode){
          //Current is Chrome Directory
          case 0:
            if (this.jsSubfolder.length != 0) {
            var Path = this.getPrefDirectoryPath("UChrm") + dSep + this.jsSubfolder + dSep + Filename;
            } else {
               var Path = this.getPrefDirectoryPath("UChrm") + dSep + Filename;
            }
            break;
          //Current is Profile Directory
          case 1:
            var Path = this.getPrefDirectoryPath("ProfD") + dSep + Filename;
            break;
          //Current is Root
          case 2:
            var Path = Filename;
            break;
          //Current is CSS folder
          case 3:
            var Path = this.getPrefDirectoryPath("UChrm") + dSep + "CSS" + dSep + Filename;
            break;
          //Current is CSSWeb folder
          case 4:
            var Path = this.getPrefDirectoryPath("UChrm") + dSep + "CSSWeb" + dSep + Filename;
            break;
          //Current is Sonstige CSS-Dateien folder
          case 5:
            var Path = this.getPrefDirectoryPath("UChrm") + dSep + "CSSAbout" + dSep + Filename;
            break;
    	  //Current is CSSShadow folder
          case 6:
            var Path = this.getPrefDirectoryPath("UChrm") + dSep + "CSSShadow" + dSep + Filename;
            break;			
          //Current is Chrome Directory
          case 7:	  
    	    var Path = this.getPrefDirectoryPath("UChrm") + dSep + Filename;
            break;
    	  //Current is Scripte folder
          case 8:
            var Path = this.getPrefDirectoryPath("UChrm") + dSep + "Scripte" + dSep + Filename;
            break;	
    	  //Current is distribution folder
          case 9:
            var Path = this.getPrefDirectoryPath("CurProcD") + dSep + "distribution" + dSep + Filename;
            break;	
        }
        this.launch(this.TextOpenExe,Path);
      },
    
      dirOpen:function(Path){
        if (this.vFileManager.length != 0) {
          var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
          var process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
          var args = [Path];
          file.initWithPath(this.vFileManager);
          process.init(file);
          // Verzeichnis mit anderem Dateimanager oeffnen
          process.run(false, args, args.length);
         } else {
          // Verzeichnis mit Dateimanager des Systems oeffnen
          var dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
          dir.initWithPath(Path);
          dir.launch();
        }
      },
    
      prefDirOpen:function(prefDir){
        Path = this.getPrefDirectoryPath(prefDir);
        this.dirOpen(Path);
      },
    
      getPrefDirectoryPath:function(str){
        // get profile directory
        var file = Components.classes["@mozilla.org/file/directory_service;1"]
          .getService(Components.interfaces.nsIProperties)
          .get(str, Components.interfaces.nsIFile);
        if (str == 'CurProcD') {
          file = file.parent;
        };
        return file.path;
      },
    
      launch:function(RanPath,OpenPath){
        var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsIFile);
        var proc = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
        var args = [OpenPath];
        file.initWithPath(RanPath);
        // falls der im Konfigurationsabschnitt definierte Editor nicht gefunden wird, auf Einstellung in about:config ausweichen:
        if (!file.exists()) {
          var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
          RanPath = pref.getCharPref("view_source.editor.path");
          file.initWithPath(RanPath);
        }
        proc.init(file);
        proc.run(false, args, args.length);
      },
    
      stringComparison:function(a, b){
        a = a.toLowerCase();
        a = a.replace(/ä/g,"a");
        a = a.replace(/ö/g,"o");
        a = a.replace(/ü/g,"u");
        a = a.replace(/ß/g,"s");
        b = b.toLowerCase();
        b = b.replace(/ä/g,"a");
        b = b.replace(/ö/g,"o");
        b = b.replace(/ü/g,"u");
        b = b.replace(/ß/g,"s");
        return(a==b)?0:(a>b)?1:-1;
      },
    
      getScripts:function(iType) {
        // Arrays (jeweils ein Array fuer uc.js und uc.xul) nehmen Namen der gefundenen Skripte auf
        let ucJsScripts = [];
        let ucXulScripts = [];
        // Suchmuster, also die Dateierweiterungen uc.js und uc.xul
        let extjs = /\.uc\.js$/i;
        //let extxul = /\.uc\.xul$/i;
        let aFolder = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
        aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path+uProfMenu.getDirSep()+this.jsSubfolder);
        // files mit Eintraegen im Chrome-Ordner befuellen
        let files = aFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
        // Ordner bzw. files durchlaufen und kontrollieren, ob gesuchte Dateien dabei sind
        while (files.hasMoreElements()) {
          let file = files.getNext().QueryInterface(Ci.nsIFile);
          // uc.js gefunden -> im Array ablegen
          if (extjs.test(file.leafName)) ucJsScripts.push(file.leafName);
          // uc.xul gefunden -> im Array ablegen
          //if (extxul.test(file.leafName)) ucXulScripts.push(file.leafName);
        }
        if (this.sortScripts) {
          ucJsScripts.sort(this.stringComparison);
          //ucXulScripts.sort(this.stringComparison);
        }
        // Aufruf der naechsten Methoden um die beiden Untermenues oder die Zwischenablage zu befuellen
        if (iType==0) {
          this.fillMenu("submenu-ucjs","submenu-ucjs-items", "Scripte",ucJsScripts,"uProfMenu_ucjs",0);
          //this.fillMenu("submenu-ucxul","submenu-ucxul-items", "uc.xul",ucXulScripts,"uProfMenu_ucxul",0);
         } else {
          var result = this.fillClipboardValue(ucJsScripts,ucXulScripts);
          Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper).copyString(result);
        }
      },
    
    
      getCss:function(iType) {
        // Array nimmt Namen der gefundenen css-Dateien auf
        let cssFiles = [];
        // Suchmuster, also die Dateierweiterung css
        let extcss = /\.css$/i;
        let aFolder = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
        if (iType==3) {
          aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path+this.getDirSep()+"CSS");
         } else if (iType==4) {
          aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path+this.getDirSep()+"CSSWeb");
         } else if (iType==5) {
          aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path+this.getDirSep()+"CSSAbout");
    	 } else if (iType==6) {
          aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path+this.getDirSep()+"CSSShadow");  
        }
        // files mit Eintraegen im CSS- bzw. CSSWeb-Ordner befuellen
        let files = aFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
        // Ordner bzw. files durchlaufen und kontrollieren, ob gesuchte Dateien dabei sind
        while (files.hasMoreElements()) {
          let file = files.getNext().QueryInterface(Ci.nsIFile);
          // css gefunden -> im Array ablegen
          if (extcss.test(file.leafName)) cssFiles.push(file.leafName);
        }
        if (this.sortScripts) {
          cssFiles.sort(this.stringComparison);
        }
        // Untermenue befuellen
        if (iType==3) {
          this.fillMenu("submenu-css","submenu-css-items","CSS-Dateien",cssFiles,"uProfMenu_css",3);
         } else if (iType==4) {
          this.fillMenu("submenu-cssweb","submenu-cssweb-items","CSSWeb-Dateien",cssFiles,"uProfMenu_css",4);
         } else if (iType==5) {
          this.fillMenu("submenu-cssabout","submenu-cssabout-items","CSSAbout-Dateien",cssFiles,"uProfMenu_css",5);
         } else if (iType==6) {
          this.fillMenu("submenu-cssshadow","submenu-cssshadow-items","CSSShadow-Dateien",cssFiles,"uProfMenu_css",6);
         }
      },
    
      fillMenu:function(whichsubmenu, whichsubmenuitems, strlabel, scriptArray,sClass,sTyp) {
        // Beschriftung des Untermenues mit Anzahl der gefundenen Dateien ergaenzen
        var e = document.getElementById(whichsubmenu);
        e.setAttribute('label',strlabel + ' (' + scriptArray.length + ')');
        var popup = document.getElementById(whichsubmenuitems);
        // zunaechst Untermenue zuruecksetzen
        while(popup.hasChildNodes()){
          popup.removeChild(popup.firstChild);
        }
        // Untermenue endlich befuellen
        for (var i = scriptArray.length-1; i > -1; i--) {
          // Typunterscheidung (userChromeJS-Skript oder about: oder css)
          if (sTyp==0){
            var mitem = this.createME("menuitem",scriptArray[i],"uProfMenu.edit(0,'"+scriptArray[i]+"')",sClass,0);
    		mitem.addEventListener('click', function(event) {
    			uProfMenu.openAtGithub(event,'"+scriptArray[i]+"');
    			event.preventDefault();
    		},true);
    		
            mitem.setAttribute("tooltiptext"," Linksklick: Bearbeiten,\n Mittelklick: https://github.com/.../"+this.cleanFileName(scriptArray[i])+" oeffnen,\n Rechtsklick: Suche auf GitHub");
           } else if (sTyp==1){
            var mitem = this.createME("menuitem",scriptArray[i],"openTrustedLinkIn('"+scriptArray[i]+"','tab')",sClass,0);
           } else if (sTyp==3){
            var mitem = this.createME("menuitem",scriptArray[i],"uProfMenu.edit(3,'"+scriptArray[i]+"')",sClass,0);
           } else if (sTyp==4){
            var mitem = this.createME("menuitem",scriptArray[i],"uProfMenu.edit(4,'"+scriptArray[i]+"')",sClass,0);
           } else if (sTyp==5){
            var mitem = this.createME("menuitem",scriptArray[i],"uProfMenu.edit(5,'"+scriptArray[i]+"')",sClass,0);
    	   }else if (sTyp==6){
            var mitem = this.createME("menuitem",scriptArray[i],"uProfMenu.edit(6,'"+scriptArray[i]+"')",sClass,0);		
           } else if (sTyp==7){
            var mitem = this.createME("menuitem",scriptArray[i].label,scriptArray[i].command,sClass,0);
           }
          popup.insertBefore(mitem, popup.firstChild);
        }
      },
    
      fillClipboardValue:function(sArray,xArray) {
        var retValue;
        var s = 0;
        var x = 0;
        s = sArray.length;
        x = xArray.length;
        switch(this.enableScriptsToClip) {
          case 1:
            retValue = "userChromeJS/uc.js ("+s+"):\n------------------------\n"+sArray.join("\n")+
                       "\n\nuserChromeJS/uc.xul ("+x+"):\n-------------------------\n"+xArray.join("\n");
            break;
          default:
            retValue = "userChromeJS/uc.js ("+s+"):\n------------------------";
            for (var i = 0; i < s ; i++) {
              j = i + 1;
              retValue = retValue + "\n" + j + ". " + sArray[i];
            }
            retValue = retValue + "\n\nuserChromeJS/uc.xul ("+x+"):\n-------------------------";
            if (this.enableScriptsToClip==2) s = 0;
            for (var i = 0; i < x ; i++) {
              j = i + s + 1;
              retValue = retValue + "\n" + j + ". " + xArray[i];
            }
            break;
        }
        return retValue;
      },
    
      createME:function(sTyp,sLabel,sCommand,sClass,sId) {
        // Anlegen von menuitem, menu oder menupop - fuer bestimmte Typen nicht eingesetzte Parameter werden als 0 uebergeben
        const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
        var m = document.createElementNS(XUL_NS, sTyp);
        switch (sTyp) {
          case "menuitem":
            // this.createME("menuitem","Label des Items","ZuzuweisenderCodeFueroncommand","GewuenschteKlasseDesItems",0)
            m.setAttribute('label', sLabel);
            m.setAttribute('class',sClass);
    		m.addEventListener('command', function(event) {
    			Function(sCommand)();
    		}, true);
    		
            break;
          case "menu":
            // this.createME("menu","Label des Menues",0,0,"GewuenschteIdDesMenues")
            m.setAttribute('label', sLabel);
            m.setAttribute('id', sId);
            break;
          case "menupopup":
            //this.createME("menupopup",0,0,0,"GewuenschteIdDesMenupopups");
            m.setAttribute('id', sId);
            break;
        }
        return m;
      },
    
      openAtGithub:function(e,sScript) {
        if (e.button==1){
          // Mittelklick - Seite auf GitHub oeffnen (funktioniert nur, wenn Ordner- und bereinigter Dateiname [ohne Erweiterung] uebereinstimmen):
          var sUrl = "https://github.com/ardiman/userChrome.js/tree/master/"+this.cleanFileName(sScript);
          openWebLinkIn(sUrl, 'tab');
        }
        if (e.button==2){
          // Rechtsklick - Suche auf GitHub starten (funktioniert nur, wenn der Dateiname im Code hinterlegt ist):
          e.preventDefault();
          var sUrl = "https://github.com/search?langOverride=&language=&q="+sScript+"&repo=&start_value=1&type=Code";
          openWebLinkIn(sUrl, 'tab');
          document.getElementById("ExtraConfigMenu-popup").hidePopup();
        }
      },
    
      cleanFileName:function(sName) {
        sName = sName.toLowerCase();
        /* Das folgende Array enthaelt regulaere Ausdruecke, um ungueltige Zeichenfolgen entfernen:
        /Datei-Erweiterungen am Ende/, /"ucjs_" am Anfang/, /"_"gefolgtVonZahlUndDanachBeliebigenZeichen/
        / "_fx"gefolgtVonZahl(en)/, /"-" oder "+" oder "."/, /"_v"gefolgtVonZahlen
        */
        var regs = [/\.uc\.js$/,/\.uc\.xul$/,/^ucjs_/,/_\d.+/,/_fx\d+/,/[-+\.]/g,/_v\d+/];
        for (var i = 0; i < regs.length; i++) {
          sName = sName.replace(regs[i],"");
        }
        return sName;
      }
    
    };
    
    uProfMenu.init();
    Alles anzeigen

    Zitat von .DeJaVu

    wobei xyz123 das Element des entsprechenden Eintrags ist.

    Alles was ich dazu gefunden habe ist probiert worden, aber ohne Erfolg.:rolleyes:

  • Ganze Seite nach unten oder oben Scrollen

    • FuchsFan
    • 2. Mai 2025 um 14:39
    Zitat von Mira_Belle

    aber mir ist aufgefallen, dass in der Nightly nicht mehr "gehovert" wird!

    Den Button selbst schon, aber mir gelingt es auch nicht, den Pfeilen eine andere Farbe zu geben.

  • Selektor für kleinen Pfeil in CSS-Code zum extra-config-menü.uc.js ab v139

    • FuchsFan
    • 2. Mai 2025 um 14:28

    Ich bitte in der Sache nochmals um Hilfe. Im Beitrag #1 ist der zweite Codee für Hoover vorhanden, was bis zur Version 138 für jeden einzelnen Button den roten Pfeil bringt. Sieht dann so aus:

    In Version 139/140 will mir das nicht gelingen, es auch dort so einzurichten. Wenn ich z.B. diesen Code dafür einsetze, so werden alle Button gleichzeitig angesprochen.

    CSS
    /*rechts der kleine Pfeil bei hoover*/
    #ExtraConfigMenu-popup:hover > menu::after {
      content: "" !important;
      background-image: url("..//icons/down2.png") !important;
      margin-right: 12px !important; 
      display: block !important;
      background-repeat: no-repeat !important;
      background-position: 0px 3px !important;
      background-size: 14px 14px !important;
    }

    Was dann so aussieht:

    Bilder

    • 140.png
      • 8,45 kB
      • 310 × 140
  • Selektor für kleinen Pfeil in CSS-Code zum extra-config-menü.uc.js ab v139

    • FuchsFan
    • 1. Mai 2025 um 19:08
    Zitat von grisu2099

    Dann war meine Schuß ins Blaue ja wenigstens ein halber Treffer...

    Genau so ist es. :thumbup:

    Zitat von .DeJaVu

    einfach nur ärgerlich - und unhöflich gegenüber den Helfern.

    Ich bitte alle Helfer um Verzeihung, wusste nicht, dass es so wichtig ist.

  • Selektor für kleinen Pfeil in CSS-Code zum extra-config-menü.uc.js ab v139

    • FuchsFan
    • 1. Mai 2025 um 17:29
    Zitat von Sören Hentzschel

    oder es wurde nicht bedacht, dass wenn ::after genutzt wird, es zwingend die Eigenschaft content geben muss

    Das war natürlich der gröbste Fehler, ich bedanke mich für den Hinweis.

    Zitat von .DeJaVu

    Wäre noch hilfreich, das Script zu posten, mindestens zu verlinken.

    Es lag aber nicht zwingend an dem Script, denn darin hat sich nichts geändert. Gibt es hier im Forum an jeder Ecke.;)

    Zitat von Horstmann

    Wie ebenfalls erwähnt, ist .menu-right jetzt wohl menu::after, und hat einen anderen Pfad, irgendwie sowas.

    Danke, das hat mich jetzt auf die Lösung gebracht, denn content  fehlte, und es muss jetzt dazu background-image heißen.

    Damit funktioniert es dann wieder;

    CSS
    #ExtraConfigMenu-popup menu::after {
      content: "" !important;
      background-image: url("..//icons/rechts6.png") !important;
    }
  • Selektor für kleinen Pfeil in CSS-Code zum extra-config-menü.uc.js ab v139

    • FuchsFan
    • 1. Mai 2025 um 14:48
    Zitat von grisu2099

    Mal ein Schuß ins Blaue

    Das hatte ich auch gesehen, aber will mir trotzdem nicht gelingen.:rolleyes:

  • Selektor für kleinen Pfeil in CSS-Code zum extra-config-menü.uc.js ab v139

    • FuchsFan
    • 1. Mai 2025 um 14:12

    Bis zur Version 138 funktioniert dafür dieser Code:

    CSS
    /*rechts der kleine Pfeil*/
    #ExtraConfigMenu-popup menu > .menu-right {
    	list-style-image: url("..//icons/rechts6.png") !important;
    }
    
    #ExtraConfigMenu-popup menu:hover > .menu-right {
      list-style-image: url("..//icons/down2.png") !important;
      margin-right: 8px !important; 
      padding-right: 20px !important;
      display: block !important;
      width: 16px !important;
      height: 16px !important;
      background-repeat: no-repeat !important;
      background-position: 0px 0px !important;
      background-size: 17px 17px !important;
    }
    Alles anzeigen


    Ich finde den neuen Selektor dafür nicht, bitte helfen.

  • Firefox v136.0a1 - Skript „saveTo“ funktioniert nicht mehr

    • FuchsFan
    • 19. April 2025 um 22:06
    Zitat von 2002Andreas

    Kompl. Skript dann:

    2002Andreas

    Sorry, Andreas, konnte nicht mehr online sein.

    Mein Dank geht an dich, das funktioniert perfekt, wie immer bei dir. :thumbup::thumbup::thumbup::)

    Ich wünsche dir, und auch allen Mitlesern, schöne Osterfeiertage.<3

  • Firefox v136.0a1 - Skript „saveTo“ funktioniert nicht mehr

    • FuchsFan
    • 19. April 2025 um 16:38
    Zitat von 2002Andreas

    Zeile 25 im Skript:

    Habe es im Original übernommen, aber lässt sich nicht ändern.

    Ich stelle mal das geänderte Script hier ein, schaust du mal bitte, ob es bei dir funktioniert.

    CSS
    // ==UserScript==
    // @include       chrome://mozapps/content/downloads/unknownContentType.xhtml
    // @charset       UTF-8
    // @version       Fx114+
    
    // ==/UserScript==
    (function () {
    	
    	if (location.href !== 'chrome://mozapps/content/downloads/unknownContentType.xhtml') return;
    	
      const Cu = Components.utils;
      const { FileUtils } = ChromeUtils.importESModule( 'resource://gre/modules/FileUtils.sys.mjs');
        
      setTimeout(function () {
        saveTo();
      }, 200);
    
      function saveTo() {
        // Config
        const dirArray = [
    	        ['D:\\Download Firefox', 'Download Firefox'],
                ['D:\\Download Firefox\\Dokumente'],
                ['D:\\Download Firefox\\Bilder'],
                ['D:\\Download Firefox\\Software'], 
                ['D:\\Download Firefox\\Ablage'],
                ['D:\\Download Firefox\\Sonstiges'],
                ["C:\\", "C:"],
                ["E:\\", "E:"],
                ];
        const button = document.getElementById('unknownContentType').getButton('cancel');
        const saveTo = button.parentNode.insertBefore(document.createXULElement('button'), button);
        const saveToMenu = saveTo.appendChild(document.createXULElement('menupopup'));
    
        saveTo.classList.toggle('dialog-button');
        saveTo.label = 'Speichern in…';
        saveTo.type = 'menu';
    
    
        const css =`
          hbox.dialog-button-box button.dialog-button menupopup {
            background: gold !important;
            min-width: 220px !important;
            padding: 5px !important;
            margin: 15px 0 0 -62px !important;
            border: 3px solid dodgerblue !important;
        }
            hbox.dialog-button-box button.dialog-button menupopup menuitem{
            appearance: none !important;
            color: blue !important;
            background: #fefefc !important; 
            border: 1px solid silver !important;
            margin-top: 1px !important;
            padding-left: 12px !important;
        }
            hbox.dialog-button-box button.dialog-button menupopup menuitem:hover {
            background: greenyellow !important;
            border: 1px solid red !important;
        }    
            hbox.dialog-button-box button.dialog-button menupopup menuitem.menuitem-iconic label.menu-iconic-text{
            color: blue !important;    
            font-size: 15px !important;
            font-weight: 600 !important;
                padding: 3px !important;
    			padding-left: 85px !important;
    			padding-right: 12px !important;
    
        } 
    	/* [FF139+] -> */
    		hbox.dialog-button-box button.dialog-button menupopup menuitem:not([highlightable]) > .menu-highlightable-text, menuitem[highlightable] > .menu-text {
    			  display: none;
    		}
    		/* <- [FF139+] */
    
    	`;
    
        const sss = Cc['@mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
        const uri = Services.io.newURI('data:text/css,' + encodeURIComponent(css));
        sss.loadAndRegisterSheet(uri, sss.AGENT_SHEET);
    
        dirArray.forEach(function (directory) {
          const [name, dir] = [directory[1], directory[0]];
          const mi = document.createXULElement('menuitem');
          const item = saveToMenu.appendChild(mi);
          item.setAttribute('label', (name || (dir.match(/[^\\/]+$/) || [dir])[0]));
          item.setAttribute('image', 'moz-icon:file:///' + dir + '\\');
          item.setAttribute('class', 'menuitem-iconic');
          item.addEventListener('click', function () {
            const locationtext = document.getElementById('locationtext');
            const pathFile = dir + '\\' + (locationtext ? locationtext.value : document.getElementById('location').value);
            const file = new FileUtils.File(pathFile);
            dialog.mLauncher.saveDestinationAvailable(file);
            dialog.onCancel = function () {};
            close();
          });
        });
      }
    }());
    Alles anzeigen
  • Firefox v136.0a1 - Skript „saveTo“ funktioniert nicht mehr

    • FuchsFan
    • 19. April 2025 um 16:07
    Zitat von 2002Andreas
    Zitat von BrokenHeart

    Jetzt sollte es auch in der Nightly wieder so funktionieren

    :thumbup:

    2002Andreas

    Hilf mir mal bitte, ich bekomme den Text nicht nach rechts verlagert.:rolleyes:

  • Mehrzeilige Tableiste für aktuelle Firefox-Versionen

    • FuchsFan
    • 8. April 2025 um 16:38
    Zitat von BrokenHeart

    Ich glaube, jetzt ist ein guter Zeitpunkt gekommen, dieses Dinosaurier-Skript (aus-)sterben zu lassen.

    BrokenHeart

    Ich möchte es aber nicht versäumen mich für Deine Arbeit zu bedanken, es war echt ein tolles Script.

    In weiser Voraussicht (wegen der häufigen Anpassungen) habe ich rechtzeitig für mich eine neue Arbeitsweise mit den Tabs eingerichtet, und mich auch daran gewöhnt. Alles hat ein ......... ! Danke BrokenHeart! :thumbup::)

  • Mehrzeilige Tableiste für aktuelle Firefox-Versionen

    • FuchsFan
    • 7. April 2025 um 18:22
    Zitat von Endor

    Der Autor hat was neues:

    Ja, und damit funktioniert auch das Verschieben der Tabs wieder.

  • Tabs ganz unten

    • FuchsFan
    • 7. April 2025 um 11:58
    Zitat von yaqwa

    Seit der Version 137 ist die Tab leiste wieder oben. Bitte um hilfe

    Wenn du die aktuelle Version von hier Mehrzeilige Tableiste für aktuelle Firefox-Versionen hast, dann funktioniert es bis Version 139.

  • Mehrzeilige Tableiste eine leere Zeile (Fehler)

    • FuchsFan
    • 6. April 2025 um 18:27
    Zitat von 2002Andreas

    Es geht auch etwas schneller

    :thumbup:;)

  • Mehrzeilige Tableiste eine leere Zeile (Fehler)

    • FuchsFan
    • 6. April 2025 um 18:00
    Zitat von Platos

    Du weisst nicht zufällig, wie ich in diesem (neuen) Skript diesen Pfeil rechts bei der Tableiste wegmache

    Doch, eine Möglichkeit hat 2002Andreas dir im vorherigen Beitrag gezeigt.

    Für mich habe ich das so gemacht, ein Rechtsklick auf eine freie Stelle in der Tabbar, und dann Symbolleiste anpassen auswählen.

    In der Folge dann mit der linken Maus das Pfeil-Symbol anfassen und z.B. in das Fenster ziehen (kann auch in das große linke abgelegt werden),

  • Mehrzeilige Tableiste eine leere Zeile (Fehler)

    • FuchsFan
    • 6. April 2025 um 14:18
    Zitat von Platos

    Naja, manchmal hilft ein kleiner Input um festzustellen, dass irgendwas schief gelaufen ist

    Da bist du nicht allein, glaube es mir.;)

  • Mehrzeilige Tableiste eine leere Zeile (Fehler)

    • FuchsFan
    • 6. April 2025 um 13:53
    Zitat von Platos

    Hat jemand eine Ahnung, wie man das beheben kann?

    Kann ich nicht, aber diese Version 135+ habe ich zum Test in Nightly, da ist alles "normal". Darfst du probieren, eventuell hilft es weiter.

    CSS
    // ==UserScript==
    // @name           MultiRowTabLiteforFx.uc.js
    // @namespace      Based on Alice0775's zzzz-MultiRowTab_LiteforFx48.uc.js
    // @description    Mehrzeilige Tableiste - Experimentelle CSS Version
    // @include        main
    // @compatibility  Firefox 135+
    // @version        2025/01/06 12:00
    // ==/UserScript==
    "use strict";
    
    MultiRowTabLiteforFx();
    function MultiRowTabLiteforFx() {
    if (!window.gBrowser) { return; }
    
        // -- Config --
        														// Vergleichbarer CSS Code in userChrome.css Datei wird vorrangig behandelt!
    
        const                                   	    	    // Mehrzeilige Tableiste Ein/Aus Anzahl der Tabzeilen
        MultiRowTab_OnOff_and_TabBar_Rows =     		2     ,// [-1] = Mehrzeilige Tableiste aktiv unbegrenzte Anzahl von Zeilen.
                                                	    	 	//  0   = Mehrzeilige Tableiste aus.
                                                	    		//  1   = Mehrzeilige Tableiste aktiv. Standard = 1 Zeile. Bei Berührung
    															//        der Tableiste mit der der Maus, werden die zweite und die folgenden Zeilen
                                                             	//        bis zur angegebenen Anzahl von Zeilen angezeigt.
    	                                                        //  2   = Mehrzeilige Tableiste aktiv. Anzahl der Tabzeilen angeben.
    	    
        TabBar_Rows_on_MouseOver =              		3      ,// Standard = 1 Zeile. Anzahl der Zeilen angeben, die angezeigt werden sollen, 
    	                                                        // wenn der Mauszeiger über die Tableiste bewegt wird. Voraussetzung: 
    															// „MultiRowTab_OnOff_and_TabBar_Rows“ auf „1“ setzen.
    	    
        TabBar_DisplayTime_on_MouseOver =       		1      ,// Sie können die Anzeigezeit (Sekunden) festlegen, wann die zweite und die folgenden
    	                                                        // Zeilen beim Mouseover angezeigt werden. Das Display zeigt den eingestellten Wert 
    															// (Sekunden) an und kehrt dann zur ersten Zeile zurück.
    
    															// Position der Tab-Leiste.
        TabBar_Position =          	    	    		0      ,// [0] = Standard
    															// 1   = unter der Symbolleiste
    															// 2   = unter dem Fenster
    
    															// Positionen der Tab-Leiste und der Lesezeichen-Symbolleiste tauschen.
    															// sofern die Position der Tab-Leiste unterhalb der Symbolleiste festgelegt ist.
    															// Voraussetzung: Setze "TabBar_Position" auf "1".
        Bookmark_Toolbar_Position =             	    true   ,// [true] = Menüleiste, Navigationsleiste, Lesezeichenleiste, Tableiste
    															// false = Menüleiste, Navigationsleiste, Tableiste, Lesezeichensymbolleiste
    
    															// Tab-Höhe „UI-Dichte“
        UI_Density_Compact =               			    26	   ,// Standard = 29 Pixelbei Kompakt
        UI_Density_Normal =                			    26	   ,// Standard = 36 Pixel bei Normal
        UI_Density_Touch =                 			    26	   ,// Standard = 41 Pixel bei Touch
    
    															// Tab-Breite
        Tab_Min_Width =                    			270		   ,// Standard - Mindestwert = 76px
        Tab_Max_Width =                    			271		   ,// Standard - Maxwert = 225px
    															// Bei gleichen Werten bei Min und Max, wird die Tabbreite fixiert!
    
    															// „Tab schließen“ Schaltfläche
        Tab_Close_Button =                 			3		   ,// [0] = Standard
    															//  1  = Ausgeblendet
    															//  2  = Auf allen Tabs anzeigen
    															//  3  = Nur bei Mausberührung anzeigen
    															//  4  = Aktive Tabs werden immer angezeigt, inaktive Tabs
    															// werden beim Mouseover angezeigt. *Standard für vertikalen Tab-Modus.
    
    															// ProtonUI Erscheinungsbild der Tabs ändern
        Proton_Margins =                   			false       ,// [true] = Darstellung ProtonUI
    															// Die Höhe der Tab-Leiste entspricht der Höhe der UI-Dichte plus dem Leerraum darüber
    															// und darunter.                                                 
    															// false  = Darstellung wie bei browser.proton.enabled auf false, was man vor Firefox 90
    															// noch einstellen konnte.
    															// Wenn der Leerraum um die Tabs auf 0 und die Höhe auf die UI-Dichte eingestellt
    															// ist, ist sie 4 Pixel breiter und 8 Pixel niedriger als die Standardeinstellung.
    								 
    															// Ränder auf der linken und rechten Seite der Tabs
        Tab_Separators  =                  			false      ,// [false] = Nicht anzeigen
    															// true    = Anzeigen
    															// Rahmen CSS wurde extrahiert und angepasst, an Aussehen wie bei browser.proton.enabled
    															// auf false, was man vor Firefox 90 noch einstellen konnte.
    									
    															// Voraussetzung: „TabBar_Position“ auf „0“ setzen.
        TitleBar_Button_Autohide =         			false	   ,// [false] = Aktiviert
    															// true    = Deaktiviert
    	    
    															// Äußeren Rahmen der Titelleistenschaltfläche [-□×] reduzieren und transparent machen.
        TitleBar_Button_DisplayTime =       		0.6		   ,// Dauer der Anzeige in Sekunden, nach der Rückkehr zur Originalgröße und dem Aufheben
    															// der Transparenz per Mouseover angeben.
    
    															// Tab-Leiste von Anfang an auf die angegebene Höhe einstellen.
    															// Voraussetzung: „MultiRowTab_OnOff_and_TabBar_Rows“ auf „2“ oder höher setzen.
        Set_the_TabBar_to_the_Specified_Height =	false  	   ,// [false] = Die Tab-Leiste wird höher, wenn der nächsten Zeile weitere Tabs hinzugefügt werden.
                                                	    	 	//  true   = Verwendung: Die Tab-Leiste wird von Anfang an auf die angegebene Höhe eingestellt 
    
                                                	    	 	// „.tabDropIndicator“, der beim Ziehen und Ablegen eines Tabs angezeigt wird, ersetzen.
                                                	    	 	// Voraussetzung: „MultiRowTab_OnOff_and_TabBar_Rows“ auf einen anderen Wert als „0“ setzen.
        Tab_Drop_Indicator =                    	false  	   ,// [false] = Stecknadel Symbol 📍
    															// true    = Rote Linie (2px × 29px) als Symbol
    
                                                	    	 	// Position der angepinnten Tabs
                                                	    	 	// Voraussetzung: „MultiRowTab_OnOff_and_TabBar_Rows“ auf einen Wert ungleich „0“ setzen.
        Separate_Tabs_and_PinnedTabs =     			false  	   ,// [false] = Standard
    															// true    = Angeheftete Tabs von der Tab-Leiste lösen und in die darüber liegende 
    															// Zeile verschieben. Breite der angehefteten Tabs für die Position der 
    															// angehefteten Tabs „true“ anpassen.
    
        PinnedTab_Width =                   		false	   ,// [false] = Kein Standard
    															//  true   = Breite angehefteter Tabs anpassen, z. B. „Tab-Breite“.
    
        PinnedTab_Min_Width =               		76   	   ,// Standard Mindestbreite =  76 Pixel
        PinnedTab_Max_Width =               		225   	   ,// Standard Maximalbreite = 225 Pixel
    															// Bei gleichen Werten ist die Breite fixiert.
    
                                                	    	 	// Angeheftete Tab, Schließen Schaltfläche
                                                	    	 	// Voraussetzung: „Separate_Tabs_and_PinnedTabs“ auf „true“ setzen.
        PinnedTab_Close_Button =                	0   	   ,// [0] = Standard
                                                	    	 	//  1  = auf allen Tabs sichtbar
                                                	    		//  2  = auf Tab bei Mouseover anzeigen
                                                	    	 	//  3  = Aktiver Tab immer sichtbar, inaktiver Tab bei Mouseover sichtbar 
    															// *Standard für vertikalen Tab-Modus.
    
    															// Tab-Leisten-Ziehbereich
        Left_Drag_Area =                   			0		   ,// Linker Ziehbereich Breite: Standard 40 Pixel
        Right_Drag_Area =                  			0		   ,// Rechter Ziehbereich Breite: Standard 40 Pixel
        Maximize_Left_Drag_Area =   	    		false      ,// true = Linken Ziehbereich bei maximiertem Fenster anzeigen. Standard ausgeblendet.
        Fullscreen_Drag_Area =             			false	   ,// true = Linken und rechten Ziehbereich bei Vollbild anzeigen. Standard ausgeblendet.
    															// Wenn die Titelleiste angezeigt wird, funktioniert sie nicht als Drag-Bereich, selbst
    															// wenn „.titlebar-spacer“ angezeigt wird. Daher habe ich dafür gesorgt, dass sie nichts bewirkt.
        // -- Config Ende --
    
        css = `
    
        #TabsToolbar:not([collapsed="true"]) {
    
          :root[uidensity="compact"] & {
            --tab-min-height: ${UI_Density_Compact}px;
          }
          :root:not([uidensity]) & {
            --tab-min-height: ${UI_Density_Normal}px;
          }
          :root[uidensity="touch"] & {
            --tab-min-height: ${UI_Density_Touch}px;
          }
    
          #tabbrowser-tabs {
            min-height: calc(var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px);
    
            ${MultiRowTab_OnOff_and_TabBar_Rows != 0 ? `
              &[overflow] {
                padding-inline: 0 !important;
                & > #tabbrowser-arrowscrollbox {
                  & > .tabbrowser-tab[pinned] {
                    display: flex;
                    margin-inline-start: 0 !important;
                    position: static !important;
                  }
                  &::part(scrollbox) {
                    padding-inline: 0;
                  }
                }
                & + #new-tab-button {
                  display: none;
                }
              }
    
              ${Tab_Drop_Indicator ? `
                & > .tab-drop-indicator {
                  background: url(
                    data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAdCAIAAAAPVCo9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAASSURBVBhXY3growJEQ5+SUQEAOb1EM8kwskcAAAAASUVORK5CYII=
                  ) no-repeat center;
                }
              ` : ``}
    
              #tabbrowser-arrowscrollbox {
                &::part(scrollbox) {
                  & > slot {
                    flex-wrap: wrap;
                  }
    
                  ${MultiRowTab_OnOff_and_TabBar_Rows != -1 ? `
                    ${MultiRowTab_OnOff_and_TabBar_Rows == 1 ? `
                      ${TabBar_Rows_on_MouseOver == 0 || TabBar_Rows_on_MouseOver == 1 ? `
                        max-height: calc((var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px) * 2);
                      ` : `
                        max-height: calc((var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px) * ${TabBar_Rows_on_MouseOver});
                      `}
                      &:not(:hover) {
                        max-height: calc(var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px) !important;
                        ${Proton_Margins ? `scrollbar-width: none;` : ``}
                        transition: all 0s ease-in-out ${TabBar_DisplayTime_on_MouseOver}s;
                      }
                    ` : `
                      ${Set_the_TabBar_to_the_Specified_Height ? `
                        min-height: calc((var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px) * ${MultiRowTab_OnOff_and_TabBar_Rows});
                        & > slot {
                          max-height: calc(var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px);
                        }
                      ` : `
                        max-height: calc((var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px) * ${MultiRowTab_OnOff_and_TabBar_Rows});
                      `}
                    `}
    
                    overflow: hidden auto;
                    & scrollbar {
                      -moz-window-dragging: no-drag;
                    }
                  ` : ``}
    
                }
                &::part(overflow-start-indicator),
                &::part(overflow-end-indicator),
                &::part(scrollbutton-up),
                &::part(scrollbutton-down) {
                  display: none;
                }
    
                ${Separate_Tabs_and_PinnedTabs ? `
                  &:has(> .tabbrowser-tab[fadein][pinned]) {
                    &::part(scrollbox) {
                      & > slot::after {
                        display: flow-root list-item;
                        content: "";
                        flex-basis: -moz-available;
                        height: 0;
                        overflow: hidden;
                      }
                    }
                  }
                  .tabbrowser-tab[fadein] {
                    &:not([pinned]) {
                      #tabbrowser-tabs[haspinnedtabs] & {
                        &, & + :not(#tabs-newtab-button) {
                          order: 1;
                        }
                      }
                    }
                    &[pinned] {
                      .tab-background:after {
                        content: "📌";
                        font-size: 11px;
                        right: -2px;
                        position: absolute;
                        top: -2px;
                      }
    
                      ${PinnedTab_Width ? `
                        flex: 100 100;
                        max-width: ${PinnedTab_Max_Width}px;
                        min-width: ${PinnedTab_Min_Width}px;
                        .tab-throbber, .tab-icon-pending, .tab-icon-image, .tab-sharing-icon-overlay, .tab-icon-overlay {
                          margin-inline-end: 5.5px !important;
                        }
    
                        ${PinnedTab_Close_Button == 1 ? `
                          .tab-close-button {
                            display: flex;
                          }
                        ` : PinnedTab_Close_Button == 2 ? `
                          .tab-close-button {
                            display: none;
                          }
                          &:hover .tab-close-button {
                            display: flex;
                          }
                        ` : PinnedTab_Close_Button == 3 ? `
                          &:not([selected]):hover,
                          &[selected] {
                            .tab-close-button {
                              display: flex;
                            }
                          }
                        ` : ``}
    
                      ` : ``}
    
                    }
                  }
                ` : ``}
    
                #tabbrowser-tabs[haspinnedtabs]:not([positionpinnedtabs]):not([orient="vertical"]) > & {
                  &  > .tabbrowser-tab:nth-child(1 of :not([pinned], [hidden])) {
                    margin-inline-start: 0 !important;
                  }
                }
    
              }
            ` : ``}
          }
    
          .tabbrowser-tab[fadein]:not([pinned]) {
            max-width: ${Tab_Max_Width}px;
            min-width: ${Tab_Min_Width}px;
    
            ${Tab_Close_Button == 1 ? `
              .tab-close-button {
                display: none;
              }
            ` : Tab_Close_Button == 2 ? `
              .tab-close-button {
                display: flex;
              }
            ` : Tab_Close_Button == 3 ? `
              .tab-close-button {
                display: none;
    			background: none !important;
    			fill: white !important;
    			scale: 1.3 !important;
              }
              &:hover .tab-close-button {
                display: flex;
              }
    		  .tab-close-button.close-icon:hover {
    			fill: red !important;
              }	
            ` : Tab_Close_Button == 4 ? `
              &:not([selected]):hover {
                .tab-close-button {
                  display: flex;
                }
              }
            ` : ``}
    
          }
    
          ${Tab_Separators ? `
            .titlebar-spacer[type="pre-tabs"] {
              border-inline-end: 1px solid color-mix(in srgb, currentColor 20%, transparent);
            }
            .tabbrowser-tab {
              &::after,
              &::before {
                border-left: 1px solid color-mix(in srgb, currentColor 50%, transparent);
                height: calc(var(--tab-min-height) - 15%);
                margin-block: auto;
              }
              &:hover::after,
              &[multiselected]::after,
              #tabbrowser-tabs:not([movingtab]) &:has(+ .tabbrowser-tab:hover)::after,
              #tabbrowser-tabs:not([movingtab]) &:has(+ [multiselected])::after {
                height: 100%;
              }
              &::after,
              #tabbrowser-tabs[movingtab] &[visuallyselected]::before {
                display: flex;
                content: "";
              }
            }
          ` : ``}
    
          ${Proton_Margins ? `` : `
            .tabbrowser-tab,
            .toolbarbutton-1 {
              padding: 0;
            }
            .tabbrowser-tab,
            #tabs-newtab-button {
              height: var(--tab-min-height);
            }
            .tabbrowser-tab {
              .tab-background {
                box-shadow: none;
                margin-block: 0;
              }
              .tab-label-container,
              .tab-close-button {
                height: var(--tab-min-height);
                max-height: 24px;
              }
              .tab-close-button {
                padding-block: 0;
              }
              &[usercontextid] > .tab-stack > .tab-background > .tab-context-line {
                margin-block-start: 1px !important;
              }
            }
          `}
    
        ${TabBar_Position == 0 ? `
          .titlebar-buttonbox-container {
            height: calc(var(--tab-min-height) + ${Proton_Margins ? 8 : 0}px);
          }
    
          ${TitleBar_Button_Autohide ? `
            & > .titlebar-buttonbox-container {
              background-color: color-mix(in srgb, currentColor 20%, transparent);
              position: fixed;
              right: 0;
              &:not(:hover) {
                height: 6px;
                .titlebar-button {
                  padding: 0;
                }
                &,& .titlebar-button {
                  opacity: 0;
                  transition: all 0s ease-in-out ${TitleBar_Button_DisplayTime}s;
                }
              }
            }
          ` : ``}
    
        }` : `
    
          ${TabBar_Position == 1 || TabBar_Position == 2 ? `
            & > .titlebar-buttonbox-container {
                display: none;
            }}
            #nav-bar {
              &:not(.browser-titlebar) {
                :root[customtitlebar] #toolbar-menubar[autohide="true"] ~ &,
                :root[inFullscreen] #toolbar-menubar ~ & {
                  & > .titlebar-buttonbox-container {
                    display: flex;
                  }
                }
              }
              .titlebar-button {
                padding-block: 0;
              }
            }
          ` : ``}
    
          body:has(> #navigator-toolbox:not([tabs-hidden])) {
            ${TabBar_Position == 1 ? `
              script, toolbar:not(#TabsToolbar ${Bookmark_Toolbar_Position ? `` : `, #PersonalToolbar`}) {
                order: -1;
              }
            ` : TabBar_Position == 2 ? `
              & > #fullscr-toggler[hidden] + tabbox,
              :root[inFullscreen] & > tabbox:hover {
                border-top: 0.01px solid var(--chrome-content-separator-color);
              }
              & > tabbox > #navigator-toolbox {
                border-block: none !important;
              }
              :root[inFullscreen] & {
                & > #navigator-toolbox {
                  transition: none;
                  &:has(~ tabbox:hover) {
                    margin-top: 0 !important;
                  }
                  &:hover ~ tabbox > #navigator-toolbox {
                    display: flex;
                  }
                }
                & > tabbox:not(:hover) {
                  border-top: 0.01px solid transparent;
                  & > #navigator-toolbox {
                    display: none;
                  }
                }
              }
            ` : ``}
          }
    
        `}
    
        toolbar[id$="bar"].browser-titlebar {
          .titlebar-spacer {
            &[type="pre-tabs"] {
              width: ${Left_Drag_Area}px;
            }
            &[type="post-tabs"] {
              width: ${Right_Drag_Area}px;
            }
            ${Maximize_Left_Drag_Area ? `
              :root[customtitlebar]:not([sizemode="normal"], [inFullscreen]) &[type="pre-tabs"] {
                display: flex;
              }
            ` : ``}
            ${Fullscreen_Drag_Area ? `
              :root[customtitlebar][inFullscreen] & {
                display: flex;
              }
            ` : ``}
          }
          #navigator-toolbox[tabs-hidden] & {
            #new-tab-button {
              display: none;
            }
          }
        }
    
        `,
        sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService),
        uri = Services.io.newURI("data:text/css;charset=UTF=8," + encodeURIComponent(css));
        ["0", "2", "dragend", "SSTabRestored", "TabAttrModified"].find(eventType => {
          if(!sss.sheetRegistered(uri, eventType)) sss.loadAndRegisterSheet(uri, eventType);
          if (MultiRowTab_OnOff_and_TabBar_Rows > 0) {
            gBrowser.tabContainer.addEventListener(eventType, (e) => {
              e.target.scrollIntoView({ behavior: "instant", block: "nearest" })
            })
          }
        })
    
        if (TabBar_Position == 2) {
          document.body.appendChild(
            document.createXULElement("tabbox")
          ).appendChild(
            document.importNode(document.getElementById("navigator-toolbox"))
          ).appendChild(
            document.adoptNode(document.getElementById("TabsToolbar"))
          )
        }
    
        gBrowser.tabContainer.addEventListener("dragover", function(event) { this._on_dragover(event); }, false)
        gBrowser.tabContainer.addEventListener("drop", function(event) { this._on_drop(event); }, false)
        gBrowser.tabContainer.on_dragover = function(event) { return false; }
        gBrowser.tabContainer.on_drop = function(event) { return false; }
    
        gBrowser.tabContainer._on_dragover = function(event) {
          var effects = this.getDropEffectForTabDrag(event);
    
          var ind = this._tabDropIndicator;
          if (effects == "" || effects == "none") {
            ind.hidden = true;
            return;
          }
          event.preventDefault();
          event.stopPropagation();
    
          var arrowScrollbox = this.arrowScrollbox;
    
          if (this.verticalMode || MultiRowTab_OnOff_and_TabBar_Rows == 0) {
    
          // autoscroll the tab strip if we drag over the scroll
          // buttons, even if we aren't dragging a tab, but then
          // return to avoid drawing the drop indicator
          var pixelsToScroll = 0;
          if (this.overflowing) {
            switch (event.originalTarget) {
              case arrowScrollbox._scrollButtonUp:
                pixelsToScroll = arrowScrollbox.scrollIncrement * -1;
                break;
              case arrowScrollbox._scrollButtonDown:
                pixelsToScroll = arrowScrollbox.scrollIncrement;
                break;
            }
            if (pixelsToScroll) {
              arrowScrollbox.scrollByPixels(
                (RTL_UI ? -1 : 1) * pixelsToScroll,
                true
              );
            }
          }
    
          let draggedTab = event.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0);
          if (
            (effects == "move" || effects == "copy") &&
            this == draggedTab.container &&
            !draggedTab._dragData.fromTabList
          ) {
            ind.hidden = true;
    
         // if (this.#isAnimatingMoveTogetherSelectedTabs()) {
         //   // Wait for moving selected tabs together animation to finish.
         //   return;
         // }
            this._finishMoveTogetherSelectedTabs(draggedTab);
    
            if (effects == "move") {
              // Pinned tabs in expanded vertical mode are on a grid format and require
              // different logic to drag and drop.
           // if (this.#isContainerVerticalPinnedExpanded(draggedTab)) {
           //   this.#animateExpandedPinnedTabMove(event);
           //   return;
           // }
              this._animateTabMove(event);
              return;
            }
          }
    
          this._finishAnimateTabMove();
    
          }
    
          if (effects == "link") {
            let tab = this._getDragTargetTab(event, { ignoreTabSides: true });
            if (tab) {
              if (!this._dragTime) {
                this._dragTime = Date.now();
              }
              if (Date.now() >= this._dragTime + this._dragOverDelay) {
                this.selectedItem = tab;
              }
              ind.hidden = true;
              return;
            }
          }
    
          var tabRect, rect = arrowScrollbox.getBoundingClientRect();
          var newMargin, newMarginY;
          if (pixelsToScroll) {
            // if we are scrolling, put the drop indicator at the edge
            // so that it doesn't jump while scrolling
            let scrollRect = arrowScrollbox.scrollClientRect;
            let minMargin = this.verticalMode
              ? scrollRect.top - rect.top
              : scrollRect.left - rect.left;
            let maxMargin = this.verticalMode
              ? Math.min(minMargin + scrollRect.height, scrollRect.bottom)
              : Math.min(minMargin + scrollRect.width, scrollRect.right);
            if (RTL_UI) {
              [minMargin, maxMargin] = [
                this.clientWidth - maxMargin,
                this.clientWidth - minMargin,
              ];
            }
            newMargin = pixelsToScroll > 0 ? maxMargin : minMargin;
          } else {
            let newIndex = this._getDropIndex(event);
            let children = this.allTabs;
            if (newIndex === children.length) {
              tabRect = this.visibleTabs.at(-1).getBoundingClientRect();
              if (this.verticalMode) {
                newMargin = tabRect.bottom - rect.top;
              } else if (RTL_UI) {
                newMargin = rect.right - tabRect.left;
              } else {
                newMargin = tabRect.right - rect.left;
              }
            } else {
              tabRect = children[newIndex].getBoundingClientRect();
              if (this.verticalMode) {
                newMargin = rect.top - tabRect.bottom;
              } else if (RTL_UI) {
                newMargin = rect.right - tabRect.right;
              } else {
                newMargin = tabRect.left - rect.left;
              }
            }
            newMarginY = tabRect.top - rect.top + tabRect.height / 2 - rect.height / 2;
          }
    
          ind.hidden = false;
          newMargin += this.verticalMode ? ind.clientHeight : ind.clientWidth / 2;
          if (RTL_UI) {
            newMargin *= -1;
          }
          ind.style.transform = this.verticalMode
            ? "translateY(" + Math.round(newMargin) + "px)"
            : MultiRowTab_OnOff_and_TabBar_Rows == 0
            ? "translateX(" + Math.round(newMargin) + "px)"
            : "translate(" + Math.round(newMargin) + "px, " + Math.round(newMarginY) + "px)";
        }
    
        gBrowser.tabContainer._on_drop = function(event) {
          var dt = event.dataTransfer;
          var dropEffect = dt.dropEffect;
          var draggedTab;
          let movingTabs;
          if (dt.mozTypesAt(0)[0] == TAB_DROP_TYPE) {
            // tab copy or move
            draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
            // not our drop then
            if (!draggedTab) {
              return;
            }
            movingTabs = draggedTab._dragData.movingTabs;
            draggedTab.container._finishMoveTogetherSelectedTabs(draggedTab);
          }
    
          this._tabDropIndicator.hidden = true;
          event.stopPropagation();
          if (draggedTab && dropEffect == "copy") {
            // copy the dropped tab (wherever it's from)
            let newIndex = this._getDropIndex(event);
            let draggedTabCopy;
            for (let tab of movingTabs) {
              let newTab = gBrowser.duplicateTab(tab);
              gBrowser.moveTabTo(newTab, newIndex++);
              if (tab == draggedTab) {
                draggedTabCopy = newTab;
              }
            }
            if (draggedTab.container != this || event.shiftKey) {
              this.selectedItem = draggedTabCopy;
            }
          } else if (draggedTab && draggedTab.container == this) {
            let oldTranslateX = Math.round(draggedTab._dragData.translateX);
            let oldTranslateY = Math.round(draggedTab._dragData.translateY);
            let tabWidth = Math.round(draggedTab._dragData.tabWidth);
            let tabHeight = Math.round(draggedTab._dragData.tabHeight);
            let translateOffsetX = oldTranslateX % tabWidth;
            let translateOffsetY = oldTranslateY % tabHeight;
            let newTranslateX = oldTranslateX - translateOffsetX;
            let newTranslateY = oldTranslateY - translateOffsetY;
    
            // Update both translate axis for pinned vertical expanded tabs
            if (oldTranslateX > 0 && translateOffsetX > tabWidth / 2) {
              newTranslateX += tabWidth;
            } else if (oldTranslateX < 0 && -translateOffsetX > tabWidth / 2) {
              newTranslateX -= tabWidth;
            }
            if (oldTranslateY > 0 && translateOffsetY > tabHeight / 2) {
              newTranslateY += tabHeight;
            } else if (oldTranslateY < 0 && -translateOffsetY > tabHeight / 2) {
              newTranslateY -= tabHeight;
            }
    
            let dropIndex;
            if (draggedTab._dragData.fromTabList) {
              dropIndex = this._getDropIndex(event);
            } else {
              dropIndex = this.verticalMode || MultiRowTab_OnOff_and_TabBar_Rows == 0
                ? "animDropIndex" in draggedTab._dragData && draggedTab._dragData.animDropIndex
                : this._getDropIndex(event);
            }
            let incrementDropIndex = true;
            if (dropIndex && dropIndex > movingTabs[0]._tPos) {
              dropIndex--;
              incrementDropIndex = false;
            }
    
            let shouldTranslate =
              !gReduceMotion && !("groupDropIndex" in draggedTab._dragData);
         // if (this.#isContainerVerticalPinnedExpanded(draggedTab)) {
         //   shouldTranslate &&=
         //     (oldTranslateX && oldTranslateX != newTranslateX) ||
         //     (oldTranslateY && oldTranslateY != newTranslateY);
         // } else
            if (this.verticalMode) {
              shouldTranslate &&= oldTranslateY && oldTranslateY != newTranslateY;
            } else {
              shouldTranslate &&= oldTranslateX && oldTranslateX != newTranslateX;
            }
    
            if (shouldTranslate) {
              for (let tab of movingTabs) {
                tab.toggleAttribute("tabdrop-samewindow", true);
                tab.style.transform = `translate(${newTranslateX}px, ${newTranslateY}px)`;
                let postTransitionCleanup = () => {
                  tab.removeAttribute("tabdrop-samewindow");
    
                  this._finishAnimateTabMove();
                  if (dropIndex !== false) {
                    gBrowser.moveTabTo(tab, dropIndex);
                    if (incrementDropIndex) {
                      dropIndex++;
                    }
                  }
    
                  gBrowser.syncThrobberAnimations(tab);
                };
                if (gReduceMotion) {
                  postTransitionCleanup();
                } else {
                  let onTransitionEnd = transitionendEvent => {
                    if (
                      transitionendEvent.propertyName != "transform" ||
                      transitionendEvent.originalTarget != tab
                    ) {
                      return;
                    }
                    tab.removeEventListener("transitionend", onTransitionEnd);
    
                    postTransitionCleanup();
                  };
                  tab.addEventListener("transitionend", onTransitionEnd);
                }
              }
            } else {
              let groupTab =
                "groupDropIndex" in draggedTab._dragData
                  ? this.allTabs[draggedTab._dragData.groupDropIndex]
                  : null;
              this._finishAnimateTabMove();
              if (dropIndex !== false) {
                for (let tab of movingTabs) {
                  gBrowser.moveTabTo(tab, dropIndex);
                  if (incrementDropIndex) {
                    dropIndex++;
                  }
                }
              }
              if (groupTab) {
                gBrowser.addTabGroup([groupTab, ...movingTabs], {
                  insertBefore: draggedTab,
                });
              }
            }
          } else if (draggedTab) {
            // Move the tabs. To avoid multiple tab-switches in the original window,
            // the selected tab should be adopted last.
            const dropIndex = this._getDropIndex(event);
            let newIndex = dropIndex;
            let selectedTab;
            let indexForSelectedTab;
            for (let i = 0; i < movingTabs.length; ++i) {
              const tab = movingTabs[i];
              if (tab.selected) {
                selectedTab = tab;
                indexForSelectedTab = newIndex;
              } else {
                const newTab = gBrowser.adoptTab(tab, newIndex, tab == draggedTab);
                if (newTab) {
                  ++newIndex;
                }
              }
            }
            if (selectedTab) {
              const newTab = gBrowser.adoptTab(
                selectedTab,
                indexForSelectedTab,
                selectedTab == draggedTab
              );
              if (newTab) {
                ++newIndex;
              }
            }
    
            // Restore tab selection
            gBrowser.addRangeToMultiSelectedTabs(
              gBrowser.tabs[dropIndex],
              gBrowser.tabs[newIndex - 1]
            );
          } else {
            // Pass true to disallow dropping javascript: or data: urls
            let links;
            try {
              links = browserDragAndDrop.dropLinks(event, true);
            } catch (ex) {}
    
            if (!links || links.length === 0) {
              return;
            }
    
            let inBackground = Services.prefs.getBoolPref(
              "browser.tabs.loadInBackground"
            );
            if (event.shiftKey) {
              inBackground = !inBackground;
            }
    
            let targetTab = this._getDragTargetTab(event, { ignoreTabSides: true });
            let userContextId = this.selectedItem.getAttribute("usercontextid");
            let replace = !!targetTab;
            let newIndex = this._getDropIndex(event);
            let urls = links.map(link => link.url);
            let csp = browserDragAndDrop.getCsp(event);
            let triggeringPrincipal =
              browserDragAndDrop.getTriggeringPrincipal(event);
    
            (async () => {
              if (
                urls.length >=
                Services.prefs.getIntPref("browser.tabs.maxOpenBeforeWarn")
              ) {
                // Sync dialog cannot be used inside drop event handler.
                let answer = await OpenInTabsUtils.promiseConfirmOpenInTabs(
                  urls.length,
                  window
                );
                if (!answer) {
                  return;
                }
              }
    
              gBrowser.loadTabs(urls, {
                inBackground,
                replace,
                allowThirdPartyFixup: true,
                targetTab,
                newIndex,
                userContextId,
                triggeringPrincipal,
                csp,
              });
            })();
          }
    
          if (draggedTab) {
            delete draggedTab._dragData;
          }
        }
    
    }
    Alles anzeigen

Unterstütze uns!

Jährlich (2025)

82,4 %

82,4% (535,86 von 650 EUR)

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