Last active
October 27, 2025 04:21
-
-
Save wpeasy/741114f7dde704c9274c1b968e3ec054 to your computer and use it in GitHub Desktop.
Advanced Themer, Move
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 characters
| /* UPDATED 23/10/2025 */ | |
| (() => { | |
| // ==================================== | |
| // Detect if in Bricks Builder Editor | |
| // ==================================== | |
| const isInBricksEditor = () => { | |
| // Check for bricks=run query parameter (most reliable) | |
| const urlParams = new URLSearchParams(window.location.search); | |
| return urlParams.get('bricks') === 'run'; | |
| }; | |
| // ==================================== | |
| // Run your code only in Bricks editor | |
| // ==================================== | |
| if (isInBricksEditor()) { | |
| // YOUR CODE HERE | |
| // Add your editor-specific code below | |
| } | |
| // ==================================== | |
| // Or wait for DOM ready | |
| // ==================================== | |
| document.addEventListener('DOMContentLoaded', () => { | |
| if (isInBricksEditor()) { | |
| // YOUR CODE HERE | |
| } | |
| }); | |
| // ==================================== | |
| // Wait for Bricks editor to initialize | |
| // ==================================== | |
| if (isInBricksEditor()) { | |
| // State management | |
| const STORAGE_KEY = 'bricks_move_sticky_css_enabled'; | |
| let isEnabled = localStorage.getItem(STORAGE_KEY) === 'true'; | |
| let mainObserver = null; | |
| let resizeObserver = null; | |
| let styleObserver = null; | |
| const cleanupObservers = () => { | |
| if (resizeObserver) { | |
| resizeObserver.disconnect(); | |
| resizeObserver = null; | |
| } | |
| if (styleObserver) { | |
| styleObserver.disconnect(); | |
| styleObserver = null; | |
| } | |
| }; | |
| const setupObserver = () => { | |
| // Set up MutationObserver for #brxcStructureBottomContainer | |
| const targetElement = document.querySelector('#bricks-structure main #brxcStructureBottomContainer'); | |
| if (targetElement) { | |
| mainObserver = new MutationObserver((mutations) => { | |
| if (!isEnabled) return; // Skip if disabled | |
| mutations.forEach((mutation) => { | |
| // Check for added nodes | |
| mutation.addedNodes.forEach((node) => { | |
| if (node.nodeType === 1 && node.id === 'brxc-sticky-css') { | |
| const iframeWrapper = document.querySelector('#bricks-builder-iframe-wrapper'); | |
| if (iframeWrapper) { | |
| // Append as last child of the wrapper | |
| iframeWrapper.appendChild(node); | |
| // Inject CSS for styling .brxc-action elements | |
| const styleId = 'brxc-sticky-custom-styles'; | |
| if (!document.getElementById(styleId)) { | |
| const style = document.createElement('style'); | |
| style.id = styleId; | |
| style.textContent = ` | |
| #brxc-sticky-css .brxc-action { | |
| color: var(--builder-color-accent) !important; | |
| fill: var(--builder-color-accent) !important; | |
| } | |
| `; | |
| document.head.appendChild(style); | |
| } | |
| const builderIframe = iframeWrapper.querySelector('iframe#bricks-builder-iframe'); | |
| if (builderIframe) { | |
| // Clean up any existing observers first | |
| cleanupObservers(); | |
| // Function to calculate and set iframe height | |
| const updateIframeHeight = () => { | |
| const stickyCssHeight = node.offsetHeight; | |
| builderIframe.setAttribute('style', `height: calc(100% - ${stickyCssHeight + 7}px);`); | |
| }; | |
| // Set initial height | |
| updateIframeHeight(); | |
| // Watch for height changes on #brxc-sticky-css | |
| resizeObserver = new ResizeObserver(() => { | |
| if (isEnabled) { | |
| updateIframeHeight(); | |
| } | |
| }); | |
| resizeObserver.observe(node); | |
| // Also watch for style attribute changes (for immediate updates) | |
| styleObserver = new MutationObserver(() => { | |
| if (isEnabled) { | |
| updateIframeHeight(); | |
| } | |
| }); | |
| styleObserver.observe(node, { | |
| attributes: true, | |
| attributeFilter: ['style'] | |
| }); | |
| } | |
| } | |
| } | |
| }); | |
| // Check for removed nodes | |
| mutation.removedNodes.forEach((node) => { | |
| if (node.nodeType === 1 && node.id === 'brxc-sticky-css') { | |
| const iframeWrapper = document.querySelector('#bricks-builder-iframe-wrapper'); | |
| if (iframeWrapper) { | |
| const builderIframe = iframeWrapper.querySelector('iframe#bricks-builder-iframe'); | |
| if (builderIframe) { | |
| builderIframe.style.height = ''; | |
| } | |
| } | |
| } | |
| }); | |
| }); | |
| }); | |
| // Start observing | |
| mainObserver.observe(targetElement, { | |
| childList: true, // Watch for direct children changes | |
| subtree: true // Watch all descendants | |
| }); | |
| return true; | |
| } else { | |
| return false; | |
| } | |
| }; | |
| // Toggle function | |
| window.toggleMoveStickyCSS = () => { | |
| isEnabled = !isEnabled; | |
| localStorage.setItem(STORAGE_KEY, isEnabled); | |
| // Update button state | |
| const button = document.querySelector('.brxc-item[data-balloon="Move Sticky CSS"]'); | |
| if (button) { | |
| if (isEnabled) { | |
| button.classList.add('active'); | |
| // If sticky CSS already exists, move it immediately | |
| const stickyElement = document.querySelector('#brxc-sticky-css'); | |
| if (stickyElement) { | |
| const iframeWrapper = document.querySelector('#bricks-builder-iframe-wrapper'); | |
| if (iframeWrapper && !iframeWrapper.contains(stickyElement)) { | |
| iframeWrapper.appendChild(stickyElement); | |
| // Inject CSS | |
| const styleId = 'brxc-sticky-custom-styles'; | |
| if (!document.getElementById(styleId)) { | |
| const style = document.createElement('style'); | |
| style.id = styleId; | |
| style.textContent = ` | |
| #brxc-sticky-css .brxc-action { | |
| color: var(--builder-color-accent) !important; | |
| fill: var(--builder-color-accent) !important; | |
| } | |
| `; | |
| document.head.appendChild(style); | |
| } | |
| const builderIframe = iframeWrapper.querySelector('iframe#bricks-builder-iframe'); | |
| if (builderIframe) { | |
| const updateIframeHeight = () => { | |
| const stickyCssHeight = stickyElement.offsetHeight; | |
| builderIframe.setAttribute('style', `height: calc(100% - ${stickyCssHeight + 7}px);`); | |
| }; | |
| updateIframeHeight(); | |
| const resizeObserver = new ResizeObserver(() => { | |
| updateIframeHeight(); | |
| }); | |
| resizeObserver.observe(stickyElement); | |
| const styleObserver = new MutationObserver(() => { | |
| updateIframeHeight(); | |
| }); | |
| styleObserver.observe(stickyElement, { | |
| attributes: true, | |
| attributeFilter: ['style'] | |
| }); | |
| } | |
| } | |
| } | |
| } else { | |
| button.classList.remove('active'); | |
| } | |
| } | |
| // If disabling, move sticky CSS back to original location | |
| if (!isEnabled) { | |
| cleanupObservers(); | |
| const stickyElement = document.querySelector('#brxc-sticky-css'); | |
| const originalContainer = document.querySelector('#bricks-structure main #brxcStructureBottomContainer'); | |
| const iframeWrapper = document.querySelector('#bricks-builder-iframe-wrapper'); | |
| const builderIframe = iframeWrapper?.querySelector('iframe#bricks-builder-iframe'); | |
| // Reset iframe BEFORE moving element | |
| if (builderIframe) { | |
| builderIframe.removeAttribute('style'); | |
| } | |
| // Then move element back | |
| if (stickyElement && originalContainer && !originalContainer.contains(stickyElement)) { | |
| originalContainer.appendChild(stickyElement); | |
| } | |
| // Reset iframe again AFTER moving element (in case something triggered) | |
| setTimeout(() => { | |
| if (builderIframe) { | |
| builderIframe.removeAttribute('style'); | |
| } | |
| }, 100); | |
| } | |
| }; | |
| // Try to set up observer immediately | |
| if (!setupObserver()) { | |
| // If not ready, wait for DOM and try again | |
| document.addEventListener('DOMContentLoaded', () => { | |
| if (!setupObserver()) { | |
| // If still not ready, wait for full load | |
| window.addEventListener('load', () => { | |
| setTimeout(() => { | |
| setupObserver(); | |
| }, 500); | |
| }); | |
| } | |
| }); | |
| } | |
| // Add custom button to panel header | |
| const addPanelButton = () => { | |
| const panelActions = document.querySelector('#bricks-structure #bricks-panel-header .actions'); | |
| // Check if Sticky CSS button exists and is active | |
| const stickyCssButton = panelActions?.querySelector('[data-balloon="Sticky CSS"]'); | |
| if (!stickyCssButton || !stickyCssButton.classList.contains('active')) { | |
| return; // Don't show our button if Sticky CSS is not active | |
| } | |
| if (panelActions && !document.querySelector('.brxc-item[data-balloon="Move Sticky CSS"]')) { | |
| const li = document.createElement('li'); | |
| li.className = isEnabled ? 'brxc-item active' : 'brxc-item'; | |
| li.setAttribute('data-balloon', 'Move Sticky CSS'); | |
| li.setAttribute('data-balloon-pos', 'bottom'); | |
| li.onclick = () => window.toggleMoveStickyCSS(); | |
| li.innerHTML = `<span class="bricks-svg-wrapper"><svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" style="fill:currentColor;fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2" viewBox="0 0 24 24"><path d="M3.495 1.754c-.21 0-.42.072-.56.199a.51.51 0 0 0-.18.471l2 13.555c.03.232.23.423.51.495l6 1.595c.14.04.3.04.44 0l7-1.595c.29-.064.5-.263.54-.502l2-13.556a.52.52 0 0 0-.18-.471.85.85 0 0 0-.56-.199h-17zm4 3.19c-.41 0-.75.271-.75.598s.34.598.75.598h5.98l-5.83 2.464c-.3.127-.46.406-.38.669.08.264.38.455.73.455h7.17l-.37 2.926-2.8.638-2.8-.638-.15-1.188c-.04-.327-.41-.566-.82-.534s-.71.327-.67.654l.2 1.595c.03.239.24.446.54.518l3.5.797c.14.032.28.032.41 0l3.5-.797c.3-.064.51-.271.54-.518l.5-3.987a.54.54 0 0 0-.19-.463.83.83 0 0 0-.56-.199h-4.98l5.83-2.464c.3-.128.46-.407.38-.67s-.38-.454-.73-.454z" style="fill:currentColor"/><path d="M3.597 21.62a1 1 0 0 1 0-2h16.217a1 1 0 0 1 0 2z"/></svg></span>`; | |
| panelActions.appendChild(li); | |
| } | |
| }; | |
| // Try to add button after a delay to ensure panel is loaded | |
| setTimeout(addPanelButton, 1000); | |
| // Also try on window load as fallback | |
| window.addEventListener('load', () => { | |
| setTimeout(addPanelButton, 500); | |
| }); | |
| // Watch for changes to the Sticky CSS button to show/hide our button | |
| const watchStickyCssButton = () => { | |
| const panelActions = document.querySelector('#bricks-structure #bricks-panel-header .actions'); | |
| if (!panelActions) { | |
| // Retry if panel not found | |
| setTimeout(watchStickyCssButton, 500); | |
| return; | |
| } | |
| const checkAndUpdateButton = () => { | |
| const ourButton = document.querySelector('.brxc-item[data-balloon="Move Sticky CSS"]'); | |
| const stickyCssButton = panelActions.querySelector('[data-balloon="Sticky CSS"]'); | |
| if (stickyCssButton && stickyCssButton.classList.contains('active')) { | |
| if (!ourButton) { | |
| addPanelButton(); | |
| } | |
| } else { | |
| if (ourButton) { | |
| ourButton.remove(); | |
| } | |
| // Reset everything when Sticky CSS button is toggled off | |
| const stickyElement = document.querySelector('#brxc-sticky-css'); | |
| const originalContainer = document.querySelector('#bricks-structure main #brxcStructureBottomContainer'); | |
| const iframeWrapper = document.querySelector('#bricks-builder-iframe-wrapper'); | |
| // Move sticky element back to original location if it was moved | |
| if (stickyElement && originalContainer && !originalContainer.contains(stickyElement)) { | |
| originalContainer.appendChild(stickyElement); | |
| } | |
| // Reset iframe height to 100% | |
| if (iframeWrapper) { | |
| const builderIframe = iframeWrapper.querySelector('iframe#bricks-builder-iframe'); | |
| if (builderIframe) { | |
| builderIframe.removeAttribute('style'); | |
| } | |
| } | |
| // Also disable our toggle if it was enabled | |
| if (isEnabled) { | |
| isEnabled = false; | |
| localStorage.setItem(STORAGE_KEY, 'false'); | |
| } | |
| } | |
| }; | |
| // Watch for any mutations in the panel actions area | |
| const observer = new MutationObserver(() => { | |
| checkAndUpdateButton(); | |
| }); | |
| observer.observe(panelActions, { | |
| attributes: true, | |
| childList: true, | |
| subtree: true, | |
| attributeFilter: ['class'] | |
| }); | |
| // Also check initially | |
| checkAndUpdateButton(); | |
| // Periodically check as backup (in case mutation observer misses something) | |
| setInterval(checkAndUpdateButton, 2000); | |
| }; | |
| setTimeout(watchStickyCssButton, 1000); | |
| window.addEventListener('load', () => { | |
| setTimeout(watchStickyCssButton, 500); | |
| }); | |
| // YOUR OTHER CODE HERE (runs in editor) | |
| } else { | |
| // YOUR FRONTEND CODE HERE | |
| } | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment