USO - Display additional infos & fixes

Display additional information. Total installs, update date, initial release date. Fix site's navigability.

Versión del día 13/06/2023. Echa un vistazo a la versión más reciente.

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Necesitará instalar una extensión como Tampermonkey para instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name         USO - Display additional infos & fixes
// @namespace    https://github.com/Procyon-b 
// @version      0.3.4
// @description  Display additional information. Total installs, update date, initial release date. Fix site's navigability.
// @author       Achernar
// @match        https://userstyles.org/*
// @run-at       document-start
// @grant        none
// ==/UserScript==

(function() {
"use strict";

var initial=true, firstPage=true;

// catch site errors
if (location.pathname.startsWith('/styles/[styleId]/')) {
  let u=location.pathname.substr(17);
  history.replaceState({}, null, u);
  location.pathname=u;
  return;
  }


// XHR -- XML
self.XMLHttpRequest = class extends self.XMLHttpRequest {
  open(...args) {
    let t=this;
    // intercept and source code
    if ( arguments[1].startsWith('https://gateway.userstyles.org/styles/getStyleCss/') ) {
      styleLoaded=styleID || -1;
      loadCSS=1;
      this.addEventListener('load', function(){
        var id=t.responseURL.split('/').pop();
        if (styles[id] && !styles[id].sourceCode) styles[id].sourceCode=JP(t.response).result;
        });
      }
    return super.open(...args);
    }
  }

// JSON.parse
var JP=JSON.parse;
JSON.parse=function(){
  var r=JP(...arguments);
  getStyles(r);
  return r;
}

// stop svg js animation
window.requestAnimationFrame=function(){}

// handle data
var stylesA=[], styles={};
var total=0, styleLoaded;
var closeBut;

function getStyles(o) {
  stylesA=parseObj(o, [], ['styles', 'stylesList', 'style']);
  stylesA.forEach((e) => {
    if (e.id && !styles[e.id]) {
      styles[e.id]=Object.assign({}, e);
      total++;
      }
    });
  }

function parseObj(o, A, n=[]) {
  var k, v;
  if ( (typeof o != 'object') || !Array.isArray(A)) return;
  for (k in o) {
    v=o[k];
    if ((typeof v == 'object') && n.includes(k)) A=A.concat(v);
    if (typeof v == 'object') A=parseObj(v, A, n);
    }
  return A;
  }

var done, newL, Tit, title, title0='Website Themes & Skins by Stylish | Userstyles.org',
    userID, cancelNextRS=0, dontCancel='', site='',
    bgPage='/', blockTitle;

if (document.readyState != 'loading') init('"already done"', 1);
else {
  document.addEventListener('DOMContentLoaded', (ev) => { init('DOM');} );
  window.addEventListener('load', (ev) => { init('wLoad', 1);} );
  }


function chkState(a) {
  var u=a[2];
  if (u == '/styles/browse') {
    if (bgPage.startsWith(u)) u=bgPage;
    } 
  else if (u.startsWith('/styles/[styleId]/')) {
    title='';
    document.title=title0;
    u=bgPage;
    }
  else if (u.startsWith('/user-profile/[...userId]')) {
    if (userID || __NEXT_DATA__) {
      u='/user-profile/'+(userID || __NEXT_DATA__.query.userId);
      }
    }
  a[2]=u;
  }

// hide logo when scrolled. (saves cpu on old hardware)
var Logo, LHidden=false;
function hideLogo() {
  function toggle(set) {
    if ( Logo=(Logo && Logo.parentNode && Logo) || document.querySelector('[class^="welcome-banner_top_"] svg') )
      LHidden=Logo.classList.toggle('hideMe',set);
    else LHidden=set;
    }
  window.addEventListener('scroll', function() {
    if (window.scrollY > 200) {
      if (LHidden) return;
      toggle(true);
      }
    else if (LHidden) toggle(false);
    });
  }

var reactID;

function init(v, old) {
  if (done) return;
  newL=document.querySelector('#__next');
  if (!newL) {
    if (old && ST) ST.remove(); 
    return;
    }
  addSt();
  hideLogo();
  let t;
  done=true;
  reactID= (t=Object.keys(newL).find( (v) => v.startsWith('__react') )) && t.split('$')[1];
  
  if (__NEXT_DATA__.page == '/styles/[styleId]/[[...styleParams]]') bgPage='/';
  else if ( (__NEXT_DATA__.page == '/styles/browse/[[...categoryParams]]') || (__NEXT_DATA__.page == '/user-profile/[...userId]') )
    bgPage='/'+__NEXT_DATA__.props.metaTagsData.og.url.split('/').slice(3).join('/');
  
  let pushState=history.pushState;
  history.pushState=function(){
    let u=arguments[2];
    // ignore if same state
    if (cancelNextRS && (dontCancel == u) ) {
      dontCancel='';
      }
    else if (cancelNextRS || (u == location.pathname) ) {
      //cancelNextRS=false;
      cancelNextRS && cancelNextRS--;
      dontCancel='';
      selfTitle=blockTitle=true;
      return;
      }
    initial=false;
    firstPage=false;
    chkState(arguments);
    
    if (u.startsWith('/user-profile/') && (u[13] != '[') ) userID=u.split('/')[2];
    if ( (u == '/') || u.startsWith('/user-profile/') || u.startsWith('/styles/browse/') ) bgPage=u;
    
    pushState.apply(history, arguments);
    if (location.pathname.startsWith('/styles/')) {
      addData('from pushState (path)');
      }
    }

  var hback=history.back,
      hforward=history.forward,
      hgo=history.go,
      hreplaceState=history.replaceState;
  
  history.replaceState=function() {
    if (cancelNextRS && (dontCancel == arguments[2]) ) {
      dontCancel='';
      }
    else if (cancelNextRS || (arguments[2] == location.pathname) ) {
      cancelNextRS && cancelNextRS--;
      dontCancel='';
      selfTitle=blockTitle=true;
      return;
      }
    initial=false;
    firstPage=false;
    return hreplaceState.apply(history, arguments);
    }


  window.addEventListener('popstate', (ev) => {
    if (location.pathname.startsWith('/user-profile/')) {
      if (newL.querySelector(':scope > [class^="style_mainWrapper_"]')) {
        let e=newL.querySelector(':scope > [class^="style_mainWrapper_"] a[data-stylish="close-style-page-button"]');
        if (e) {
          e.click();
          }
        }
      }
    else if (location.pathname.startsWith('/styles/')) {
      let i, r, e=document.querySelector('a[href^="'+location.pathname+'"]');

      if (!e) {
        r=newL.querySelectorAll('[class^="styles-list_styleRow_"]');
        let st, ost;
        
        let ID=location.pathname.split('/')[2]
        
        for (i=0; i < r.length; i++) {
          if (r[i]['__reactFiber$'+reactID] && (ID == r[i]['__reactFiber$'+reactID].key.split('-').pop()) ) {
            e=r[i];
            break;
            }
          }
        }

      if (!e) {
        let A=document.querySelector('a[href^="/styles/"][href*="1"]');
        if (A) {
          let react=Object.keys(A).find( (v) => v.startsWith('__reactFiber') );
          e=document.createElement('a');
          e.href=location.pathname;
          e.style='display: none !important;';
          let r=newL.querySelector(':scope > div > [class^="Home_homepageWrapper_"]')
          if (r) r.appendChild(e);
          }
        }
      if (e) e.click();
      }
    else if (location.pathname == '/') {
      let e=newL.querySelector(':scope > [class^="style_mainWrapper_"] a[data-stylish="close-style-page-button"]');
      if (e) {
        cancelNextRS=1;
        e.click();
        }
      }
    });

  
  // check Title
  var Tit = document.querySelector('title'), selfTitle=false;
  new MutationObserver(function(mutations) {
    if (selfTitle) { selfTitle=false; return; }
    if (title && !Tit.textContent.startsWith(title) ) {
      document.title=title;
      selfTitle=true;
      }
    }).observe(Tit, { attributes: false, subtree: false, childList: true });

  site=document.title.split('|')[1] || '';
  if (site) site=' |'+site;

  // detect (no) popup
  new MutationObserver(function(mutations) {
    if (!newL.querySelector(':scope > [class^="style_mainWrapper_"]')) {
      title='';
      document.title=title0;
      if (location.pathname.startsWith('/styles/')) {
        if (firstPage && !initial) {
          }
        }
      }
    else {
      addData('from is popup');
      }
    
    }).observe(newL, { attributes: false, subtree: false, childList: true });

  // mutation add-er
  
    // sub Mut
    function mutToast() {
      let r=newL.querySelector(':scope > .Toastify ~ div[class=""], :scope > .Toastify ~ div[class^="MainLayout_mainLayout__"]');
      if (r && r.attributes.obs) {
        return;
        }
      if (r) {
        new MutationObserver(function(muts) {
        for (let mut of muts) {
          if (mut.addedNodes.length && mut.previousSibling && (mut.previousSibling.localName == 'header') ) {
            addDataTiles();
            watchGrid();
            break;
            }
          }          
        }).observe(r, { attributes: true, subtree: false, childList: true });
        r.setAttribute('obs', 'tiles');
        }

      // added cards ?
      watchGrid();
      }

    function watchGrid() {
      var r=newL.querySelector('[class^="styles-grid_gridItems_"]') ||
        newL.querySelector('[class^="styles-gallery_scrollWrapper_"] > div:not([class])');
      if (r.attributes.obs) {
        return;
        }
      if (r) {new MutationObserver(function(muts) {
        for (let mut of muts) {
          if (mut.addedNodes.length) { 
            addDataTiles();
            break;
            }
          }          
        }).observe(r, { attributes: true, subtree: false, childList: true });
        r.setAttribute('obs', 'grid');
        }
      }

  new MutationObserver(function(muts) {
    let mut;
    for (mut of muts) {
      
      // new body
      if (mut.addedNodes.length && mut.previousSibling && (mut.previousSibling.className == 'Toastify') ) {
        addDataTiles();

        // new list
        mutToast();
        break;
        }
      
      } 
    }).observe(newL, { attributes: false, subtree: false, childList: true });
  newL.setAttribute('obs', null);
  mutToast();
  addDataTiles();

  if (location.pathname.startsWith('/styles/')) {
        setTimeout((e) => {addData('from ini '+v)}, 0);
        }
  }

var totalI, styleID, showCSS, loadCSS;

function getCSS(id, callback) {
  if (id && (typeof callback == 'function') ) {
    fetch('https://gateway.userstyles.org/styles/getStyleCss/'+id)
      .then((response) => response.json())
      .then((data) => callback(data));
    }
  }

function addData() {
  var id=styleID=location.pathname.split('/')[2],
      s=styles[id];

  if (initial) {
    // this is the only case when this has to be done.
    var t=newL.querySelector('[class^="style-header_close_"]')
    if (!closeBut || (closeBut !== t) ) {
      closeBut=t;
      if (closeBut) {
        closeBut.addEventListener('click', function() {
          cancelNextRS=1;
          dontCancel='/';
          title='';
          document.title=title0;
          history.pushState({}, null, '/');
          });
        }
      }
    }
  
  if (!s) return;
  var a=document.querySelector('#weekly-installs');
  if (!a) return;

  if (!totalI || !totalI._root.parentNode) {
    totalI=a.cloneNode(true);
    totalI.id='totalInstalls';
    totalI.dataset.tooltipContent='';
    totalI._v=totalI.querySelector(':scope div span');
    totalI._v.textContent='';
    var tt=a.nextElementSibling, ttTI;
    if ( tt.attributes.role && (tt.attributes.role.value == 'tooltip') ) ttTI=tt.cloneNode(true);
    if (!ttTI) {
      ttTI=document.createElement('div');
      ttTI.innerHTML='<div role="tooltip" _model class="react-tooltip styles-module_tooltip__mnnfp styles-module_dark__xNqje react-tooltip__place-top styles-module_show__2NboJ" style="visibility: hidden;">test<div class="react-tooltip-arrow styles-module_arrow__K0L3T" style="left: 40px; bottom: -4px;"></div></div>';
      ttTI=ttTI.firstElementChild;
      tt=totalI;
      }
    if (ttTI) {
      a.parentNode.insertBefore(ttTI, tt.nextSibling);
      if (ttTI.childNodes.length == 1) {
        let T=document.createTextNode('Total installs');
        ttTI.insertBefore(T, ttTI.firstChild);
        }
      else ttTI.childNodes[0].textContent='Total installs';
      totalI.onmouseenter=function(){
        ttTI.style.opacity='0.9';
        ttTI.style.visibility='visible';
        if (ttTI._init) return;
        ttTI._init=true;
        if (ttTI.attributes._model) {
          ttTI.style.top=(totalI.offsetTop - 47) +'px'; 
          ttTI.style.left=(totalI.offsetLeft -10) +'px';
          }
        else {
          ttTI.style.left=(totalI.offsetLeft - a.offsetLeft + tt.offsetLeft)+'px';
          ttTI.style.top=tt.style.top;
          ttTI.firstElementChild.setAttribute('style', tt.firstElementChild.attributes.style.value);
          }
        };
      totalI.onmouseleave=function(){ttTI.style.opacity='0'; ttTI.style.visibility='hidden';};
      }
    var i=totalI.querySelector(':scope > svg'), i2;
    if (i) {
      i2=i.cloneNode(true);
      totalI.insertBefore(i2, i.nextSibling);
      i2.style='margin-left: -17px';
      }
    a.parentNode.insertBefore(totalI, (tt || a).nextSibling);
    totalI._root=totalI.closest('[class^="style_mainWrapper_"]');

    showCSS=totalI._root.querySelector('[class*="style-info_showCss_"]');
    if (showCSS) {
      new MutationObserver(function(mutations) {
        let e;
        if (e=showCSS.parentNode.querySelector('[class^="Popup_modalWrapper_"] textarea')) {
          if (loadCSS) {loadCSS=0; return;}
          if (styles[styleID].sourceCode) e.value=styles[styleID].sourceCode;
          else {
            e.value='';
            getCSS(styleID, function(v){e.value=styles[styleID].sourceCode=v.result;} );
            }
          }
        }).observe(showCSS.parentNode, { attributes: false, subtree: false, childList: true });
      }
    }
  else {
    let e=totalI._root.querySelector('[class^="Popup_modalWrapper_"] textarea');
    if (e) {
      if (styles[styleID].sourceCode) e.value=styles[styleID].sourceCode;
      else {
        e.value='';
        getCSS(styleID, function(v){e.value=styles[styleID].sourceCode=v.result;} );
        }
      }
    }

  let v=parseInt(s.totalInstallsCount);
  let vd=a.querySelector('span'), vdv=vd.innerText;
  if (vdv.endsWith('k')) vdv=Math.floor(parseFloat(vdv) * 1000);
  else vdv=parseInt(vdv);
  if (vdv > v) {vd.style='text-decoration: line-through; text-decoration-color: red;';}
  else vd.style='';
  if (v > 1000) v=(v/1000).toFixed(1)+'k';
  totalI._v.textContent=v;
  document.title=title=s.name+site;

  setTimeout(function(){
    if (!totalI._root.parentNode) addData('after');
    },10);
  }

function addDataTiles() {
  var a=document.querySelectorAll('[data-stylish^="strip-cube-styles"]:not(._done), [data-stylish^="grid-cube-styles"]:not(._done)');
  
  a.forEach((e) => e.classList.add('_done'));
  var i=0;
  add2Tiles();
  
  function add2Tiles() {
    var max=Date.now() + 100;
    for (; i < a.length; i++) {
      if (Date.now() > max) {
        setTimeout(add2Tiles, 0);
        return;
        }
      
      let e=a[i].querySelector('[class*="style-cube_activeUsers_"]');
      if (!e) continue;
      let h=a[i].querySelector('a[href^="/styles/"]');
      if (!h) continue;
      let s=styles[h.pathname.split('/')[2]];
      if (!s) continue;
  
      let r=a[i].querySelector('[class^="style-cube_styleDetails_"]');

      let tot=e.cloneNode(true);
      e.title='Weekly installs';
      tot.classList.add('_totalInstalls');
      tot.title='Total installs';
      let _v=tot.querySelector(':scope div span');
      _v.textContent='';
      
      let I=tot.querySelector(':scope > svg'), i2;
      if (I) {
        i2=I.cloneNode(true);
        tot.insertBefore(i2, I.nextSibling);
        i2.style='margin-left: -9px';
        }
      
      // insert total
      e.parentNode.insertBefore(tot, e);
  
      let v=parseInt(s.totalInstallsCount);
      if (v > 1000) v=(v/1000).toFixed(1)+'k';
      _v.textContent=v;
      
      // add dates
      e=document.createElement('div');
      e.className='_dates_';
      let C=s.created.split('T')[0], U=s.updated.split('T')[0];
      e.innerHTML=(C == U ? '':'<span title="Last updated">'+U+'</span>')+'<span title="Date created">'+C+'</span>';
      r.appendChild(e);
      
      // add user name
      e=a[i].querySelector('[class^="style-cube_authorAvatar_"]');
      if (e) e.title=s.user.name;
      }
    }
  }


var iST=`
.hideMe {
  display: none;
}
div[class^="style_mainWrapper__"] {
  padding-top: 0;
}

[data-stylish^="strip-cube-styles"] [class^="style-cube_topWrapper_"],
[data-stylish^="grid-cube-styles"] [class^="style-cube_topWrapper_"] {
  margin-bottom: 0;
}
[data-stylish^="strip-cube-styles"] [class^="style-cube_styleDetails_"],
[data-stylish^="grid-cube-styles"] [class^="style-cube_styleDetails_"] {
  flex-direction: row wrap;
  background: var(--bg, gray);
  margin-top: 2px;
  transition: unset !important;
  transition-delay: unset !important;
  padding-top: 2px;
  color: white;
}
[data-stylish^="strip-cube-styles"] [class^="style-cube_styleDetails_"] > *,
[data-stylish^="grid-cube-styles"] [class^="style-cube_styleDetails_"] > * {
  text-overflow: ellipsis;
  overflow: hidden;
  word-break: break-all;
}
[data-stylish^="strip-cube-styles"] [class^="style-cube_styleDetails_"] [class^="style-cube_activeUsers_"],
[data-stylish^="grid-cube-styles"] [class^="style-cube_styleDetails_"] [class^="style-cube_activeUsers_"] {
  width: auto !important;
  margin-left: auto;
}
[data-stylish^="strip-cube-styles"] [class^="style-cube_styleDetails_"] [class^="style-cube_activeUsers_"] + [class^="style-cube_activeUsers_"],
[data-stylish^="grid-cube-styles"] [class^="style-cube_styleDetails_"] [class^="style-cube_activeUsers_"] + [class^="style-cube_activeUsers_"] {
  margin-left: 1em;
}
[data-stylish^="strip-cube-styles"] [class^="style-cube_styleDetails_"] [class^="style-cube_activeUsers_"] svg,
[data-stylish^="grid-cube-styles"] [class^="style-cube_styleDetails_"] [class^="style-cube_activeUsers_"] svg {
  fill: white;
  display: block;
}
  
[data-stylish^="strip-cube-styles"] [class^="style-cube_styleDetails_"] [class^="style-cube_name_"] *,
[data-stylish^="grid-cube-styles"] [class^="style-cube_styleDetails_"] [class^="style-cube_name_"] * {
  text-overflow: ellipsis;
  overflow: hidden;
}
[data-stylish^="strip-cube-styles"] [class^="style-cube_styleDetails_"] > [class^="style-cube_styleName_"],
[data-stylish^="grid-cube-styles"] [class^="style-cube_styleDetails_"] > [class^="style-cube_styleName_"] {
  oline-height: normal;
  flex-basis: calc(100% - 40px);
}
[data-stylish^="strip-cube-styles"] [class^="style-cube_styleDetails_"] > [class^="style-cube_details_"],
[data-stylish^="grid-cube-styles"] [class^="style-cube_styleDetails_"] > [class^="style-cube_details_"] {
  width: auto !important;
  margin-left: auto;
  ooutline: 2px solid red !important;
}

[data-stylish^="strip-cube-styles"] [class*="style-cube_withHover_"]:hover,
[data-stylish^="grid-cube-styles"] [class*="style-cube_withHover_"]:hover {
  transform: unset !important;
  transition: unset !important;
  transition-delay: unset !important;
  background-color: unset !important;
  --bg: DarkSlateGrey;
}

._dates_._dates_ {
  flex-basis: 100%;
  margin-top: 2px;
  text-align: right;
}
._dates_ span {
  color: lightgray;
  font-size: 11px;
}
._dates_ span + span {
  margin-left: 1em;
}

[class^="styles-strip_stripItemsWrapper_"] > button {
  display: none !important;
}
[class^="styles-strip_stripItemsWrapper_"] {
  overflow-x: scroll;
  padding-bottom: 4px;
}
[class^="styles-strip_stripItemsWrapper_"]::-webkit-scrollbar {
  height: 8px !important;
}
[class^="styles-strip_items_"] {
  transform: unset !important;
}

:not(g):not(button):not([class^="style_mainWrapper_"])) {
  transform: unset !important;
  transition: unset !important;
  transition-delay: unset !important;
}
svg[transform*="rotate(-180)"] {
  transform: rotate(-180deg) !important;
}

[class^="category-filter_borderRadios_"] {
  display: none;
}

[class^="styles-list_styleName_"] {
  word-break: break-word;
}

[role="tooltip"] .react-tooltip-arrow {
  bottom: -7px !important;
  border-color: var(--rt-color-dark) transparent;
  border-style: solid;
  border-width: 7px 7px 0 7px;
  display: block;
  background: transparent;
  transform: none;
}

#totalInstalls {
  order: -1;
}

/* fix prothemes sliding right-left - 20230613*/
[class^="styles-strip_sliderWrapper_"][class*="styles-strip_lastPage_"] {
  left: -40px !important;
  right: auto !important;
}
`;

addSt();

var ST;
function addSt() {
  if (!iST) {
    document.documentElement.appendChild(ST);
    return;
    }
  try {
    ST=document.createElement('style');
    document.documentElement.appendChild(ST);
    ST.textContent=iST;
    iST='';
  }catch(e){
    setTimeout(addSt,0); }
}


})();