Google Maps – One-Click Embed Extractor

Click a floating button → get the clean <iframe> embed code or just the src in the clipboard.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey, Greasemonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्क्रिप्ट व्यवस्थापक एक्स्टेंशन इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्क्रिप्ट व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्टाईल व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

// ==UserScript==
// @name         Google Maps – One-Click Embed Extractor
// @namespace    gmaps-embed
// @version      1.0
// @description  Click a floating button → get the clean <iframe> embed code or just the src in the clipboard.
// @author       Bekkibau
// @match        https://www.google.com/maps/*
// @grant        none
// ==/UserScript==

(() => {
  'use strict';

  // ---- CSS for the popup -------------------------------------------------
  const style = document.createElement('style');
  style.textContent = `
    #grok-embed-popup {
      position: fixed;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      max-width: 90vw;
      max-height: 90vh;
      background: #fff;
      border-radius: 12px;
      box-shadow: 0 8px 32px rgba(0,0,0,.3);
      z-index: 2000;
      font-family: Roboto, Arial, sans-serif;
      overflow: hidden;
      display: flex;
      flex-direction: column;
    }
    #grok-embed-popup header {
      padding: 12px 16px;
      background: #1a73e8;
      color: #fff;
      font-weight: 500;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }
    #grok-embed-popup pre {
      margin: 0;
      padding: 16px;
      background: #f8f9fa;
      overflow: auto;
      flex: 1;
      font-size: 13px;
      line-height: 1.4;
    }
    #grok-embed-popup .actions {
      padding: 12px 16px;
      display: flex;
      gap: 8px;
      justify-content: flex-end;
      background: #fff;
      border-top: 1px solid #dadce0;
    }
    #grok-embed-popup button {
      padding: 6px 12px;
      border: none;
      border-radius: 4px;
      font: inherit;
      cursor: pointer;
    }
    #grok-embed-popup button.copy {
      background: #1a73e8;
      color: #fff;
    }
    #grok-embed-popup button.close {
      background: #dadce0;
      color: #3c4043;
    }
    #grok-embed-popup .actions button.copy.src {
      background: #34a853;
    }
    #grok-embed-popup .actions button.copy:disabled {
      opacity: 0.7;
      cursor: not-allowed;
    }
  `;

  document.head.appendChild(style);

  let popup = null;

  // ---- Show popup with embed code ----------------------------------------
  const showEmbedPopup = (iframeHTML) => {
    popup?.remove();
    popup = null;

    // Extract src attribute
    const srcMatch = iframeHTML.match(/src="([^"]+)"/i);
    const srcURL = srcMatch ? srcMatch[1] : '(not found)';

    const container = document.createElement('div');
    container.id = 'grok-embed-popup';
    container.innerHTML = `
      <header>
        <span>Embed code</span>
        <button class="close" title="Close">✕</button>
      </header>
      <pre>${iframeHTML.replace(/</g, '&lt;').replace(/>/g, '&gt;')}</pre>
      <div class="actions">
        <button class="copy full">Copy Full &lt;iframe&gt;</button>
        <button class="copy src">Copy src URL</button>
        <button class="close">Close</button>
      </div>
    `;

    // Copy handlers
    const copyBtn = (text, btn) => async () => {
      await navigator.clipboard.writeText(text);
      const orig = btn.textContent;
      btn.textContent = 'Copied!';
      btn.disabled = true;
      setTimeout(() => {
        btn.textContent = orig;
        btn.disabled = false;
      }, 1500);
    };

    container.querySelector('.copy.full')
      .addEventListener('click', copyBtn(iframeHTML, container.querySelector('.copy.full')));
    container.querySelector('.copy.src')
      .addEventListener('click', copyBtn(srcURL, container.querySelector('.copy.src')));

    // Close handlers
    const close = () => {
      container.remove();
      popup = null;
    };
    container.querySelectorAll('.close').forEach(b => b.addEventListener('click', close));
    container.addEventListener('click', e => e.target === container && close());

    document.body.appendChild(container);
    popup = container;
  };

  // ---- Create floating button --------------------------------------------
  const btn = document.createElement('button');
  btn.textContent = '📋 Embed';
  Object.assign(btn.style, {
    position: 'fixed',
    right: '20px',
    bottom: '20px',
    zIndex: 9999,
    padding: '10px 14px',
    font: 'bold 14px/1 sans-serif',
    color: '#fff',
    background: '#1a73e8',
    border: 'none',
    borderRadius: '50px',
    boxShadow: '0 2px 6px rgba(0,0,0,.3)',
    cursor: 'pointer',
    userSelect: 'none'
  });
  btn.title = 'Extract Google Maps embed iframe (one click)';
  document.body.appendChild(btn);

  // ---- Find UI elements by meaning ---------------------------------------
  const findShareButton = () => {
    return (
      document.querySelector('button[aria-label="Share"]') ||
      [...document.querySelectorAll('button')]
        .find(b => /share/i.test(b.textContent)) ||
      document.querySelector('button[jsaction*="share"]')
    );
  };

  const findEmbedTab = () => {
    return [...document.querySelectorAll('[role="tab"], button')]
      .find(el => /embed\s*a?\s*map/i.test(el.textContent));
  };

  const waitFor = (condition, timeout = 8000) => new Promise((res, rej) => {
    const start = Date.now();
    const check = () => {
      const el = condition();
      if (el) return res(el);
      if (Date.now() - start > timeout) return rej(new Error('Timeout'));
      requestAnimationFrame(check);
    };
    check();
  });

  // ---- Main extraction routine -------------------------------------------
  const extractEmbed = async () => {
    const ourBtn = document.getElementById('grok-embed-btn');
    if (ourBtn) ourBtn.style.display = 'none';

    try {
      const shareBtn = findShareButton();
      if (!shareBtn) throw new Error('Share button not found');
      shareBtn.click();

      const embedTab = await waitFor(findEmbedTab);
      embedTab.click();

      const input = await waitFor(() =>
        document.querySelector('input[readonly][value*="iframe"][value*="maps/embed"]')
      );

      const div = document.createElement('div');
      div.innerHTML = input.value;
      const iframeHTML = div.innerHTML;

      // Close modal
      const closeModal = () => {
        const closeBtn = document.querySelector('button[aria-label="Close"], button[aria-label="close"]');
        if (closeBtn) return closeBtn.click();

        const backdrop = document.querySelector('[role="dialog"]')?.parentElement;
        if (backdrop) return backdrop.click();

        document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));
      };
      closeModal();

      // Wait for modal to disappear
      await waitFor(() => !document.querySelector('[role="dialog"]'), 1000).catch(() => {});

      // Show popup with embed code
      showEmbedPopup(iframeHTML);

    } catch (e) {
      console.error('Embed extraction error:', e);
    } finally {
      if (ourBtn) ourBtn.style.display = '';
    }
  };

  // ---- Bind click event --------------------------------------------------
  btn.addEventListener('click', extractEmbed);
})();