将Firefox插件导入Edge/Chrome中

news2025/3/1 1:07:28

目录

    • 前言
    • 导出火狐插件.xpi格式
    • 插件导入edge/chorme中
    • 错误示范1
    • 错误示范2
    • 修改过程
      • manifest.json
      • dict文件夹修改
        • backgroundScript.js
        • injectedScript.js
        • debug过程
        • 最终backgroundScript.js和injectedScript.js代码
    • 完工阶段
    • 修改后的源码

前言

因为博主本人想在edge/chrome中使用cph-submit插件

  • vscode中cph,实现一键将代码提交到Codeforces
  • 但是只有firefox的插件
  • 另外两个比较麻烦,nodejs还有版本问题。

写这篇文章有三个原因:

  1. 网上暂且没找到firefox插件导入edge/chrome的方法

  2. 博主个人感觉这个debug过程比较有意义

  3. 也希望能帮助到其他人。

省流:最终可用的版本如下,直接下载解压开发人员模式导入edge插件即可:

  • https://wwf.lanzout.com/iJ3Gl21r9vja
  • 导入的流程可以见本文章节**“插件导入edge/chorme中”**
  • 可能还有点小bug,暂且没修好,但是能用(确信

导出火狐插件.xpi格式

在火狐浏览器中打开这个about:profiles,就可以看到了

  • 这就是你当前浏览器用户的存储文件夹

在这里插入图片描述

然后点击打开文件夹

点击extensions,进去就可以看到你安装的插件的.xpi格式,这边我只安装了一个(名为cph-submit)。

但是其实你可以通过修改时间来判断哪个是哪个(大不了卸掉再装一下,最新的那个)

在这里插入图片描述

  • 一般也就一两个

然后把这个文件复制出来,找个空的目录放一下,我将它重命名为cph-submit.xpi

右键解压到文件夹(我用的360解压软件)

  • 这一步如果没法完成,你可以修改后缀名为.zip
  • 然后再解压,效果一样

在这里插入图片描述

因为解压完的文件夹不一定直接用

  • 有些 Firefox 扩展可能需要进行一些代码修改才能在 Edge/Chrome 上运行,
  • 需要修改 manifest.json 文件以符合 Edge/Chrome 的格式。

插件导入edge/chorme中

随后在edge/chrome浏览器中,打开开发人员模式

  • 进入edge://extensions/

在这里插入图片描述

然后就会出现这些按钮

在这里插入图片描述

然后从“加载解压缩的扩展”

  • 也就是我刚刚发的
  • https://wwf.lanzout.com/iJ3Gl21r9vja
  • 这个解压缩后,导入进去

随后应该就可以用了,可以跳转到“完工阶段”查看效果

错误示范1

不能用.crx格式导入

  • 不要将刚解压的文件夹的路径打包成为.crx格式,
  • 大概率会G掉

如下所示

在这里插入图片描述

选择解压后的路径

在这里插入图片描述

在这里插入图片描述

随后就可以看到

在这里插入图片描述

不过.crx才是我们要用的,.pem不需要

.crx直接拖进浏览器中,点击添加拓展

在这里插入图片描述

启动按键是灰色的,这是错误示范,所以不能这样

直接用解压好的就没下面这个问题

在这里插入图片描述

错误示范2

如果你修改的,有问题

  • 第一种情况,初始化的时候就有问题,那么一导入就是挂的

在这里插入图片描述

  • 第二种情况,运行到一半,用到才有问题

会先正常显示,然后在挂掉(错误/重新加载两个一开始不显示)

此时你其实可以点进去错误,查看哪里错了,然后修改

当然,一般修改工作量也挺大的

可以交给GPT来改

在这里插入图片描述

在这里插入图片描述

这些错误是可以展开的,直到报错后针对性修改

(无关紧要的)提醒:

要是你不知道firefox和edge他们的manifest.json的差别,其实你可以本地找一下edge拓展的源文件,然后对比下

当然,我都喂给了GPT,让他帮忙修改

C:\Users\<你的电脑用户名>\AppData\Local\Microsoft\Edge\User Data\Default\Extensions

有问题的话,得删除插件

然后再从文件夹导入这个插件

修改过程

manifest.json

点进文件夹,查看manifest.json如下

{
  "name": "CPH Submit",
  "manifest_version": 2,
  "homepage_url": "https://github.com/agrawal-d/cph-submit",
  "version": "1.6.0",
  "description": "Codeforces Submit add-on for Competitive Programming Helper.",
  "background": {
    "scripts": ["dist/backgroundScript.js"]
  },
  "permissions": ["*://localhost/*", "*://codeforces.com/*", "webNavigation"],
  "icons": {
    "48": "icon-48.png"
  },
  "browser_specific_settings": {
    "gecko": {
      "id": "{5dd8fd6e-0733-41a7-abc4-e19fba703de9}",
      "strict_min_version": "49.0"
    }
  }
}

我将其修改:

  • manifest_version:
    • 2 改为 3
  • background:
    • scripts 改为 service_worker,并增加 "type": "module"
  • action:
    • 添加 action 部分,用于定义插件的图标和默认标题。
  • host_permissions:
    • 添加 host_permissionsoptional_host_permissions 来管理插件的权限。
  • 删除key字段:
    • 不再包含key字段,因为这是开发中的插件,不是发布到商店的版本。
  • permissions:
    • 保留 activeTabwebNavigationscripting 权限。
  • host_permissions:
    • 使用 host_permissions 来指定对 localhostcodeforces.com 的访问权限。
  • 删除 optional_host_permissions:
    • 移除 optional_host_permissions 字段,因为它包含的权限已经在 host_permissions 中。
{
  "name": "CPH Submit",
  "manifest_version": 3,
  "homepage_url": "https://github.com/agrawal-d/cph-submit",
  "version": "1.6.0",
  "description": "Codeforces Submit add-on for Competitive Programming Helper.",
  "background": {
    "service_worker": "dist/backgroundScript.js",
    "type": "module"
  },
  "permissions": ["activeTab", "webNavigation", "scripting"],
  "icons": {
    "48": "icon-48.png"
  },
  "action": {
    "default_icon": {
      "48": "icon-48.png"
    },
    "default_title": "CPH Submit"
  },
  "host_permissions": ["*://localhost/*", "*://codeforces.com/*"]
}

dict文件夹修改

还需要修改解压文件夹中的dictbackgroundScript.jsinjectedScript.js

  • 并不能从火狐直接移植到chrome/edge
  • 里面的browser API 需要修改为chrome API
    • **Edge浏览器现在基于Chromium,所以使用与Chrome相同的API。**二者可以共享,但是与火狐不行
    • 因此,只需要将代码中的 browser 替换为 chrome,并使用 chrome.scripting.executeScript 来代替 browser.tabs.executeScript
  • 需要修改的地方可能还有
    • browser 替换为 chrome:所有 browser API 调用替换为 chrome
      • browser.tabs.create 修改为 chrome.tabs.create
      • browser.windows.update 修改为 chrome.windows.update
      • 使用 chrome.scripting.executeScript 代替 browser.tabs.executeScript
      • browser.tabs.sendMessage 修改为 chrome.tabs.sendMessage
backgroundScript.js

backgroundScript.js 是浏览器扩展的背景脚本,负责处理一些全局的后台任务,例如:

  1. 后台逻辑:处理定时任务、全局事件监听器等。
  2. 与服务器通信:从服务器获取数据,处理服务器响应。
  3. 管理浏览器标签页:创建、更新或关闭标签页。
  4. 在不同页面间传递消息:与内容脚本(如 injectedScript.js)进行通信。

在该扩展中,backgroundScript.js 主要负责从服务器获取提交信息,并在相应的 Codeforces 页面中自动提交代码。

代码在"最终backgroundScript.js和injectedScript.js代码"(

injectedScript.js

injectedScript.js 是注入到目标网页中的脚本,负责与网页内容进行交互,例如:

  1. 操作网页的 DOM:读取和修改网页中的元素,例如表单字段。
  2. 接收消息并执行操作:从背景脚本接收消息,并根据消息内容执行相应的操作。
  3. 模拟用户行为:自动填写表单、点击按钮等。

在该扩展中,injectedScript.js 主要负责在 Codeforces 提交页面上自动填写表单,并模拟用户点击提交按钮。

代码在"最终backgroundScript.js和injectedScript.js代码"(

debug过程

个人修改的debug过程

  • 解压文件夹中的dictbackgroundScript.jsinjectedScript.js

先将其改为最简单的.js,确保backgroundScript.js导入没问题

console.log('Service worker registered successfully');

监听下控制台

在这里插入图片描述

看起来可以导入

逐渐加入代码

在这里插入图片描述

最终backgroundScript.js和injectedScript.js代码

最后backgroundScript.js修改结果如下

const config = {
  cphServerEndpoint: new URL("http://localhost:27121/getSubmit"),
  cfSubmitPage: new URL("https://codeforces.com/problemset/submit"),
  loopTimeOut: 3000,
  debug: false
};

const log = (...args) => {
  if (config.debug) {
    console.log(...args);
  }
};

const isContestProblem = (problemUrl) => {
  return problemUrl.indexOf("contest") !== -1;
};

const getSubmitUrl = (problemUrl) => {
  if (!isContestProblem(problemUrl)) {
    return config.cfSubmitPage.href;
  }
  const url = new URL(problemUrl);
  const contestNumber = url.pathname.split("/")[2];
  const submitURL = `https://codeforces.com/contest/${contestNumber}/submit`;
  return submitURL;
};

const handleSubmit = async (problemName, languageId, sourceCode, problemUrl) => {
  if (problemName === "" || languageId === -1 || sourceCode === "") {
    log("Invalid arguments to handleSubmit");
    return;
  }

  log("isContestProblem", isContestProblem(problemUrl));

  chrome.tabs.create({ active: true, url: getSubmitUrl(problemUrl) }, (tab) => {
    chrome.windows.update(tab.windowId, { focused: true });

    if (tab.id === undefined) {
      log("No tab id to send message to", tab);
      return;
    }

    chrome.tabs.onUpdated.addListener(function listener(tabId, changeInfo) {
      if (tabId === tab.id && changeInfo.status === 'complete') {
        chrome.tabs.onUpdated.removeListener(listener);

        chrome.scripting.executeScript({
          target: { tabId: tab.id },
          files: ["/dist/injectedScript.js"]
        }, () => {
          chrome.tabs.sendMessage(tab.id, {
            type: "cph-submit",
            problemName,
            languageId,
            sourceCode,
            url: problemUrl,
          }, () => {
            if (chrome.runtime.lastError) {
              console.error("Error sending message:", chrome.runtime.lastError);
            } else {
              log("Message sent to tab with script");
            }
          });
        });
      }
    });
  });
};

const mainLoop = async () => {
  let cphResponse;
  try {
    const headers = new Headers();
    headers.append("cph-submit", "true");

    const request = new Request(config.cphServerEndpoint.href, {
      method: "GET",
      headers,
    });

    cphResponse = await fetch(request);
  } catch (err) {
    log("Error while fetching cph response", err);
    return;
  }

  if (!cphResponse.ok) {
    log("Error while fetching cph response", cphResponse);
    return;
  }

  const response = await cphResponse.json();

  if (response.empty) {
    log("Got empty valid response from CPH");
    return;
  }

  log("Got non-empty valid response from CPH");
  handleSubmit(response.problemName, response.languageId, response.sourceCode, response.url);
};

setInterval(mainLoop, config.loopTimeOut);

console.log('Service worker registered successfully');

以及injectedScript.js修改结果如下

console.log("cph-submit script injected");

const isContestProblem = (problemUrl) => {
  return problemUrl.indexOf("contest") !== -1;
};

const handleData = (data) => {
  console.log("Handling submit message");
  const languageEl = document.getElementsByName("programTypeId")[0];
  const sourceCodeEl = document.getElementById("sourceCodeTextarea");

  sourceCodeEl.value = data.sourceCode;
  languageEl.value = data.languageId.toString();

  if (!isContestProblem(data.url)) {
    const problemNameEl = document.getElementsByName("submittedProblemCode")[0];
    problemNameEl.value = data.problemName;
  } else {
    const problemIndexEl = document.getElementsByName("submittedProblemIndex")[0];
    let problemName = data.url.split("/problem/")[1];

    if (problemName == "0") {
      problemName = "A";
    }
    problemIndexEl.value = problemName;
  }

  console.log("Submitting problem");
  const submitBtn = document.querySelector(".submit");
  submitBtn.disabled = false;
  submitBtn.click();
};

console.log("Adding event listener");

chrome.runtime.onMessage.addListener((data, sender) => {
  console.log("Got message", data, sender);
  if (data.type === "cph-submit") {
    handleData(data);
  }
});

完工阶段

点击competitive Companion,将样例一键导入vscode中

在这里插入图片描述

随后,在右侧编写代码

在这里插入图片描述

然后点击Submit提交代码

在这里插入图片描述

就成功在edge上,先自动跳转到提交界面,然后自动填写代码,提交表单

最后自动跳转到这个界面,提交成功

在这里插入图片描述

修改后的源码

上面其实也可以复制下来

我整理了可以直接用的版本

https://wwf.lanzout.com/iJ3Gl21r9vja

蓝奏云盘下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1819966.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CPU基础扫盲:开发人员不得不了解的CPU那些事

文章目录 一、CPU简介1、单核CPU的组成2、多核CPU的组成3、存储器的层级架构4、CPU的X86和arm架构的区别&#xff08;1&#xff09;指令和指令集&#xff08;2&#xff09;主要的CPU架构指令集分类&#xff08;3&#xff09;CPU 32位和64位是指什么&#xff08;4&#xff09;安…

『 Linux 』动态库的加载

文章目录 动静态库的区别动态库-共享库动态库的加载动态库的管理 总结 动静态库的区别 动态库(Dynamic Libraries) 链接方式 动态链接,程序在运行时(而不是在编译时)与动态库链接; 操作系统负责加载动态库文件; 文件大小 使用动态库的应用程序通常其可执行文件大小更小; 因…

简单操作,智能自动化:Windows键鼠模拟软件

一个 Windows 自动化工具&#xff0c;可模拟键盘和鼠标&#xff0c;自动执行任何流程和动作&#xff0c;只需录制动作并运行即可&#xff0c;无需编写脚本&#xff0c;只需按录制&#xff0c;然后播放即可&#xff0c;大小仅 35 KB&#xff0c;且免费无广告。 界面介绍 **打开…

LLM下载、私有化部署与ollam应用

参考&#xff1a; Qwen2 阿里最强开源大模型&#xff08;Qwen2-7B&#xff09;本地部署、API调用和WebUI对话机器人-CSDN博客 本地快速安装运行史上最强开源LLaMa3大模型 - 廖雪峰的官方网站 (liaoxuefeng.com) 1.下载网站 1.https://www.hugging-face.org/ 2.https://hf-m…

嵌入式linux中设备树使用of函数操作基本方法

各位开发者大家好,今天主要给大家分享一下,如何使用of操作函数,获取对应设备树节点先关的属性信息。 第一:of_find_property函数 of_find_property 函数用于在设备树中查找节点下具有指定名称的属性。如果找到了该属性,可以通过返回的属性结构体指针进行进一步的操作,比…

强大高效,推荐这两款分析文章和抠图的AI工具

ChatDOC ChatDOC是一款基于ChatGPT的AI阅读辅助工具&#xff0c;旨在通过与用户指定的文档进行对话来处理用户的专属数据。它能够帮助用户快速提取文档中的信息&#xff0c;支持多种文件格式&#xff0c;并提供准确的答案。此外&#xff0c;ChatDOC还具备智能格式化、自动摘要生…

博客摘录「 AXI三种接口及DMA DDR XDMA介绍(应用于vivado中的ip调用)」2024年6月10日

关键要点&#xff1a; 1.AXI Stream经过协议转换可使用AXI_FULL&#xff08;PS与PL间的接口&#xff0c;如GP、HP和ACP&#xff09;。 2.传输数据类里就涉及一个握手协议&#xff0c;即在主从双方数据通信前&#xff0c;有一个握手的过程。基本内容&#xff1a;数据的传输源会…

A股上市公司MSCI ESG评级面板数据(2017-2023)

数据简介&#xff1a;MSCI ESG&#xff08;Environmental, Social, and Governance&#xff09;评级是由 MSCI Inc. 提供的一项服务&#xff0c;旨在评估公司在环境、社会和治理方面的表现。MSCI 是一家全球领先的投资研究和指数提供商&#xff0c;其 ESG 评级被广泛用于评估企…

6月13日 Qtday1

#include "mywidget.h" //腾讯会议的登录界面 MyWidget::MyWidget(QWidget *parent): QMainWindow(parent) {this->setFixedSize(468,830);//主窗口大小this->setStyleSheet("background-color:rgb(255,255,255)");//主窗口背景this->setWindowTi…

采用ava+B/S架构开发的工业级UWB(Ultra-Wideband)室内定系统源码UWB定位系统技术接口及技术特点

采用avaB/S架构开发的工业级UWB&#xff08;Ultra-Wideband&#xff09;室内定系统源码UWB定位系统技术接口及技术特点 UWB&#xff08;Ultra-Wideband&#xff09;定位技术本身并不直接连接蓝牙或其他无线通信技术进行定位。然而&#xff0c;在实际应用中&#xff0c;UWB定位技…

Salesforce‘s 爱因斯坦机器人助手引领工业聊天机器人时代

CRM的对话式人工智能助手&#xff0c;根据公司数据提供可靠的人工智能响应及日本工业聊天机器人现状 【前言】 爱因斯坦助手&#xff08;Einstein Copilot&#xff09;提供可靠的响应&#xff0c;因为它基于公司独特的数据和元数据&#xff0c;使其能够深入了解公司的业务和客…

STM32F103ZET6_HAL_CAN

1定义时钟 2定义按键 按键上拉电阻 3开启串口 4打开CAN&#xff08;具体什么意思上一篇讲了&#xff09; 5生成代码 /* USER CODE BEGIN Header */ /********************************************************************************* file : main.c* brief …

vue+elementplus模拟“山野愚人居”简单实现个人博客

目录 一、项目介绍 二、项目截图 1.项目结构图 2.项目首页 3.文章详情 4.留言 5.读者 三、源码实现 1.项目依赖package.json 2.项目启动 3.读者页面源码 四、总结 一、项目介绍 模仿原博客&#xff1a;山野愚人居 - 记录我的生活、所见、所闻、所想…… 本项目参考以…

RedHat8.4离线升级内核(漏洞编号CVE-2024-1086)

一、背景 针对Linux内核提取权限漏洞 (漏洞编号CVE-2024-1086&#xff09;&#xff0c;整理离线环境的修复方案。本文以离线修复方案为主进行说明&#xff0c;第八章对在线修复方案进行说明。 (一) 漏洞简介 近日&#xff0c;绿盟科技CERT监测网上有研究员公开披露了一个Lin…

解决electron设置透明背景后,引入element-plus样式问题

首先给当前窗口设置自定义窗口以及背景色。 const mainWindow new BrowserWindow({width: 900,height: 670,show: false,autoHideMenuBar: true,...(process.platform linux ? { icon } : {}),webPreferences: {preload: join(__dirname, ../preload/index.js),sandbox: fal…

问题:棕色试剂瓶用于盛装见光易分解的试剂或溶剂。 #其他#学习方法#微信

问题&#xff1a;棕色试剂瓶用于盛装见光易分解的试剂或溶剂。 A、正确 B、错误 参考答案如图所示

高创新 | CEEMDAN-VMD-BiLSTM-Attention双重分解+双向长短期记忆神经网络+注意力机制多元时间序列预测

目录 效果一览基本介绍模型设计程序设计参考资料 效果一览 基本介绍 高创新 | CEEMDAN-VMD-BiLSTM-Attention双重分解双向长短期记忆神经网络注意力机制多元时间序列预测 本文提出一种基于CEEMDAN 的二次分解方法&#xff0c;通过样本熵重构CEEMDAN 分解后的序列&#xff0c;复…

【iOS】KVC相关总结

目录 1. 什么是KVC&#xff1f;2. 访问对象属性常用方法声明基础使用KeyPath路径多值操作 3. 访问集合属性4. 集合运算符自定义集合运算符 5. 非对象值处理访问基本数据类型访问结构体 6. 属性验证7. 设值和取值原理基本的Getter搜索模式基本的Setter搜索模式NSMutableArray搜索…

webpack代码分割

webpack代码分割方式 entry配置&#xff1a;通过多个 entry 文件来实现动态加载(按需加载)&#xff1a;通过主动使用import来动态加载抽取公共代码&#xff1a;使用splitChunks配置来抽取公共代码 基础概念 概念含义Entry入口&#xff0c;Webpack 执行构建的第一步将从 Entr…

vue 中多个表单元素控一个校验规则

1. 场景一 <el-form-itemlabel"确认时长方式"prop"preSubResourceDurationDay" ><div class"confirmDurationDay">最晚使用日期前<el-input-numberv-model"form.preSubResourceDurationDay":precision"0"cla…