Skip to content

Instantly share code, notes, and snippets.

@DarrenSem
Last active April 14, 2025 15:51
Show Gist options
  • Save DarrenSem/0d9da09fc5a7b95abcc0df95d65b02c7 to your computer and use it in GitHub Desktop.
Save DarrenSem/0d9da09fc5a7b95abcc0df95d65b02c7 to your computer and use it in GitHub Desktop.
width.js - Bookmarklet for OpenAI playground to fix maxWidth of "Configure" panel (due to latest layout update); add as browser Favorite then click to toggle visibility
// width.js - Bookmarklet for OpenAI playground to fix maxWidth of "Configure" panel (due to latest layout update); add as browser Favorite then click to toggle visibility
// https://gist.github.com/DarrenSem/0d9da09fc5a7b95abcc0df95d65b02c7
// 05Apr2025 234pm: will now FIRST close "Configure" if already opened as slide-in panel version (could have BOTH versions visible!)
// 2016 char javascript:void function(){const a=null,b="innerText",c=(b,c=1)=>{let d=b;for(;c--&&(d=d?.parentElement););return d||a},d=(a,b)=>a.test(b??""),e=()=>{const a=document.querySelectorAll("button > span > span + span.sr-only"),c=Array.from(a).filter((a,c)=>{const e=a[b],f=d(/Configure/,e);return console.log({isTextConfigure:f,text:e,el:a,i:c}),f});return console.log({collConfigureButtons:c,collButtonSpans:a,selButtonSpans:"button > span > span + span.sr-only"}),c},f=e=>{let f,g,h=a;const i=c(e,1),j=i.querySelectorAll("button");for(f of j)if(g=f.dataset,console.log({dataset:g,elButton:f}),!d(/\S/,f[b])&&"secondary"==g?.color&&"md"==g?.size&&"md"==g?.gutterSize){h=f;break}return console.log({elCloseButton:h,collButtons:j,elGrandParent:i,elParent:e}),h},g=500,h=a=>{const b=a[0],d=c(b,10);return d?console.log({configureDiv:d}):console.log({elConfigureFirst:b,collConfigureButtons:a}),d},i=location,j=()=>i.W,k=a=>{i.W=a};(async()=>new Promise(a=>{let b,h=e(),i=0;for(b of h){const a=c(b,11),e=a?.className,g=!d(/flex/,e)&&!d(/h-full/,e);console.log({classText:e,isSlider:g,elParentDiv:a,elConfigure:b}),g&&++i&&f(a)?.click?.()}return console.log({sliderCount:i,collConfigureButtonsOriginal:h,MS_BEFORE_CLOSING_CONFIGURATION_SLIDER:g}),setTimeout(()=>a(e()),i&&g)}))().then(b=>{const c=h(b);if(!c)return;const d=getComputedStyle(c).maxWidth;console.log({computedMaxWidth:d});const e=d=="0px",f=c.style;e?(console.log("\nisShrunk="+e+"; [restore previous value]; computedMaxWidth via getComputedStyle() WAS "+0+"px; used getMaxWidth() to GET stored MAXWIDTH via getMaxWidth() which was "+j()+" (before we expand it back)"),f.removeProperty("max-width"),f.removeProperty("width"),k(a)):(k("none"==d?"":d),console.log("\nisShrunk="+e+"; [store current value]; computedMaxWidth via getComputedStyle() was ["+d+"] aka NOT "+0+"px; used setMaxWidth() to store MAXWIDTH so it has now been SET to "+j()+" (before shrinking it)"),f.setProperty("max-width","0px","important"),f.setProperty("width","0px","important"))})}();
// 05Apr2025 1145am: logic rewrite so it now is always able to getDivToResize() - by locating "Configure" button (and then moving "up" 10 levels)
// 1226 char javascript:void function(){const a=(a,b=1)=>{let c=a;for(;b--&&(c=c?.parentElement););return c||null},b=()=>{const b=Array.from(document.querySelectorAll("button > span > span + span.sr-only")),c=b.filter((a,b)=>{const c=a.innerText,d="Configure"==c;return console.log({isTextConfigure:d,text:c,i:b,el:a}),d}),d=c[0],e=a(d,10);return e?console.log({configureDiv:e}):console.log({elConfigureFirst:d,collConfigure:c,collButtonSpans:b}),e},c=location,d=()=>c.W,e=a=>{c.W=a};(()=>{const a=b();if(!a)return;const c=getComputedStyle(a).maxWidth;console.log({computedMaxWidth:c});const f=c=="0px",g=a.style;f?(console.log("\nisSmol="+f+"; [restore previous value]; computedMaxWidth via getComputedStyle() WAS "+0+"px; used getMaxWidth() to GET stored MAXWIDTH via getMaxWidth() which was "+d()+" (so we can expand it back)"),g.removeProperty("max-width"),g.removeProperty("width"),e(null)):(e("none"===c?"":c),console.log("\nisSmol="+f+"; [store current value]; computedMaxWidth via getComputedStyle() was ["+c+"] aka NOT "+0+"px; used setMaxWidth() to store MAXWIDTH so it has now been SET to "+d()+" (before shrinking it)"),g.maxWidth=0,g.setProperty("max-width","0px","important"),g.setProperty("width","0px","important"))})()}();
const NULL = null;
const TEXT_PROP = "innerText";
// get PARENT element (# levels above startingElement)
const above = (startingElement, levels = 1) => {
let el = startingElement;
while (levels-- && (el = el?.parentElement));
return el || NULL;
};
const testRegEx = (pattern, str) => {
return pattern.test(str ?? "");
};
const getConfigureButtons = () => {
const selButtonSpans = "button > span > span + span.sr-only";
const collButtonSpans = document.querySelectorAll(selButtonSpans);
const collConfigureButtons = Array.from(collButtonSpans)
.filter( (el, i) => {
const text = el[TEXT_PROP];
const isTextConfigure = testRegEx(/Configure/, text);
console.log({ isTextConfigure, text, el, i });
return isTextConfigure;
} );
console.log({ collConfigureButtons, collButtonSpans, selButtonSpans });
return collConfigureButtons;
};
const getCloseButton = (elParent) => {
let elCloseButton = NULL;
let elButton;
let dataset;
const elGrandParent = above(elParent, 1);
const collButtons = elGrandParent.querySelectorAll("button");
for (elButton of collButtons) {
dataset = elButton.dataset;
console.log({ dataset, elButton });
if (
!testRegEx(/\S/, elButton[TEXT_PROP])
&& dataset?.color == "secondary"
&& dataset?.size == "md"
&& dataset?.gutterSize == "md"
) {
elCloseButton = elButton;
break;
};
};
console.log({ elCloseButton, collButtons, elGrandParent, elParent });
return elCloseButton;
};
const MS_BEFORE_CLOSING_CONFIGURATION_SLIDER = 500;
const closeConfigureSlider = async () =>
{
// close "Configure" if already opened as slide-in panel version
// NOTE: this is required because it is possible to have BOTH versions visible at the same time!
// 1. check if any of the "Configure" buttons are located inside the slide-in panel version
// 2. early exit if not, otherwise wait for completion of auto-clicking the "🡢|" button to close it (slide-out)
return new Promise( resolve => {
let elConfigure;
let collConfigureButtonsOriginal = getConfigureButtons();
let sliderCount = 0;
for (elConfigure of collConfigureButtonsOriginal) {
// get the "Configure" button's PARENT element (11 levels above us), to identify if the "slide-in" version
// (based on elParentDiv's classText NOT containing "flex h-full", and then the label-less button's unique color + size + gutterSize)
const elParentDiv = above(elConfigure, 11);
const classText = elParentDiv?.className;
const isSlider = !testRegEx(/flex/, classText) && !testRegEx(/h-full/, classText);
console.log({ classText, isSlider, elParentDiv, elConfigure });
if (isSlider && ++sliderCount) {
getCloseButton(elParentDiv)?.click?.();
};
};
console.log({ sliderCount, collConfigureButtonsOriginal, MS_BEFORE_CLOSING_CONFIGURATION_SLIDER });
return setTimeout(
() => resolve( getConfigureButtons() ),
sliderCount && MS_BEFORE_CLOSING_CONFIGURATION_SLIDER
);
} );
};
const getDivToResize = (collConfigureButtons) => {
const elConfigureFirst = collConfigureButtons[0];
// get the "Configure" button's PARENT element (10 levels above us)
const configureDiv = above(elConfigureFirst, 10);
if (!configureDiv) {
console.log({ elConfigureFirst, collConfigureButtons });
} else {
console.log({ configureDiv });
// RESULT = <div class="gEVJr"> (parent = <div class="flex h-full">, grandparent = <div class="uNbBQ" style="--composer-height: 124px;">)
};
return configureDiv;
};
// temp "storage" hack; easier to troubleshoot console.log(document.location) than console.log(globalThis)
const loc = location;
const getMaxWidth = () => {
return loc.W;
};
const setMaxWidth = (value) => {
loc.W = value;
};
const toggleMaxWidth = (collConfigureButtons) => {
const newSize = 0;
const configureDiv = getDivToResize(collConfigureButtons);
if (!configureDiv) {
return;
};
const computedMaxWidth = getComputedStyle(configureDiv).maxWidth;
console.log({ computedMaxWidth });
const isShrunk = computedMaxWidth == newSize + "px";
const style = configureDiv.style;
if (isShrunk) {
// restore previous value (so we get TOGGLE effect)
console.log( "\n"
+ "isShrunk=" + isShrunk
+ "; [restore previous value]"
+ "; computedMaxWidth via getComputedStyle() WAS " + newSize + "px"
+ "; used getMaxWidth() to GET stored MAXWIDTH via getMaxWidth() which was " + getMaxWidth() + " (before we expand it back)"
);
// remove the inline style's max-width prop
style.removeProperty("max-width");
// clean up the inline width prop too
style.removeProperty("width");
setMaxWidth(NULL);
} else {
// store current value (so we get TOGGLE effect)
setMaxWidth(computedMaxWidth != "none" ? computedMaxWidth : "");
console.log( "\n"
+ "isShrunk=" + isShrunk
+ "; [store current value]"
+ "; computedMaxWidth via getComputedStyle() was [" + computedMaxWidth + "] aka NOT " + newSize + "px"
+ "; used setMaxWidth() to store MAXWIDTH so it has now been SET to " + getMaxWidth() + " (before shrinking it)"
);
// forcefully set the max-width prop to 50px, even if !important is used
style.setProperty("max-width", newSize + "px", "important");
// set the width prop to 50px as well, just in case
style.setProperty("width", newSize + "px", "important");
};
};
// console.clear();
closeConfigureSlider().then(toggleMaxWidth);
@DarrenSem
Copy link
Author

https://gist.github.com/DarrenSem/4d37711fb71a484b6ed2356c60e3c94a = above.js (PARENT element, levels = #) + next.js (SIBLING element, levels = #) helper functions instead of foo.parentElement.parentElement.parentElement etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment