pastebin - collaborative debugging tool
kpaste.net RSS


Maps button
Posted by Anonymous on Tue 8th Oct 2024 20:14
raw | new post
view followups (newest first): Maps button by Anonymous

  1. // ==UserScript==
  2. // @name         Restore Google Maps Button to Search Bar
  3. // @namespace    http://tampermonkey.net/
  4. // @version      1.0
  5. // @description  Restores the "Maps" button to the Google search bar.
  6. // @author       n1ghtmare_13
  7. // @match        *://www.google.com/*
  8. // @match        *://www.google.pl/*
  9. // @grant        none
  10. // @run-at       document-start
  11. // ==/UserScript==
  12.  
  13. (function () {
  14.     'use strict';
  15.  
  16.     let mapsUrl = '';
  17.     let buttonAdded = false;
  18.     const texts = {
  19.         'Maps': {
  20.             'en': 'Maps',
  21.             'pl': 'Mapy'
  22.         },
  23.         'Open in Maps': {
  24.             'en': 'Open in Maps',
  25.             'pl': 'Otwórz w mapach'
  26.         }
  27.     };
  28.  
  29.     function getSearchQuery() {
  30.         return new URLSearchParams(window.location.search).get('q');
  31.     }
  32.  
  33.     function getUserLanguage() {
  34.         return document.documentElement.lang || 'en';
  35.     }
  36.  
  37.     function getText(key) {
  38.         const userLang = getUserLanguage();
  39.         return (texts[key] && texts[key][userLang]) || (texts[key] && texts[key].en) || key;
  40.  
  41.     }
  42.  
  43.     function updateMapsUrl() {
  44.         const searchQuery = getSearchQuery();
  45.         if (searchQuery) {
  46.             mapsUrl = 'https://maps.google.com/maps?q=' + encodeURIComponent(searchQuery);
  47.         }
  48.         console.log('Updated mapsUrl:', mapsUrl);
  49.     }
  50.  
  51.     function insertMapsButton() {
  52.         console.log('Attempting to insert Maps button');
  53.         if (!mapsUrl || buttonAdded) {
  54.             console.log('No mapsUrl or button already added, skipping button insertion');
  55.             return;
  56.         }
  57.  
  58.         const existingMapsButton = document.evaluate(
  59.             "//a[normalize-space(text())='" + getText('Maps') + "']",
  60.             document,
  61.             null,
  62.             XPathResult.FIRST_ORDERED_NODE_TYPE,
  63.             null
  64.         ).singleNodeValue;
  65.  
  66.         if (existingMapsButton && !existingMapsButton.closest('g-popup')) {
  67.             console.log('Updating existing Maps button');
  68.             existingMapsButton.href = mapsUrl;
  69.             buttonAdded = true;
  70.             return;
  71.         }
  72.  
  73.         const referenceAnchor = document.evaluate(
  74.             "//div[@role='navigation']//div[@jsslot]/a | //a[contains(., 'Images')] | //a[contains(., 'Grafika')]",
  75.             document,
  76.             null,
  77.             XPathResult.FIRST_ORDERED_NODE_TYPE,
  78.             null
  79.         ).singleNodeValue;
  80.  
  81.         if (!referenceAnchor) {
  82.             console.log('Reference anchor not found');
  83.             return;
  84.         }
  85.  
  86.         console.log('Reference anchor found:', referenceAnchor);
  87.  
  88.         const mapsAnchor = referenceAnchor.cloneNode(true);
  89.         mapsAnchor.href = mapsUrl;
  90.         mapsAnchor.style.marginLeft = '6px';
  91.  
  92.         const spanOrDiv = mapsAnchor.querySelector('span') || mapsAnchor.querySelector('div');
  93.         if (spanOrDiv) {
  94.             spanOrDiv.textContent = getText('Maps');
  95.             spanOrDiv.style.borderBottom = 'none';
  96.             spanOrDiv.removeAttribute('selected');
  97.         }
  98.  
  99.         referenceAnchor.parentNode.insertBefore(mapsAnchor, referenceAnchor.nextSibling);
  100.         console.log('Maps button inserted');
  101.         buttonAdded = true;
  102.     }
  103.  
  104.     function setMapImageLink() {
  105.         if (!mapsUrl) return;
  106.  
  107.         const luMapElement = document.getElementById('lu_map');
  108.         if (luMapElement) {
  109.             const parentAnchor = luMapElement.closest('a');
  110.             if (parentAnchor) {
  111.                 if (!parentAnchor.href || parentAnchor.href.trim() === "") {
  112.                     parentAnchor.href = mapsUrl;
  113.                 }
  114.             } else {
  115.                 const newAnchor = document.createElement('a');
  116.                 newAnchor.href = mapsUrl;
  117.                 luMapElement.parentNode.insertBefore(newAnchor, luMapElement);
  118.                 newAnchor.appendChild(luMapElement);
  119.             }
  120.         } else {
  121.             const fallbackDiv = document.querySelector('div.V1GY4c');
  122.             if (fallbackDiv) {
  123.                 const imgElement = fallbackDiv.querySelector('img:not([src=""])');
  124.                 if (imgElement && !imgElement.closest('a[href]:not([href=""]):not([href=" "])')) {
  125.                     const newAnchor = document.createElement('a');
  126.                     newAnchor.href = mapsUrl;
  127.                     imgElement.parentNode.insertBefore(newAnchor, imgElement);
  128.                     newAnchor.appendChild(imgElement);
  129.                 }
  130.             }
  131.         }
  132.     }
  133.  
  134.     function addMapsShortcut() {
  135.         if (!mapsUrl) return;
  136.  
  137.         const sodP3bElement = document.querySelector('.SodP3b');
  138.         if (sodP3bElement) {
  139.             const anchor = document.createElement('a');
  140.             Object.assign(anchor.style, {
  141.                 position: 'absolute',
  142.                 top: '5px',
  143.                 left: '5px',
  144.                 padding: '10px',
  145.                 zIndex: '10',
  146.                 borderRadius: '20px',
  147.                 textDecoration: 'none',
  148.                 fontWeight: 'bold',
  149.                 color: getPageTextColor(), // Dynamic text color
  150.                 background: getPageBackgroundColor(), // Dynamic background color
  151.                 boxShadow: '0px 4px 6px rgba(0, 0, 0, 0.1)', // Subtle shadow
  152.                 transition: 'background 0.3s ease, color 0.3s ease' // Smooth transition
  153.             });
  154.             anchor.textContent = getText('Open in Maps');
  155.             anchor.href = mapsUrl;
  156.  
  157.             // Add hover effect for better interactivity
  158.             anchor.addEventListener('mouseenter', function () {
  159.                 anchor.style.background = invertColor(getPageBackgroundColor());
  160.                 anchor.style.color = invertColor(getPageTextColor());
  161.             });
  162.             anchor.addEventListener('mouseleave', function () {
  163.                 anchor.style.background = getPageBackgroundColor();
  164.                 anchor.style.color = getPageTextColor();
  165.             });
  166.  
  167.             sodP3bElement.append(anchor);
  168.         }
  169.     }
  170.  
  171.     function getPageBackgroundColor() {
  172.         const bgColor = window.getComputedStyle(document.body).backgroundColor;
  173.         return isColorDark(bgColor) ? '#f5f5f5' : '#000'; // Light for dark background, dark for light background
  174.     }
  175.  
  176.     function getPageTextColor() {
  177.         const bgColor = window.getComputedStyle(document.body).backgroundColor;
  178.         return isColorDark(bgColor) ? '#333' : '#fff'; // Light text for dark background, dark text for light background
  179.     }
  180.  
  181.     function invertColor(hex) {
  182.         let color = hex.substring(1); // Remove the hash
  183.         if (color.length === 3) {
  184.             color = color.split('').map(c => c + c).join(''); // Convert shorthand to full form
  185.         }
  186.         let inverted = (Number(`0x1${color}`) ^ 0xFFFFFF).toString(16).substr(1).toUpperCase();
  187.         return `#${inverted}`;
  188.     }
  189.  
  190.     function isColorDark(color) {
  191.         const rgb = color.match(/\d+/g).map(Number); // Extract RGB components
  192.         // Calculate brightness (perceived luminance formula)
  193.         const brightness = 0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2];
  194.         return brightness < 128; // Dark color if brightness < 128
  195.     }
  196.  
  197.     function setupMapsButton() {
  198.         if (buttonAdded) {
  199.             console.log('Button already added, skipping setup');
  200.             return;
  201.         }
  202.         console.log('Setting up Maps button');
  203.         updateMapsUrl();
  204.         insertMapsButton();
  205.         setMapImageLink();
  206.         addMapsShortcut();
  207.     }
  208.  
  209.     // Use MutationObserver to detect when the search results are loaded
  210.     const observer = new MutationObserver((mutations, obs) => {
  211.         const searchResults = document.getElementById('search');
  212.         if (searchResults) {
  213.             console.log('Search results detected, setting up Maps button');
  214.             setupMapsButton();
  215.             obs.disconnect(); // Stop observing once we've added the button
  216.         }
  217.     });
  218.  
  219.     // Start observing the document with the configured parameters
  220.     observer.observe(document, {
  221.         childList: true,
  222.         subtree: true
  223.     });
  224.  
  225.     // Also try to set up the button when the DOM is fully loaded
  226.     document.addEventListener('DOMContentLoaded', () => {
  227.         console.log('DOMContentLoaded event fired');
  228.         setupMapsButton();
  229.     });
  230.  
  231.     // Additional fallback for cases where the button might not be added
  232.     window.addEventListener('load', () => {
  233.         console.log('Window load event fired');
  234.         setupMapsButton();
  235.     });
  236. })();

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at