tiss_developer_tweaks

for tiss-developers - a better tiss it is.

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name           tiss_developer_tweaks
// @namespace      https://greasyfork.org/de/users/157797-lual
// @match          https://*.tiss.tuwien.ac.at/*
// @match          https://*.apps.dev.csd.tuwien.ac.at/*
// @match          http://localhost:3*/*
// @exclude        /^https?://dev.tiss.tuwien.ac.at.*$/
// @exclude        /^https?://odevmaster.tiss.tuwien.ac.at.*$/
// @exclude        /^https?://account.tiss.tuwien.ac.at.*$/
// @exclude        /^https?://keycloak.devcloud.tiss.tuwien.ac.at.*$/
// @exclude        /^https?://jenkins.devcloud.tiss.tuwien.ac.at.*$/
// @exclude        /^https?://datengrube.tiss.tuwien.ac.at.*$/
// @exclude        /^https?://rocketchat.devcloud.tiss.tuwien.ac.at.*$/
// @exclude        /^https?://secure-sso.devcloud.tiss.tuwien.ac.at.*$/
// @exclude        /^https?://jitsi.apps.dev.csd.tuwien.ac.at.*$/
// @exclude        /^https?://kibana.apps.dev.csd.tuwien.ac.at.*$/
// @exclude        /^https?://chat.apps.dev.csd.tuwien.ac.at.*$/
// @exclude        /^https?://sso.apps.dev.csd.tuwien.ac.at.*$/
// @version        0.61
// @author         lual
// @description    for tiss-developers - a better tiss it is.
// @author         fg (csd)
// @grant          GM_addStyle
// @grant          GM_getValue
// @grant          GM_setValue
// @grant          GM_registerMenuCommand
// @icon           https://tiss.tuwien.ac.at/favicon.ico
// ==/UserScript==
// changes:        2017-11-01 publish on greasyfork
//                            https://greasyfork.org/de/scripts/34721-tiss-developer-tweaks
//                 2017-11-03 mark current menu entry
//                            fill unused space - use whole screen width
//                 2017-11-06 production warning border also for chrome
//                 2018-08-03 bugfix - production warning border - for tiss-help-system
//                 2018-08-03 add next.devcloud
//                 2018-09-18 dynamic environment list
//                 2018-09-18 exclude dev.tiss.tuwien.ac.at (redmine)
//                 2018-09-18 fix XML rendering for firefox
//                 2018-09-18 exclude odevmaster.tiss.tuwien.ac.at
//                 2018-09-18 exclude others
//                 2018-09-18 check if this is a tiss site or abort
//                 2018-09-29 decrease score for unused sites
//                 2018-09-29 rightAlign tabs
//                 2018-09-30 add menu entry to remove last environment tab
//                 2018-10-15 bugfix - maxsize
//                 2018-10-23 if corrupt - reset local stored environment list
//                 2019-03-06 exclude account.tiss + keycloak.devcloud (neues gasTUser Portal)
//                 2019-04-30 change favicon for non-tiss-sites
//                            red    favicon for prod
//                 2019-08-22 menuepunkt "Service Center" > " Personen" hervorheben
//                 2020-05-06 include apps.dev.csd.tuwien.ac.at
//                 2020-05-26 "leader line" fix for #39268
//                 2020-10-07 andi w. : "Benutzer wechseln" - link @ jtiss-sites
//                 2021-01-27 prepare tiss style 3.x parallel useable to 2.x
//                 2021-01-28 style 3.x toggle menu scroll independence
//                 2021-02-15 style 3.x menu scroll height = content height 
//                 2022-11-10 convert deprecated @include to @match
//                 2023-03-29 icon of script
///////////////////////////////////////////////////////////////////////////////
var Util = {
  log: function () {
    var args = [].slice.call(arguments);
    args.unshift('%c' + SCRIPT_NAME + ':', 'font-weight: bold;color: purple;');
    console.log.apply(console, args);
  },
  storeGet: function(key) {
    if (typeof GM_getValue === "undefined") {
      var value = localStorage.getItem(key);
      if (value === "true" || value === "false") {
        return (value === "true") ? true : false;
      }
      return value;
    }
    return GM_getValue(key);
  },
  storeSet: function(key, value) {
    if (typeof GM_setValue === "undefined") {
      return localStorage.setItem(key, value);
    }
    return GM_setValue(key, value);
  },
  storeDel: function(key) {
    if (typeof GM_deleteValue === "undefined") {
      return localStorage.removeItem(key);
    }
    return GM_deleteValue(key);
  },
  //moves an item in an array - (given arr will be altered!)
  move: function(arr, old_index, new_index) {
      while (old_index < 0) {
          old_index += arr.length;
      }
      while (new_index < 0) {
          new_index += arr.length;
      }
      if (new_index >= arr.length) {
          let k = new_index - arr.length;
          while ((k--) + 1) {
              arr.push(undefined);
          }
      }
       arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
     return arr;
  }
};

