// ==UserScript==
// @name Search Google Maps Back
// @name:fr Retour de Google Maps Dans Recherche
// @namespace http://tampermonkey.net/
// @version 2024-10-22
// @description This script bring google maps button back, makes search maps (big/mini and micro one) clickable and adds Open in Maps button back. It might not work anymore in a few months and need an update so feel free to update it whenever you want, I'll try to do it whenever I can.
// @description:fr Ce script remet le bouton google maps, rend les cartes de recherche (grandes/mini et micro) cliquables et ajoute le bouton Open in Maps (Ouvrir sur Maps) aux grandes cartes. Il se peut qu'il ne fonctionne plus dans quelques mois et qu'une mise à jour soit nécessaire, alors n'hésitez pas à le mettre à jour quand vous le souhaitez, pour ma part je le ferai dès que possible.
// @author Mimouy | Mimo (Mohamed) Bouyakhlef : https://github.com/mimouy
// @match https://www.google.com/search*
// @include https://www.google.tld/search*
// @icon https://i.ibb.co/RcMNxV3/gmback.jpg
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
function addMapsButton() {
// Find the list container of existing tabs
const tabsContainer = document.querySelector('.crJ18e');
//Get the search query
const searchQuery = new URLSearchParams(window.location.search).get('q');
//Use the search query as a link
const mapsLink = `//maps.google.com/maps?q=${searchQuery}`;
// Adding the Maps button to the tab if not already in
if (tabsContainer) {
// Check if already has a Maps button
let hasGoogleMapsLink = false;
tabsContainer.querySelectorAll('a').forEach(link => {
if (link.href.includes('google.com/maps')) {
hasGoogleMapsLink = true;
}
});
if (hasGoogleMapsLink) {
//Already has a Maps button
} else {
// Create the Maps button elements (updated)
const mapsListItem = document.createElement('div');
mapsListItem.jsname = 'VIftV';
// mapsListItem.classList.add('Ap1Qsc');
mapsListItem.setAttribute('role', 'listitem');
// Replace this entire section with the provided <a> element
const mapsButton = document.createElement('a');
mapsButton.href = mapsLink;
mapsButton.jsname = "ONH4Gc";
mapsButton.classList.add("LatpMc");
mapsButton.classList.add("nPDzT");
mapsButton.classList.add("T3FoJb");
mapsButton.dataset.navigation = "server";
mapsButton.dataset.hveid = "CAEQCA";
//mapsButton.textContent = "Maps"; // Set the inner text if need to
const mapsButtonText = document.createElement('div');
mapsButtonText.jsname = "bVqjv";
mapsButtonText.classList.add("YmvwI");
mapsButtonText.textContent = "Maps";
mapsButton.appendChild(mapsButtonText);
// Append the mapsButton to the list item
mapsListItem.appendChild(mapsButton);
// Insert the Maps button after the All button
const firstTabsChild = tabsContainer.firstElementChild;
firstTabsChild.insertBefore(mapsButton, firstTabsChild.children[1]);
}
}
// Find the small map element if any, to map it clickable
const smallMapElement = document.querySelector('.KY6ERe');
if (smallMapElement) {
// Look for the links (or div) parent
const targetElement = smallMapElement.querySelector('.ZqGZZ.xP81Pd');
//Look for the micro map image
if (targetElement) {
//Is the mini map image a link ?
if (targetElement.tagName.toLowerCase() === 'a') {
//Mini map is already a link, nothing to do
}else{
//Create a new Map image which will be a link
let newMapImage = document.createElement('a');
let parent = targetElement.parentNode;
let children = targetElement.childNodes;
// Copy all attributes and childs to the newMapImage
Array.prototype.forEach.call(targetElement.attributes, function (attr) {
newMapImage.setAttribute(attr.name, attr.value);
});
Array.prototype.forEach.call(children, function (elem) {
newMapImage.appendChild(elem);
});
newMapImage.href = mapsLink;
//Replace old image by the new (link) one
parent.replaceChild(newMapImage, targetElement);
}
} else {
//
}
} else {
//No small map
}
// Find the micro map element if any, to make it clickable
const microMapElement = document.querySelector('.Ggdpnf.kno-fb-ctx');
if (microMapElement) {
// Look for the link's (which is a div if none) parent
const microTargetElement = microMapElement.querySelector('* > * > a');
if (microTargetElement) {
if (microTargetElement.tagName.toLowerCase() === 'a' && microTargetElement.hasAttribute('href')) {
//Micro map is already a link, nothing to do
}else{
//Micro map is not a link (do not have a href)
microTargetElement.href = mapsLink;
// Create the Zoom icon div
const newDiv = document.createElement('div');
newDiv.setAttribute('jscontroller', 'hnlzI');
newDiv.setAttribute('class', 'sEtYzd duf-h TUOsUe BSRXQc sxd9Pc');
newDiv.setAttribute('jsaction', 'KQB0gd;rcuQ6b:npT2md');
newDiv.setAttribute('data-ved', '2ahUKEwjo44_p66CJAxXtFFkFHcHlDIUQkNEBegQIUxAJ');
// Create img element (zoom icon) inside the div
const img = document.createElement('img');
img.setAttribute('class', 'kf0xcf oYQBg FIfWIe Tbiej u60jwe');
img.setAttribute('src', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABIAgMAAAAog1vUAAAACVBMVEUAAACaoKaaoKZGj4K4AAAAA3RSTlMA/58J4rd5AAAAdUlEQVR4AeXPAQaEYBgG4RGLDhJ7nIVJgI7SJdrzBsA/ABF6AYPH9/GufVRvSsCZNJk0Ny2roTZD7YY6DIWhMBSGwlAYCkMlHYz7k315er2gd+YbYW5aVsZ0bmOa3IcUCkNhKAyFoTAUhsJQGApDofq7Ib1hF4lkK+5yFPqsAAAAAElFTkSuQmCC');
img.setAttribute('alt', '');
img.setAttribute('height', '24');
img.setAttribute('width', '24');
img.setAttribute('data-csiid', 'nQAXZ6ihIe2p5NoPwcuzqAg_9');
img.setAttribute('data-atf', '0');
newDiv.style.cssText = `
background-color: rgba(48, 49, 52, 0.8);
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.2);
height: 32px;
width: 32px;
display: block;
outline: 0;
position: absolute;
top: 4px;
vertical-align: middle;
right: 4px;
`;
// Append the img to the Zoom div
newDiv.appendChild(img);
// Find the gImg element
const gImgElement = microTargetElement.querySelector('g-img');
// Insert the zoom icon right after the gImh element so it shows on it (top right)
if (gImgElement) {
gImgElement.parentNode.insertBefore(newDiv, gImgElement.nextSibling);
} else {
//no gImg found !?
}
}
} else {
//Didn't find the link !?
}
} else {
//No small map
}
//lu map section (when yout type an exact address)
const addressMapElement = document.querySelector('.lu_map_section');
if (addressMapElement) {
// Searching for the link containing "maps/dir/"
const adirElement = document.querySelector('a[href*="maps/dir/"]');
if (adirElement) {
// Clone link
const clonedAElement = adirElement.cloneNode(true);
clonedAElement.href = mapsLink;
// Insert the clone which will become a Map button
adirElement.parentNode.insertBefore(clonedAElement, adirElement.nextSibling);
// Searching the "Direction" text
const targetDiv = clonedAElement.querySelector('.QuU3Wb.sjVJQd');
if (targetDiv) {
// Changing "Direction" to "Map"
const newDiv = document.createElement('div');
newDiv.textContent = 'Map';
targetDiv.innerHTML = '';
targetDiv.appendChild(newDiv);
// Creating Map SVG element
const svgElement = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svgElement.setAttribute('focusable', 'false');
svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
svgElement.setAttribute('viewBox', '0 0 24 24');
svgElement.style.width = '60%';
svgElement.style.fill = '#8ab4f8';
const pathElement = document.createElementNS('http://www.w3.org/2000/svg', 'path');
pathElement.setAttribute('d', 'M20.5 3l-.16.03L15 5.1 9 3 3.36 4.9c-.21.07-.36.25-.36.48V20.5c0 .28.22.5.5.5l.16-.03L9 18.9l6 2.1 5.64-1.9c.21-.07.36-.25.36-.48V3.5c0-.28-.22-.5-.5-.5zM15 19l-6-2.11V5l6 2.11V19z');
svgElement.appendChild(pathElement);
//Searching the icon div
const svgDiv = clonedAElement.querySelector('.kHtcsd');
if(svgDiv){
svgDiv.innerHTML = '';
svgDiv.appendChild(svgElement);
}
}
} else {
//No direction link found ?
}
}else{
//No lu_map_section found
}
//Big expandable map change direction to open in maps
// Wait for the page to load entirely
window.addEventListener('load', () => {
// Find the big map's buttons div class="EeWPwe", which contains Direction and Open in maps
const bigMapButtonsElement = document.querySelector('.EeWPwe');
if (bigMapButtonsElement) {
// Find all bigMapButtonsElement a childs (which are Direction and Open in Maps buttons)
const aElements = bigMapButtonsElement.querySelectorAll('a');
// If there is only one <a> = No Open in maps button, only Direction one
if (aElements.length === 1) {
// Clone it
const clonedAElement = aElements[0].cloneNode(true);
// Change the link for Direction to Maps one
if (clonedAElement.href.includes('maps/dir/')) {
clonedAElement.href = mapsLink;
}
// Add the clone
aElements[0].parentNode.insertBefore(clonedAElement, aElements[0].nextSibling);
// Find the element with "m0MNmc" which contains text "Direction" and change it to Open in Maps (Sorry for ppl who have their google in other langages)
const m0MNmcSpan = clonedAElement.querySelector('.m0MNmc');
if (m0MNmcSpan) {
m0MNmcSpan.textContent = 'Open in Maps'; //You can put whatever you want here, if you want it to show in another langage
}
// Find the "POUQwd WN4Zxc" span in the clone, which is the icon one, and change it to Maps icon
const pouqwdElement = clonedAElement.querySelector('.POUQwd.WN4Zxc');
if (pouqwdElement) {
// Create maps icon
const newDiv = document.createElement('div');
newDiv.className = 'POUQwd WN4Zxc';
newDiv.innerHTML = `
<span>
<span style="height:20px;line-height:20px;width:20px" class="z1asCe Y5lOv">
<svg focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M20.5 3l-.16.03L15 5.1 9 3 3.36 4.9c-.21.07-.36.25-.36.48V20.5c0 .28.22.5.5.5l.16-.03L9 18.9l6 2.1 5.64-1.9c.21-.07.36-.25.36-.48V3.5c0-.28-.22-.5-.5-.5zM15 19l-6-2.11V5l6 2.11V19z"></path>
</svg>
</span>
</span>
`;
// Replace it
pouqwdElement.parentNode.replaceChild(newDiv, pouqwdElement);
}
} else if (aElements.length > 1) {
//There are two elements so I think there's no need to do anything, as the second one must be "Open in Maps" button
} else {
//No <a> found ?
}
}else {
//No "EeWPwe" found ?
}
});
}
// Call the function to add the button
addMapsButton();
})();