字节笔记本

2026年2月22日

沉浸式翻译扩展 Background.js 源码解析

本文介绍沉浸式翻译(Immersive Translate)浏览器扩展的背景脚本(background.js)实现。这是一个已归档的开源项目,提供了双语对照网页翻译功能,支持 Chrome、Firefox 等主流浏览器。

项目概述

沉浸式翻译扩展的核心架构采用典型的浏览器扩展设计模式,分为以下几个主要组件:

  • Background Script - 后台脚本,处理浏览器事件和跨页面通信
  • Content Script - 内容脚本,直接操作网页 DOM 进行翻译
  • Popup - 弹出窗口,提供快速设置界面
  • Options Page - 选项页面,完整的配置管理

Background.js 核心功能解析

1. 错误处理与工具函数

javascript
"use strict";

// 避免在控制台输出 "Receiving end does not exist" 错误
function checkedLastError() {
  chrome.runtime.lastError
}

2. MIME 类型追踪

后台脚本通过 webRequest API 监听响应头,获取页面的 MIME 类型,用于后续 PDF 文件检测:

javascript
var tabToMimeType = {}
chrome.webRequest.onHeadersReceived.addListener(function(details) {
  if (details.tabId !== -1) {
    let contentTypeHeader = null
    for (const header of details.responseHeaders) {
      if (header.name.toLowerCase() === 'content-type') {
        contentTypeHeader = header
        break
      }
    }
    tabToMimeType[details.tabId] = contentTypeHeader && contentTypeHeader.value.split(';', 1)[0]
  }
}, { urls: ['*://*/*'], types: ['main_frame'] }, ['responseHeaders']);

3. 消息通信机制

Background 脚本作为消息中转站,处理来自 Content Script 的各类请求:

Action功能说明
getMainFramePageLanguageState获取主框架页面语言状态
getMainFrameTabLanguage获取原始标签页语言
setPageLanguageState更新页面语言状态并刷新右键菜单
openOptionsPage打开选项页面
detectTabLanguage检测标签页语言
getTabHostName获取当前标签页主机名
getTabMimeType获取标签页 MIME 类型
detectLanguage检测文本语言

4. 右键菜单管理

动态创建和管理浏览器右键菜单,根据翻译状态切换菜单文本:

javascript
function updateContextMenu(pageLanguageState = "original") {
  let contextMenuTitle
  if (pageLanguageState === "translated") {
    contextMenuTitle = chrome.i18n.getMessage("btnRestore")
  } else {
    const targetLanguage = twpConfig.get("targetLanguage")
    contextMenuTitle = chrome.i18n.getMessage("msgTranslateFor", twpLang.codeToLanguage(targetLanguage))
  }
  // 创建或更新菜单...
}

5. 扩展安装与更新处理

javascript
chrome.runtime.onInstalled.addListener(details => {
  if (details.reason == "install") {
    // 首次安装,打开选项页面
    chrome.tabs.create({ url: chrome.runtime.getURL("/options/options.html") })
  } else if (details.reason == "update") {
    // 版本更新,清理翻译缓存
    twpConfig.onReady(async () => {
      translationCache.deleteTranslationCache()
      // 处理快捷键配置迁移...
    })
  }
})

6. 图标状态管理

根据页面翻译状态和浏览器主题动态更新扩展图标:

javascript
function getSVGIcon() {
  const svgXml = \`...\` // SVG 模板
  let svg64
  if (pageLanguageState === "translated" && twpConfig.get("popupBlueWhenSiteIsTranslated") === "yes") {
    // 翻译完成状态 - 蓝色图标
    svg64 = svgXml.replace(/\\\$(\\\(fill\\\-opacity\\\))\;/g, "1.0")
    svg64 = btoa(svg64.replace(/\\\$(\\\(fill\\\))\;/g, "#45a1ff"))
  } else {
    // 默认状态 - 根据主题调整
    svg64 = svgXml.replace(/\\\$(\\\(fill\\\-opacity\\\))\;/g, "0.5")
    // 根据 darkMode 和 themeColorPopupText 设置颜色...
  }
  return 'data:image/svg+xml;base64,' + svg64
}

7. 快捷键支持

支持三种快捷键操作:

javascript
chrome.commands.onCommand.addListener(command => {
  if (command === "hotkey-toggle-translation") {
    // 切换翻译状态
    chrome.tabs.sendMessage(tabs[0].id, { action: "toggle-translation" })
  } else if (command === "hotkey-toggle-dual") {
    // 切换双语显示模式
    twpConfig.set("isShowDualLanguage", ...)
  } else if (command === "hotkey-swap-page-translation-service") {
    // 切换翻译服务(Google/Yandex)
    twpConfig.set("pageTranslatorService", ...)
  }
})

8. 自动翻译功能

通过 webNavigation API 实现链接点击后的自动翻译:

javascript
function enableTranslationOnClickingALink() {
  chrome.tabs.onActivated.addListener(tabsOnActivated)
  chrome.tabs.onRemoved.addListener(tabsOnRemoved)
  chrome.runtime.onMessage.addListener(runtimeOnMessage)
  chrome.webNavigation.onCommitted.addListener(webNavigationOnCommitted)
  chrome.webNavigation.onDOMContentLoaded.addListener(webNavigationOnDOMContentLoaded)
}

技术特点

  1. Manifest V3 兼容 - 支持最新的 Chrome 扩展标准
  2. 跨浏览器支持 - 兼容 Chrome、Firefox、Edge 等主流浏览器
  3. 移动设备适配 - 针对移动端浏览器做了特殊处理
  4. 主题感知 - 自动适配浏览器的深色/浅色主题
  5. 国际化支持 - 使用 chrome.i18n API 实现多语言

项目链接

许可证

MPL-2.0 (Mozilla Public License 2.0)

分享: