// ==UserScript==
// @name Google Search sidebar
// @namespace http://tampermonkey.net/
// @version 0.1.3
// @description Add a sidebar on Google search for easier information filtering
// @author Kamiya Minoru
// @match https://www.google.com/*
// @match https://www.google.com.tw/*
// @match https://www.google.co.jp/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
const userLang = navigator.language || navigator.userLanguage;
const i18n = {
'zh-TW': {
languageSection: '語言過濾',
timeSection: '時間過濾',
advancedSearch: '進階搜尋',
languages: {
any: '不限語言搜尋',
zhTW: '以繁體中文搜尋',
zh: '以中文搜尋',
ja: '以日文搜尋',
en: '以英文搜尋'
},
times: {
any: '不限時間',
hour: '過去1小時',
day: '過去24小時',
week: '過去7天',
month: '過去1個月',
months3: '過去3個月',
year: '過去1年'
}
},
'ja': {
languageSection: '言語フィルター',
timeSection: '期間フィルター',
advancedSearch: '検索オプション',
languages: {
any: '言語指定なし',
zhTW: '繁体中国語で検索',
zh: '中国語で検索',
ja: '日本語で検索',
en: '英語で検索'
},
times: {
any: '期間指定なし',
hour: '1時間以内',
day: '24時間以内',
week: '1週間以内',
month: '1か月以内',
months3: '3か月以内',
year: '1年以内'
}
},
'en': {
languageSection: 'Language Filter',
timeSection: 'Time Filter',
advancedSearch: 'Advanced Search',
languages: {
any: 'Any Language',
zhTW: 'Traditional Chinese Only',
zh: 'Chinese Only',
ja: 'Japanese Only',
en: 'English Only'
},
times: {
any: 'Any Time',
hour: 'Past Hour',
day: 'Past 24 Hours',
week: 'Past Week',
month: 'Past Month',
months3: 'Past 3 Months',
year: 'Past Year'
}
}
};
function getLocale() {
if (i18n[userLang]) {
return i18n[userLang];
}
const primaryLang = userLang.split('-')[0];
if (i18n[primaryLang]) {
return i18n[primaryLang];
}
return i18n['en'];
}
const locale = getLocale();
const languageFilters = [
{ text: locale.languages.any, param: '' },
{ text: locale.languages.zhTW, param: '&lr=lang_zh-TW' },
{ text: locale.languages.zh, param: '&lr=lang_zh' },
{ text: locale.languages.ja, param: '&lr=lang_ja' },
{ text: locale.languages.en, param: '&lr=lang_en' }
];
const timeFilters = [
{ text: locale.times.any, param: '' },
{ text: locale.times.hour, param: '&tbs=qdr:h' },
{ text: locale.times.day, param: '&tbs=qdr:d' },
{ text: locale.times.week, param: '&tbs=qdr:w' },
{ text: locale.times.month, param: '&tbs=qdr:m' },
{ text: locale.times.months3, param: '&tbs=qdr:m3' },
{ text: locale.times.year, param: '&tbs=qdr:y' }
];
function createAdvancedSearchLink() {
const link = document.createElement('a');
link.textContent = locale.advancedSearch;
link.href = getAdvancedSearchUrl();
link.style.cssText = `
display: block;
color: #1a73e8;
text-decoration: none;
font-size: 13px;
padding: 8px;
margin-top: 10px;
background: #f8f9fa;
border-radius: 8px;
text-align: center;
transition: background-color 0.2s;
`;
link.addEventListener('mouseover', () => {
link.style.backgroundColor = '#e8f0fe';
});
link.addEventListener('mouseout', () => {
link.style.backgroundColor = '#f8f9fa';
});
return link;
}
function createFilterSection(title, filters) {
const section = document.createElement('div');
section.style.cssText = `
margin: 10px 0;
padding: 8px;
background: #f8f9fa;
border-radius: 8px;
`;
const titleElement = document.createElement('h3');
titleElement.textContent = title;
titleElement.style.cssText = `
margin: 0 0 8px 0;
font-size: 13px;
color: #202124;
font-weight: 500;
`;
section.appendChild(titleElement);
const linkContainer = document.createElement('div');
linkContainer.style.cssText = `
display: flex;
flex-direction: column;
gap: 6px;
`;
filters.forEach(filter => {
const link = document.createElement('a');
link.textContent = filter.text;
link.href = getCurrentUrlWithParam(filter.param);
link.style.cssText = `
color: #1a73e8;
text-decoration: none;
font-size: 12px;
padding: 3px 6px;
border-radius: 4px;
transition: background-color 0.2s;
`;
link.addEventListener('mouseover', () => {
link.style.backgroundColor = '#e8f0fe';
});
link.addEventListener('mouseout', () => {
link.style.backgroundColor = 'transparent';
});
linkContainer.appendChild(link);
});
section.appendChild(linkContainer);
return section;
}
function getCurrentUrlWithParam(param) {
const url = new URL(window.location.href);
// Remove existing language or time parameters
url.searchParams.delete('lr');
url.searchParams.delete('tbs');
// Add new parameters
if (param) {
const cleanParam = param.startsWith('&') ? param.substring(1) : param;
const [key, value] = cleanParam.split('=');
url.searchParams.set(key, value);
}
return url.toString();
}
function getAdvancedSearchUrl() {
const url = new URL('https://www.google.com/advanced_search');
const currentParams = new URLSearchParams(window.location.search);
// Append current search parameters to the advanced search URL
currentParams.forEach((value, key) => {
url.searchParams.set(key, value);
});
return url.toString();
}
function addFiltersToPage() {
const searchResults = document.getElementById('search');
if (!searchResults) return;
const sidebar = document.createElement('div');
sidebar.style.cssText = `
position: fixed;
top: 10px;
left: 10px;
width: 160px;
z-index: 1000;
`;
sidebar.appendChild(createFilterSection(locale.languageSection, languageFilters));
sidebar.appendChild(createFilterSection(locale.timeSection, timeFilters));
sidebar.appendChild(createAdvancedSearchLink());
document.body.appendChild(sidebar);
}
const observer = new MutationObserver((mutations, obs) => {
const searchResults = document.getElementById('search');
if (searchResults) {
addFiltersToPage();
obs.disconnect();
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
})();