WSJ Cross-Site Google Search

Add floating button to search WSJ English <-> Chinese versions 在 WSJ 英文/中文页面添加浮动搜索按钮,快速在 Google 上搜索对应语言站点的文章(英文 ↔ 中文)。

// ==UserScript==
// @name         WSJ Cross-Site Google Search
// @namespace    http://tampermonkey.net/
// @version      2.2
// @description  Add floating button to search WSJ English <-> Chinese versions 在 WSJ 英文/中文页面添加浮动搜索按钮,快速在 Google 上搜索对应语言站点的文章(英文 ↔ 中文)。
// @author       vacuity
// @license      MIT
// @match        https://www.wsj.com/*
// @match        https://cn.wsj.com/*
// @grant        GM_openInTab
// ==/UserScript==

(function() {
    'use strict';

    // Determine which site we are on
    const isEnglishSite = location.hostname === "www.wsj.com";
    const isChineseSite = location.hostname === "cn.wsj.com";

    // Set target site and button label accordingly
    let targetSite, buttonLabel;
    if (isEnglishSite) {
        targetSite = "site:cn.wsj.com";
        buttonLabel = "🔍 WSJ CN Search";
    } else if (isChineseSite) {
        targetSite = "site:www.wsj.com";
        buttonLabel = "🔍 WSJ EN Search";
    } else {
        return;
    }

    // Create floating button
    const btn = document.createElement("button");
    btn.innerText = buttonLabel;
    Object.assign(btn.style, {
        position: "fixed",
        bottom: "20px",
        right: "20px",
        zIndex: "9999",
        padding: "10px 15px",
        background: "#0071c5",
        color: "#fff",
        border: "none",
        borderRadius: "6px",
        cursor: "pointer",
        fontSize: "14px"
    });
    document.body.appendChild(btn);

    // Helper: safely extract JSON from utag_data
    function getUtagData() {
        try {
            const script = document.querySelector("script#utag_data_script");
            if (script && script.textContent.includes("window.utag_data")) {
                const match = script.textContent.match(/window\.utag_data\s*=\s*(\{.*\})/s);
                if (match) return JSON.parse(match[1]);
            }
        } catch (e) {
            console.error("Failed to parse utag_data", e);
        }
        return null;
    }

    btn.addEventListener("click", () => {
        const canonical = document.querySelector("link[rel='canonical']");
        if (!canonical) return alert("No canonical URL found.");

        // Extract slug keywords (English-side rule only)
        const url = canonical.href;
        const slug = url.split("/").pop().split("-").slice(0, 4).join("-");

        // Extract metadata
        const utag = getUtagData();
        let pubDate = null;
        let authors = [];

        if (utag) {
            if (utag.article_author) {
                // Normalize delimiters
                const rawAuthors = utag.article_author.replace(/\//g, "|");
                authors = rawAuthors.split("|").map(a => `"${a.trim()}"`);
            }
            if (utag.article_publish) {
                pubDate = new Date(utag.article_publish.split(" ")[0]);
            }
        }

        let query = "";

        if (isEnglishSite) {
            // 🔎 From EN → CN
            if (pubDate) {
                const year = pubDate.getFullYear();
                if (year <= 2024) {
                    // slug OR authors, plus year
                    let parts = [`"${slug}"`];
                    if (authors.length > 0) {
                        if (authors.length > 1) {
                            parts.push("(" + authors.join(" ") + ")");
                        } else {
                            parts.push(authors[0]);
                        }
                    }
                    query = `${targetSite} (${parts.join(" OR ")}) ${year}`;
                } else {
                    // 2025+ → slug only
                    query = `${targetSite} ("${slug}")`;
                }
            } else {
                // fallback → slug + authors
                let parts = [`"${slug}"`];
                if (authors.length > 0) {
                    if (authors.length > 1) {
                        parts.push("(" + authors.join(" ") + ")");
                    } else {
                        parts.push(authors[0]);
                    }
                }
                query = `${targetSite} (${parts.join(" OR ")})`;
            }
        } else if (isChineseSite) {
            // 🔎 From CN → EN (author only, ignore slug)
            if (authors.length > 0) {
                let parts;
                if (authors.length > 1) {
                    parts = "(" + authors.join(" ") + ")";
                } else {
                    parts = authors[0];
                }
                if (pubDate) {
                    const year = pubDate.getFullYear();
                    query = `${targetSite} ${parts} ${year}`;
                } else {
                    query = `${targetSite} ${parts}`;
                }
            } else {
                // no authors → fallback to slug
                query = `${targetSite} "${slug}"`;
            }
        }

        const googleUrl = `https://www.google.com/search?q=${encodeURIComponent(query)}`;
        GM_openInTab(googleUrl, { active: true });
    });
})();