Greasy Fork is available in English.

SearchTimeMachine 搜索时光机

Display time filtering function in the right sidebar. 在右侧栏中显示时间过滤功能

Instalează acest script?
Script sugerat de autor

Poate îți va plăcea șiSite Quick Open网页快开.

Instalează acest script
// ==UserScript==
// @name         SearchTimeMachine 搜索时光机
// @namespace    http://tampermonkey.net/
// @version      0.0.2
// @description  Display time filtering function in the right sidebar. 在右侧栏中显示时间过滤功能
// @author       Exisi
// @license      MIT License
// @match        *.baidu.com/s*
// @match        *.google.com.*/search*
// @match        *.google.com/search*
// @match        *.google.com.hk/search*
// @match        *.bing.com/*search*
// @match        *.yahoo.com/search*
// @match        *.yandex.com/search*
// ==/UserScript==
(function () {
	"use strict";
	const data = [
		{
			name: "bing",
			timeFilterClass: [".b_dropdown div", "b_ans"],
			sideBarElement: "#b_context",
		},
		{
			name: "baidu",
			timeFilterClass: [],
			sideBarElement: "#content_right",
		},
		{
			name: "google",
			timeFilterClass: ["#hdtbMenus", "g-menu"],
			sideBarElement: "#rcnt>div:not(#center_col)",
			container: "#rcnt",
		},
		{
			name: "yahoo",
			timeFilterClass: ["#horizontal-bar .last .timefilter-list"],
			sideBarElement: "#right",
		},
		{
			name: "yandex",
			timeFilterClass: [],
			sideBarElement: "#search-result-aside",
		},
	];
	const url = window.location.href;
	const urlParams = new URLSearchParams(window.location.search);
	const type = data.findIndex((item) => url.includes(item.name));

	let filterItem = document.querySelector(data[type].timeFilterClass[0]);
	let sidebar = document.querySelector(data[type].sideBarElement);

	const style = document.createElement("style");
	style.innerHTML = `.form-footer button:hover{ background-color: #f5f5f6 !important;}`;
	document.head.appendChild(style);

	const customRangeFilter = `<div style="margin-top: 10px;font-size: 13px; border-top: 1px solid #ccc;">
		<div style="margin: 10px 0;">自定义范围</div>
		<form id="customDateFilter">
			<div class="form-container" style="display:flex;">
				<input class="filter-date-start" type="date"
					style="border-radius: 2px;border: 1px solid #ddd; line-height: 16px; padding: 5px;" />
				<input class="filter-date-end" type="date"
					style="margin-left: 10px; border-radius: 2px;border: 1px solid #ddd; line-height: 16px; padding: 5px;" />
			</div>
			<div class="form-footer" style="margin: 10px 0; display: flex; justify-content: space-between; align-items: center">
				<span class="validateMessage" style="visibility: hidden; color:red;font-size:12px;">*日期不合法</span>
				<button style="cursor:pointer; padding: 0 10px; min-height: 32px; background-color: #FAFAF9; color: #111; border-radius: 2px; border: 1px solid #ddd;">应用</button>
			</div>
		</form>
	</div>`;

	if (data[type].name == "bing") {
		const cloneFilterItem = filterItem.cloneNode(true);
		cloneFilterItem.style.padding = 0;
		cloneFilterItem.querySelectorAll("a").forEach((item) => {
			item.style.color = "#666";
			item.style.borderRadius = "5px";
			item.addEventListener("mouseover", () => {
				item.style.backgroundColor = "#f5f5f5";
			});
			item.addEventListener("mouseout", () => {
				item.style.backgroundColor = "#ffffff";
			});
		});

		const timeFilterItem = document.createElement("li");
		timeFilterItem.appendChild(cloneFilterItem);
		timeFilterItem.className = data[type].timeFilterClass[1] + " sidebar-filter";
		timeFilterItem.style.marginBottom = "35px";
		timeFilterItem.style.borderRadius = "6px";
		timeFilterItem.style.marginTop = "5px";
		timeFilterItem.style.padding = "10px 20px 5px 20px";
		timeFilterItem.style.border = "1px solid #ddd";

		sidebar.prepend(timeFilterItem);

		const customDateFilter = document.createElement("div");
		customDateFilter.innerHTML = customRangeFilter;
		const innerFilterItem = document.querySelector(data[type].sideBarElement + " .sidebar-filter");
		innerFilterItem.appendChild(customDateFilter);

		const startDateInput = document.querySelector(".filter-date-start");
		const endDateInput = document.querySelector(".filter-date-end");

		startDateInput.addEventListener("change", () => {
			if (!validateDate(startDateInput.value)) {
				startDateInput.value = "";
				return;
			}
		});

		endDateInput.addEventListener("change", () => {
			if (!validateDate(endDateInput.value)) {
				endDateInput.value = "";
				return;
			}
		});

		const rangeFilterBtn = document.querySelector(".form-footer button");
		rangeFilterBtn.addEventListener("click", (e) => {
			e.preventDefault();
			const startDateText = startDateInput.value;
			const endDateText = endDateInput.value;

			if (!startDateText || !endDateText) {
				return;
			}

			const startDayDiff = getDiffDay(startDateText, "1970/1/1");
			const endDayDiff = getDiffDay(endDateText, "1970/1/1");

			urlParams.set("filters", `ex1:"ez5_${startDayDiff}_${endDayDiff}"`);
			window.location.search = urlParams.toString();
		});
	}

	if (data[type].name == "baidu") {
		style.innerHTML += `.sidebar-filter-list li { background-color: #ffffff; padding: 5px; list-style-type: none; cursor: pointer; } .sidebar-filter-list li:hover { background-color: #f1f4fe; color: #2440b3; }`;

		const filterList = document.createElement("ul");
		filterList.className = "sidebar-filter-list";

		const liUnlimited = document.createElement("li");
		const liOneDay = document.createElement("li");
		const liOneWeek = document.createElement("li");
		const liOneMonth = document.createElement("li");
		const liOneYear = document.createElement("li");

		liUnlimited.textContent = "时间不限";
		liOneDay.textContent = "一天内";
		liOneWeek.textContent = "一周内";
		liOneMonth.textContent = "一月内";
		liOneYear.textContent = "一年内";

		liUnlimited.addEventListener("click", () => {
			urlParams.delete("gpc");
			window.location.search = urlParams.toString();
		});
		liOneDay.addEventListener("click", () => {
			const now = new Date();
			const curTimestamp = now.getTime().toString().slice(0, -3);
			const preDay = now.setDate(now.getDate() - 1);
			const preDayTimestamp = preDay.toString().slice(0, -3);

			const rangeTimeStamp = `stf=${preDayTimestamp},${curTimestamp}|stftype=1`;
			urlParams.set("gpc", rangeTimeStamp);
			window.location.search = urlParams.toString();
		});
		liOneWeek.addEventListener("click", () => {
			const now = new Date();
			const curTimestamp = now.getTime().toString().slice(0, -3);
			const preDay = now.setDate(now.getDate() - 7);
			const preDayTimestamp = preDay.toString().slice(0, -3);

			const rangeTimeStamp = `stf=${preDayTimestamp},${curTimestamp}|stftype=1`;
			urlParams.set("gpc", rangeTimeStamp);
			window.location.search = urlParams.toString();
		});
		liOneMonth.addEventListener("click", () => {
			const now = new Date();
			const curTimestamp = now.getTime().toString().slice(0, -3);
			const preMonth = now.setMonth(now.getMonth() - 1);
			const preMonthTimestamp = preMonth.toString().slice(0, -3);

			const rangeTimeStamp = `stf=${preMonthTimestamp},${curTimestamp}|stftype=1`;
			urlParams.set("gpc", rangeTimeStamp);
			window.location.search = urlParams.toString();
		});
		liOneYear.addEventListener("click", () => {
			const now = new Date();
			const curTimestamp = now.getTime().toString().slice(0, -3);
			const preYear = now.setFullYear(now.getFullYear() - 1);
			const preYearTimestamp = preYear.toString().slice(0, -3);

			const rangeTimeStamp = `stf=${preYearTimestamp},${curTimestamp}|stftype=1`;
			urlParams.set("gpc", rangeTimeStamp);
			window.location.search = urlParams.toString();
		});

		filterList.appendChild(liUnlimited);
		filterList.appendChild(liOneDay);
		filterList.appendChild(liOneWeek);
		filterList.appendChild(liOneMonth);
		filterList.appendChild(liOneYear);

		const customDateFilter = document.createElement("div");
		customDateFilter.innerHTML = customRangeFilter;

		const filterSidebarItem = document.createElement("div");
		filterSidebarItem.style.marginBottom = "20px";
		filterSidebarItem.appendChild(filterList);
		filterSidebarItem.appendChild(customDateFilter);

		sidebar.prepend(filterSidebarItem);

		const startDateInput = document.querySelector(".filter-date-start");
		const endDateInput = document.querySelector(".filter-date-end");

		startDateInput.addEventListener("change", () => {
			if (!validateDate(startDateInput.value)) {
				startDateInput.value = "";
				return;
			}
		});

		endDateInput.addEventListener("change", () => {
			if (!validateDate(endDateInput.value)) {
				endDateInput.value = "";
				return;
			}
		});

		const rangeFilterBtn = document.querySelector(".form-footer button");
		rangeFilterBtn.addEventListener("click", (e) => {
			e.preventDefault();
			const startDateText = startDateInput.value;
			const endDateText = endDateInput.value;

			if (!startDateText || !endDateText) {
				return;
			}

			const startDateTimestamp = new Date(startDateText).getTime().toString().slice(0, -3);
			const endDateTimestamp = new Date(endDateText).getTime().toString().slice(0, -3);

			urlParams.set("gpc", `stf=${startDateTimestamp},${endDateTimestamp}|stftype=2`);
			window.location.search = urlParams.toString();
		});
	}

	if (data[type].name == "google") {
		const observer = new MutationObserver(() => {
			filterItem = document.querySelector(data[type].timeFilterClass[0]);

			if (!filterItem) {
				return;
			}

			const filterMenu = filterItem.querySelectorAll("g-menu")[1];

			if (!filterMenu) {
				return;
			}

			const cloneFilterItem = filterMenu.cloneNode(true);
			cloneFilterItem.style.border = "1px solid #dadce0";
			cloneFilterItem.style.boxSizing = "border-box";
			cloneFilterItem.style.borderRadius = "8px";
			cloneFilterItem.style.padding = "5px";
			cloneFilterItem.style.marginBottom = "15px";

			if (!sidebar) {
				sidebar = document.createElement("div");
				sidebar.style.width = "372px";
				sidebar.style.marginLeft = "76px";
				const container = document.querySelector(data[type].container);
				container.appendChild(sidebar);
			}
			sidebar.prepend(cloneFilterItem);
			observer.disconnect();
		});
		observer.observe(document.body, { childList: true, subtree: true });
	}

	if (data[type].name == "yahoo") {
		const cloneFilterItem = filterItem.cloneNode(true);
		cloneFilterItem.className = "";
		cloneFilterItem.style.backgroundColor = "#fcfbfb";
		cloneFilterItem.style.marginBottom = "15px";
		cloneFilterItem.style.padding = "5px";
		cloneFilterItem.style.border = "1px solid rgba(0,0,0,.03)";
		cloneFilterItem.style.borderRadius = "16px";

		sidebar.prepend(cloneFilterItem);
	}

	if (data[type].name == "yandex") {
		style.innerHTML += `.sidebar-filter-list{ margin:0; padding: 10px; background-color: #ffffff; border-radius: 16px; box-shadow: 0 4px 12px 0#0d234308; } .sidebar-filter-list li { background-color: #ffffff; padding: 5px; list-style-type: none; cursor: pointer; } .sidebar-filter-list li:hover { background-color: #f1f4fe; color: #2440b3; }`;

		const filterList = document.createElement("ul");
		filterList.className = "sidebar-filter-list";

		const liUnlimited = document.createElement("li");
		const liOneDay = document.createElement("li");
		const liTwoWeek = document.createElement("li");
		const liOneMonth = document.createElement("li");

		liUnlimited.textContent = "All time";
		liOneDay.textContent = "Last day";
		liTwoWeek.textContent = "Last 2 weeks";
		liOneMonth.textContent = "Last month";

		liUnlimited.addEventListener("click", () => {
			urlParams.delete("within");
			window.location.search = urlParams.toString();
		});
		liOneDay.addEventListener("click", () => {
			urlParams.set("within", "77");
			window.location.search = urlParams.toString();
		});
		liTwoWeek.addEventListener("click", () => {
			urlParams.set("within", "1");
			window.location.search = urlParams.toString();
		});
		liOneMonth.addEventListener("click", () => {
			urlParams.set("within", "2");
			window.location.search = urlParams.toString();
		});

		filterList.appendChild(liUnlimited);
		filterList.appendChild(liOneDay);
		filterList.appendChild(liTwoWeek);
		filterList.appendChild(liOneMonth);

		const filterSidebarItem = document.createElement("div");
		filterSidebarItem.style.marginBottom = "20px";
		filterSidebarItem.appendChild(filterList);

		sidebar.prepend(filterSidebarItem);
	}

	function validateDate(date) {
		const validateMesBlock = document.querySelector(".validateMessage");
		const startDateInput = document.querySelector(".filter-date-start");
		const endDateInput = document.querySelector(".filter-date-end");

		if (isNaN(Date.parse(date))) {
			validateMesBlock.innerText = "*日期不合法";
			validateMesBlock.style.visibility = "visible";
			return false;
		}

		if (startDateInput.value && endDateInput.value && startDateInput.value > endDateInput.value) {
			validateMesBlock.innerText = "*开始日期不能大于结束日期";
			validateMesBlock.style.visibility = "visible";
			return false;
		}

		validateMesBlock.style.visibility = "hidden";
		return true;
	}

	function getDiffDay(startDate, endDate) {
		const oneDay = 1000 * 60 * 60 * 24;
		const timestamp = Date.parse(startDate) - Date.parse(endDate);
		return Math.floor(timestamp / oneDay);
	}
})();