您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Move Outlook's app rail to the header.
// ==UserScript== // @name Outlook App Rail to Header // @namespace http://www.alittleresearch.com.au/ // @version 2025-04-03 // @description Move Outlook's app rail to the header. // @author Nick Sheppard // @license MIT // @contributionURL https://ko-fi.com/npsheppard // @match https://outlook.office.com/* // @match https://outlook.live.com/* // @icon https://www.alittleresearch.com.au/sites/default/files/alriconbl-transbg-32x32.png // @grant none // ==/UserScript== /////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2025 Nicholas Paul Sheppard. See README.md for details // // Buy me a Ko-Fi at https://ko-fi.com/npsheppard. /////////////////////////////////////////////////////////////////////////////// // set which buttons should remain in the header buttons region const headerButtonsConf = { 'owaMeetNowButton_container': false, 'teams_container': false, 'owaPremiumBtn_container': false, 'owaNoteFeedButton_container': false, 'owaTimePanelBtn_container': false, 'owaActivityFeedButton_container': false, 'owaSettingsBtn_container': true, 'owaTipsBtn_container': false, 'owaChatButton_container': false, 'owaChatCopilotButton_container': false, 'OwaMergedNotificationPane_container': false }; var documentObserver = null; // main function (function() { 'use strict'; // create the document observer and start observing createDocumentObserver(); connectDocumentObserver(); })(); /////////////////////////////////////////////////////////////////////////////// // Document observer functions. // // The document observer looks for changes to the left rail (id LeftRail) // and the main application panel (id MainModule). // // The left rail is only created once. As soon as we find it, we can set its // display style to none, with nothing further to do. // // The main module is rebuilt several times during construction of the page, // and again when switching from Mail to Calendar view, and vice versa. Each // time, we attach a new observer to it, which updates the header buttons // region (id headerButtonsRegionId) for the new main module. /////////////////////////////////////////////////////////////////////////////// // Create the document observer function createDocumentObserver() { documentObserver = new MutationObserver((mutations) => { var leftRail = null; var mainModule = null; for (const m of mutations) { for (const node of m.addedNodes) { var ancestor = node; while (ancestor != null) { if (ancestor.id === "LeftRail") { // found the left rail leftRail = ancestor; break; } else if (ancestor.id === "MainModule") { // found the main module mainModule = ancestor; break; } ancestor = ancestor.parentNode; } } } if (leftRail != null) { // hide the left rail leftRail.style.display = "none"; } if (mainModule != null) { // observe the main module; the callback function will insert the rail items into the header var mainModuleObserver = new MutationObserver(onMainModuleMutation); mainModuleObserver.observe(mainModule, { childList: true, subtree: true, attributes: false, characterData: false }); } }); } // Start the document observer function connectDocumentObserver() { documentObserver.observe(document.body, { childList: true, subtree: true, attributes: false, characterData: false }); } // Stop the document observer function disconnectDocumentObserver() { documentObserver.disconnect(); } /////////////////////////////////////////////////////////////////////////////// // Respond to mutation of the main module, inserting the app rail into the // header. // // The header buttons are contained within a div with id headerButtonsRegionId. // Each button is identified by a class name, which is used as a key in the // headerButtonsConf structure. // // Each item from the app rail is contained by a div with class ___77lcry0, // which is one out of many classes they have. We don't need to identify them // individually, so the class name works for our purposes. // // Input: // mutations - the mutations // observer - the observer /////////////////////////////////////////////////////////////////////////////// function onMainModuleMutation(mutations, observer) { // disconnect the observer; a new one will attach when Outlook updates the main module if (observer != null) { observer.disconnect(); } // remove unwanted children const headerButtonsRegion = document.getElementById("headerButtonsRegionId"); var child = headerButtonsRegion.firstElementChild; while (child != null) { const next = child.nextElementSibling; if (child.id in headerButtonsConf && !headerButtonsConf[child.id]) { headerButtonsRegion.removeChild(child); } if (child.classList.contains("___77lcry0")) { headerButtonsRegion.removeChild(child); } child = next; } // disconnect to document observer to prevent infinite recursion disconnectDocumentObserver(); // insert the app rail buttons at the start of the header button region const apps = fetchAppRailCollection(); for (var i = apps.length - 1; i >= 0 ; i--) { headerButtonsRegion.insertAdjacentElement("afterbegin", apps[i]); } // reconnect the document observer connectDocumentObserver(); } /////////////////////////////////////////////////////////////////////////////// // Manage the collection of buttons on the app rail. // // App buttons appear on the app rail at various times during building of the // page. The fetchRailButtons() function checks for new buttons that have // appeared since the last invocation and moves them into the // appRailCollection array, from where they'll later be inserted into the // header region. // // The app rail is a div with id LeftRail. This div is further divided into two // div more elements, one with class ___1w2h5wn that contains the applications // and another with class ___1fkhojs that contains the "More apps" button. Each // button is contained in a div with class ___77lcry0. We preserve the order of // the two div's using the appRailSeparator variable. // /////////////////////////////////////////////////////////////////////////////// var appRailCollection = []; var appRailSeparator = 0; function fetchAppRailCollection() { // check for new items added to the top div of the left rail const leftRailCollection1 = document.querySelectorAll("#LeftRail .___1w2h5wn .___77lcry0"); for (let i = 0; i < leftRailCollection1.length; i++) { // remove from the left rail leftRailCollection1.item(i).parentNode.removeChild(leftRailCollection1.item(i)); // insert into the collection before the separator if (appRailCollection.length > 0) { appRailCollection.splice(appRailSeparator, 0, leftRailCollection1.item(i)); } else { appRailCollection.push(leftRailCollection1.item(i)); } appRailSeparator++; } // check for new items added to the bottom div of the left rail const leftRailCollection2 = document.querySelectorAll("#LeftRail .___1fkhojs .___77lcry0"); for (let i = 0; i < leftRailCollection2.length; i++) { // remove from the left rail leftRailCollection2.item(i).parentNode.removeChild(leftRailCollection2.item(i)); // insert into the collection at the end appRailCollection.push(leftRailCollection2.item(i)); } // return the collection for use by the callback return appRailCollection; }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址