- // ==UserScript==
- // @name gmx - show new unread
- // @name:fr gmx - marquer nouveaux messages
- // @name:de gmx - zeige neues ungelesenes
- // @name:es gmx - mostrar nuevos no leídos
- // @namespace https://github.com/Procyon-b
- // @version 0.6.2
- // @description Mark folders with new unread messages (gmx / web.de)
- // @description:fr Marque les dossiers contenant de nouveaux messages (gmx / web.de)
- // @description:de Markieren Sie Ordner mit neuen ungelesenen Nachrichten (gmx / web.de)
- // @description:es Marcar carpetas con nuevos mensajes no leídos (gmx / web.de)
- // @author Achernar
-
- // @match https://3c.gmx.net/mail/client/*
- // @match https://3c-bap.gmx.net/mail/client/*
- // @include https://3c-bs.gmx.tld/mail/client/*
- // @match https://3c.web.de/mail/client/*
- // @match https://3c-bap.web.de/mail/client/*
-
- // @match https://navigator.gmx.net/*
- // @match https://bap.navigator.gmx.net/*
- // @include https://navigator-bs.gmx.tld/*
- // @match https://navigator.web.de/*
- // @match https://bap.navigator.web.de/*
-
- // @grant GM_setValue
- // @grant GM_getValue
- // ==/UserScript==
-
- (function() {
- "use strict";
-
- var h=location.host.split('.');
-
- window.addEventListener('blur', function(ev) {
- window.top.postMessage({blur:1},'*');
- });
- window.addEventListener('focus', function(ev) {
- window.top.postMessage({focus:1},'*');
- });
-
- let f=document.hasFocus();
- window.top.postMessage({focus:f, NOblur:!f},'*');
-
-
- // main frame (top)
- if (location.host.startsWith('navigator') || location.host.startsWith('bap.navigator') ) {
- var TO, marked, TOb, focus=false, mailFrame, data=document.getElementById('user-data');
- try {
- if (data) data=JSON.parse(data.text);
- }catch(e){};
-
-
- window.addEventListener('message', function(ev) {
- if (typeof ev.data != 'object') return;
-
- if (ev.data.getUserId) {
- ev.source.window.postMessage({userId:data.hashedUasAccountId}, ev.origin);
- mailFrame={w:ev.source.window, origin:ev.origin};
- return;
- }
-
- if (ev.data.focus) {
- focus=true;
- if (TOb) {clearTimeout(TOb); TOb=null;}
- else if (marked) onF();
- }
- if (ev.data.blur) {
- focus=false;
- if (TO) {
- TOb=setTimeout(function(){
- TOb=null;
- onB();
- }, 1000);
- }
- }
-
- mailFrame && mailFrame.w.postMessage({focus:focus, blur:!focus}, mailFrame.origin);
-
- function onF() {
- onB();
- TO=setTimeout( function(){
- TO=null;
- marked=false;
- document.title=document.title.replace(/^\(.*?\) */,'');
- }, 3000);
- }
- function onB() {
- if (TO) {clearTimeout(TO); TO=null;}
- }
-
- if (!focus && ev.data.new) {
- marked=true;
- document.title='(*) '+document.title.replace(/^\(.*?\) */,'');
- }
- }, false);
-
- return;
- }
-
-
- // folders frame
- if (location.pathname.startsWith('/mail/client/') ) {
- if (window.parent === window) return;
-
- var e=document.querySelector('#navigation');
- if (!e) return;
-
- // call top to get userid
- window.top.postMessage({getUserId:true},'*');
-
- var focus=false, userId, folders={}, ignore=['vfol3','vfol2'];
-
- window.addEventListener('message', function(ev){
- if (typeof ev.data != 'object') return;
-
- if (ev.data.userId) {
- userId=ev.data.userId;
- let sFolders={};
- try{sFolders=GM_getValue(userId,{});}catch(e){}
- folders={userId:userId};
-
- // find all folders
- let a=document.querySelectorAll('#navigation NOul, #navigation li > .folder'),
- lvl=[], L, t, id, panel, New=false;
- for (let i=0,e; e=a[i]; i++) {
- L= parseInt( (L=/lvl(\d+)/.exec(e.parentNode.parentNode.classList)) && L[1] );
- lvl[L]=id=e.id;
- if (L==1) {
- panel= (panel=e.closest('.navigation')) && (panel=panel.querySelector(':scope > .panel-head'));
- if (panel && panel.title && panel.querySelector('.badge') ) panel=panel.title;
- else panel='';
- }
-
- let badge=e.querySelector('.badge');
- folders[id]={lvl:L, ur:badge && parseInt(badge.innerText)};
- if (ignore.includes(id)) folders[id].ignore=1;
- // the 3 default folders without badge
- if (!badge) folders[id].nobadge=1;
-
- let label=e.querySelector('.label');
- if (label) {
- folders[id].name=label.innerText.trim();
- // fix for closed folders
- if ( /\((\d+)\/\d+\)$/.exec(label.title) ) folders[id].ur=parseInt(RegExp.$1);
- }
-
- // is part of panel with badge
- if (panel) folders[id].panel=panel;
-
- // is subfolder
- if (t=lvl[L-1]) {
- folders[id].p=t;
- folders[t].sub=1;
- }
-
- if (sFolders[id]) {
- if (t=sFolders[id].mark) folders[id].mark=t;
- if (folders[id].ur > sFolders[id].ur) {
- folders[id].mark=1;
- New=true;
- }
- if (!folders[id].ur || !badge) delete folders[id].mark;
- }
- }
- try{GM_setValue(userId, folders);}catch(e){}
- buildCSS();
- if (!f && New) window.top.postMessage({new:1},'*');
- return;
- }
-
- if (ev.data.focus) focus=true;
- if (ev.data.blur) focus=false;
- }, false);
-
- function buildCSS(ret) {
- var s='/*userscript test*/', fol={}, pan={}, i;
- for (i in folders) {
- let f=folders[i];
- if (f.ignore) continue;
- if (f.mark || f.fmark) {
- s+='div.nav-item[id="'+i+'"] .badge{background-color: red !important; color: white !important;}';
- while (f.p) {
- if (!f.ignore) fol[f.p]=1;
- f=folders[f.p];
- }
- if (f.panel) {
- pan[f.panel]=1;
- }
- }
- }
- for (i in fol) { s+='div.nav-item[id="'+i+'"]:not(.open) .badge{background-color: red;}'; }
- for (i in pan) { s+='div.navigation > div.panel-head[title="'+i+'"] .badge{background-color: red; color: white;}'; }
- if (ret) return s;
- style.innerText=s;
- }
-
- var st={}, options={attributes: false, subtree: true, childList: true };
-
- var style=document.createElement('style');
- if (style.styleSheet) style.styleSheet.cssText = '';
- else style.appendChild(document.createTextNode(''));
- (document.head || document.documentElement).appendChild(style);
- buildCSS();
-
- const obs = new MutationObserver(function(mutL){
- let n, o, t, save=false, New=false;
- for (let mut of mutL) {
- if ( (t=mut.target) && (t.className=='badge') ) {
- if ( (n=mut.addedNodes[0]) && (n.nodeType==3) ) {
- var div=t.closest('div.nav-item.folder'), id=div && (id=div.id), q=parseInt(n.data);
- if (!id || !folders[id]) continue;
- if (folders[id].sub) {
- let cl=div.classList.contains('open') ? false:true;
- if (cl) {
- var tit= (tit=div.querySelector('.label')) && tit.title;
- let qt=-1;
- if ( /\((\d+)\/\d+\)$/.exec(tit) ) qt=parseInt(RegExp.$1);
- if (qt>=0) q=qt;
- }
- }
- if (folders[id].ur == q) continue;
- if (q <= folders[id].ur) delete folders[id].mark;
- else {
- folders[id].mark=1;
- New=true;
- }
- folders[id].ur=q;
- save=true;
- }
- }
- }
-
- if (save) {
- buildCSS();
- try{GM_setValue(userId, folders);}catch(e){}
- }
- if (!focus && New) window.top.postMessage({new:1},'*');
- });
- obs.observe(e, options);
-
- e.addEventListener('click', function(ev){
- if (ev.ctrlKey) {
- if (ev.target.classList.contains('folder-config') || ev.target.parentNode.classList.contains('folder-config') ) {
- let fol=ev.target.closest('div.nav-item.folder');
- if (!fol || fol.classList.contains('has-open-flyout') || (!fol.classList.contains('open') && fol.firstElementChild.classList.contains('toggle')) ) return;
- ev.stopPropagation();
- if (folders[fol.id].mark) {
- delete folders[fol.id].mark;
- buildCSS();
- try{GM_setValue(userId, folders);}catch(e){}
- }
- return false;
- }
- }
- },true);
-
- }
-
- })();