[AMD] Auto Expand Option(s)

Automatically opens the first option.

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

You will need to install an extension such as Tampermonkey to install this 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         [AMD] Auto Expand Option(s)
// @description  Automatically opens the first option.
// @author       Magic of Lolis <[email protected]>
// @icon         https://www.amd.com/themes/custom/amd/favicon.ico
// @version      1.0.5
// @supportURL   https://github.com/magicoflolis/userscriptrepo/issues/new
// @namespace    https://github.com/magicoflolis/userscriptrepo/tree/master/AMDAutoOpen#amd-auto-expand
// @homepageURL  https://github.com/magicoflolis/userscriptrepo/tree/master/AMDAutoOpen#amd-auto-expand
// @match        https://www.amd.com/*/support/*
// @grant        navigator.userAgent
// @compatible   chrome
// @compatible   firefox
// @compatible   edge
// @compatible   opera
// @run-at       document-end
// @noframes
// ==/UserScript==

'use strict';
(() => {
  //#region Config
  /** Choice Options:
   * @param {string} choice - first | all | none | windows or Windows 11 - 64-Bit Edition...etc */
  let choice = 'first';
  /** Enable/disable Reduce Clutter:
   * @param {boolean} reduce_clutter - Removes some clutter */
  let reduce_clutter = true;
  /** Auto Scroll Amount:
   * @param {number} scroll_amount - Set to 0 disables auto scroll AND 'Top' button */
  let scroll_amount = 110;
  /** Top Button CSS:
   * @param {string} css - You can customize the look here */
  let css = `.aeo-top-btn {
  bottom: 1rem;
  right: 1rem;
  color: #000;
  border: 2px solid #000;
  font-size: 14px;
  font-weight: bold;
  width: auto;
  min-height: 5px;
  margin: 0 3px;
  padding: 10px 15px;
  cursor: pointer;
  text-transform: uppercase;
  text-align: center;
  white-space: normal;
  position:fixed;
}
.os-group summary .summary {
  margin-left: .5em;
}
/** Removes more clutter */
[id="colorbox"],
[id="cboxOverlay"],
.PPLightBox {
  display: none !important;
  z-index: -1 !important;
  visibility: hidden !important;
}`;
  //#endregion

  const err = (...msg) =>
    console.error(
      '[%cAMD%c] %cERROR',
      'color: rgb(237, 28, 36);',
      '',
      'color: rgb(249, 24, 128);',
      ...msg
    );
  // const log = (...msg) =>
  //   console.log(
  //     '[%cAMD%c] %cDBG',
  //     'color: rgb(237, 28, 36);',
  //     '',
  //     'color: rgb(255, 212, 0);',
  //     ...msg
  //   );
  // const info = (...msg) => console.info('[%cAMD%c] %cINF', 'color: rgb(237, 28, 36);', '', 'color: rgb(0, 186, 124);', ...msg);

  /**
   * Object is Null
   * @param {Object} obj - Object
   * @returns {boolean} Returns if statement true or false
   */
  const isNull = (obj) => {
    return Object.is(obj, null) || Object.is(obj, undefined);
  };
  /**
   * Object is Blank
   * @param {(Object|Object[]|string)} obj - Array, Set, Object or String
   * @returns {boolean} Returns if statement true or false
   */
  const isBlank = (obj) => {
    return (
      (typeof obj === 'string' && Object.is(obj.trim(), '')) ||
      (obj instanceof Set && Object.is(obj.size, 0)) ||
      (Array.isArray(obj) && Object.is(obj.length, 0)) ||
      (obj instanceof Object &&
        typeof obj.entries !== 'function' &&
        Object.is(Object.keys(obj).length, 0))
    );
  };
  /**
   * Object is Empty
   * @param {(Object|Object[]|string)} obj - Array, object or string
   * @returns {boolean} Returns if statement true or false
   */
  const isEmpty = (obj) => {
    return isNull(obj) || isBlank(obj);
  };
  /**
   * Add Event Listener
   * @param {Object} root - Selected Element
   * @param {string} type - root Event Listener
   * @param {Function} callback - Callback function
   * @param {Object} [options={}] - (Optional) Options
   * @returns {Object} Returns selected Element
   */
  const ael = (root, type, callback, options = {}) => {
    try {
      root = root || document || document.documentElement;
      if (/Mobi/.test(navigator.userAgent) && type === 'click') {
        type = 'mouseup';
        root.addEventListener('touchstart', callback);
        root.addEventListener('touchend', callback);
      }
      if (type === 'fclick') {
        type = 'click';
      }
      return root.addEventListener(type, callback, options);
    } catch (ex) {
      return err(ex);
    }
  };
  /**
   * Form Attributes of Element
   * @param {Object} elt - Element
   * @param {string} cname - (Optional) Element class name
   * @param {Object} [attrs={}] - (Optional) Element attributes
   * @returns {Object} Returns created Element
   */
  const formAttrs = (el, cname, attrs = {}) => {
    try {
      if (!isEmpty(cname)) {
        el.className = cname;
      }
      if (!isEmpty(attrs)) {
        for (const key in attrs) {
          if (key === 'dataset') {
            for (const key2 in attrs[key]) {
              el[key][key2] = attrs[key][key2];
            }
          } else if (key === 'click') {
            ael(el, 'click', attrs[key]);
          } else if (key === 'container') {
            if (typeof key === 'function') {
              key();
            }
          } else {
            el[key] = attrs[key];
          }
        }
      }
      return el;
    } catch (ex) {
      err(ex);
      return el;
    }
  };
  const make = (element, cname, attrs = {}) => {
    let el;
    try {
      el = document.createElement(element);
      return formAttrs(el, cname, attrs);
    } catch (ex) {
      err(ex);
      return el;
    }
  };
  const loadCSS = (css, name = 'common') => {
    const s = make('style', `aeo-${name}`, {
      innerHTML: css,
    });
    return !document.head.contains(s) ? document.head.appendChild(s) : false;
  };
  /**
   * Prefix for document.querySelector()
   * @param {Object} element - Element for query selection
   * @param {Object} [root=document] - Root selector Element
   * @returns {Object} Returns root.querySelector(element)
   */
  const qs = (element, root) => {
    root = root ?? document ?? document.body;
    return root.querySelector(element);
  };
  /**
   * Prefix for document.querySelectorAll()
   * @param {Object} element - Elements for query selection
   * @param {Object} [root=document] - Root selector Element
   * @returns {Object} Returns root.querySelectorAll(element)
   */
  const qsA = (element, root) => {
    root = root ?? document ?? document.body;
    return root.querySelectorAll(element);
  };
  /**
   * Prefix for document.querySelector() w/ Promise
   * @param {Object} element - Element for query selection
   * @param {Object} [root=document] - Root selector Element
   * @returns {Object} Returns root.querySelector(element)
   */
  const query = async (element, root) => {
    root = root ?? document ?? document.body;
    while (root.querySelector(element) === null) {
      await new Promise((resolve) => requestAnimationFrame(resolve));
    }
    return root.querySelector(element);
  };
  const top_btn = make('input', 'aeo-top-btn', {
    value: 'Top',
    type: 'button',
    onclick: () => {
      return window.scroll(0, scroll_amount);
    },
  });
  const initScript = async () => {
    try {
      loadCSS(css);
      if (scroll_amount > 0) {
        document.body.append(top_btn);
        window.scroll(0, scroll_amount);
        window.onscroll = () => {
          document.documentElement.scrollTop > scroll_amount
            ? top_btn.setAttribute('style', 'display: inline-block !important')
            : top_btn.setAttribute('style', 'display: none !important');
        };
      }
      if (reduce_clutter) {
        if (qs('[id="scrollspy"]')) {
          qs('[id="scrollspy"]').setAttribute(
            'style',
            'padding: 0px !important'
          );
        }
        const ads = [
          qs('.panel'),
          qs('[role="banner"]'),
          qs('[role="contentinfo"]'),
        ];
        for (const ad of ads) {
          if (isEmpty(ad)) continue;
          ad.remove();
        }
      }
      if (!isEmpty(choice) && !choice.match(/none/gi)) {
        if (choice === 'first') {
          qs('details.os-group').setAttribute('open', '');
        } else {
          for (const details of qsA('details.os-group')) {
            if (choice === 'all') {
              details.setAttribute('open', '');
            } else {
              const re = new RegExp(`${choice}+`, 'gi');
              const txt = details.children[0].textContent;
              if (!isEmpty(txt)) {
                const find = txt.match(re) ?? [];
                if (!isEmpty(find)) {
                  details.setAttribute('open', '');
                }
              }
            }
          }
        }
      }
      await query('details.os-group .os-row a');
      await query('details.os-group summary .summary');
      for (const details of qsA('details.os-group')) {
        const summary = qs('summary > span.summary', details);
        // for(const driver of qsA('.driver .field--type-uri > a[href]', details)) { };
        const driver = qs('.driver-metadata a', details);
        summary.textContent = driver.href;
        summary.onclick = (e) => {
          e.preventDefault();
          const dlBtn = make('a', 'amd_Downloader');
          dlBtn.href = driver.href;
          dlBtn.click();
          dlBtn.remove();
        };
      }
    } catch (ex) {
      err(ex);
    }
  };
  initScript();
})();
/**
* Defaults:
*
* choice = 'first'
* reduce_clutter = true
* scroll_amount = 110
* css = `.aeo-top-btn {
  bottom: 1rem;
  right: 1rem;
  color: #000;
  border: 2px solid #000;
  font-size: 14px;
  font-weight: bold;
  width: auto;
  min-height: 5px;
  margin: 0 3px;
  padding: 10px 15px;
  cursor: pointer;
  text-transform: uppercase;
  text-align: center;
  white-space: normal;
  position:fixed;
}
...`
*/