Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name Google Maps Addon (Simplified ES6+)
- // @namespace http://tampermonkey.net/
- // @version 2025-06-19
- // @description Restore Maps button on Google Search + update map thumbnail link in preview. Handles AJAX/SPAs and Tampermonkey GUI settings. Static English labels, optimized logic, uses stable attribute selector for map preview container.
- // @author You
- // @match https://www.google.com/search*
- // @grant GM_registerMenuCommand
- // @grant GM_getValue
- // @grant GM_setValue
- // ==/UserScript==
- (() => {
- 'use strict';
- // =======================
- // Configuration
- // =======================
- const defaultSettings = {
- enableMapsButton: true,
- enableThumbnailUpdate: true
- };
- // Simple wrapper around GM_getValue/GM_setValue with defaults
- const settings = {
- get: key => GM_getValue(key, defaultSettings[key]),
- set: (key, value) => GM_setValue(key, value)
- };
- // Register Tampermonkey menu items to toggle features
- const registerSettingsMenu = () => {
- GM_registerMenuCommand(
- `Maps Button: ${settings.get('enableMapsButton') ? 'ON' : 'OFF'}`,
- () => toggleSetting('enableMapsButton')
- );
- GM_registerMenuCommand(
- `Map Thumbnail Update: ${settings.get('enableThumbnailUpdate') ? 'ON' : 'OFF'}`,
- () => toggleSetting('enableThumbnailUpdate')
- );
- };
- // Toggle a boolean setting and reload to apply
- const toggleSetting = key => {
- const newValue = !settings.get(key);
- settings.set(key, newValue);
- alert(`Setting changed: ${key} → ${newValue ? 'ON' : 'OFF'}. Reloading...`);
- location.reload();
- };
- // =======================
- // Utility functions
- // =======================
- const getQuery = () => new URLSearchParams(location.search).get('q') || '';
- // Build the Maps URL for the current query
- const buildMapsHref = () => `https://maps.google.com/maps?q=${encodeURIComponent(getQuery())}`;
- // =======================
- // Create and insert Maps button in horizontal tabs
- // =======================
- const createMapsButton = href => {
- // Reuse Google’s classes for visual consistency
- const a = document.createElement('a');
- a.className = 'nPDzT T3FoJb gpt-maps-btn';
- a.href = href;
- a.target = '_blank';
- a.rel = 'noopener noreferrer';
- const div = document.createElement('div');
- div.className = 'GKS7s';
- div.setAttribute('jsname', 'bVqjv');
- const span = document.createElement('span');
- span.className = 'FMKtTb UqcIvb';
- span.setAttribute('jsname', 'pIvPIe');
- span.style.fontWeight = 'bold';
- span.textContent = 'Maps'; // static English label
- div.appendChild(span);
- a.appendChild(div);
- return a;
- };
- const insertMapsButton = () => {
- if (!settings.get('enableMapsButton')) return;
- const tabs = document.querySelector('.IUOThf');
- if (!tabs || tabs.querySelector('.gpt-maps-btn')) return;
- const href = buildMapsHref();
- const button = createMapsButton(href);
- tabs.appendChild(button);
- };
- // =======================
- // Observe and update map thumbnail in the right-side preview
- // =======================
- const observeMapThumbnail = () => {
- if (!settings.get('enableThumbnailUpdate')) return;
- const updateThumbs = () => {
- const href = buildMapsHref();
- // Find all containers with stable attribute jscontroller="lvAdvf"
- document.querySelectorAll('[jscontroller="lvAdvf"]').forEach(container => {
- const thumbLink = container.querySelector('a');
- if (!thumbLink) return;
- // Skip if already correct
- if (thumbLink.href === href) return;
- // Update link
- Object.assign(thumbLink, {
- href,
- target: '_blank',
- rel: 'noopener noreferrer'
- });
- // Add a label if not already present
- // Use a distinctive class to avoid duplicating
- if (!thumbLink.querySelector('.z3dsh')) {
- const label = document.createElement('span');
- label.className = 'z3dsh';
- label.textContent = 'View on Maps'; // static English label
- thumbLink.appendChild(label);
- }
- });
- };
- // Observe DOM changes so that if Google re-renders preview, we update again
- const observer = new MutationObserver(() => {
- updateThumbs();
- });
- observer.observe(document.body, { childList: true, subtree: true });
- // Initial run
- updateThumbs();
- };
- // =======================
- // Handle dynamic SPA changes for the horizontal tabs
- // =======================
- const observePageChanges = () => {
- const observer = new MutationObserver(() => {
- insertMapsButton();
- });
- observer.observe(document.body, { childList: true, subtree: true });
- };
- // Wait until Google’s horizontal tabs container appears, then insert button
- const waitForGoogleTabs = () => {
- const interval = setInterval(() => {
- if (document.querySelector('.IUOThf')) {
- clearInterval(interval);
- insertMapsButton();
- }
- }, 250);
- };
- // =======================
- // Initialization
- // =======================
- registerSettingsMenu();
- waitForGoogleTabs();
- observePageChanges();
- observeMapThumbnail();
- })();
Add Comment
Please, Sign In to add comment