var SCRIPT_NAME = 'tiss_developer_tweaks';
var TISS_ENV_LIST_MAXSIZE = 7;

Util.log('started');

///////////////////////////////////////////////////////////////////////////////
// don't modify anything and exit script if document format is not html
// (because maybe the site is XML-format and firefox can't handle that
// https://bugzilla.mozilla.org/show_bug.cgi?id=1401793)
if (!(document.doctype && document.doctype.nodeName ==="html")){
  Util.log('doctype != html -> abort purposely...');
  throw new Error("tiss_developer_tweaks - aborted");
}
///////////////////////////////////////////////////////////////////////////////

var isTissStyle2x = (document.getElementsByClassName("clearfix toolNav")[0] != null);
//Util.log('isTissStyle2x: '+ isTissStyle2x);

var isTissStyle3x = (document.getElementsByClassName("main-navigation")[0] != null);
Util.log('isTissStyle3x: '+ isTissStyle3x);

var checkMenu = isTissStyle2x ?
    document.getElementsByClassName("clearfix toolNav")[0]:
    checkMenu = document.getElementsByClassName("main-navigation")[0];

if (checkMenu == null){
  //this is not tiss - (maybe a better_errors-page)
  //change favicon
  var Favicon = document.createElement('link');
  Favicon.setAttribute('rel', 'shortcut icon');
  Favicon.setAttribute('href', '/images/icons/favicontest.ico');
  var head = document.getElementsByTagName('head')[0];
  head.appendChild(Favicon);
  //abort
  Util.log('this is not tiss? -> abort purposely...');
  throw new Error("tiss_developer_tweaks - aborted");
}
///////////////////////////////////////////////////////////////////////////////
//menuepunkt "Service Center" > " Personen" hervorheben
var serviceCenterMenu = document.querySelectorAll("#menuAnchor_SERVICE_CENTER_PERSON, #menuItem_1581, #menuAnchor_1581")[0];
if (!!serviceCenterMenu) {
  serviceCenterMenu.setAttribute("style", "text-decoration-line: overline underline; text-decoration-style: wavy;");
}

///////////////////////////////////////////////////////////////////////////////

let tissEnvListInitial = [
    { "host": 'tiss.tuwien.ac.at',
      "prot": 'https:',
      "text": 'Echtsystem!',
      "protect": true,
      "score": 0,
      "last_use": Date.now()
    }
  ]
let tissEnvList = []
let tissEnvListUnparsed = Util.storeGet('tissEnvList');

try {
    if (tissEnvListUnparsed==null) {
        // fill initial
        tissEnvList = tissEnvListInitial;
    } else {
        //Util.log('tissEnvListUnparsed: ' + tissEnvListUnparsed);
        tissEnvList = JSON.parse(tissEnvListUnparsed);
    }
    // validate tissEnvList - check if each entry has all elements
    tissEnvList.forEach(function(e) {
      if (!('host' in e)) { throw "Parsing tissEnvList not possible!";};
      if (!('prot' in e)) { throw "Parsing tissEnvList not possible!";};
      if (!('text' in e)) { throw "Parsing tissEnvList not possible!";};
      if (!('protect' in e)) { throw "Parsing tissEnvList not possible!";};
      if (!('score' in e)) { throw "Parsing tissEnvList not possible!";};
      if (!('last_use' in e)) { throw "Parsing tissEnvList not possible!";};
    });
}
catch (e) {
    Util.log('Error: ' + e);
    Util.log('Reset tissEnvList!');
    tissEnvList = tissEnvListInitial;
}

