- // ==UserScript==
- // @name [AMD] Auto Expand Option(s)
- // @description Automatically opens the first option.
- // @author Magic of Lolis <magicoflolis@tuta.io>
- // @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;
- }
- ...`
- */