From 3b76e03a5269d3344aeed11f8a1c036435622204 Mon Sep 17 00:00:00 2001 From: WenyanLiu Date: Sun, 10 Nov 2024 20:24:30 +0800 Subject: [PATCH] Fix issue #1: Add Rank Filter. --- css/filter.css | 38 ++++++++++++++++ js/filter.js | 115 +++++++++++++++++++++++++++++++++++++++++++++++++ manifest.json | 3 +- script.js | 2 + 4 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 css/filter.css create mode 100644 js/filter.js diff --git a/css/filter.css b/css/filter.css new file mode 100644 index 0000000..4ede83c --- /dev/null +++ b/css/filter.css @@ -0,0 +1,38 @@ +.ccf-filter { + position: fixed; + top: 120px; + right: 30px; + z-index: 9999; + background: #fff; + border: 1px solid #ddd; + border-radius: 8px; + padding: 12px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); +} + +.ccf-filter button { + display: block; + width: 100%; + margin: 4px 0; + padding: 8px 16px; + border: 1px solid #ddd; + border-radius: 4px; + background: #fff; + cursor: pointer; + font-size: 14px; + transition: all 0.2s ease; +} + +.ccf-filter button:hover { + background: #f5f5f5; +} + +.ccf-filter button.active { + background: #4285f4; + color: #fff; + border-color: #4285f4; +} + +.paper-hidden { + display: none !important; +} diff --git a/js/filter.js b/js/filter.js new file mode 100644 index 0000000..39b0789 --- /dev/null +++ b/js/filter.js @@ -0,0 +1,115 @@ +/** + * MIT License + * + * Copyright (c) 2019-2024 WenyanLiu (https://github.com/WenyanLiu/CCFrank4dblp) + */ + +const filter = { + currentFilter: "ALL", + processedEntries: new Set(), + + init() { + if (!window.location.hostname.startsWith("dblp")) { + return; + } + + this.createFilterButtons(); + this.bindEvents(); + this.setupInfiniteScrollHandler(); + }, + + createFilterButtons() { + const filterDiv = document.createElement("div"); + filterDiv.className = "ccf-filter"; + filterDiv.innerHTML = ` + + + + + `; + document.body.appendChild(filterDiv); + }, + + setupInfiniteScrollHandler() { + const observer = new IntersectionObserver((entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + this.applyFilter(true); + } + }); + }); + + const trigger = document.querySelector("#completesearch-publs"); + if (trigger) { + observer.observe(trigger); + } + + window.addEventListener( + "scroll", + this.debounce(() => { + this.applyFilter(true); + }, 200), + ); + }, + + applyFilter(preserveExisting = false) { + const entries = document.querySelectorAll( + "#completesearch-publs > div > ul > li", + ); + entries.forEach((entry) => { + const entryId = entry.querySelector("a")?.href || entry.innerHTML; + if (this.processedEntries.has(entryId) && preserveExisting) { + return; + } + + this.processedEntries.add(entryId); + + const hasCCFC = entry.textContent.includes("CCF C"); + const hasCCFB = entry.textContent.includes("CCF B"); + const hasCCFA = entry.textContent.includes("CCF A"); + + let shouldShow = false; + + if (this.currentFilter === "ALL") { + shouldShow = true; + } else if (this.currentFilter === "C" && hasCCFC) { + shouldShow = true; + } else if (this.currentFilter === "B" && hasCCFB) { + shouldShow = true; + } else if (this.currentFilter === "A" && hasCCFA) { + shouldShow = true; + } + + const currentlyVisible = entry.style.display !== "none"; + if (currentlyVisible !== shouldShow || !preserveExisting) { + entry.style.display = shouldShow ? "" : "none"; + } + }); + }, + + debounce(func, wait) { + let timeout; + return function executedFunction(...args) { + const later = () => { + clearTimeout(timeout); + func(...args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; + }, + + bindEvents() { + document.querySelector(".ccf-filter").addEventListener("click", (e) => { + if (e.target.tagName === "BUTTON") { + document.querySelectorAll(".ccf-filter button").forEach((btn) => { + btn.classList.remove("active"); + }); + e.target.classList.add("active"); + + this.currentFilter = e.target.dataset.rank; + this.applyFilter(false); + } + }); + }, +}; diff --git a/manifest.json b/manifest.json index fbb7d20..6a9458d 100644 --- a/manifest.json +++ b/manifest.json @@ -107,7 +107,7 @@ "https://www.webofscience.com/*", "https://www.semanticscholar.org/*" ], - "css": ["css/style.css"], + "css": ["css/style.css", "css/filter.css"], "js": [ "lib/jquery-3.5.1.min.js", "js/dblp.js", @@ -118,6 +118,7 @@ "js/apiCache.js", "js/ccf.js", "js/fetchRank.js", + "js/filter.js", "data/ccfRankAbbr.js", "data/ccfRankFull.js", "data/ccfRankDb.js", diff --git a/script.js b/script.js index 26cb1ac..1214c65 100644 --- a/script.js +++ b/script.js @@ -15,3 +15,5 @@ if (window.location.hostname.startsWith("dblp")) { } else if (window.location.hostname.includes("webofscience")) { wos.run(); } + +filter.init();