GreasyFork: User Control Panel Button

To add User Control Panel Button into navigation bar

目前为 2023-09-21 提交的版本。查看 最新版本

// ==UserScript==
// @name        GreasyFork: User Control Panel Button
// @namespace   UserScripts
// @match       https://greasyfork.org/*
// @grant       none
// @version     0.1.4
// @license     MIT
// @author      CY Fung
// @description To add User Control Panel Button into navigation bar
// ==/UserScript==


(async () => {


  function bufferToHex(buffer) {
    const byteArray = new Uint8Array(buffer);
    const len = byteArray.length;
    const hexCodes = new Array(len * 2);
    const chars = '0123456789abcdef';
    for (let i = 0, j = 0; i < len; i++) {
      const byte = byteArray[i];
      hexCodes[j++] = chars[byte >> 4];
      hexCodes[j++] = chars[byte & 0x0F];
    }
    return hexCodes.join('');
  }

  async function digestMessage(message) {
    const encoder = new TextEncoder("utf-8");
    const msgUint8 = encoder.encode(message);
    const hashBuffer = await crypto.subtle.digest('SHA-1', msgUint8);
    return bufferToHex(hashBuffer);
  }

  if(!document.querySelector('.sign-out-link') || document.querySelector('.sign-in-link')) return;

  let plink = document.querySelector('.user-profile-link');
  if (!plink) return;

  let href = plink.querySelector('a[href*="/users/"]').href;

  let mi = href.indexOf('/users/');
  if (mi < 0) return;

  if(href.includes('/users/sign')) return;




  let dm = await digestMessage(href);

  const stKey = `gf_control_panel_${dm}`
  

  for (let trialN = 8; trialN--;) {
    let s = sessionStorage.getItem(stKey);
    let d = typeof s ==='string' ? parseInt(s) : 0;
    if(d > 9 && Date.now()-d < 8000) await new Promise(r => setTimeout(r, 320));
    else break;
  }

  const cpHTML = await new Promise(resolve => {


    let t = sessionStorage.getItem(stKey)

    if (`${t}`.length > 32) resolve(t);


    sessionStorage.setItem(stKey, `${Date.now()}`);


    fetch(href, {
      method: "GET",
      mode: "cors",
      cache: "force-cache",
      credentials: "same-origin",
      redirect: "follow",
      referrerPolicy: "no-referrer",


    }).then(res => res.text()).then(async res => {


      let template = document.createElement('template');
      template.innerHTML = res;
      let w = template.content;

      let cp = w.querySelector('#control-panel');

      if (!cp) return;

      const html = cp.innerHTML.trim();

      sessionStorage.setItem(stKey, html);

      resolve(html);


    });



  });

  if (!cpHTML || typeof cpHTML !== 'string') return;

  let cpm = document.createElement('template');

  cpm.innerHTML = cpHTML;

  let h = (cpm.content.querySelector('h3') || cpm.content.querySelector('header'));
  if (!h) return;

  let nav = document.createElement('nav');

  for (const anchor of cpm.content.querySelectorAll('li a[href]')) {
    let li = nav.appendChild(document.createElement('li'));
    li.appendChild(anchor);
  }

  let pos = document.querySelectorAll('#site-nav>nav>li.with-submenu');
  pos = pos.length >= 1 ? pos[pos.length - 1] : null;

  if (!pos) return;

  let tm = document.createElement('template');
  tm.innerHTML = `

          <li class="with-submenu" style="display: block;">
            <a href="#" onclick="return false">${h.textContent}</a>
            <nav>
              ${nav.innerHTML}
            </nav>
          </li>

  `.trim();
  pos.parentNode.insertBefore(tm.content, pos.nextSibling)



})();