//Util.log('tissEnvList: ' + JSON.stringify(tissEnvList, null, "  "));

var i = tissEnvList.findIndex(function (x) { return (x.host === window.location.host && x.prot===window.location.protocol); });
if (i===-1) {
  //aktuelle seite ist noch nicht in liste - in liste aufnehmen
  //vorher noch maxsize prüfen
  if(tissEnvList.length>TISS_ENV_LIST_MAXSIZE){
    Util.log('tissEnvList wird zu lange. Letzter Link fliegt raus:' + tissEnvList[tissEnvList.length-1].text)
    tissEnvList.pop();
  };
  tissEnvList.push({
    "host": window.location.host,
    "prot": window.location.protocol,
    "text": window.location.host.replace('.tiss.tuwien.ac.at','').replace('.apps.dev.csd.tuwien.ac.at','.ac').replace('devcloud','dc').replace('localhost','lh'),
    "protect": false,
    "score":0,
    "last_use": Date.now()
  });
  Util.log('Neu in tissEnvList aufgenommen:' + tissEnvList[tissEnvList.length-1].text)
}
else {
  //aktuelle seite ist bereits in liste
  //score erhöhen
  tissEnvList[i].score = Math.max(1,tissEnvList[i].score + 1 );
  tissEnvList[i].last_use=Date.now();
  if (tissEnvList[i].protect===false && i>0 && tissEnvList[i-1].protect===false && tissEnvList[i].score > tissEnvList[i-1].score) {
    //um einen platz nach vorne sortieren
    Util.move(tissEnvList, i, i-1);
    Util.log(tissEnvList[i].text + ' rutscht mit score ' + tissEnvList[i].score + ' einen platz nach vorne! ')
  }
}

// score aller seiten verringern, die schon länger nicht aufgerufen wurden
for (i = 0; i < tissEnvList.length; ++i) {
  var last_use_in_days_ago = Math.round(( Date.now() - new Date(Number(tissEnvList[i].last_use))) / 86400000 ) //(24 * 1000 * 60 * 60 * 1000[ms])
  //Util.log(tissEnvList[i].text + ' wurde vor ' + last_use_in_days_ago + ' tagen zuletzt aufgerufen.');
  tissEnvList[i].score = Math.max(-10000, Math.min(10,(tissEnvList[i].score - Math.round(last_use_in_days_ago / 5))));
}

//limit list size
tissEnvList.splice(TISS_ENV_LIST_MAXSIZE + 1);
//tissEnvList is now actual - write to local storage
//Util.log('tissEnvList: ' + JSON.stringify(tissEnvList, null, "  "));
Util.storeSet('tissEnvList', JSON.stringify(tissEnvList, null, "  "));

