pastebin - collaborative debugging tool
kpaste.net RSS


Maps button
Posted by Anonymous on Tue 8th Oct 2024 20:15
raw | new post
modification of post by Anonymous (view diff)

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

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