Last active
March 7, 2026 16:22
-
-
Save volkanunsal/94db50629cad816eca84c836e0232a4f to your computer and use it in GitHub Desktop.
Revisions
-
volkanunsal revised this gist
Mar 7, 2026 . No changes.There are no files selected for viewing
-
volkanunsal revised this gist
Mar 7, 2026 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -6,8 +6,8 @@ // @version 2026.0307.1122 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/9b9156c042bbc9a22d80871c6d44b8ee0ff7cc5a/collapse-studio-buttons-container.user.js // @updateURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/9b9156c042bbc9a22d80871c6d44b8ee0ff7cc5a/collapse-studio-buttons-container.user.js // @match https://notebooklm.google.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=google.com // @grant GM_addStyle -
volkanunsal revised this gist
Mar 7, 2026 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ // ==UserScript== // @name Collapse Studio Buttons Container // @namespace https://github.com/volkanunsal // @version 2026.0307.1122 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js -
volkanunsal revised this gist
Mar 7, 2026 . No changes.There are no files selected for viewing
-
volkanunsal revised this gist
Mar 7, 2026 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ // ==UserScript== // @name Collapse Studio Buttons Container // @namespace https://github.com/volkanunsal // @version 2026.0307.1112 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js @@ -16,7 +16,7 @@ // ==/UserScript== "use strict";(()=>{var N=class{constructor(e={}){this.namespace=e.namespace,this.prefix=[this.namespace,e.prefix].filter(Boolean).join(" "),this.enabled=e.enabled!==!1,this.timestamp=e.timestamp!==!1,this.timestampFormat=e.timestampFormat||"locale"}isVerbose(){try{return!!localStorage.getItem("VERBOSE_LOGGING")}catch{return!1}}getTimestamp(){let e=new Date;return this.timestampFormat==="ISO"?e.toISOString():e.toLocaleString()}formatMessage(e,...t){let s=[this.prefix];return this.timestamp&&s.push(`[${this.getTimestamp()}]`),s.push(`[${e.toUpperCase()}]`),[s.join(" "),...t]}debug(...e){!this.enabled||!this.isVerbose()||console.debug(...this.formatMessage("debug",...e))}info(...e){!this.enabled||!this.isVerbose()||console.info(...this.formatMessage("info",...e))}warn(...e){this.enabled&&console.warn(...this.formatMessage("warn",...e))}error(...e){this.enabled&&console.error(...this.formatMessage("error",...e))}log(...e){!this.enabled||!this.isVerbose()||console.log(...this.formatMessage("log",...e))}custom(e,...t){this.enabled&&console.log(...this.formatMessage(e,...t))}group(e,t){if(!this.enabled)return t();console.group(`${this.prefix} ${e}`);try{t()}finally{console.groupEnd()}}groupCollapsed(e,t){if(!this.enabled)return t();console.groupCollapsed(`${this.prefix} ${e}`);try{t()}finally{console.groupEnd()}}table(e,t){this.enabled&&(this.info("Table data:"),console.table(e,t))}time(e){this.enabled&&console.time(`${this.prefix} ${e}`)}timeEnd(e){this.enabled&&console.timeEnd(`${this.prefix} ${e}`)}timeLog(e){this.enabled&&console.timeLog(`${this.prefix} ${e}`)}enable(){this.enabled=!0}disable(){this.enabled=!1}setPrefix(e){this.prefix=e}};function L(u={}){return new N(u)}function V(u,e){function t(s){return s.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"")}if(window.trustedTypes){let c=window.trustedTypes.createPolicy("myHTMLPolicy",{createHTML:t}).createHTML(e);u.innerHTML=c}else{let s=t(e);u.innerHTML=s}}async function P(u){let{tagName:e,id:t,attributes:s={},parentSelector:c="body",parentElement:m,textContent:l,innerHTML:y,innerElement:x,returnElement:$=!0,checkExisting:E=!0,replaceExisting:H=!1,insertionMethod:g="append",contextElement:b,waitTimeout:I=3e4,persistent:D=!1,autoRemove:C=!0,debounceDelay:_=500,observerConfig:h={childList:!0,subtree:!0,attributes:!1,attributeOldValue:!1,characterData:!1,characterDataOldValue:!1},namespace:A,onMount:O}=u,n=L({prefix:"[createElement]",namespace:A}),r={action:"create",tagName:e,id:t,parentMethod:c?"selector":"element",parentIdentifier:c||(m?m.tagName:"unknown"),waitTimeout:I,insertionMethod:g};if(n.info(`Starting element creation: <${e}> with ID="${t}"${b?" (conditional)":""} using ${g} insertion`),!e||typeof e!="string")return n.error("Element creation failed: Tag parameter is required and must be a string",r),null;if(!t||typeof t!="string")return n.error("Element creation failed: ID parameter is required and must be a non-empty string",r),null;if(!c&&!m)return n.error("Element creation failed: Either parentSelector or parentElement must be provided",r),null;if(g!=="append"&&g!=="insertBeforeElement"&&g!=="prepend")return n.error("Element creation failed: insertionMethod must be 'append', 'insertBeforeElement', or 'prepend'",r),null;function v(a,i,o){try{let p=new DOMParser().parseFromString(i,"text/html"),d=p.querySelector("parsererror");if(d)throw new Error(`HTML parsing error: ${d.textContent}`);let M=Array.from(p.body.childNodes);return M.length===0?(n.warn(`No valid elements found in HTML string: "${i.substring(0,50)}${i.length>50?"...":""}"`,o),!1):(M.forEach(w=>{let k=a.ownerDocument.importNode(w,!0);a.appendChild(k)}),n.debug(`Created DOM elements programmatically: "${i.substring(0,50)}${i.length>50?"...":""}" (${M.length} elements)`,o),!0)}catch(f){n.warn(`DOMParser failed, attempting fallback method: ${f.message}`,o);try{return V(a,i),n.debug(`Successfully created DOM elements via fallback method: "${i.substring(0,50)}${i.length>50?"...":""}"`,o),!0}catch(p){return n.error(`DOM insertion failed: ${p.message}`,{...o,originalError:f.message,fallbackError:p.message}),!1}}}function T(){try{let a=null;if(E&&(a=document.getElementById(t),a))if(r.action="exists",H)n.info(`Found existing element with ID="${t}", replacing as requested`,r),a.remove(),r.action="replace";else return n.warn(`Element with ID="${t}" already exists, skipping creation. Use replaceExisting=true to replace.`,r),$?a:null;let i=m;if(!i&&c){let d=document.querySelector(c);if(!d)return n.error(`Element creation failed: Parent element not found with selector: ${c}`,r),null;i=d,n.debug(`Found parent element with selector: ${c}`,r)}if(!i)return n.error("Element creation failed: No valid parent element found",r),null;let o=document.createElement(e);n.debug(`Created DOM element: <${e}>`,r),o.setAttribute("id",t),n.debug(`Set required ID attribute: id="${t}"`,r);let f=Object.keys(s).length;if(f>0&&(Object.entries(s).forEach(([d,M])=>{M!=null&&(o.setAttribute(d,String(M)),n.debug(`Set attribute: ${d}="${M}"`,r))}),n.debug(`Applied ${f} additional attributes to element`,r)),x&&typeof x=="function")try{let d=x();d instanceof HTMLElement?(o.appendChild(d),n.debug("Inserted child element via innerElement callback",r)):(n.warn("innerElement callback did not return a valid HTMLElement, falling back to other content methods",r),l!==void 0?(o.textContent=l,n.debug(`Set textContent: "${l.substring(0,100)}${l.length>100?"...":""}"`,r)):y!==void 0&&v(o,y,r))}catch(d){n.error("Error executing innerElement callback, falling back to other content methods:",d,r),l!==void 0?(o.textContent=l,n.debug(`Set textContent: "${l.substring(0,100)}${l.length>100?"...":""}"`,r)):y!==void 0&&v(o,y,r)}else l!==void 0?(o.textContent=l,n.debug(`Set textContent: "${l.substring(0,100)}${l.length>100?"...":""}"`,r)):y!==void 0&&v(o,y,r);if(g==="insertBeforeElement")if(i.parentElement)i.parentElement.insertBefore(o,i),n.debug("Inserted element before parent",r);else return n.error("Element insertion failed: Parent element has no parent to insert before",r),null;else g==="prepend"?(i.insertBefore(o,i.firstChild),n.debug("Prepended element as first child of parent",r)):(i.appendChild(o),n.debug("Appended element to end of parent",r));if(O&&typeof O=="function")try{O(o),n.debug(`Successfully called onMount callback for element ID="${t}"`,r)}catch(d){n.warn(`Error in onMount callback for element ID="${t}":`,d,r)}let p=`Element creation successful: <${e}> (ID="${t}") ${r.action==="replace"?"replaced and ":""}${g}ed to ${r.parentMethod==="selector"?`parent selected by "${c}"`:"provided parent element"}${b?" (after content element)":""}`;return n.info(p,{...r,success:!0,hasAttributes:f>0,hasContent:!!(l||y||x),parentTagName:i.tagName,elementPath:o.tagName+"#"+o.id+(o.className?`.${o.className.replace(/\s+/g,".")}`:"")}),$?o:null}catch(a){let i=`Element creation failed with exception: ${a.message||"Unknown error"}`;return n.error(i,{...r,success:!1,error:a.message||"Unknown error",stack:a.stack||"No stack trace available"}),null}}async function S(){try{if(typeof b=="function"){let a=await b();return a instanceof HTMLElement&&document.contains(a)}else if(typeof b=="string")return document.querySelector(b)!==null}catch(a){n.warn(`Error checking content element for element ID="${t}":`,a)}return!1}function B(){if(!D&&!C)return;n.info(`Setting up ${D?"persistent":""}${D&&C?" and ":""}${C?"auto-removal":""} monitoring for element ID="${t}"`);let a=null,i=new MutationObserver(async()=>{a&&clearTimeout(a),a=setTimeout(async()=>{n.debug(`Persistent monitoring check triggered for element ID="${t}"`);let f=await S(),p=document.getElementById(t);f?D&&!p?(n.info(`Context element found but managed element missing, recreating element ID="${t}"`),T()):n.debug(`Both context and managed elements exist for ID="${t}"`):C&&p?(n.info(`Context element no longer present, removing managed element ID="${t}"`),p.remove()):n.debug(`Context element no longer present for element ID="${t}"`)},_)}),o={childList:h.childList===!0,subtree:h.subtree===!0,attributes:h.attributes===!0,attributeOldValue:h.attributeOldValue===!0,characterData:h.characterData===!0,characterDataOldValue:h.characterDataOldValue===!0};i.observe(document.documentElement||document.body,o),n.debug(`Started persistent MutationObserver for element ID="${t}"`)}if(!b)return T();if(n.info(`Checking initial condition for element ID="${t}"`,{...r,waitCondition:typeof b=="function"?"callback":b,persistent:D}),await S()){n.info(`Initial content element already satisfied for element ID="${t}"`,r);let a=T();return(D||C)&&B(),a}return new Promise(a=>{let i=Date.now(),o=null,f=null,p=!1;function d(w){p||C&&(p=!0,o&&(clearTimeout(o),o=null),f&&(f.disconnect(),f=null,n.debug(`Disconnected MutationObserver for element ID="${t}"`,r)),a(w))}o=setTimeout(()=>{n.error(`Element creation failed: Wait condition timeout after ${I}ms for element ID="${t}"`,{...r,success:!1,timeoutReached:!0,waitCondition:typeof b=="function"?"callback":b}),d(null)},I),n.info(`Setting up MutationObserver for element ID="${t}"`,{...r,observerConfig:h,waitCondition:typeof b=="function"?"callback":b}),f=new MutationObserver(async w=>{if(!p&&(n.debug(`MutationObserver detected ${w.length} mutations for element ID="${t}"`,r),await S())){let k=Date.now()-i;n.info(`Wait condition satisfied via MutationObserver for element ID="${t}" after DOM changes`,{...r,elapsedTime:k});let R=T();(D||C)&&B(),d(R)}});let M={childList:h.childList===!0,subtree:h.subtree===!0,attributes:h.attributes===!0,attributeOldValue:h.attributeOldValue===!0,characterData:h.characterData===!0,characterDataOldValue:h.characterDataOldValue===!0};f.observe(document.documentElement||document.body,M),n.debug(`Started MutationObserver monitoring for element ID="${t}"`,{...r,target:"document.documentElement"})})}function q({selector:u,onReady:e,onRemoved:t}){let s=new Set,c=()=>typeof u=="function"?u():document.querySelector(u),m=c();m&&m instanceof HTMLElement&&(s.add(m),e(m));let l=new MutationObserver(y=>{y.forEach(x=>{x.addedNodes.forEach($=>{if($.nodeType===Node.ELEMENT_NODE){let E=c();E&&E instanceof HTMLElement&&!s.has(E)&&(s.add(E),e(E)),typeof u=="string"&&$ instanceof Element&&$.querySelectorAll(u).forEach(g=>{g instanceof HTMLElement&&!s.has(g)&&(s.add(g),e(g))})}}),t&&x.removedNodes.forEach($=>{$.nodeType===Node.ELEMENT_NODE&&s.forEach(E=>{($===E||$ instanceof Element&&$.contains(E))&&(s.delete(E),t(E))})})})});return l.observe(document.body,{childList:!0,subtree:!0}),()=>{l.disconnect(),s.clear()}}(async function(){"use strict";GM_addStyle(` .create-artifact-buttons-container { transition: height 0.3s ease-in-out, margin-bottom 0.3s ease-in-out, margin-top 0.3s ease-in-out, opacity 0.2s ease-in-out 0.1s, overflow 0s ease-in-out 0s; margin-top: 16px !important; @@ -34,4 +34,4 @@ .panel-collapsed #collapse-studio-buttons-container-box, [aria-label^="Close"] + #collapse-studio-buttons-container-box { display: none !important; } `);let u=L({prefix:"UserScript",namespace:"[CollapseStudioButtonsContainer]"}),e=GM_getValue("studioButtonsContainerCollapsed",!1);u.log(`Studio buttons container is currently ${e?"collapsed":"expanded"}`);let t=()=>document.querySelector(".create-artifact-buttons-container"),s=()=>{P({tagName:"span",namespace:"[CollapseStudioButtonsContainer]",id:"collapse-studio-buttons-container-box",insertionMethod:"insertBeforeElement",autoRemove:!1,attributes:{},parentSelector:".toggle-studio-panel-button",contextElement:".studio-panel",innerHTML:'<button mat-icon-button="" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger toggle-studio-panel-button mat-unthemed ng-star-inserted" mat-ripple-loader-class-name="mat-mdc-button-ripple" mat-ripple-loader-centered="" aria-label="Collapse studio panel" jslog="" style=""><span class="mat-mdc-button-persistent-ripple mdc-icon-button__ripple"></span><mat-icon role="img" aria-hidden="true" class="mat-icon notranslate material-symbols-outlined mat-icon-rtl-mirror google-symbols mat-icon-no-color" data-mat-icon-type="font">dock_to_top</mat-icon><span class="mat-focus-indicator"></span><span class="mat-mdc-button-touch-target"></span><span class="mat-ripple mat-mdc-button-ripple"></span></button>',onMount:c=>{c.addEventListener("click",async()=>{u.log("Toggle button clicked");let m=t();if(m){m.classList.toggle("collapsed");let l=m.classList.contains("collapsed");GM_setValue("studioButtonsContainerCollapsed",l),u.log(`Studio buttons container ${l?"collapsed":"expanded"}`)}else u.error("Create artifact buttons container not found")})}})};q({selector:t,onReady:c=>{e&&c.classList.add("collapsed");let m=Array.from(c.childNodes).filter(x=>x instanceof Element).length/2,y=document.querySelector("basic-create-artifact-button")?.getClientRects()[0]?.height||58;c.style.height=`calc(${y}px * ${m} + ${(m-1)*8}px)`,s()}})})();})(); -
volkanunsal revised this gist
Mar 7, 2026 . No changes.There are no files selected for viewing
-
volkanunsal revised this gist
Mar 7, 2026 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ // ==UserScript== // @name Collapse Studio Buttons Container // @namespace https://github.com/volkanunsal // @version 2026.0307.1109 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js -
volkanunsal revised this gist
Feb 28, 2026 . No changes.There are no files selected for viewing
-
volkanunsal revised this gist
Feb 28, 2026 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ // ==UserScript== // @name Collapse Studio Buttons Container // @namespace https://github.com/volkanunsal // @version 2026.0228.1623 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js -
volkanunsal revised this gist
Feb 28, 2026 . No changes.There are no files selected for viewing
-
volkanunsal revised this gist
Feb 28, 2026 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ // ==UserScript== // @name Collapse Studio Buttons Container // @namespace https://github.com/volkanunsal // @version 2026-02-28:3 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js -
volkanunsal revised this gist
Feb 28, 2026 . No changes.There are no files selected for viewing
-
volkanunsal revised this gist
Feb 28, 2026 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ // ==UserScript== // @name Collapse Studio Buttons Container // @namespace https://github.com/volkanunsal // @version 2026-02-28:2 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js -
volkanunsal revised this gist
Feb 28, 2026 . No changes.There are no files selected for viewing
-
volkanunsal revised this gist
Feb 28, 2026 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ // ==UserScript== // @name Collapse Studio Buttons Container // @namespace https://github.com/volkanunsal // @version 2026-02-28 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js -
volkanunsal revised this gist
Dec 7, 2025 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ // ==UserScript== // @name Collapse Studio Buttons Container // @namespace https://github.com/volkanunsal // @version 2025-12-07 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js -
volkanunsal revised this gist
Nov 28, 2025 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ // ==UserScript== // @name Collapse Studio Buttons Container // @namespace https://github.com/volkanunsal // @version 2025-11-28 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js -
volkanunsal revised this gist
Nov 22, 2025 . 1 changed file with 4 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,8 +1,9 @@ /* eslint-disable */ // @ts-nocheck // ==UserScript== // @name Collapse Studio Buttons Container // @namespace https://github.com/volkanunsal // @version 2025-11-22 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js @@ -15,7 +16,7 @@ // ==/UserScript== "use strict";(()=>{var N=class{constructor(e={}){this.namespace=e.namespace,this.prefix=[this.namespace,e.prefix].filter(Boolean).join(" "),this.enabled=e.enabled!==!1,this.timestamp=e.timestamp!==!1,this.timestampFormat=e.timestampFormat||"locale"}getTimestamp(){let e=new Date;return this.timestampFormat==="ISO"?e.toISOString():e.toLocaleString()}formatMessage(e,...t){let s=[this.prefix];return this.timestamp&&s.push(`[${this.getTimestamp()}]`),s.push(`[${e.toUpperCase()}]`),[s.join(" "),...t]}debug(...e){this.enabled&&console.debug(...this.formatMessage("debug",...e))}info(...e){this.enabled&&console.info(...this.formatMessage("info",...e))}warn(...e){this.enabled&&console.warn(...this.formatMessage("warn",...e))}error(...e){this.enabled&&console.error(...this.formatMessage("error",...e))}log(...e){this.enabled&&console.log(...this.formatMessage("log",...e))}custom(e,...t){this.enabled&&console.log(...this.formatMessage(e,...t))}group(e,t){if(!this.enabled)return t();console.group(`${this.prefix} ${e}`);try{t()}finally{console.groupEnd()}}groupCollapsed(e,t){if(!this.enabled)return t();console.groupCollapsed(`${this.prefix} ${e}`);try{t()}finally{console.groupEnd()}}table(e,t){this.enabled&&(this.info("Table data:"),console.table(e,t))}time(e){this.enabled&&console.time(`${this.prefix} ${e}`)}timeEnd(e){this.enabled&&console.timeEnd(`${this.prefix} ${e}`)}timeLog(e){this.enabled&&console.timeLog(`${this.prefix} ${e}`)}enable(){this.enabled=!0}disable(){this.enabled=!1}setPrefix(e){this.prefix=e}};function L(u={}){return new N(u)}function P(u,e){function t(s){return s.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"")}if(window.trustedTypes){let c=window.trustedTypes.createPolicy("myHTMLPolicy",{createHTML:t}).createHTML(e);u.innerHTML=c}else{let s=t(e);u.innerHTML=s}}async function V(u){let{tagName:e,id:t,attributes:s={},parentSelector:c="body",parentElement:m,textContent:l,innerHTML:y,innerElement:x,returnElement:$=!0,checkExisting:E=!0,replaceExisting:H=!1,insertionMethod:g="append",contextElement:b,waitTimeout:I=3e4,persistent:D=!1,autoRemove:C=!0,debounceDelay:A=500,observerConfig:h={childList:!0,subtree:!0,attributes:!1,attributeOldValue:!1,characterData:!1,characterDataOldValue:!1},namespace:_,onMount:v}=u,n=L({prefix:"[createElement]",namespace:_}),r={action:"create",tagName:e,id:t,parentMethod:c?"selector":"element",parentIdentifier:c||(m?m.tagName:"unknown"),waitTimeout:I,insertionMethod:g};if(n.info(`Starting element creation: <${e}> with ID="${t}"${b?" (conditional)":""} using ${g} insertion`),!e||typeof e!="string")return n.error("Element creation failed: Tag parameter is required and must be a string",r),null;if(!t||typeof t!="string")return n.error("Element creation failed: ID parameter is required and must be a non-empty string",r),null;if(!c&&!m)return n.error("Element creation failed: Either parentSelector or parentElement must be provided",r),null;if(g!=="append"&&g!=="insertBeforeElement"&&g!=="prepend")return n.error("Element creation failed: insertionMethod must be 'append', 'insertBeforeElement', or 'prepend'",r),null;function O(a,i,o){try{let p=new DOMParser().parseFromString(i,"text/html"),d=p.querySelector("parsererror");if(d)throw new Error(`HTML parsing error: ${d.textContent}`);let M=Array.from(p.body.childNodes);return M.length===0?(n.warn(`No valid elements found in HTML string: "${i.substring(0,50)}${i.length>50?"...":""}"`,o),!1):(M.forEach(w=>{let k=a.ownerDocument.importNode(w,!0);a.appendChild(k)}),n.debug(`Created DOM elements programmatically: "${i.substring(0,50)}${i.length>50?"...":""}" (${M.length} elements)`,o),!0)}catch(f){n.warn(`DOMParser failed, attempting fallback method: ${f.message}`,o);try{return P(a,i),n.debug(`Successfully created DOM elements via fallback method: "${i.substring(0,50)}${i.length>50?"...":""}"`,o),!0}catch(p){return n.error(`DOM insertion failed: ${p.message}`,{...o,originalError:f.message,fallbackError:p.message}),!1}}}function T(){try{let a=null;if(E&&(a=document.getElementById(t),a))if(r.action="exists",H)n.info(`Found existing element with ID="${t}", replacing as requested`,r),a.remove(),r.action="replace";else return n.warn(`Element with ID="${t}" already exists, skipping creation. Use replaceExisting=true to replace.`,r),$?a:null;let i=m;if(!i&&c){let d=document.querySelector(c);if(!d)return n.error(`Element creation failed: Parent element not found with selector: ${c}`,r),null;i=d,n.debug(`Found parent element with selector: ${c}`,r)}if(!i)return n.error("Element creation failed: No valid parent element found",r),null;let o=document.createElement(e);n.debug(`Created DOM element: <${e}>`,r),o.setAttribute("id",t),n.debug(`Set required ID attribute: id="${t}"`,r);let f=Object.keys(s).length;if(f>0&&(Object.entries(s).forEach(([d,M])=>{M!=null&&(o.setAttribute(d,String(M)),n.debug(`Set attribute: ${d}="${M}"`,r))}),n.debug(`Applied ${f} additional attributes to element`,r)),x&&typeof x=="function")try{let d=x();d instanceof HTMLElement?(o.appendChild(d),n.debug("Inserted child element via innerElement callback",r)):(n.warn("innerElement callback did not return a valid HTMLElement, falling back to other content methods",r),l!==void 0?(o.textContent=l,n.debug(`Set textContent: "${l.substring(0,100)}${l.length>100?"...":""}"`,r)):y!==void 0&&O(o,y,r))}catch(d){n.error("Error executing innerElement callback, falling back to other content methods:",d,r),l!==void 0?(o.textContent=l,n.debug(`Set textContent: "${l.substring(0,100)}${l.length>100?"...":""}"`,r)):y!==void 0&&O(o,y,r)}else l!==void 0?(o.textContent=l,n.debug(`Set textContent: "${l.substring(0,100)}${l.length>100?"...":""}"`,r)):y!==void 0&&O(o,y,r);if(g==="insertBeforeElement")if(i.parentElement)i.parentElement.insertBefore(o,i),n.debug("Inserted element before parent",r);else return n.error("Element insertion failed: Parent element has no parent to insert before",r),null;else g==="prepend"?(i.insertBefore(o,i.firstChild),n.debug("Prepended element as first child of parent",r)):(i.appendChild(o),n.debug("Appended element to end of parent",r));if(v&&typeof v=="function")try{v(o),n.debug(`Successfully called onMount callback for element ID="${t}"`,r)}catch(d){n.warn(`Error in onMount callback for element ID="${t}":`,d,r)}let p=`Element creation successful: <${e}> (ID="${t}") ${r.action==="replace"?"replaced and ":""}${g}ed to ${r.parentMethod==="selector"?`parent selected by "${c}"`:"provided parent element"}${b?" (after content element)":""}`;return n.info(p,{...r,success:!0,hasAttributes:f>0,hasContent:!!(l||y||x),parentTagName:i.tagName,elementPath:o.tagName+"#"+o.id+(o.className?`.${o.className.replace(/\s+/g,".")}`:"")}),$?o:null}catch(a){let i=`Element creation failed with exception: ${a.message||"Unknown error"}`;return n.error(i,{...r,success:!1,error:a.message||"Unknown error",stack:a.stack||"No stack trace available"}),null}}async function S(){try{if(typeof b=="function"){let a=await b();return a instanceof HTMLElement&&document.contains(a)}else if(typeof b=="string")return document.querySelector(b)!==null}catch(a){n.warn(`Error checking content element for element ID="${t}":`,a)}return!1}function B(){if(!D&&!C)return;n.info(`Setting up ${D?"persistent":""}${D&&C?" and ":""}${C?"auto-removal":""} monitoring for element ID="${t}"`);let a=null,i=new MutationObserver(async()=>{a&&clearTimeout(a),a=setTimeout(async()=>{n.debug(`Persistent monitoring check triggered for element ID="${t}"`);let f=await S(),p=document.getElementById(t);f?D&&!p?(n.info(`Context element found but managed element missing, recreating element ID="${t}"`),T()):n.debug(`Both context and managed elements exist for ID="${t}"`):C&&p?(n.info(`Context element no longer present, removing managed element ID="${t}"`),p.remove()):n.debug(`Context element no longer present for element ID="${t}"`)},A)}),o={childList:h.childList===!0,subtree:h.subtree===!0,attributes:h.attributes===!0,attributeOldValue:h.attributeOldValue===!0,characterData:h.characterData===!0,characterDataOldValue:h.characterDataOldValue===!0};i.observe(document.documentElement||document.body,o),n.debug(`Started persistent MutationObserver for element ID="${t}"`)}if(!b)return T();if(n.info(`Checking initial condition for element ID="${t}"`,{...r,waitCondition:typeof b=="function"?"callback":b,persistent:D}),await S()){n.info(`Initial content element already satisfied for element ID="${t}"`,r);let a=T();return(D||C)&&B(),a}return new Promise(a=>{let i=Date.now(),o=null,f=null,p=!1;function d(w){p||C&&(p=!0,o&&(clearTimeout(o),o=null),f&&(f.disconnect(),f=null,n.debug(`Disconnected MutationObserver for element ID="${t}"`,r)),a(w))}o=setTimeout(()=>{n.error(`Element creation failed: Wait condition timeout after ${I}ms for element ID="${t}"`,{...r,success:!1,timeoutReached:!0,waitCondition:typeof b=="function"?"callback":b}),d(null)},I),n.info(`Setting up MutationObserver for element ID="${t}"`,{...r,observerConfig:h,waitCondition:typeof b=="function"?"callback":b}),f=new MutationObserver(async w=>{if(!p&&(n.debug(`MutationObserver detected ${w.length} mutations for element ID="${t}"`,r),await S())){let k=Date.now()-i;n.info(`Wait condition satisfied via MutationObserver for element ID="${t}" after DOM changes`,{...r,elapsedTime:k});let F=T();(D||C)&&B(),d(F)}});let M={childList:h.childList===!0,subtree:h.subtree===!0,attributes:h.attributes===!0,attributeOldValue:h.attributeOldValue===!0,characterData:h.characterData===!0,characterDataOldValue:h.characterDataOldValue===!0};f.observe(document.documentElement||document.body,M),n.debug(`Started MutationObserver monitoring for element ID="${t}"`,{...r,target:"document.documentElement"})})}function q({selector:u,onReady:e,onRemoved:t}){let s=new Set,c=()=>typeof u=="function"?u():document.querySelector(u),m=c();m&&m instanceof HTMLElement&&(s.add(m),e(m));let l=new MutationObserver(y=>{y.forEach(x=>{x.addedNodes.forEach($=>{if($.nodeType===Node.ELEMENT_NODE){let E=c();E&&E instanceof HTMLElement&&!s.has(E)&&(s.add(E),e(E)),typeof u=="string"&&$ instanceof Element&&$.querySelectorAll(u).forEach(g=>{g instanceof HTMLElement&&!s.has(g)&&(s.add(g),e(g))})}}),t&&x.removedNodes.forEach($=>{$.nodeType===Node.ELEMENT_NODE&&s.forEach(E=>{($===E||$ instanceof Element&&$.contains(E))&&(s.delete(E),t(E))})})})});return l.observe(document.body,{childList:!0,subtree:!0}),()=>{l.disconnect(),s.clear()}}(async function(){"use strict";GM_addStyle(` .create-artifact-buttons-container { transition: height 0.3s ease-in-out, margin-bottom 0.3s ease-in-out, margin-top 0.3s ease-in-out, opacity 0.2s ease-in-out 0.1s, overflow 0s ease-in-out 0s; margin-top: 16px !important; @@ -33,4 +34,4 @@ .panel-collapsed #collapse-studio-buttons-container-box, [aria-label^="Close"] + #collapse-studio-buttons-container-box { display: none !important; } `);let u=L({prefix:"UserScript",namespace:"[CollapseStudioButtonsContainer]"}),e=GM_getValue("studioButtonsContainerCollapsed",!1);u.log(`Studio buttons container is currently ${e?"collapsed":"expanded"}`);let t=()=>document.querySelector(".create-artifact-buttons-container"),s=()=>{V({tagName:"span",namespace:"[CollapseStudioButtonsContainer]",id:"collapse-studio-buttons-container-box",insertionMethod:"insertBeforeElement",autoRemove:!1,attributes:{},parentSelector:".toggle-studio-panel-button",contextElement:".studio-panel",innerHTML:'<button mat-icon-button="" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger toggle-studio-panel-button mat-unthemed ng-star-inserted" mat-ripple-loader-class-name="mat-mdc-button-ripple" mat-ripple-loader-centered="" aria-label="Collapse studio panel" jslog="" style=""><span class="mat-mdc-button-persistent-ripple mdc-icon-button__ripple"></span><mat-icon role="img" aria-hidden="true" class="mat-icon notranslate material-symbols-outlined mat-icon-rtl-mirror google-symbols mat-icon-no-color" data-mat-icon-type="font">dock_to_top</mat-icon><span class="mat-focus-indicator"></span><span class="mat-mdc-button-touch-target"></span><span class="mat-ripple mat-mdc-button-ripple"></span></button>',onMount:c=>{c.addEventListener("click",async()=>{u.log("Toggle button clicked");let m=t();if(m){m.classList.toggle("collapsed");let l=m.classList.contains("collapsed");GM_setValue("studioButtonsContainerCollapsed",l),u.log(`Studio buttons container ${l?"collapsed":"expanded"}`)}else u.error("Create artifact buttons container not found")})}})};q({selector:t,onReady:c=>{e&&c.classList.add("collapsed");let m=Array.from(c.childNodes).filter(x=>x instanceof Element).length/2,y=document.querySelector("basic-create-artifact-button")?.getClientRects()[0]?.height||58;c.style.height=`calc(${y}px * ${m} + ${(m-1)*8}px)`,s()}})})();})(); -
volkanunsal revised this gist
Sep 17, 2025 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,7 +2,7 @@ // ==UserScript== // @name Collapse Studio Buttons Container // @namespace https://github.com/volkanunsal // @version 2025-09-17 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js @@ -33,4 +33,4 @@ .panel-collapsed #collapse-studio-buttons-container-box, [aria-label^="Close"] + #collapse-studio-buttons-container-box { display: none !important; } `);let u=L({prefix:"UserScript",namespace:"[CollapseStudioButtonsContainer]"}),e=GM_getValue("studioButtonsContainerCollapsed",!1);u.log(`Studio buttons container is currently ${e?"collapsed":"expanded"}`);let t=()=>document.querySelector(".create-artifact-buttons-container"),s=()=>{V({tagName:"span",namespace:"[CollapseStudioButtonsContainer]",id:"collapse-studio-buttons-container-box",insertionMethod:"insertBeforeElement",autoRemove:!1,attributes:{},parentSelector:".toggle-studio-panel-button",contextElement:".studio-panel",innerHTML:'<button mat-icon-button="" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger toggle-studio-panel-button mat-unthemed ng-star-inserted" mat-ripple-loader-class-name="mat-mdc-button-ripple" mat-ripple-loader-centered="" aria-label="Collapse studio panel" jslog="" style=""><span class="mat-mdc-button-persistent-ripple mdc-icon-button__ripple"></span><mat-icon role="img" aria-hidden="true" class="mat-icon notranslate material-symbols-outlined mat-icon-rtl-mirror google-symbols mat-icon-no-color" data-mat-icon-type="font">dock_to_top</mat-icon><span class="mat-focus-indicator"></span><span class="mat-mdc-button-touch-target"></span><span class="mat-ripple mat-mdc-button-ripple"></span></button>',onMount:c=>{c.addEventListener("click",async()=>{u.log("Toggle button clicked");let m=t();if(m){m.classList.toggle("collapsed");let l=m.classList.contains("collapsed");GM_setValue("studioButtonsContainerCollapsed",l),u.log(`Studio buttons container ${l?"collapsed":"expanded"}`)}else u.error("Create artifact buttons container not found")})}})};q({selector:t,onReady:c=>{e&&c.classList.add("collapsed");let m=Array.from(c.childNodes).filter(l=>l instanceof Element).length/2;c.style.height=`calc(95.46366667px * ${m})`,s()}})})();})(); -
volkanunsal revised this gist
Sep 15, 2025 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,7 +2,7 @@ // ==UserScript== // @name Collapse Studio Buttons Container // @namespace https://github.com/volkanunsal // @version 2025-09-15 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js @@ -15,7 +15,7 @@ // ==/UserScript== "use strict";(()=>{var N=class{constructor(e={}){this.namespace=e.namespace,this.prefix=[this.namespace,e.prefix].filter(Boolean).join(" "),this.enabled=e.enabled!==!1,this.timestamp=e.timestamp!==!1,this.timestampFormat=e.timestampFormat||"locale"}getTimestamp(){let e=new Date;return this.timestampFormat==="ISO"?e.toISOString():e.toLocaleString()}formatMessage(e,...t){let s=[this.prefix];return this.timestamp&&s.push(`[${this.getTimestamp()}]`),s.push(`[${e.toUpperCase()}]`),[s.join(" "),...t]}debug(...e){this.enabled&&console.debug(...this.formatMessage("debug",...e))}info(...e){this.enabled&&console.info(...this.formatMessage("info",...e))}warn(...e){this.enabled&&console.warn(...this.formatMessage("warn",...e))}error(...e){this.enabled&&console.error(...this.formatMessage("error",...e))}log(...e){this.enabled&&console.log(...this.formatMessage("log",...e))}custom(e,...t){this.enabled&&console.log(...this.formatMessage(e,...t))}group(e,t){if(!this.enabled)return t();console.group(`${this.prefix} ${e}`);try{t()}finally{console.groupEnd()}}groupCollapsed(e,t){if(!this.enabled)return t();console.groupCollapsed(`${this.prefix} ${e}`);try{t()}finally{console.groupEnd()}}table(e,t){this.enabled&&(this.info("Table data:"),console.table(e,t))}time(e){this.enabled&&console.time(`${this.prefix} ${e}`)}timeEnd(e){this.enabled&&console.timeEnd(`${this.prefix} ${e}`)}timeLog(e){this.enabled&&console.timeLog(`${this.prefix} ${e}`)}enable(){this.enabled=!0}disable(){this.enabled=!1}setPrefix(e){this.prefix=e}};function L(u={}){return new N(u)}function P(u,e){function t(s){return s.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"")}if(window.trustedTypes){let c=window.trustedTypes.createPolicy("myHTMLPolicy",{createHTML:t}).createHTML(e);u.innerHTML=c}else{let s=t(e);u.innerHTML=s}}async function V(u){let{tagName:e,id:t,attributes:s={},parentSelector:c="body",parentElement:m,textContent:l,innerHTML:M,innerElement:x,returnElement:y=!0,checkExisting:E=!0,replaceExisting:H=!1,insertionMethod:g="append",contextElement:b,waitTimeout:I=3e4,persistent:D=!1,autoRemove:C=!0,debounceDelay:A=500,observerConfig:h={childList:!0,subtree:!0,attributes:!1,attributeOldValue:!1,characterData:!1,characterDataOldValue:!1},namespace:_,onMount:v}=u,n=L({prefix:"[createElement]",namespace:_}),r={action:"create",tagName:e,id:t,parentMethod:c?"selector":"element",parentIdentifier:c||(m?m.tagName:"unknown"),waitTimeout:I,insertionMethod:g};if(n.info(`Starting element creation: <${e}> with ID="${t}"${b?" (conditional)":""} using ${g} insertion`),!e||typeof e!="string")return n.error("Element creation failed: Tag parameter is required and must be a string",r),null;if(!t||typeof t!="string")return n.error("Element creation failed: ID parameter is required and must be a non-empty string",r),null;if(!c&&!m)return n.error("Element creation failed: Either parentSelector or parentElement must be provided",r),null;if(g!=="append"&&g!=="insertBeforeElement"&&g!=="prepend")return n.error("Element creation failed: insertionMethod must be 'append', 'insertBeforeElement', or 'prepend'",r),null;function O(a,i,o){try{let p=new DOMParser().parseFromString(i,"text/html"),d=p.querySelector("parsererror");if(d)throw new Error(`HTML parsing error: ${d.textContent}`);let $=Array.from(p.body.childNodes);return $.length===0?(n.warn(`No valid elements found in HTML string: "${i.substring(0,50)}${i.length>50?"...":""}"`,o),!1):($.forEach(w=>{let k=a.ownerDocument.importNode(w,!0);a.appendChild(k)}),n.debug(`Created DOM elements programmatically: "${i.substring(0,50)}${i.length>50?"...":""}" (${$.length} elements)`,o),!0)}catch(f){n.warn(`DOMParser failed, attempting fallback method: ${f.message}`,o);try{return P(a,i),n.debug(`Successfully created DOM elements via fallback method: "${i.substring(0,50)}${i.length>50?"...":""}"`,o),!0}catch(p){return n.error(`DOM insertion failed: ${p.message}`,{...o,originalError:f.message,fallbackError:p.message}),!1}}}function T(){try{let a=null;if(E&&(a=document.getElementById(t),a))if(r.action="exists",H)n.info(`Found existing element with ID="${t}", replacing as requested`,r),a.remove(),r.action="replace";else return n.warn(`Element with ID="${t}" already exists, skipping creation. Use replaceExisting=true to replace.`,r),y?a:null;let i=m;if(!i&&c){let d=document.querySelector(c);if(!d)return n.error(`Element creation failed: Parent element not found with selector: ${c}`,r),null;i=d,n.debug(`Found parent element with selector: ${c}`,r)}if(!i)return n.error("Element creation failed: No valid parent element found",r),null;let o=document.createElement(e);n.debug(`Created DOM element: <${e}>`,r),o.setAttribute("id",t),n.debug(`Set required ID attribute: id="${t}"`,r);let f=Object.keys(s).length;if(f>0&&(Object.entries(s).forEach(([d,$])=>{$!=null&&(o.setAttribute(d,String($)),n.debug(`Set attribute: ${d}="${$}"`,r))}),n.debug(`Applied ${f} additional attributes to element`,r)),x&&typeof x=="function")try{let d=x();d instanceof HTMLElement?(o.appendChild(d),n.debug("Inserted child element via innerElement callback",r)):(n.warn("innerElement callback did not return a valid HTMLElement, falling back to other content methods",r),l!==void 0?(o.textContent=l,n.debug(`Set textContent: "${l.substring(0,100)}${l.length>100?"...":""}"`,r)):M!==void 0&&O(o,M,r))}catch(d){n.error("Error executing innerElement callback, falling back to other content methods:",d,r),l!==void 0?(o.textContent=l,n.debug(`Set textContent: "${l.substring(0,100)}${l.length>100?"...":""}"`,r)):M!==void 0&&O(o,M,r)}else l!==void 0?(o.textContent=l,n.debug(`Set textContent: "${l.substring(0,100)}${l.length>100?"...":""}"`,r)):M!==void 0&&O(o,M,r);if(g==="insertBeforeElement")if(i.parentElement)i.parentElement.insertBefore(o,i),n.debug("Inserted element before parent",r);else return n.error("Element insertion failed: Parent element has no parent to insert before",r),null;else g==="prepend"?(i.insertBefore(o,i.firstChild),n.debug("Prepended element as first child of parent",r)):(i.appendChild(o),n.debug("Appended element to end of parent",r));if(v&&typeof v=="function")try{v(o),n.debug(`Successfully called onMount callback for element ID="${t}"`,r)}catch(d){n.warn(`Error in onMount callback for element ID="${t}":`,d,r)}let p=`Element creation successful: <${e}> (ID="${t}") ${r.action==="replace"?"replaced and ":""}${g}ed to ${r.parentMethod==="selector"?`parent selected by "${c}"`:"provided parent element"}${b?" (after content element)":""}`;return n.info(p,{...r,success:!0,hasAttributes:f>0,hasContent:!!(l||M||x),parentTagName:i.tagName,elementPath:o.tagName+"#"+o.id+(o.className?`.${o.className.replace(/\s+/g,".")}`:"")}),y?o:null}catch(a){let i=`Element creation failed with exception: ${a.message||"Unknown error"}`;return n.error(i,{...r,success:!1,error:a.message||"Unknown error",stack:a.stack||"No stack trace available"}),null}}async function S(){try{if(typeof b=="function"){let a=await b();return a instanceof HTMLElement&&document.contains(a)}else if(typeof b=="string")return document.querySelector(b)!==null}catch(a){n.warn(`Error checking content element for element ID="${t}":`,a)}return!1}function B(){if(!D&&!C)return;n.info(`Setting up ${D?"persistent":""}${D&&C?" and ":""}${C?"auto-removal":""} monitoring for element ID="${t}"`);let a=null,i=new MutationObserver(async()=>{a&&clearTimeout(a),a=setTimeout(async()=>{n.debug(`Persistent monitoring check triggered for element ID="${t}"`);let f=await S(),p=document.getElementById(t);f?D&&!p?(n.info(`Context element found but managed element missing, recreating element ID="${t}"`),T()):n.debug(`Both context and managed elements exist for ID="${t}"`):C&&p?(n.info(`Context element no longer present, removing managed element ID="${t}"`),p.remove()):n.debug(`Context element no longer present for element ID="${t}"`)},A)}),o={childList:h.childList===!0,subtree:h.subtree===!0,attributes:h.attributes===!0,attributeOldValue:h.attributeOldValue===!0,characterData:h.characterData===!0,characterDataOldValue:h.characterDataOldValue===!0};i.observe(document.documentElement||document.body,o),n.debug(`Started persistent MutationObserver for element ID="${t}"`)}if(!b)return T();if(n.info(`Checking initial condition for element ID="${t}"`,{...r,waitCondition:typeof b=="function"?"callback":b,persistent:D}),await S()){n.info(`Initial content element already satisfied for element ID="${t}"`,r);let a=T();return(D||C)&&B(),a}return new Promise(a=>{let i=Date.now(),o=null,f=null,p=!1;function d(w){p||C&&(p=!0,o&&(clearTimeout(o),o=null),f&&(f.disconnect(),f=null,n.debug(`Disconnected MutationObserver for element ID="${t}"`,r)),a(w))}o=setTimeout(()=>{n.error(`Element creation failed: Wait condition timeout after ${I}ms for element ID="${t}"`,{...r,success:!1,timeoutReached:!0,waitCondition:typeof b=="function"?"callback":b}),d(null)},I),n.info(`Setting up MutationObserver for element ID="${t}"`,{...r,observerConfig:h,waitCondition:typeof b=="function"?"callback":b}),f=new MutationObserver(async w=>{if(!p&&(n.debug(`MutationObserver detected ${w.length} mutations for element ID="${t}"`,r),await S())){let k=Date.now()-i;n.info(`Wait condition satisfied via MutationObserver for element ID="${t}" after DOM changes`,{...r,elapsedTime:k});let F=T();(D||C)&&B(),d(F)}});let $={childList:h.childList===!0,subtree:h.subtree===!0,attributes:h.attributes===!0,attributeOldValue:h.attributeOldValue===!0,characterData:h.characterData===!0,characterDataOldValue:h.characterDataOldValue===!0};f.observe(document.documentElement||document.body,$),n.debug(`Started MutationObserver monitoring for element ID="${t}"`,{...r,target:"document.documentElement"})})}function q({selector:u,onReady:e,onRemoved:t}){let s=new Set,c=()=>typeof u=="function"?u():document.querySelector(u),m=c();m&&m instanceof HTMLElement&&(s.add(m),e(m));let l=new MutationObserver(M=>{M.forEach(x=>{x.addedNodes.forEach(y=>{if(y.nodeType===Node.ELEMENT_NODE){let E=c();E&&E instanceof HTMLElement&&!s.has(E)&&(s.add(E),e(E)),typeof u=="string"&&y instanceof Element&&y.querySelectorAll(u).forEach(g=>{g instanceof HTMLElement&&!s.has(g)&&(s.add(g),e(g))})}}),t&&x.removedNodes.forEach(y=>{y.nodeType===Node.ELEMENT_NODE&&s.forEach(E=>{(y===E||y instanceof Element&&y.contains(E))&&(s.delete(E),t(E))})})})});return l.observe(document.body,{childList:!0,subtree:!0}),()=>{l.disconnect(),s.clear()}}(async function(){"use strict";GM_addStyle(` .create-artifact-buttons-container { transition: height 0.3s ease-in-out, margin-bottom 0.3s ease-in-out, margin-top 0.3s ease-in-out, opacity 0.2s ease-in-out 0.1s, overflow 0s ease-in-out 0s; margin-top: 16px !important; @@ -33,4 +33,4 @@ .panel-collapsed #collapse-studio-buttons-container-box, [aria-label^="Close"] + #collapse-studio-buttons-container-box { display: none !important; } `);let u=L({prefix:"UserScript",namespace:"[CollapseStudioButtonsContainer]"}),e=GM_getValue("studioButtonsContainerCollapsed",!1);u.log(`Studio buttons container is currently ${e?"collapsed":"expanded"}`);let t=()=>document.querySelector(".create-artifact-buttons-container"),s=()=>{V({tagName:"span",namespace:"[CollapseStudioButtonsContainer]",id:"collapse-studio-buttons-container-box",insertionMethod:"insertBeforeElement",autoRemove:!1,attributes:{},parentSelector:".toggle-studio-panel-button",contextElement:".studio-panel",innerHTML:'<button mat-icon-button="" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger toggle-studio-panel-button mat-unthemed ng-star-inserted" mat-ripple-loader-class-name="mat-mdc-button-ripple" mat-ripple-loader-centered="" aria-label="Collapse studio panel" jslog="" style=""><span class="mat-mdc-button-persistent-ripple mdc-icon-button__ripple"></span><mat-icon role="img" aria-hidden="true" class="mat-icon notranslate material-symbols-outlined mat-icon-rtl-mirror google-symbols mat-icon-no-color" data-mat-icon-type="font">dock_to_top</mat-icon><span class="mat-focus-indicator"></span><span class="mat-mdc-button-touch-target"></span><span class="mat-ripple mat-mdc-button-ripple"></span></button>',onMount:c=>{c.addEventListener("click",async()=>{u.log("Toggle button clicked");let m=t();if(m){m.classList.toggle("collapsed");let l=m.classList.contains("collapsed");GM_setValue("studioButtonsContainerCollapsed",l),u.log(`Studio buttons container ${l?"collapsed":"expanded"}`)}else u.error("Create artifact buttons container not found")})}})};q({selector:t,onReady:c=>{e&&c.classList.add("collapsed");let m=Array.from(c.childNodes).filter(l=>l instanceof Element).length/2;c.style.height=`calc(92.797px * ${m})`,s()}})})();})(); -
volkanunsal revised this gist
Sep 13, 2025 . No changes.There are no files selected for viewing
-
volkanunsal revised this gist
Sep 12, 2025 . 1 changed file with 4 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,7 +2,7 @@ // ==UserScript== // @name Collapse Studio Buttons Container // @namespace https://github.com/volkanunsal // @version 2025-09-12:2 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js @@ -15,7 +15,7 @@ // ==/UserScript== "use strict";(()=>{var k=class{constructor(e={}){this.namespace=e.namespace,this.prefix=[this.namespace,e.prefix].filter(Boolean).join(" "),this.enabled=e.enabled!==!1,this.timestamp=e.timestamp!==!1,this.timestampFormat=e.timestampFormat||"locale"}getTimestamp(){let e=new Date;return this.timestampFormat==="ISO"?e.toISOString():e.toLocaleString()}formatMessage(e,...n){let u=[this.prefix];return this.timestamp&&u.push(`[${this.getTimestamp()}]`),u.push(`[${e.toUpperCase()}]`),[u.join(" "),...n]}debug(...e){this.enabled&&console.debug(...this.formatMessage("debug",...e))}info(...e){this.enabled&&console.info(...this.formatMessage("info",...e))}warn(...e){this.enabled&&console.warn(...this.formatMessage("warn",...e))}error(...e){this.enabled&&console.error(...this.formatMessage("error",...e))}log(...e){this.enabled&&console.log(...this.formatMessage("log",...e))}custom(e,...n){this.enabled&&console.log(...this.formatMessage(e,...n))}group(e,n){if(!this.enabled)return n();console.group(`${this.prefix} ${e}`);try{n()}finally{console.groupEnd()}}groupCollapsed(e,n){if(!this.enabled)return n();console.groupCollapsed(`${this.prefix} ${e}`);try{n()}finally{console.groupEnd()}}table(e,n){this.enabled&&(this.info("Table data:"),console.table(e,n))}time(e){this.enabled&&console.time(`${this.prefix} ${e}`)}timeEnd(e){this.enabled&&console.timeEnd(`${this.prefix} ${e}`)}timeLog(e){this.enabled&&console.timeLog(`${this.prefix} ${e}`)}enable(){this.enabled=!0}disable(){this.enabled=!1}setPrefix(e){this.prefix=e}};function C(f={}){return new k(f)}function N(f,e){function n(u){return u.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"")}if(window.trustedTypes){let l=window.trustedTypes.createPolicy("myHTMLPolicy",{createHTML:n}).createHTML(e);f.innerHTML=l}else{let u=n(e);f.innerHTML=u}}async function B(f){let{tagName:e,id:n,attributes:u={},parentSelector:l="body",parentElement:p,textContent:s,innerHTML:h,innerElement:w,returnElement:H=!0,checkExisting:V=!0,replaceExisting:q=!1,insertionMethod:y="append",contextElement:g,waitTimeout:I=3e4,persistent:E=!1,autoRemove:M=!0,debounceDelay:A=500,observerConfig:b={childList:!0,subtree:!0,attributes:!1,attributeOldValue:!1,characterData:!1,characterDataOldValue:!1},namespace:F,onMount:T}=f,t=C({prefix:"[createElement]",namespace:F}),r={action:"create",tagName:e,id:n,parentMethod:l?"selector":"element",parentIdentifier:l||(p?p.tagName:"unknown"),waitTimeout:I,insertionMethod:y};if(t.info(`Starting element creation: <${e}> with ID="${n}"${g?" (conditional)":""} using ${y} insertion`),!e||typeof e!="string")return t.error("Element creation failed: Tag parameter is required and must be a string",r),null;if(!n||typeof n!="string")return t.error("Element creation failed: ID parameter is required and must be a non-empty string",r),null;if(!l&&!p)return t.error("Element creation failed: Either parentSelector or parentElement must be provided",r),null;if(y!=="append"&&y!=="insertBeforeElement"&&y!=="prepend")return t.error("Element creation failed: insertionMethod must be 'append', 'insertBeforeElement', or 'prepend'",r),null;function v(a,i,o){try{let m=new DOMParser().parseFromString(i,"text/html"),c=m.querySelector("parsererror");if(c)throw new Error(`HTML parsing error: ${c.textContent}`);let $=Array.from(m.body.childNodes);return $.length===0?(t.warn(`No valid elements found in HTML string: "${i.substring(0,50)}${i.length>50?"...":""}"`,o),!1):($.forEach(x=>{let O=a.ownerDocument.importNode(x,!0);a.appendChild(O)}),t.debug(`Created DOM elements programmatically: "${i.substring(0,50)}${i.length>50?"...":""}" (${$.length} elements)`,o),!0)}catch(d){t.warn(`DOMParser failed, attempting fallback method: ${d.message}`,o);try{return N(a,i),t.debug(`Successfully created DOM elements via fallback method: "${i.substring(0,50)}${i.length>50?"...":""}"`,o),!0}catch(m){return t.error(`DOM insertion failed: ${m.message}`,{...o,originalError:d.message,fallbackError:m.message}),!1}}}function D(){try{let a=null;if(V&&(a=document.getElementById(n),a))if(r.action="exists",q)t.info(`Found existing element with ID="${n}", replacing as requested`,r),a.remove(),r.action="replace";else return t.warn(`Element with ID="${n}" already exists, skipping creation. Use replaceExisting=true to replace.`,r),H?a:null;let i=p;if(!i&&l){let c=document.querySelector(l);if(!c)return t.error(`Element creation failed: Parent element not found with selector: ${l}`,r),null;i=c,t.debug(`Found parent element with selector: ${l}`,r)}if(!i)return t.error("Element creation failed: No valid parent element found",r),null;let o=document.createElement(e);t.debug(`Created DOM element: <${e}>`,r),o.setAttribute("id",n),t.debug(`Set required ID attribute: id="${n}"`,r);let d=Object.keys(u).length;if(d>0&&(Object.entries(u).forEach(([c,$])=>{$!=null&&(o.setAttribute(c,String($)),t.debug(`Set attribute: ${c}="${$}"`,r))}),t.debug(`Applied ${d} additional attributes to element`,r)),w&&typeof w=="function")try{let c=w();c instanceof HTMLElement?(o.appendChild(c),t.debug("Inserted child element via innerElement callback",r)):(t.warn("innerElement callback did not return a valid HTMLElement, falling back to other content methods",r),s!==void 0?(o.textContent=s,t.debug(`Set textContent: "${s.substring(0,100)}${s.length>100?"...":""}"`,r)):h!==void 0&&v(o,h,r))}catch(c){t.error("Error executing innerElement callback, falling back to other content methods:",c,r),s!==void 0?(o.textContent=s,t.debug(`Set textContent: "${s.substring(0,100)}${s.length>100?"...":""}"`,r)):h!==void 0&&v(o,h,r)}else s!==void 0?(o.textContent=s,t.debug(`Set textContent: "${s.substring(0,100)}${s.length>100?"...":""}"`,r)):h!==void 0&&v(o,h,r);if(y==="insertBeforeElement")if(i.parentElement)i.parentElement.insertBefore(o,i),t.debug("Inserted element before parent",r);else return t.error("Element insertion failed: Parent element has no parent to insert before",r),null;else y==="prepend"?(i.insertBefore(o,i.firstChild),t.debug("Prepended element as first child of parent",r)):(i.appendChild(o),t.debug("Appended element to end of parent",r));if(T&&typeof T=="function")try{T(o),t.debug(`Successfully called onMount callback for element ID="${n}"`,r)}catch(c){t.warn(`Error in onMount callback for element ID="${n}":`,c,r)}let m=`Element creation successful: <${e}> (ID="${n}") ${r.action==="replace"?"replaced and ":""}${y}ed to ${r.parentMethod==="selector"?`parent selected by "${l}"`:"provided parent element"}${g?" (after content element)":""}`;return t.info(m,{...r,success:!0,hasAttributes:d>0,hasContent:!!(s||h||w),parentTagName:i.tagName,elementPath:o.tagName+"#"+o.id+(o.className?`.${o.className.replace(/\s+/g,".")}`:"")}),H?o:null}catch(a){let i=`Element creation failed with exception: ${a.message||"Unknown error"}`;return t.error(i,{...r,success:!1,error:a.message||"Unknown error",stack:a.stack||"No stack trace available"}),null}}async function L(){try{if(typeof g=="function"){let a=await g();return a instanceof HTMLElement&&document.contains(a)}else if(typeof g=="string")return document.querySelector(g)!==null}catch(a){t.warn(`Error checking content element for element ID="${n}":`,a)}return!1}function P(){if(!E&&!M)return;t.info(`Setting up ${E?"persistent":""}${E&&M?" and ":""}${M?"auto-removal":""} monitoring for element ID="${n}"`);let a=null,i=new MutationObserver(async()=>{a&&clearTimeout(a),a=setTimeout(async()=>{t.debug(`Persistent monitoring check triggered for element ID="${n}"`);let d=await L(),m=document.getElementById(n);d?E&&!m?(t.info(`Context element found but managed element missing, recreating element ID="${n}"`),D()):t.debug(`Both context and managed elements exist for ID="${n}"`):M&&m?(t.info(`Context element no longer present, removing managed element ID="${n}"`),m.remove()):t.debug(`Context element no longer present for element ID="${n}"`)},A)}),o={childList:b.childList===!0,subtree:b.subtree===!0,attributes:b.attributes===!0,attributeOldValue:b.attributeOldValue===!0,characterData:b.characterData===!0,characterDataOldValue:b.characterDataOldValue===!0};i.observe(document.documentElement||document.body,o),t.debug(`Started persistent MutationObserver for element ID="${n}"`)}if(!g)return D();if(t.info(`Checking initial condition for element ID="${n}"`,{...r,waitCondition:typeof g=="function"?"callback":g,persistent:E}),await L()){t.info(`Initial content element already satisfied for element ID="${n}"`,r);let a=D();return(E||M)&&P(),a}return new Promise(a=>{let i=Date.now(),o=null,d=null,m=!1;function c(x){m||M&&(m=!0,o&&(clearTimeout(o),o=null),d&&(d.disconnect(),d=null,t.debug(`Disconnected MutationObserver for element ID="${n}"`,r)),a(x))}o=setTimeout(()=>{t.error(`Element creation failed: Wait condition timeout after ${I}ms for element ID="${n}"`,{...r,success:!1,timeoutReached:!0,waitCondition:typeof g=="function"?"callback":g}),c(null)},I),t.info(`Setting up MutationObserver for element ID="${n}"`,{...r,observerConfig:b,waitCondition:typeof g=="function"?"callback":g}),d=new MutationObserver(async x=>{if(!m&&(t.debug(`MutationObserver detected ${x.length} mutations for element ID="${n}"`,r),await L())){let O=Date.now()-i;t.info(`Wait condition satisfied via MutationObserver for element ID="${n}" after DOM changes`,{...r,elapsedTime:O});let _=D();(E||M)&&P(),c(_)}});let $={childList:b.childList===!0,subtree:b.subtree===!0,attributes:b.attributes===!0,attributeOldValue:b.attributeOldValue===!0,characterData:b.characterData===!0,characterDataOldValue:b.characterDataOldValue===!0};d.observe(document.documentElement||document.body,$),t.debug(`Started MutationObserver monitoring for element ID="${n}"`,{...r,target:"document.documentElement"})})}function S({selector:f,timeout:e=5e3,pollInterval:n=100}){return new Promise(u=>{let l=n,p=0,s=setInterval(()=>{let h=document.querySelector(f);h?(clearInterval(s),u(h)):p>=e&&(clearInterval(s),u(null)),p+=l},l)})}(async function(){"use strict";GM_addStyle(` .create-artifact-buttons-container { transition: height 0.3s ease-in-out, margin-bottom 0.3s ease-in-out, margin-top 0.3s ease-in-out, opacity 0.2s ease-in-out 0.1s, overflow 0s ease-in-out 0s; margin-top: 16px !important; @@ -30,7 +30,7 @@ transition: height 0.3s ease-in-out, margin-bottom 0.3s ease-in-out, margin-top 0.3s ease-in-out, opacity 0.2s ease-in-out 0s, overflow 0s ease-in-out 0s; overflow: hidden !important; } .panel-collapsed #collapse-studio-buttons-container-box, [aria-label^="Close"] + #collapse-studio-buttons-container-box { display: none !important; } `),S({selector:".create-artifact-buttons-container",timeout:5e3}).then(async l=>{if(l instanceof HTMLElement){let p=Array.from(l.childNodes).filter(s=>s instanceof Element).length/2;l.style.height=`calc(92.797px * ${p})`}});let f=C({prefix:"UserScript",namespace:"[CollapseStudioButtonsContainer]"}),e=GM_getValue("studioButtonsContainerCollapsed",!1);f.log(`Studio buttons container is currently ${e?"collapsed":"expanded"}`);let n=()=>document.querySelector(".create-artifact-buttons-container");(await S({selector:".create-artifact-buttons-container",timeout:3e3}))?.classList.toggle("collapsed",e),B({tagName:"span",namespace:"[CollapseStudioButtonsContainer]",id:"collapse-studio-buttons-container-box",insertionMethod:"insertBeforeElement",autoRemove:!1,attributes:{},parentSelector:".toggle-studio-panel-button",contextElement:".studio-panel",innerHTML:'<button mat-icon-button="" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger toggle-studio-panel-button mat-unthemed ng-star-inserted" mat-ripple-loader-class-name="mat-mdc-button-ripple" mat-ripple-loader-centered="" aria-label="Collapse studio panel" jslog="" style=""><span class="mat-mdc-button-persistent-ripple mdc-icon-button__ripple"></span><mat-icon role="img" aria-hidden="true" class="mat-icon notranslate material-symbols-outlined mat-icon-rtl-mirror google-symbols mat-icon-no-color" data-mat-icon-type="font">dock_to_top</mat-icon><span class="mat-focus-indicator"></span><span class="mat-mdc-button-touch-target"></span><span class="mat-ripple mat-mdc-button-ripple"></span></button>',onMount:l=>{l.addEventListener("click",async()=>{f.log("Toggle button clicked");let p=n();if(p){p.classList.toggle("collapsed");let s=p.classList.contains("collapsed");GM_setValue("studioButtonsContainerCollapsed",s),f.log(`Studio buttons container ${s?"collapsed":"expanded"}`)}else f.error("Create artifact buttons container not found")})}})})();})(); -
volkanunsal revised this gist
Sep 12, 2025 . 1 changed file with 3 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,7 +2,7 @@ // ==UserScript== // @name Collapse Studio Buttons Container // @namespace https://github.com/volkanunsal // @version 2025-09-12 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js @@ -15,12 +15,11 @@ // ==/UserScript== "use strict";(()=>{var k=class{constructor(e={}){this.namespace=e.namespace,this.prefix=[this.namespace,e.prefix].filter(Boolean).join(" "),this.enabled=e.enabled!==!1,this.timestamp=e.timestamp!==!1,this.timestampFormat=e.timestampFormat||"locale"}getTimestamp(){let e=new Date;return this.timestampFormat==="ISO"?e.toISOString():e.toLocaleString()}formatMessage(e,...n){let u=[this.prefix];return this.timestamp&&u.push(`[${this.getTimestamp()}]`),u.push(`[${e.toUpperCase()}]`),[u.join(" "),...n]}debug(...e){this.enabled&&console.debug(...this.formatMessage("debug",...e))}info(...e){this.enabled&&console.info(...this.formatMessage("info",...e))}warn(...e){this.enabled&&console.warn(...this.formatMessage("warn",...e))}error(...e){this.enabled&&console.error(...this.formatMessage("error",...e))}log(...e){this.enabled&&console.log(...this.formatMessage("log",...e))}custom(e,...n){this.enabled&&console.log(...this.formatMessage(e,...n))}group(e,n){if(!this.enabled)return n();console.group(`${this.prefix} ${e}`);try{n()}finally{console.groupEnd()}}groupCollapsed(e,n){if(!this.enabled)return n();console.groupCollapsed(`${this.prefix} ${e}`);try{n()}finally{console.groupEnd()}}table(e,n){this.enabled&&(this.info("Table data:"),console.table(e,n))}time(e){this.enabled&&console.time(`${this.prefix} ${e}`)}timeEnd(e){this.enabled&&console.timeEnd(`${this.prefix} ${e}`)}timeLog(e){this.enabled&&console.timeLog(`${this.prefix} ${e}`)}enable(){this.enabled=!0}disable(){this.enabled=!1}setPrefix(e){this.prefix=e}};function D(f={}){return new k(f)}function N(f,e){function n(u){return u.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"")}if(window.trustedTypes){let l=window.trustedTypes.createPolicy("myHTMLPolicy",{createHTML:n}).createHTML(e);f.innerHTML=l}else{let u=n(e);f.innerHTML=u}}async function B(f){let{tagName:e,id:n,attributes:u={},parentSelector:l="body",parentElement:p,textContent:s,innerHTML:h,innerElement:w,returnElement:H=!0,checkExisting:V=!0,replaceExisting:q=!1,insertionMethod:y="append",contextElement:g,waitTimeout:I=3e4,persistent:E=!1,autoRemove:x=!0,debounceDelay:A=500,observerConfig:b={childList:!0,subtree:!0,attributes:!1,attributeOldValue:!1,characterData:!1,characterDataOldValue:!1},namespace:F,onMount:v}=f,t=D({prefix:"[createElement]",namespace:F}),r={action:"create",tagName:e,id:n,parentMethod:l?"selector":"element",parentIdentifier:l||(p?p.tagName:"unknown"),waitTimeout:I,insertionMethod:y};if(t.info(`Starting element creation: <${e}> with ID="${n}"${g?" (conditional)":""} using ${y} insertion`),!e||typeof e!="string")return t.error("Element creation failed: Tag parameter is required and must be a string",r),null;if(!n||typeof n!="string")return t.error("Element creation failed: ID parameter is required and must be a non-empty string",r),null;if(!l&&!p)return t.error("Element creation failed: Either parentSelector or parentElement must be provided",r),null;if(y!=="append"&&y!=="insertBeforeElement"&&y!=="prepend")return t.error("Element creation failed: insertionMethod must be 'append', 'insertBeforeElement', or 'prepend'",r),null;function T(a,i,o){try{let m=new DOMParser().parseFromString(i,"text/html"),c=m.querySelector("parsererror");if(c)throw new Error(`HTML parsing error: ${c.textContent}`);let $=Array.from(m.body.childNodes);return $.length===0?(t.warn(`No valid elements found in HTML string: "${i.substring(0,50)}${i.length>50?"...":""}"`,o),!1):($.forEach(M=>{let O=a.ownerDocument.importNode(M,!0);a.appendChild(O)}),t.debug(`Created DOM elements programmatically: "${i.substring(0,50)}${i.length>50?"...":""}" (${$.length} elements)`,o),!0)}catch(d){t.warn(`DOMParser failed, attempting fallback method: ${d.message}`,o);try{return N(a,i),t.debug(`Successfully created DOM elements via fallback method: "${i.substring(0,50)}${i.length>50?"...":""}"`,o),!0}catch(m){return t.error(`DOM insertion failed: ${m.message}`,{...o,originalError:d.message,fallbackError:m.message}),!1}}}function C(){try{let a=null;if(V&&(a=document.getElementById(n),a))if(r.action="exists",q)t.info(`Found existing element with ID="${n}", replacing as requested`,r),a.remove(),r.action="replace";else return t.warn(`Element with ID="${n}" already exists, skipping creation. Use replaceExisting=true to replace.`,r),H?a:null;let i=p;if(!i&&l){let c=document.querySelector(l);if(!c)return t.error(`Element creation failed: Parent element not found with selector: ${l}`,r),null;i=c,t.debug(`Found parent element with selector: ${l}`,r)}if(!i)return t.error("Element creation failed: No valid parent element found",r),null;let o=document.createElement(e);t.debug(`Created DOM element: <${e}>`,r),o.setAttribute("id",n),t.debug(`Set required ID attribute: id="${n}"`,r);let d=Object.keys(u).length;if(d>0&&(Object.entries(u).forEach(([c,$])=>{$!=null&&(o.setAttribute(c,String($)),t.debug(`Set attribute: ${c}="${$}"`,r))}),t.debug(`Applied ${d} additional attributes to element`,r)),w&&typeof w=="function")try{let c=w();c instanceof HTMLElement?(o.appendChild(c),t.debug("Inserted child element via innerElement callback",r)):(t.warn("innerElement callback did not return a valid HTMLElement, falling back to other content methods",r),s!==void 0?(o.textContent=s,t.debug(`Set textContent: "${s.substring(0,100)}${s.length>100?"...":""}"`,r)):h!==void 0&&T(o,h,r))}catch(c){t.error("Error executing innerElement callback, falling back to other content methods:",c,r),s!==void 0?(o.textContent=s,t.debug(`Set textContent: "${s.substring(0,100)}${s.length>100?"...":""}"`,r)):h!==void 0&&T(o,h,r)}else s!==void 0?(o.textContent=s,t.debug(`Set textContent: "${s.substring(0,100)}${s.length>100?"...":""}"`,r)):h!==void 0&&T(o,h,r);if(y==="insertBeforeElement")if(i.parentElement)i.parentElement.insertBefore(o,i),t.debug("Inserted element before parent",r);else return t.error("Element insertion failed: Parent element has no parent to insert before",r),null;else y==="prepend"?(i.insertBefore(o,i.firstChild),t.debug("Prepended element as first child of parent",r)):(i.appendChild(o),t.debug("Appended element to end of parent",r));if(v&&typeof v=="function")try{v(o),t.debug(`Successfully called onMount callback for element ID="${n}"`,r)}catch(c){t.warn(`Error in onMount callback for element ID="${n}":`,c,r)}let m=`Element creation successful: <${e}> (ID="${n}") ${r.action==="replace"?"replaced and ":""}${y}ed to ${r.parentMethod==="selector"?`parent selected by "${l}"`:"provided parent element"}${g?" (after content element)":""}`;return t.info(m,{...r,success:!0,hasAttributes:d>0,hasContent:!!(s||h||w),parentTagName:i.tagName,elementPath:o.tagName+"#"+o.id+(o.className?`.${o.className.replace(/\s+/g,".")}`:"")}),H?o:null}catch(a){let i=`Element creation failed with exception: ${a.message||"Unknown error"}`;return t.error(i,{...r,success:!1,error:a.message||"Unknown error",stack:a.stack||"No stack trace available"}),null}}async function L(){try{if(typeof g=="function"){let a=await g();return a instanceof HTMLElement&&document.contains(a)}else if(typeof g=="string")return document.querySelector(g)!==null}catch(a){t.warn(`Error checking content element for element ID="${n}":`,a)}return!1}function P(){if(!E&&!x)return;t.info(`Setting up ${E?"persistent":""}${E&&x?" and ":""}${x?"auto-removal":""} monitoring for element ID="${n}"`);let a=null,i=new MutationObserver(async()=>{a&&clearTimeout(a),a=setTimeout(async()=>{t.debug(`Persistent monitoring check triggered for element ID="${n}"`);let d=await L(),m=document.getElementById(n);d?E&&!m?(t.info(`Context element found but managed element missing, recreating element ID="${n}"`),C()):t.debug(`Both context and managed elements exist for ID="${n}"`):x&&m?(t.info(`Context element no longer present, removing managed element ID="${n}"`),m.remove()):t.debug(`Context element no longer present for element ID="${n}"`)},A)}),o={childList:b.childList===!0,subtree:b.subtree===!0,attributes:b.attributes===!0,attributeOldValue:b.attributeOldValue===!0,characterData:b.characterData===!0,characterDataOldValue:b.characterDataOldValue===!0};i.observe(document.documentElement||document.body,o),t.debug(`Started persistent MutationObserver for element ID="${n}"`)}if(!g)return C();if(t.info(`Checking initial condition for element ID="${n}"`,{...r,waitCondition:typeof g=="function"?"callback":g,persistent:E}),await L()){t.info(`Initial content element already satisfied for element ID="${n}"`,r);let a=C();return(E||x)&&P(),a}return new Promise(a=>{let i=Date.now(),o=null,d=null,m=!1;function c(M){m||x&&(m=!0,o&&(clearTimeout(o),o=null),d&&(d.disconnect(),d=null,t.debug(`Disconnected MutationObserver for element ID="${n}"`,r)),a(M))}o=setTimeout(()=>{t.error(`Element creation failed: Wait condition timeout after ${I}ms for element ID="${n}"`,{...r,success:!1,timeoutReached:!0,waitCondition:typeof g=="function"?"callback":g}),c(null)},I),t.info(`Setting up MutationObserver for element ID="${n}"`,{...r,observerConfig:b,waitCondition:typeof g=="function"?"callback":g}),d=new MutationObserver(async M=>{if(!m&&(t.debug(`MutationObserver detected ${M.length} mutations for element ID="${n}"`,r),await L())){let O=Date.now()-i;t.info(`Wait condition satisfied via MutationObserver for element ID="${n}" after DOM changes`,{...r,elapsedTime:O});let _=C();(E||x)&&P(),c(_)}});let $={childList:b.childList===!0,subtree:b.subtree===!0,attributes:b.attributes===!0,attributeOldValue:b.attributeOldValue===!0,characterData:b.characterData===!0,characterDataOldValue:b.characterDataOldValue===!0};d.observe(document.documentElement||document.body,$),t.debug(`Started MutationObserver monitoring for element ID="${n}"`,{...r,target:"document.documentElement"})})}function S({selector:f,timeout:e=5e3,pollInterval:n=100}){return new Promise(u=>{let l=n,p=0,s=setInterval(()=>{let h=document.querySelector(f);h?(clearInterval(s),u(h)):p>=e&&(clearInterval(s),u(null)),p+=l},l)})}(async function(){"use strict";GM_addStyle(` .create-artifact-buttons-container { transition: height 0.3s ease-in-out, margin-bottom 0.3s ease-in-out, margin-top 0.3s ease-in-out, opacity 0.2s ease-in-out 0.1s, overflow 0s ease-in-out 0s; margin-top: 16px !important; margin-bottom: 16px !important; opacity: 1 !important; } .create-artifact-buttons-container.collapsed { @@ -34,4 +33,4 @@ .panel-collapsed #collapse-studio-buttons-container-box, [aria-label="Close app viewer"] + #collapse-studio-buttons-container-box, [aria-label="Close report viewer"] + #collapse-studio-buttons-container-box, [aria-label="Close note view"] + #collapse-studio-buttons-container-box, [aria-label="Close mindmap view"] + #collapse-studio-buttons-container-box { display: none !important; } `),S({selector:".create-artifact-buttons-container",timeout:5e3}).then(async l=>{if(l instanceof HTMLElement){let p=Array.from(l.childNodes).filter(s=>s instanceof Element).length/2;l.style.height=`calc(92.797px * ${p})`}});let f=D({prefix:"UserScript",namespace:"[CollapseStudioButtonsContainer]"}),e=GM_getValue("studioButtonsContainerCollapsed",!1);f.log(`Studio buttons container is currently ${e?"collapsed":"expanded"}`);let n=()=>document.querySelector(".create-artifact-buttons-container");(await S({selector:".create-artifact-buttons-container",timeout:3e3}))?.classList.toggle("collapsed",e),B({tagName:"span",namespace:"[CollapseStudioButtonsContainer]",id:"collapse-studio-buttons-container-box",insertionMethod:"insertBeforeElement",autoRemove:!1,attributes:{},parentSelector:".toggle-studio-panel-button",contextElement:".studio-panel",innerHTML:'<button mat-icon-button="" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger toggle-studio-panel-button mat-unthemed ng-star-inserted" mat-ripple-loader-class-name="mat-mdc-button-ripple" mat-ripple-loader-centered="" aria-label="Collapse studio panel" jslog="" style=""><span class="mat-mdc-button-persistent-ripple mdc-icon-button__ripple"></span><mat-icon role="img" aria-hidden="true" class="mat-icon notranslate material-symbols-outlined mat-icon-rtl-mirror google-symbols mat-icon-no-color" data-mat-icon-type="font">dock_to_top</mat-icon><span class="mat-focus-indicator"></span><span class="mat-mdc-button-touch-target"></span><span class="mat-ripple mat-mdc-button-ripple"></span></button>',onMount:l=>{l.addEventListener("click",async()=>{f.log("Toggle button clicked");let p=n();if(p){p.classList.toggle("collapsed");let s=p.classList.contains("collapsed");GM_setValue("studioButtonsContainerCollapsed",s),f.log(`Studio buttons container ${s?"collapsed":"expanded"}`)}else f.error("Create artifact buttons container not found")})}})})();})(); -
volkanunsal revised this gist
Sep 10, 2025 . 1 changed file with 4 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,7 +2,7 @@ // ==UserScript== // @name Collapse Studio Buttons Container // @namespace https://github.com/volkanunsal // @version 2025-09-10:2 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js @@ -15,7 +15,7 @@ // ==/UserScript== "use strict";(()=>{var k=class{constructor(e={}){this.namespace=e.namespace,this.prefix=[this.namespace,e.prefix].filter(Boolean).join(" "),this.enabled=e.enabled!==!1,this.timestamp=e.timestamp!==!1,this.timestampFormat=e.timestampFormat||"locale"}getTimestamp(){let e=new Date;return this.timestampFormat==="ISO"?e.toISOString():e.toLocaleString()}formatMessage(e,...n){let c=[this.prefix];return this.timestamp&&c.push(`[${this.getTimestamp()}]`),c.push(`[${e.toUpperCase()}]`),[c.join(" "),...n]}debug(...e){this.enabled&&console.debug(...this.formatMessage("debug",...e))}info(...e){this.enabled&&console.info(...this.formatMessage("info",...e))}warn(...e){this.enabled&&console.warn(...this.formatMessage("warn",...e))}error(...e){this.enabled&&console.error(...this.formatMessage("error",...e))}log(...e){this.enabled&&console.log(...this.formatMessage("log",...e))}custom(e,...n){this.enabled&&console.log(...this.formatMessage(e,...n))}group(e,n){if(!this.enabled)return n();console.group(`${this.prefix} ${e}`);try{n()}finally{console.groupEnd()}}groupCollapsed(e,n){if(!this.enabled)return n();console.groupCollapsed(`${this.prefix} ${e}`);try{n()}finally{console.groupEnd()}}table(e,n){this.enabled&&(this.info("Table data:"),console.table(e,n))}time(e){this.enabled&&console.time(`${this.prefix} ${e}`)}timeEnd(e){this.enabled&&console.timeEnd(`${this.prefix} ${e}`)}timeLog(e){this.enabled&&console.timeLog(`${this.prefix} ${e}`)}enable(){this.enabled=!0}disable(){this.enabled=!1}setPrefix(e){this.prefix=e}};function D(f={}){return new k(f)}function P(f,e){function n(c){return c.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"")}if(window.trustedTypes){let u=window.trustedTypes.createPolicy("myHTMLPolicy",{createHTML:n}).createHTML(e);f.innerHTML=u}else{let c=n(e);f.innerHTML=c}}async function B(f){let{tagName:e,id:n,attributes:c={},parentSelector:u="body",parentElement:b,textContent:s,innerHTML:h,innerElement:w,returnElement:S=!0,checkExisting:V=!0,replaceExisting:q=!1,insertionMethod:E="append",contextElement:p,waitTimeout:I=3e4,persistent:y=!1,autoRemove:x=!0,debounceDelay:F=500,observerConfig:g={childList:!0,subtree:!0,attributes:!1,attributeOldValue:!1,characterData:!1,characterDataOldValue:!1},namespace:A,onMount:v}=f,t=D({prefix:"[createElement]",namespace:A}),r={action:"create",tagName:e,id:n,parentMethod:u?"selector":"element",parentIdentifier:u||(b?b.tagName:"unknown"),waitTimeout:I,insertionMethod:E};if(t.info(`Starting element creation: <${e}> with ID="${n}"${p?" (conditional)":""} using ${E} insertion`),!e||typeof e!="string")return t.error("Element creation failed: Tag parameter is required and must be a string",r),null;if(!n||typeof n!="string")return t.error("Element creation failed: ID parameter is required and must be a non-empty string",r),null;if(!u&&!b)return t.error("Element creation failed: Either parentSelector or parentElement must be provided",r),null;if(E!=="append"&&E!=="insertBeforeElement"&&E!=="prepend")return t.error("Element creation failed: insertionMethod must be 'append', 'insertBeforeElement', or 'prepend'",r),null;function T(a,i,o){try{let m=new DOMParser().parseFromString(i,"text/html"),l=m.querySelector("parsererror");if(l)throw new Error(`HTML parsing error: ${l.textContent}`);let $=Array.from(m.body.childNodes);return $.length===0?(t.warn(`No valid elements found in HTML string: "${i.substring(0,50)}${i.length>50?"...":""}"`,o),!1):($.forEach(M=>{let O=a.ownerDocument.importNode(M,!0);a.appendChild(O)}),t.debug(`Created DOM elements programmatically: "${i.substring(0,50)}${i.length>50?"...":""}" (${$.length} elements)`,o),!0)}catch(d){t.warn(`DOMParser failed, attempting fallback method: ${d.message}`,o);try{return P(a,i),t.debug(`Successfully created DOM elements via fallback method: "${i.substring(0,50)}${i.length>50?"...":""}"`,o),!0}catch(m){return t.error(`DOM insertion failed: ${m.message}`,{...o,originalError:d.message,fallbackError:m.message}),!1}}}function C(){try{let a=null;if(V&&(a=document.getElementById(n),a))if(r.action="exists",q)t.info(`Found existing element with ID="${n}", replacing as requested`,r),a.remove(),r.action="replace";else return t.warn(`Element with ID="${n}" already exists, skipping creation. Use replaceExisting=true to replace.`,r),S?a:null;let i=b;if(!i&&u){let l=document.querySelector(u);if(!l)return t.error(`Element creation failed: Parent element not found with selector: ${u}`,r),null;i=l,t.debug(`Found parent element with selector: ${u}`,r)}if(!i)return t.error("Element creation failed: No valid parent element found",r),null;let o=document.createElement(e);t.debug(`Created DOM element: <${e}>`,r),o.setAttribute("id",n),t.debug(`Set required ID attribute: id="${n}"`,r);let d=Object.keys(c).length;if(d>0&&(Object.entries(c).forEach(([l,$])=>{$!=null&&(o.setAttribute(l,String($)),t.debug(`Set attribute: ${l}="${$}"`,r))}),t.debug(`Applied ${d} additional attributes to element`,r)),w&&typeof w=="function")try{let l=w();l instanceof HTMLElement?(o.appendChild(l),t.debug("Inserted child element via innerElement callback",r)):(t.warn("innerElement callback did not return a valid HTMLElement, falling back to other content methods",r),s!==void 0?(o.textContent=s,t.debug(`Set textContent: "${s.substring(0,100)}${s.length>100?"...":""}"`,r)):h!==void 0&&T(o,h,r))}catch(l){t.error("Error executing innerElement callback, falling back to other content methods:",l,r),s!==void 0?(o.textContent=s,t.debug(`Set textContent: "${s.substring(0,100)}${s.length>100?"...":""}"`,r)):h!==void 0&&T(o,h,r)}else s!==void 0?(o.textContent=s,t.debug(`Set textContent: "${s.substring(0,100)}${s.length>100?"...":""}"`,r)):h!==void 0&&T(o,h,r);if(E==="insertBeforeElement")if(i.parentElement)i.parentElement.insertBefore(o,i),t.debug("Inserted element before parent",r);else return t.error("Element insertion failed: Parent element has no parent to insert before",r),null;else E==="prepend"?(i.insertBefore(o,i.firstChild),t.debug("Prepended element as first child of parent",r)):(i.appendChild(o),t.debug("Appended element to end of parent",r));if(v&&typeof v=="function")try{v(o),t.debug(`Successfully called onMount callback for element ID="${n}"`,r)}catch(l){t.warn(`Error in onMount callback for element ID="${n}":`,l,r)}let m=`Element creation successful: <${e}> (ID="${n}") ${r.action==="replace"?"replaced and ":""}${E}ed to ${r.parentMethod==="selector"?`parent selected by "${u}"`:"provided parent element"}${p?" (after content element)":""}`;return t.info(m,{...r,success:!0,hasAttributes:d>0,hasContent:!!(s||h||w),parentTagName:i.tagName,elementPath:o.tagName+"#"+o.id+(o.className?`.${o.className.replace(/\s+/g,".")}`:"")}),S?o:null}catch(a){let i=`Element creation failed with exception: ${a.message||"Unknown error"}`;return t.error(i,{...r,success:!1,error:a.message||"Unknown error",stack:a.stack||"No stack trace available"}),null}}async function L(){try{if(typeof p=="function"){let a=await p();return a instanceof HTMLElement&&document.contains(a)}else if(typeof p=="string")return document.querySelector(p)!==null}catch(a){t.warn(`Error checking content element for element ID="${n}":`,a)}return!1}function H(){if(!y&&!x)return;t.info(`Setting up ${y?"persistent":""}${y&&x?" and ":""}${x?"auto-removal":""} monitoring for element ID="${n}"`);let a=null,i=new MutationObserver(async()=>{a&&clearTimeout(a),a=setTimeout(async()=>{t.debug(`Persistent monitoring check triggered for element ID="${n}"`);let d=await L(),m=document.getElementById(n);d?y&&!m?(t.info(`Context element found but managed element missing, recreating element ID="${n}"`),C()):t.debug(`Both context and managed elements exist for ID="${n}"`):x&&m?(t.info(`Context element no longer present, removing managed element ID="${n}"`),m.remove()):t.debug(`Context element no longer present for element ID="${n}"`)},F)}),o={childList:g.childList===!0,subtree:g.subtree===!0,attributes:g.attributes===!0,attributeOldValue:g.attributeOldValue===!0,characterData:g.characterData===!0,characterDataOldValue:g.characterDataOldValue===!0};i.observe(document.documentElement||document.body,o),t.debug(`Started persistent MutationObserver for element ID="${n}"`)}if(!p)return C();if(t.info(`Checking initial condition for element ID="${n}"`,{...r,waitCondition:typeof p=="function"?"callback":p,persistent:y}),await L()){t.info(`Initial content element already satisfied for element ID="${n}"`,r);let a=C();return(y||x)&&H(),a}return new Promise(a=>{let i=Date.now(),o=null,d=null,m=!1;function l(M){m||x&&(m=!0,o&&(clearTimeout(o),o=null),d&&(d.disconnect(),d=null,t.debug(`Disconnected MutationObserver for element ID="${n}"`,r)),a(M))}o=setTimeout(()=>{t.error(`Element creation failed: Wait condition timeout after ${I}ms for element ID="${n}"`,{...r,success:!1,timeoutReached:!0,waitCondition:typeof p=="function"?"callback":p}),l(null)},I),t.info(`Setting up MutationObserver for element ID="${n}"`,{...r,observerConfig:g,waitCondition:typeof p=="function"?"callback":p}),d=new MutationObserver(async M=>{if(!m&&(t.debug(`MutationObserver detected ${M.length} mutations for element ID="${n}"`,r),await L())){let O=Date.now()-i;t.info(`Wait condition satisfied via MutationObserver for element ID="${n}" after DOM changes`,{...r,elapsedTime:O});let _=C();(y||x)&&H(),l(_)}});let $={childList:g.childList===!0,subtree:g.subtree===!0,attributes:g.attributes===!0,attributeOldValue:g.attributeOldValue===!0,characterData:g.characterData===!0,characterDataOldValue:g.characterDataOldValue===!0};d.observe(document.documentElement||document.body,$),t.debug(`Started MutationObserver monitoring for element ID="${n}"`,{...r,target:"document.documentElement"})})}function N({selector:f,timeout:e=5e3,pollInterval:n=100}){return new Promise(c=>{let u=n,b=0,s=setInterval(()=>{let h=document.querySelector(f);h?(clearInterval(s),c(h)):b>=e&&(clearInterval(s),c(null)),b+=u},u)})}(async function(){"use strict";GM_addStyle(` .create-artifact-buttons-container { transition: height 0.3s ease-in-out, margin-bottom 0.3s ease-in-out, margin-top 0.3s ease-in-out, opacity 0.2s ease-in-out 0.1s, overflow 0s ease-in-out 0s; margin-top: 16px !important; @@ -31,7 +31,7 @@ transition: height 0.3s ease-in-out, margin-bottom 0.3s ease-in-out, margin-top 0.3s ease-in-out, opacity 0.2s ease-in-out 0s, overflow 0s ease-in-out 0s; overflow: hidden !important; } .panel-collapsed #collapse-studio-buttons-container-box, [aria-label="Close app viewer"] + #collapse-studio-buttons-container-box, [aria-label="Close report viewer"] + #collapse-studio-buttons-container-box, [aria-label="Close note view"] + #collapse-studio-buttons-container-box, [aria-label="Close mindmap view"] + #collapse-studio-buttons-container-box { display: none !important; } `);let f=D({prefix:"UserScript",namespace:"[CollapseStudioButtonsContainer]"}),e=GM_getValue("studioButtonsContainerCollapsed",!1);f.log(`Studio buttons container is currently ${e?"collapsed":"expanded"}`);let n=()=>document.querySelector(".create-artifact-buttons-container");(await N({selector:".create-artifact-buttons-container",timeout:3e3}))?.classList.toggle("collapsed",e),B({tagName:"span",namespace:"[CollapseStudioButtonsContainer]",id:"collapse-studio-buttons-container-box",insertionMethod:"insertBeforeElement",autoRemove:!1,attributes:{},parentSelector:".toggle-studio-panel-button",contextElement:".studio-panel",innerHTML:'<button mat-icon-button="" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger toggle-studio-panel-button mat-unthemed ng-star-inserted" mat-ripple-loader-class-name="mat-mdc-button-ripple" mat-ripple-loader-centered="" aria-label="Collapse studio panel" jslog="" style=""><span class="mat-mdc-button-persistent-ripple mdc-icon-button__ripple"></span><mat-icon role="img" aria-hidden="true" class="mat-icon notranslate material-symbols-outlined mat-icon-rtl-mirror google-symbols mat-icon-no-color" data-mat-icon-type="font">dock_to_top</mat-icon><span class="mat-focus-indicator"></span><span class="mat-mdc-button-touch-target"></span><span class="mat-ripple mat-mdc-button-ripple"></span></button>',onMount:u=>{u.addEventListener("click",async()=>{f.log("Toggle button clicked");let b=n();if(b){b.classList.toggle("collapsed");let s=b.classList.contains("collapsed");GM_setValue("studioButtonsContainerCollapsed",s),f.log(`Studio buttons container ${s?"collapsed":"expanded"}`)}else f.error("Create artifact buttons container not found")})}})})();})(); -
volkanunsal revised this gist
Sep 10, 2025 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,7 +2,7 @@ // ==UserScript== // @name Collapse Studio Buttons Container // @namespace https://github.com/volkanunsal // @version 2025-09-10 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js @@ -15,7 +15,7 @@ // ==/UserScript== "use strict";(()=>{var k=class{constructor(e={}){this.namespace=e.namespace,this.prefix=[this.namespace,e.prefix].filter(Boolean).join(" "),this.enabled=e.enabled!==!1,this.timestamp=e.timestamp!==!1,this.timestampFormat=e.timestampFormat||"locale"}getTimestamp(){let e=new Date;return this.timestampFormat==="ISO"?e.toISOString():e.toLocaleString()}formatMessage(e,...n){let c=[this.prefix];return this.timestamp&&c.push(`[${this.getTimestamp()}]`),c.push(`[${e.toUpperCase()}]`),[c.join(" "),...n]}debug(...e){this.enabled&&console.debug(...this.formatMessage("debug",...e))}info(...e){this.enabled&&console.info(...this.formatMessage("info",...e))}warn(...e){this.enabled&&console.warn(...this.formatMessage("warn",...e))}error(...e){this.enabled&&console.error(...this.formatMessage("error",...e))}log(...e){this.enabled&&console.log(...this.formatMessage("log",...e))}custom(e,...n){this.enabled&&console.log(...this.formatMessage(e,...n))}group(e,n){if(!this.enabled)return n();console.group(`${this.prefix} ${e}`);try{n()}finally{console.groupEnd()}}groupCollapsed(e,n){if(!this.enabled)return n();console.groupCollapsed(`${this.prefix} ${e}`);try{n()}finally{console.groupEnd()}}table(e,n){this.enabled&&(this.info("Table data:"),console.table(e,n))}time(e){this.enabled&&console.time(`${this.prefix} ${e}`)}timeEnd(e){this.enabled&&console.timeEnd(`${this.prefix} ${e}`)}timeLog(e){this.enabled&&console.timeLog(`${this.prefix} ${e}`)}enable(){this.enabled=!0}disable(){this.enabled=!1}setPrefix(e){this.prefix=e}};function C(f={}){return new k(f)}function P(f,e){function n(c){return c.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"")}if(window.trustedTypes){let u=window.trustedTypes.createPolicy("myHTMLPolicy",{createHTML:n}).createHTML(e);f.innerHTML=u}else{let c=n(e);f.innerHTML=c}}async function B(f){let{tagName:e,id:n,attributes:c={},parentSelector:u="body",parentElement:b,textContent:s,innerHTML:h,innerElement:w,returnElement:S=!0,checkExisting:V=!0,replaceExisting:q=!1,insertionMethod:E="append",contextElement:p,waitTimeout:I=3e4,persistent:y=!1,autoRemove:x=!0,debounceDelay:F=500,observerConfig:g={childList:!0,subtree:!0,attributes:!1,attributeOldValue:!1,characterData:!1,characterDataOldValue:!1},namespace:A,onMount:v}=f,t=C({prefix:"[createElement]",namespace:A}),r={action:"create",tagName:e,id:n,parentMethod:u?"selector":"element",parentIdentifier:u||(b?b.tagName:"unknown"),waitTimeout:I,insertionMethod:E};if(t.info(`Starting element creation: <${e}> with ID="${n}"${p?" (conditional)":""} using ${E} insertion`),!e||typeof e!="string")return t.error("Element creation failed: Tag parameter is required and must be a string",r),null;if(!n||typeof n!="string")return t.error("Element creation failed: ID parameter is required and must be a non-empty string",r),null;if(!u&&!b)return t.error("Element creation failed: Either parentSelector or parentElement must be provided",r),null;if(E!=="append"&&E!=="insertBeforeElement"&&E!=="prepend")return t.error("Element creation failed: insertionMethod must be 'append', 'insertBeforeElement', or 'prepend'",r),null;function T(a,i,o){try{let m=new DOMParser().parseFromString(i,"text/html"),l=m.querySelector("parsererror");if(l)throw new Error(`HTML parsing error: ${l.textContent}`);let $=Array.from(m.body.childNodes);return $.length===0?(t.warn(`No valid elements found in HTML string: "${i.substring(0,50)}${i.length>50?"...":""}"`,o),!1):($.forEach(M=>{let O=a.ownerDocument.importNode(M,!0);a.appendChild(O)}),t.debug(`Created DOM elements programmatically: "${i.substring(0,50)}${i.length>50?"...":""}" (${$.length} elements)`,o),!0)}catch(d){t.warn(`DOMParser failed, attempting fallback method: ${d.message}`,o);try{return P(a,i),t.debug(`Successfully created DOM elements via fallback method: "${i.substring(0,50)}${i.length>50?"...":""}"`,o),!0}catch(m){return t.error(`DOM insertion failed: ${m.message}`,{...o,originalError:d.message,fallbackError:m.message}),!1}}}function D(){try{let a=null;if(V&&(a=document.getElementById(n),a))if(r.action="exists",q)t.info(`Found existing element with ID="${n}", replacing as requested`,r),a.remove(),r.action="replace";else return t.warn(`Element with ID="${n}" already exists, skipping creation. Use replaceExisting=true to replace.`,r),S?a:null;let i=b;if(!i&&u){let l=document.querySelector(u);if(!l)return t.error(`Element creation failed: Parent element not found with selector: ${u}`,r),null;i=l,t.debug(`Found parent element with selector: ${u}`,r)}if(!i)return t.error("Element creation failed: No valid parent element found",r),null;let o=document.createElement(e);t.debug(`Created DOM element: <${e}>`,r),o.setAttribute("id",n),t.debug(`Set required ID attribute: id="${n}"`,r);let d=Object.keys(c).length;if(d>0&&(Object.entries(c).forEach(([l,$])=>{$!=null&&(o.setAttribute(l,String($)),t.debug(`Set attribute: ${l}="${$}"`,r))}),t.debug(`Applied ${d} additional attributes to element`,r)),w&&typeof w=="function")try{let l=w();l instanceof HTMLElement?(o.appendChild(l),t.debug("Inserted child element via innerElement callback",r)):(t.warn("innerElement callback did not return a valid HTMLElement, falling back to other content methods",r),s!==void 0?(o.textContent=s,t.debug(`Set textContent: "${s.substring(0,100)}${s.length>100?"...":""}"`,r)):h!==void 0&&T(o,h,r))}catch(l){t.error("Error executing innerElement callback, falling back to other content methods:",l,r),s!==void 0?(o.textContent=s,t.debug(`Set textContent: "${s.substring(0,100)}${s.length>100?"...":""}"`,r)):h!==void 0&&T(o,h,r)}else s!==void 0?(o.textContent=s,t.debug(`Set textContent: "${s.substring(0,100)}${s.length>100?"...":""}"`,r)):h!==void 0&&T(o,h,r);if(E==="insertBeforeElement")if(i.parentElement)i.parentElement.insertBefore(o,i),t.debug("Inserted element before parent",r);else return t.error("Element insertion failed: Parent element has no parent to insert before",r),null;else E==="prepend"?(i.insertBefore(o,i.firstChild),t.debug("Prepended element as first child of parent",r)):(i.appendChild(o),t.debug("Appended element to end of parent",r));if(v&&typeof v=="function")try{v(o),t.debug(`Successfully called onMount callback for element ID="${n}"`,r)}catch(l){t.warn(`Error in onMount callback for element ID="${n}":`,l,r)}let m=`Element creation successful: <${e}> (ID="${n}") ${r.action==="replace"?"replaced and ":""}${E}ed to ${r.parentMethod==="selector"?`parent selected by "${u}"`:"provided parent element"}${p?" (after content element)":""}`;return t.info(m,{...r,success:!0,hasAttributes:d>0,hasContent:!!(s||h||w),parentTagName:i.tagName,elementPath:o.tagName+"#"+o.id+(o.className?`.${o.className.replace(/\s+/g,".")}`:"")}),S?o:null}catch(a){let i=`Element creation failed with exception: ${a.message||"Unknown error"}`;return t.error(i,{...r,success:!1,error:a.message||"Unknown error",stack:a.stack||"No stack trace available"}),null}}async function L(){try{if(typeof p=="function"){let a=await p();return a instanceof HTMLElement&&document.contains(a)}else if(typeof p=="string")return document.querySelector(p)!==null}catch(a){t.warn(`Error checking content element for element ID="${n}":`,a)}return!1}function H(){if(!y&&!x)return;t.info(`Setting up ${y?"persistent":""}${y&&x?" and ":""}${x?"auto-removal":""} monitoring for element ID="${n}"`);let a=null,i=new MutationObserver(async()=>{a&&clearTimeout(a),a=setTimeout(async()=>{t.debug(`Persistent monitoring check triggered for element ID="${n}"`);let d=await L(),m=document.getElementById(n);d?y&&!m?(t.info(`Context element found but managed element missing, recreating element ID="${n}"`),D()):t.debug(`Both context and managed elements exist for ID="${n}"`):x&&m?(t.info(`Context element no longer present, removing managed element ID="${n}"`),m.remove()):t.debug(`Context element no longer present for element ID="${n}"`)},F)}),o={childList:g.childList===!0,subtree:g.subtree===!0,attributes:g.attributes===!0,attributeOldValue:g.attributeOldValue===!0,characterData:g.characterData===!0,characterDataOldValue:g.characterDataOldValue===!0};i.observe(document.documentElement||document.body,o),t.debug(`Started persistent MutationObserver for element ID="${n}"`)}if(!p)return D();if(t.info(`Checking initial condition for element ID="${n}"`,{...r,waitCondition:typeof p=="function"?"callback":p,persistent:y}),await L()){t.info(`Initial content element already satisfied for element ID="${n}"`,r);let a=D();return(y||x)&&H(),a}return new Promise(a=>{let i=Date.now(),o=null,d=null,m=!1;function l(M){m||x&&(m=!0,o&&(clearTimeout(o),o=null),d&&(d.disconnect(),d=null,t.debug(`Disconnected MutationObserver for element ID="${n}"`,r)),a(M))}o=setTimeout(()=>{t.error(`Element creation failed: Wait condition timeout after ${I}ms for element ID="${n}"`,{...r,success:!1,timeoutReached:!0,waitCondition:typeof p=="function"?"callback":p}),l(null)},I),t.info(`Setting up MutationObserver for element ID="${n}"`,{...r,observerConfig:g,waitCondition:typeof p=="function"?"callback":p}),d=new MutationObserver(async M=>{if(!m&&(t.debug(`MutationObserver detected ${M.length} mutations for element ID="${n}"`,r),await L())){let O=Date.now()-i;t.info(`Wait condition satisfied via MutationObserver for element ID="${n}" after DOM changes`,{...r,elapsedTime:O});let _=D();(y||x)&&H(),l(_)}});let $={childList:g.childList===!0,subtree:g.subtree===!0,attributes:g.attributes===!0,attributeOldValue:g.attributeOldValue===!0,characterData:g.characterData===!0,characterDataOldValue:g.characterDataOldValue===!0};d.observe(document.documentElement||document.body,$),t.debug(`Started MutationObserver monitoring for element ID="${n}"`,{...r,target:"document.documentElement"})})}function N({selector:f,timeout:e=5e3,pollInterval:n=100}){return new Promise(c=>{let u=n,b=0,s=setInterval(()=>{let h=document.querySelector(f);h?(clearInterval(s),c(h)):b>=e&&(clearInterval(s),c(null)),b+=u},u)})}(async function(){"use strict";GM_addStyle(` .create-artifact-buttons-container { transition: height 0.3s ease-in-out, margin-bottom 0.3s ease-in-out, margin-top 0.3s ease-in-out, opacity 0.2s ease-in-out 0.1s, overflow 0s ease-in-out 0s; margin-top: 16px !important; @@ -31,7 +31,7 @@ transition: height 0.3s ease-in-out, margin-bottom 0.3s ease-in-out, margin-top 0.3s ease-in-out, opacity 0.2s ease-in-out 0s, overflow 0s ease-in-out 0s; overflow: hidden !important; } .panel-collapsed #collapse-studio-buttons-container-box, [aria-label="Close app viewer"] + #collapse-studio-buttons-container-box, [aria-label="Close report viewer"] + #collapse-studio-buttons-container-box { display: none !important; } `);let f=C({prefix:"UserScript",namespace:"[CollapseStudioButtonsContainer]"}),e=GM_getValue("studioButtonsContainerCollapsed",!1);f.log(`Studio buttons container is currently ${e?"collapsed":"expanded"}`);let n=()=>document.querySelector(".create-artifact-buttons-container");(await N({selector:".create-artifact-buttons-container",timeout:3e3}))?.classList.toggle("collapsed",e),B({tagName:"span",namespace:"[CollapseStudioButtonsContainer]",id:"collapse-studio-buttons-container-box",insertionMethod:"insertBeforeElement",autoRemove:!1,attributes:{},parentSelector:".toggle-studio-panel-button",contextElement:".studio-panel",innerHTML:'<button mat-icon-button="" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger toggle-studio-panel-button mat-unthemed ng-star-inserted" mat-ripple-loader-class-name="mat-mdc-button-ripple" mat-ripple-loader-centered="" aria-label="Collapse studio panel" jslog="" style=""><span class="mat-mdc-button-persistent-ripple mdc-icon-button__ripple"></span><mat-icon role="img" aria-hidden="true" class="mat-icon notranslate material-symbols-outlined mat-icon-rtl-mirror google-symbols mat-icon-no-color" data-mat-icon-type="font">dock_to_top</mat-icon><span class="mat-focus-indicator"></span><span class="mat-mdc-button-touch-target"></span><span class="mat-ripple mat-mdc-button-ripple"></span></button>',onMount:u=>{u.addEventListener("click",async()=>{f.log("Toggle button clicked");let b=n();if(b){b.classList.toggle("collapsed");let s=b.classList.contains("collapsed");GM_setValue("studioButtonsContainerCollapsed",s),f.log(`Studio buttons container ${s?"collapsed":"expanded"}`)}else f.error("Create artifact buttons container not found")})}})})();})(); -
volkanunsal revised this gist
Sep 9, 2025 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,7 +2,7 @@ // ==UserScript== // @name Collapse Studio Buttons Container // @namespace https://github.com/volkanunsal // @version 2025-09-09:4 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js @@ -15,7 +15,7 @@ // ==/UserScript== "use strict";(()=>{var k=class{constructor(e={}){this.namespace=e.namespace,this.prefix=[this.namespace,e.prefix].filter(Boolean).join(" "),this.enabled=e.enabled!==!1,this.timestamp=e.timestamp!==!1,this.timestampFormat=e.timestampFormat||"locale"}getTimestamp(){let e=new Date;return this.timestampFormat==="ISO"?e.toISOString():e.toLocaleString()}formatMessage(e,...n){let c=[this.prefix];return this.timestamp&&c.push(`[${this.getTimestamp()}]`),c.push(`[${e.toUpperCase()}]`),[c.join(" "),...n]}debug(...e){this.enabled&&console.debug(...this.formatMessage("debug",...e))}info(...e){this.enabled&&console.info(...this.formatMessage("info",...e))}warn(...e){this.enabled&&console.warn(...this.formatMessage("warn",...e))}error(...e){this.enabled&&console.error(...this.formatMessage("error",...e))}log(...e){this.enabled&&console.log(...this.formatMessage("log",...e))}custom(e,...n){this.enabled&&console.log(...this.formatMessage(e,...n))}group(e,n){if(!this.enabled)return n();console.group(`${this.prefix} ${e}`);try{n()}finally{console.groupEnd()}}groupCollapsed(e,n){if(!this.enabled)return n();console.groupCollapsed(`${this.prefix} ${e}`);try{n()}finally{console.groupEnd()}}table(e,n){this.enabled&&(this.info("Table data:"),console.table(e,n))}time(e){this.enabled&&console.time(`${this.prefix} ${e}`)}timeEnd(e){this.enabled&&console.timeEnd(`${this.prefix} ${e}`)}timeLog(e){this.enabled&&console.timeLog(`${this.prefix} ${e}`)}enable(){this.enabled=!0}disable(){this.enabled=!1}setPrefix(e){this.prefix=e}};function C(f={}){return new k(f)}function P(f,e){function n(c){return c.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"")}if(window.trustedTypes){let u=window.trustedTypes.createPolicy("myHTMLPolicy",{createHTML:n}).createHTML(e);f.innerHTML=u}else{let c=n(e);f.innerHTML=c}}async function B(f){let{tagName:e,id:n,attributes:c={},parentSelector:u="body",parentElement:b,textContent:s,innerHTML:h,innerElement:w,returnElement:S=!0,checkExisting:V=!0,replaceExisting:q=!1,insertionMethod:E="append",contextElement:p,waitTimeout:I=3e4,persistent:y=!1,autoRemove:M=!0,debounceDelay:F=500,observerConfig:g={childList:!0,subtree:!0,attributes:!1,attributeOldValue:!1,characterData:!1,characterDataOldValue:!1},namespace:A,onMount:v}=f,t=C({prefix:"[createElement]",namespace:A}),r={action:"create",tagName:e,id:n,parentMethod:u?"selector":"element",parentIdentifier:u||(b?b.tagName:"unknown"),waitTimeout:I,insertionMethod:E};if(t.info(`Starting element creation: <${e}> with ID="${n}"${p?" (conditional)":""} using ${E} insertion`),!e||typeof e!="string")return t.error("Element creation failed: Tag parameter is required and must be a string",r),null;if(!n||typeof n!="string")return t.error("Element creation failed: ID parameter is required and must be a non-empty string",r),null;if(!u&&!b)return t.error("Element creation failed: Either parentSelector or parentElement must be provided",r),null;if(E!=="append"&&E!=="insertBeforeElement"&&E!=="prepend")return t.error("Element creation failed: insertionMethod must be 'append', 'insertBeforeElement', or 'prepend'",r),null;function T(a,i,o){try{let m=new DOMParser().parseFromString(i,"text/html"),l=m.querySelector("parsererror");if(l)throw new Error(`HTML parsing error: ${l.textContent}`);let $=Array.from(m.body.childNodes);return $.length===0?(t.warn(`No valid elements found in HTML string: "${i.substring(0,50)}${i.length>50?"...":""}"`,o),!1):($.forEach(x=>{let O=a.ownerDocument.importNode(x,!0);a.appendChild(O)}),t.debug(`Created DOM elements programmatically: "${i.substring(0,50)}${i.length>50?"...":""}" (${$.length} elements)`,o),!0)}catch(d){t.warn(`DOMParser failed, attempting fallback method: ${d.message}`,o);try{return P(a,i),t.debug(`Successfully created DOM elements via fallback method: "${i.substring(0,50)}${i.length>50?"...":""}"`,o),!0}catch(m){return t.error(`DOM insertion failed: ${m.message}`,{...o,originalError:d.message,fallbackError:m.message}),!1}}}function D(){try{let a=null;if(V&&(a=document.getElementById(n),a))if(r.action="exists",q)t.info(`Found existing element with ID="${n}", replacing as requested`,r),a.remove(),r.action="replace";else return t.warn(`Element with ID="${n}" already exists, skipping creation. Use replaceExisting=true to replace.`,r),S?a:null;let i=b;if(!i&&u){let l=document.querySelector(u);if(!l)return t.error(`Element creation failed: Parent element not found with selector: ${u}`,r),null;i=l,t.debug(`Found parent element with selector: ${u}`,r)}if(!i)return t.error("Element creation failed: No valid parent element found",r),null;let o=document.createElement(e);t.debug(`Created DOM element: <${e}>`,r),o.setAttribute("id",n),t.debug(`Set required ID attribute: id="${n}"`,r);let d=Object.keys(c).length;if(d>0&&(Object.entries(c).forEach(([l,$])=>{$!=null&&(o.setAttribute(l,String($)),t.debug(`Set attribute: ${l}="${$}"`,r))}),t.debug(`Applied ${d} additional attributes to element`,r)),w&&typeof w=="function")try{let l=w();l instanceof HTMLElement?(o.appendChild(l),t.debug("Inserted child element via innerElement callback",r)):(t.warn("innerElement callback did not return a valid HTMLElement, falling back to other content methods",r),s!==void 0?(o.textContent=s,t.debug(`Set textContent: "${s.substring(0,100)}${s.length>100?"...":""}"`,r)):h!==void 0&&T(o,h,r))}catch(l){t.error("Error executing innerElement callback, falling back to other content methods:",l,r),s!==void 0?(o.textContent=s,t.debug(`Set textContent: "${s.substring(0,100)}${s.length>100?"...":""}"`,r)):h!==void 0&&T(o,h,r)}else s!==void 0?(o.textContent=s,t.debug(`Set textContent: "${s.substring(0,100)}${s.length>100?"...":""}"`,r)):h!==void 0&&T(o,h,r);if(E==="insertBeforeElement")if(i.parentElement)i.parentElement.insertBefore(o,i),t.debug("Inserted element before parent",r);else return t.error("Element insertion failed: Parent element has no parent to insert before",r),null;else E==="prepend"?(i.insertBefore(o,i.firstChild),t.debug("Prepended element as first child of parent",r)):(i.appendChild(o),t.debug("Appended element to end of parent",r));if(v&&typeof v=="function")try{v(o),t.debug(`Successfully called onMount callback for element ID="${n}"`,r)}catch(l){t.warn(`Error in onMount callback for element ID="${n}":`,l,r)}let m=`Element creation successful: <${e}> (ID="${n}") ${r.action==="replace"?"replaced and ":""}${E}ed to ${r.parentMethod==="selector"?`parent selected by "${u}"`:"provided parent element"}${p?" (after content element)":""}`;return t.info(m,{...r,success:!0,hasAttributes:d>0,hasContent:!!(s||h||w),parentTagName:i.tagName,elementPath:o.tagName+"#"+o.id+(o.className?`.${o.className.replace(/\s+/g,".")}`:"")}),S?o:null}catch(a){let i=`Element creation failed with exception: ${a.message||"Unknown error"}`;return t.error(i,{...r,success:!1,error:a.message||"Unknown error",stack:a.stack||"No stack trace available"}),null}}async function L(){try{if(typeof p=="function"){let a=await p();return a instanceof HTMLElement&&document.contains(a)}else if(typeof p=="string")return document.querySelector(p)!==null}catch(a){t.warn(`Error checking content element for element ID="${n}":`,a)}return!1}function H(){if(!y&&!M)return;t.info(`Setting up ${y?"persistent":""}${y&&M?" and ":""}${M?"auto-removal":""} monitoring for element ID="${n}"`);let a=null,i=new MutationObserver(async()=>{a&&clearTimeout(a),a=setTimeout(async()=>{t.debug(`Persistent monitoring check triggered for element ID="${n}"`);let d=await L(),m=document.getElementById(n);d?y&&!m?(t.info(`Context element found but managed element missing, recreating element ID="${n}"`),D()):t.debug(`Both context and managed elements exist for ID="${n}"`):M&&m?(t.info(`Context element no longer present, removing managed element ID="${n}"`),m.remove()):t.debug(`Context element no longer present for element ID="${n}"`)},F)}),o={childList:g.childList===!0,subtree:g.subtree===!0,attributes:g.attributes===!0,attributeOldValue:g.attributeOldValue===!0,characterData:g.characterData===!0,characterDataOldValue:g.characterDataOldValue===!0};i.observe(document.documentElement||document.body,o),t.debug(`Started persistent MutationObserver for element ID="${n}"`)}if(!p)return D();if(t.info(`Checking initial condition for element ID="${n}"`,{...r,waitCondition:typeof p=="function"?"callback":p,persistent:y}),await L()){t.info(`Initial content element already satisfied for element ID="${n}"`,r);let a=D();return(y||M)&&H(),a}return new Promise(a=>{let i=Date.now(),o=null,d=null,m=!1;function l(x){m||M&&(m=!0,o&&(clearTimeout(o),o=null),d&&(d.disconnect(),d=null,t.debug(`Disconnected MutationObserver for element ID="${n}"`,r)),a(x))}o=setTimeout(()=>{t.error(`Element creation failed: Wait condition timeout after ${I}ms for element ID="${n}"`,{...r,success:!1,timeoutReached:!0,waitCondition:typeof p=="function"?"callback":p}),l(null)},I),t.info(`Setting up MutationObserver for element ID="${n}"`,{...r,observerConfig:g,waitCondition:typeof p=="function"?"callback":p}),d=new MutationObserver(async x=>{if(!m&&(t.debug(`MutationObserver detected ${x.length} mutations for element ID="${n}"`,r),await L())){let O=Date.now()-i;t.info(`Wait condition satisfied via MutationObserver for element ID="${n}" after DOM changes`,{...r,elapsedTime:O});let _=D();(y||M)&&H(),l(_)}});let $={childList:g.childList===!0,subtree:g.subtree===!0,attributes:g.attributes===!0,attributeOldValue:g.attributeOldValue===!0,characterData:g.characterData===!0,characterDataOldValue:g.characterDataOldValue===!0};d.observe(document.documentElement||document.body,$),t.debug(`Started MutationObserver monitoring for element ID="${n}"`,{...r,target:"document.documentElement"})})}function N({selector:f,timeout:e=5e3,pollInterval:n=100}){return new Promise(c=>{let u=n,b=0,s=setInterval(()=>{let h=document.querySelector(f);h?(clearInterval(s),c(h)):b>=e&&(clearInterval(s),c(null)),b+=u},u)})}(async function(){"use strict";GM_addStyle(` .create-artifact-buttons-container { transition: height 0.3s ease-in-out, margin-bottom 0.3s ease-in-out, margin-top 0.3s ease-in-out, opacity 0.2s ease-in-out 0.1s, overflow 0s ease-in-out 0s; margin-top: 16px !important; @@ -31,7 +31,7 @@ transition: height 0.3s ease-in-out, margin-bottom 0.3s ease-in-out, margin-top 0.3s ease-in-out, opacity 0.2s ease-in-out 0s, overflow 0s ease-in-out 0s; overflow: hidden !important; } .panel-collapsed #collapse-studio-buttons-container-box, [aria-label="Close app viewer"] + #collapse-studio-buttons-container-box { display: none !important; } `);let f=C({prefix:"UserScript",namespace:"[CollapseStudioButtonsContainer]"}),e=GM_getValue("studioButtonsContainerCollapsed",!1);f.log(`Studio buttons container is currently ${e?"collapsed":"expanded"}`);let n=()=>document.querySelector(".create-artifact-buttons-container");(await N({selector:".create-artifact-buttons-container",timeout:3e3}))?.classList.toggle("collapsed",e),B({tagName:"span",namespace:"[CollapseStudioButtonsContainer]",id:"collapse-studio-buttons-container-box",insertionMethod:"insertBeforeElement",autoRemove:!1,attributes:{},parentSelector:".toggle-studio-panel-button",contextElement:".studio-panel",innerHTML:'<button mat-icon-button="" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger toggle-studio-panel-button mat-unthemed ng-star-inserted" mat-ripple-loader-class-name="mat-mdc-button-ripple" mat-ripple-loader-centered="" aria-label="Collapse studio panel" jslog="" style=""><span class="mat-mdc-button-persistent-ripple mdc-icon-button__ripple"></span><mat-icon role="img" aria-hidden="true" class="mat-icon notranslate material-symbols-outlined mat-icon-rtl-mirror google-symbols mat-icon-no-color" data-mat-icon-type="font">dock_to_top</mat-icon><span class="mat-focus-indicator"></span><span class="mat-mdc-button-touch-target"></span><span class="mat-ripple mat-mdc-button-ripple"></span></button>',onMount:u=>{u.addEventListener("click",async()=>{f.log("Toggle button clicked");let b=n();if(b){b.classList.toggle("collapsed");let s=b.classList.contains("collapsed");GM_setValue("studioButtonsContainerCollapsed",s),f.log(`Studio buttons container ${s?"collapsed":"expanded"}`)}else f.error("Create artifact buttons container not found")})}})})();})(); -
volkanunsal revised this gist
Sep 9, 2025 . 1 changed file with 5 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,7 +2,7 @@ // ==UserScript== // @name Collapse Studio Buttons Container // @namespace https://github.com/volkanunsal // @version 2025-09-09:3 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js @@ -15,9 +15,9 @@ // ==/UserScript== "use strict";(()=>{var k=class{constructor(e={}){this.namespace=e.namespace,this.prefix=[this.namespace,e.prefix].filter(Boolean).join(" "),this.enabled=e.enabled!==!1,this.timestamp=e.timestamp!==!1,this.timestampFormat=e.timestampFormat||"locale"}getTimestamp(){let e=new Date;return this.timestampFormat==="ISO"?e.toISOString():e.toLocaleString()}formatMessage(e,...n){let c=[this.prefix];return this.timestamp&&c.push(`[${this.getTimestamp()}]`),c.push(`[${e.toUpperCase()}]`),[c.join(" "),...n]}debug(...e){this.enabled&&console.debug(...this.formatMessage("debug",...e))}info(...e){this.enabled&&console.info(...this.formatMessage("info",...e))}warn(...e){this.enabled&&console.warn(...this.formatMessage("warn",...e))}error(...e){this.enabled&&console.error(...this.formatMessage("error",...e))}log(...e){this.enabled&&console.log(...this.formatMessage("log",...e))}custom(e,...n){this.enabled&&console.log(...this.formatMessage(e,...n))}group(e,n){if(!this.enabled)return n();console.group(`${this.prefix} ${e}`);try{n()}finally{console.groupEnd()}}groupCollapsed(e,n){if(!this.enabled)return n();console.groupCollapsed(`${this.prefix} ${e}`);try{n()}finally{console.groupEnd()}}table(e,n){this.enabled&&(this.info("Table data:"),console.table(e,n))}time(e){this.enabled&&console.time(`${this.prefix} ${e}`)}timeEnd(e){this.enabled&&console.timeEnd(`${this.prefix} ${e}`)}timeLog(e){this.enabled&&console.timeLog(`${this.prefix} ${e}`)}enable(){this.enabled=!0}disable(){this.enabled=!1}setPrefix(e){this.prefix=e}};function C(f={}){return new k(f)}function P(f,e){function n(c){return c.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"")}if(window.trustedTypes){let u=window.trustedTypes.createPolicy("myHTMLPolicy",{createHTML:n}).createHTML(e);f.innerHTML=u}else{let c=n(e);f.innerHTML=c}}async function B(f){let{tagName:e,id:n,attributes:c={},parentSelector:u="body",parentElement:b,textContent:s,innerHTML:h,innerElement:w,returnElement:S=!0,checkExisting:V=!0,replaceExisting:q=!1,insertionMethod:E="append",contextElement:p,waitTimeout:I=3e4,persistent:y=!1,autoRemove:M=!0,debounceDelay:F=500,observerConfig:g={childList:!0,subtree:!0,attributes:!1,attributeOldValue:!1,characterData:!1,characterDataOldValue:!1},namespace:A,onMount:T}=f,t=C({prefix:"[createElement]",namespace:A}),r={action:"create",tagName:e,id:n,parentMethod:u?"selector":"element",parentIdentifier:u||(b?b.tagName:"unknown"),waitTimeout:I,insertionMethod:E};if(t.info(`Starting element creation: <${e}> with ID="${n}"${p?" (conditional)":""} using ${E} insertion`),!e||typeof e!="string")return t.error("Element creation failed: Tag parameter is required and must be a string",r),null;if(!n||typeof n!="string")return t.error("Element creation failed: ID parameter is required and must be a non-empty string",r),null;if(!u&&!b)return t.error("Element creation failed: Either parentSelector or parentElement must be provided",r),null;if(E!=="append"&&E!=="insertBeforeElement"&&E!=="prepend")return t.error("Element creation failed: insertionMethod must be 'append', 'insertBeforeElement', or 'prepend'",r),null;function v(a,i,o){try{let m=new DOMParser().parseFromString(i,"text/html"),l=m.querySelector("parsererror");if(l)throw new Error(`HTML parsing error: ${l.textContent}`);let $=Array.from(m.body.childNodes);return $.length===0?(t.warn(`No valid elements found in HTML string: "${i.substring(0,50)}${i.length>50?"...":""}"`,o),!1):($.forEach(x=>{let O=a.ownerDocument.importNode(x,!0);a.appendChild(O)}),t.debug(`Created DOM elements programmatically: "${i.substring(0,50)}${i.length>50?"...":""}" (${$.length} elements)`,o),!0)}catch(d){t.warn(`DOMParser failed, attempting fallback method: ${d.message}`,o);try{return P(a,i),t.debug(`Successfully created DOM elements via fallback method: "${i.substring(0,50)}${i.length>50?"...":""}"`,o),!0}catch(m){return t.error(`DOM insertion failed: ${m.message}`,{...o,originalError:d.message,fallbackError:m.message}),!1}}}function D(){try{let a=null;if(V&&(a=document.getElementById(n),a))if(r.action="exists",q)t.info(`Found existing element with ID="${n}", replacing as requested`,r),a.remove(),r.action="replace";else return t.warn(`Element with ID="${n}" already exists, skipping creation. Use replaceExisting=true to replace.`,r),S?a:null;let i=b;if(!i&&u){let l=document.querySelector(u);if(!l)return t.error(`Element creation failed: Parent element not found with selector: ${u}`,r),null;i=l,t.debug(`Found parent element with selector: ${u}`,r)}if(!i)return t.error("Element creation failed: No valid parent element found",r),null;let o=document.createElement(e);t.debug(`Created DOM element: <${e}>`,r),o.setAttribute("id",n),t.debug(`Set required ID attribute: id="${n}"`,r);let d=Object.keys(c).length;if(d>0&&(Object.entries(c).forEach(([l,$])=>{$!=null&&(o.setAttribute(l,String($)),t.debug(`Set attribute: ${l}="${$}"`,r))}),t.debug(`Applied ${d} additional attributes to element`,r)),w&&typeof w=="function")try{let l=w();l instanceof HTMLElement?(o.appendChild(l),t.debug("Inserted child element via innerElement callback",r)):(t.warn("innerElement callback did not return a valid HTMLElement, falling back to other content methods",r),s!==void 0?(o.textContent=s,t.debug(`Set textContent: "${s.substring(0,100)}${s.length>100?"...":""}"`,r)):h!==void 0&&v(o,h,r))}catch(l){t.error("Error executing innerElement callback, falling back to other content methods:",l,r),s!==void 0?(o.textContent=s,t.debug(`Set textContent: "${s.substring(0,100)}${s.length>100?"...":""}"`,r)):h!==void 0&&v(o,h,r)}else s!==void 0?(o.textContent=s,t.debug(`Set textContent: "${s.substring(0,100)}${s.length>100?"...":""}"`,r)):h!==void 0&&v(o,h,r);if(E==="insertBeforeElement")if(i.parentElement)i.parentElement.insertBefore(o,i),t.debug("Inserted element before parent",r);else return t.error("Element insertion failed: Parent element has no parent to insert before",r),null;else E==="prepend"?(i.insertBefore(o,i.firstChild),t.debug("Prepended element as first child of parent",r)):(i.appendChild(o),t.debug("Appended element to end of parent",r));if(T&&typeof T=="function")try{T(o),t.debug(`Successfully called onMount callback for element ID="${n}"`,r)}catch(l){t.warn(`Error in onMount callback for element ID="${n}":`,l,r)}let m=`Element creation successful: <${e}> (ID="${n}") ${r.action==="replace"?"replaced and ":""}${E}ed to ${r.parentMethod==="selector"?`parent selected by "${u}"`:"provided parent element"}${p?" (after content element)":""}`;return t.info(m,{...r,success:!0,hasAttributes:d>0,hasContent:!!(s||h||w),parentTagName:i.tagName,elementPath:o.tagName+"#"+o.id+(o.className?`.${o.className.replace(/\s+/g,".")}`:"")}),S?o:null}catch(a){let i=`Element creation failed with exception: ${a.message||"Unknown error"}`;return t.error(i,{...r,success:!1,error:a.message||"Unknown error",stack:a.stack||"No stack trace available"}),null}}async function L(){try{if(typeof p=="function"){let a=await p();return a instanceof HTMLElement&&document.contains(a)}else if(typeof p=="string")return document.querySelector(p)!==null}catch(a){t.warn(`Error checking content element for element ID="${n}":`,a)}return!1}function H(){if(!y&&!M)return;t.info(`Setting up ${y?"persistent":""}${y&&M?" and ":""}${M?"auto-removal":""} monitoring for element ID="${n}"`);let a=null,i=new MutationObserver(async()=>{a&&clearTimeout(a),a=setTimeout(async()=>{t.debug(`Persistent monitoring check triggered for element ID="${n}"`);let d=await L(),m=document.getElementById(n);d?y&&!m?(t.info(`Context element found but managed element missing, recreating element ID="${n}"`),D()):t.debug(`Both context and managed elements exist for ID="${n}"`):M&&m?(t.info(`Context element no longer present, removing managed element ID="${n}"`),m.remove()):t.debug(`Context element no longer present for element ID="${n}"`)},F)}),o={childList:g.childList===!0,subtree:g.subtree===!0,attributes:g.attributes===!0,attributeOldValue:g.attributeOldValue===!0,characterData:g.characterData===!0,characterDataOldValue:g.characterDataOldValue===!0};i.observe(document.documentElement||document.body,o),t.debug(`Started persistent MutationObserver for element ID="${n}"`)}if(!p)return D();if(t.info(`Checking initial condition for element ID="${n}"`,{...r,waitCondition:typeof p=="function"?"callback":p,persistent:y}),await L()){t.info(`Initial content element already satisfied for element ID="${n}"`,r);let a=D();return(y||M)&&H(),a}return new Promise(a=>{let i=Date.now(),o=null,d=null,m=!1;function l(x){m||M&&(m=!0,o&&(clearTimeout(o),o=null),d&&(d.disconnect(),d=null,t.debug(`Disconnected MutationObserver for element ID="${n}"`,r)),a(x))}o=setTimeout(()=>{t.error(`Element creation failed: Wait condition timeout after ${I}ms for element ID="${n}"`,{...r,success:!1,timeoutReached:!0,waitCondition:typeof p=="function"?"callback":p}),l(null)},I),t.info(`Setting up MutationObserver for element ID="${n}"`,{...r,observerConfig:g,waitCondition:typeof p=="function"?"callback":p}),d=new MutationObserver(async x=>{if(!m&&(t.debug(`MutationObserver detected ${x.length} mutations for element ID="${n}"`,r),await L())){let O=Date.now()-i;t.info(`Wait condition satisfied via MutationObserver for element ID="${n}" after DOM changes`,{...r,elapsedTime:O});let _=D();(y||M)&&H(),l(_)}});let $={childList:g.childList===!0,subtree:g.subtree===!0,attributes:g.attributes===!0,attributeOldValue:g.attributeOldValue===!0,characterData:g.characterData===!0,characterDataOldValue:g.characterDataOldValue===!0};d.observe(document.documentElement||document.body,$),t.debug(`Started MutationObserver monitoring for element ID="${n}"`,{...r,target:"document.documentElement"})})}function N({selector:f,timeout:e=5e3,pollInterval:n=100}){return new Promise(c=>{let u=n,b=0,s=setInterval(()=>{let h=document.querySelector(f);h?(clearInterval(s),c(h)):b>=e&&(clearInterval(s),c(null)),b+=u},u)})}(async function(){"use strict";GM_addStyle(` .create-artifact-buttons-container { transition: height 0.3s ease-in-out, margin-bottom 0.3s ease-in-out, margin-top 0.3s ease-in-out, opacity 0.2s ease-in-out 0.1s, overflow 0s ease-in-out 0s; margin-top: 16px !important; margin-bottom: 16px !important; height: 289px !important; @@ -28,7 +28,8 @@ opacity: 0 !important; margin-top: 0 !important; margin-bottom: 0 !important; transition: height 0.3s ease-in-out, margin-bottom 0.3s ease-in-out, margin-top 0.3s ease-in-out, opacity 0.2s ease-in-out 0s, overflow 0s ease-in-out 0s; overflow: hidden !important; } .panel-collapsed #collapse-studio-buttons-container-box { display: none !important; -
volkanunsal revised this gist
Sep 9, 2025 . 1 changed file with 4 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,7 +2,7 @@ // ==UserScript== // @name Collapse Studio Buttons Container // @namespace https://github.com/volkanunsal // @version 2025-09-09:2 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js @@ -30,4 +30,7 @@ margin-bottom: 0 !important; transition: height 0.3s ease-in-out, margin-bottom 0.3s ease-in-out, margin-top 0.3s ease-in-out, opacity 0.2s ease-in-out 0s; } .panel-collapsed #collapse-studio-buttons-container-box { display: none !important; } `);let f=C({prefix:"UserScript",namespace:"[CollapseStudioButtonsContainer]"}),e=GM_getValue("studioButtonsContainerCollapsed",!1);f.log(`Studio buttons container is currently ${e?"collapsed":"expanded"}`);let n=()=>document.querySelector(".create-artifact-buttons-container");(await N({selector:".create-artifact-buttons-container",timeout:3e3}))?.classList.toggle("collapsed",e),B({tagName:"span",namespace:"[CollapseStudioButtonsContainer]",id:"collapse-studio-buttons-container-box",insertionMethod:"insertBeforeElement",autoRemove:!1,attributes:{},parentSelector:".toggle-studio-panel-button",contextElement:".studio-panel",innerHTML:'<button mat-icon-button="" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger toggle-studio-panel-button mat-unthemed ng-star-inserted" mat-ripple-loader-class-name="mat-mdc-button-ripple" mat-ripple-loader-centered="" aria-label="Collapse studio panel" jslog="" style=""><span class="mat-mdc-button-persistent-ripple mdc-icon-button__ripple"></span><mat-icon role="img" aria-hidden="true" class="mat-icon notranslate material-symbols-outlined mat-icon-rtl-mirror google-symbols mat-icon-no-color" data-mat-icon-type="font">dock_to_top</mat-icon><span class="mat-focus-indicator"></span><span class="mat-mdc-button-touch-target"></span><span class="mat-ripple mat-mdc-button-ripple"></span></button>',onMount:u=>{u.addEventListener("click",async()=>{f.log("Toggle button clicked");let b=n();if(b){b.classList.toggle("collapsed");let s=b.classList.contains("collapsed");GM_setValue("studioButtonsContainerCollapsed",s),f.log(`Studio buttons container ${s?"collapsed":"expanded"}`)}else f.error("Create artifact buttons container not found")})}})})();})(); -
volkanunsal revised this gist
Sep 9, 2025 . 1 changed file with 0 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,7 +4,6 @@ Collapse Studio Buttons Container is a userscript that adds a collapse/expand bu  ## Key Features - Adds a collapse/expand button to the studio panel header. -
volkanunsal revised this gist
Sep 9, 2025 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,11 +2,11 @@ // ==UserScript== // @name Collapse Studio Buttons Container // @namespace https://github.com/volkanunsal // @version 2025-09-09 // @description Collapses the studio buttons container by default // @author Volkan Unsal // @downloadURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js // @updateURL https://gist.githubusercontent.com/volkanunsal/94db50629cad816eca84c836e0232a4f/raw/collapse-studio-buttons-container.user.js // @match https://notebooklm.google.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=google.com // @grant GM_addStyle
NewerOlder