function populateMenu() {
  if (isTissStyle2x) {

      var menu;
      menu = document.getElementsByClassName("clearfix toolNav")[0];
      if (menu == null){
          return
      }
      var li;
      var newLink;
      var text;
      var newSpan;
      // Füge "Benutzer wechseln" hinzu wenn: der Punkt nicht schon existiert UND der Benutzer eingeloggt ist UND es nicht das Echtsystem ist
      if (!menu.textContent.includes("Benutzer wechseln") && document.getElementsByClassName("toolLogout").length >= 1 && window.location.host != tissEnvList[0].host) {
          li = document.createElement("li");
          li.classList.add('rightAlign');
          newSpan = document.createElement("span");
          newLink = document.createElement("a");
          newLink.setAttribute('href','/admin/authentifizierung/benutzer_wechseln');
          newLink.innerHTML = 'Benutzer wechseln';
          newSpan.appendChild(newLink);
          li.appendChild(newSpan);
          menu.appendChild(li);
      }
      for (var i = tissEnvList.length-1; i >= 0; i-- ) {
          if (tissEnvList[i].score === -10000) { continue; }
          li = document.createElement("li");
          li.classList.add('rightAlign');
          li.setAttribute("id", SCRIPT_NAME + "_tab_"+i);
          newSpan = document.createElement("span");
          if (window.location.host == tissEnvList[i].host)
          {
              text = document.createTextNode(tissEnvList[i].text);
              newSpan.appendChild(text);
              newSpan.setAttribute("style", "color:grey; font-weight: bold;");
              newSpan.setAttribute("style", "color:grey; font-weight: bold; background: #FFFFFF; border-left: 1px solid #CDDAE1; border-right: 1px solid #CDDAE1; border-top: 1px solid #CDDAE1; padding-left:4px; padding-right:4px; background: linear-gradient(to top, #F5FAFD, #FFFFFF);");
          } else {
              newLink = document.createElement("a");
              newLink.setAttribute('href',tissEnvList[i].prot + '//' + tissEnvList[i].host + window.location.pathname + window.location.search + window.location.hash);
              newLink.innerHTML = '&nbsp;' + tissEnvList[i].text + '&nbsp;';
              newSpan.appendChild(newLink);
          }
          li.appendChild(newSpan);
          menu.appendChild(li);
      }
  } else if(isTissStyle3x) {
      var mainNavigation;
      mainNavigation = document.getElementsByClassName("main-navigation")[0];
      if (mainNavigation == null){
          return
      }
      var newSpan3;
      var text3;
      var newLink3;

      //todo anpassen für isTissStyle3x: das benutzer wechseln ist neuerdings ins dropdown links gewandert
      // Füge "Benutzer wechseln" hinzu wenn: der Punkt nicht schon existiert UND der Benutzer eingeloggt ist UND es nicht das Echtsystem ist
      //var li3;
      //var newLink3;
      //var text3;
      //var newSpan3;
      //if (!menu3.textContent.includes("Benutzer wechseln") && document.getElementsByClassName("toolLogout").length >= 1 && window.location.host != tissEnvList[0].host) {
      //    li3 = document.createElement("li");
      //    li3.classList.add('rightAlign');
      //    newSpan3 = document.createElement("span");
      //    newLink3 = document.createElement("a");
      //    newLink3.setAttribute('href','/admin/authentifizierung/benutzer_wechseln');
      //    newLink3.innerHTML = 'Benutzer wechseln';
      //    newSpan3.appendChild(newLink3);
      //    li.appendChild(newSpan3);
      //    menu3.appendChild(li3);
      //}

      // Füge Links zu anderen Systemen dazu
      var sysNavigation = document.createElement("nav");
      sysNavigation.setAttribute("id", SCRIPT_NAME + "_navigation");
      sysNavigation.classList.add('desktop-only');
      sysNavigation.classList.add('main-navigation');
      sysNavigation.setAttribute("style", "padding-top:14px;");

      for (var i3 = tissEnvList.length-1; i3 >= 0; i3-- ) {
          if (tissEnvList[i3].score === -10000) { continue; }
          newSpan3 = document.createElement("span");
          if (window.location.host == tissEnvList[i3].host)
          {
              newLink3 = document.createElement("a");
              newLink3.setAttribute('href','/');
              newLink3.innerHTML = '&nbsp;' + tissEnvList[i3].text + '&nbsp;';
              newLink3.setAttribute("style", "padding-left:4px; padding-right:4px; font-size:12px;");
              newLink3.classList.add('education');
              newLink3.classList.add('research');
              newLink3.classList.add('organization');
              newLink3.setAttribute("id", SCRIPT_NAME + "_tab_"+i);
              newSpan3.appendChild(newLink3);
          } else {
              newLink3 = document.createElement("a");
              newLink3.setAttribute('href',tissEnvList[i3].prot + '//' + tissEnvList[i3].host + window.location.pathname + window.location.search + window.location.hash);
              newLink3.innerHTML = '&nbsp;' + tissEnvList[i3].text + '&nbsp;';
              newLink3.setAttribute("style", "padding-left:4px; padding-right:4px; font-size:12px;");
              newLink3.setAttribute("id", SCRIPT_NAME + "_tab_"+i);
              newSpan3.appendChild(newLink3);
          }
          sysNavigation.appendChild(newSpan3);
      }
      mainNavigation.prepend(sysNavigation);

  }
}
populateMenu();

GM_registerMenuCommand(SCRIPT_NAME + ': Remove last Environment Tab!', function() {
    var i = tissEnvList.length-1
    var tab_to_remove = document.getElementById(SCRIPT_NAME + "_tab_"+i);
    if (tab_to_remove != null){
      Util.log('Clear last Tab...');
      tab_to_remove.style.visibility = "hidden";
      //tab_to_remove.parentNode.removeChild(tab_to_remove);
      tissEnvList.pop();
      //tissEnvList  - write to local storage
      Util.storeSet('tissEnvList', JSON.stringify(tissEnvList, null, "  "));
    }
});
////////////////////////////////////////////////////////////////////////////////
//ECHTSYSTEM! - warning-bar
//(kopiert von userstyle tiss-env-border https://userstyles.org/styles/121958/tiss-env-border)
//@-moz-document regexp(".*[^\.]tiss[\.]tuwien[\.]ac[\.]at.*"){ body:before... } funktioniert leider nur im ff
    if (window.location.host == 'tiss.tuwien.ac.at')
    {
      GM_addStyle(`
        body:before {
          content: " ";
          position: fixed;
          background: #FF0000;
          left: 0;
          right: 0;
          height: 11px;
          z-index:100;
          background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' height='11px' width='90px'><text x='9' y='9' fill='white' font-size='10' font-weight='bold' font-family='Arial, Helvetica, sans-serif' >ECHTSYSTEM ! </text></svg>");
          top: 0;
        }
        body {
          margin-top:11px;
        }
     `);
      //change prod favicon
      var FaviconProd = document.createElement('link');
      FaviconProd.setAttribute('rel', 'shortcut icon');
      FaviconProd.setAttribute('href', '/images/icons/faviconrot.ico');
      var header = document.getElementsByTagName('head')[0];
      header.appendChild(FaviconProd);
    }
////////////////////////////////////////////////////////////////////////////////
// mark current menu entry
if(isTissStyle2x) {
    GM_addStyle(`
#supNav ul li.currentPageItem > span > a {
background: #FFFFFF;
border-bottom: 1px solid #CDDAE1;
border-top: 1px solid #CDDAE1;
}
.organisation #supNav ul li.currentPageItem > span > a {
background: linear-gradient(to right, #DAC4F3, #F5FAFD, #F5FAFD, #F5FAFD, #F5FAFD, #FFFFFF);
}
.lehre #supNav ul li.currentPageItem > span > a {
background: linear-gradient(to right, #DA923C, #F5FAFD, #F5FAFD, #F5FAFD, #F5FAFD, #FFFFFF);
}
.forschung #supNav ul li.currentPageItem > span > a {
background: linear-gradient(to right, #9FC65A, #F5FAFD, #F5FAFD, #F5FAFD, #F5FAFD, #FFFFFF);
}
#shadow_top {
z-index: 0;}
`);
}
////////////////////////////////////////////////////////////////////////////////
// fill unused space - use whole screen width
if(isTissStyle2x) {
  GM_addStyle("body>#wrapper {max-width: 98%!important;}");
}

////////////////////////////////////////////////////////////////////////////////
// menu scroll independece
var tissMenuScrollIndependence = Util.storeGet('tissMenuScrollIndependence')
tissMenuScrollIndependence = (tissMenuScrollIndependence === undefined) ? false : tissMenuScrollIndependence; //tissMenuScrollIndependence ??= false;
if(isTissStyle3x && tissMenuScrollIndependence) {
  //GM_addStyle("main, ul#submenu {height: calc(100vh - 128px); overflow-y:auto;}");
  var currentContentHeight = document.getElementById("content").offsetHeight;
  GM_addStyle("ul#submenu {height: max(" + currentContentHeight + "px, calc(100vh - 128px)); overflow-y:auto;}");
}

GM_registerMenuCommand(SCRIPT_NAME + ': Menu scroll independence', toggleScrollIndependence);
function toggleScrollIndependence() {
    Util.storeSet('tissMenuScrollIndependence', !tissMenuScrollIndependence);
    alert((tissMenuScrollIndependence ? 'Menu scrollbar is disabled now!' : 'Menu scrollbar is enabled now!') + 'Takes affect after a Reload (F5).');
};

////////////////////////////////////////////////////////////////////////////////
// recalculate "leader line" (usage see #39268) start and endpoints
// by firing a fake resize event
window.dispatchEvent(new Event('resize'));
////////////////////////////////////////////////////////////////////////////////
Util.log('End');