李恒道 发表于 2024-4-15 00:10:54

尝试抹平Tampermonkey的VSCode开发体验(四)

之前我们确定了如何直接通过dispatch触发更新脚本
所以可以直接编写上传和更新的代码

```js
async function setTMScript(uuid = "new-user-script", scriptContent) {
return new Promise((resolve, reject) => {
    const isCreated = uuid === "new-user-script";
    const sender = JSON.parse(fakeMessageSender);
    if (!isCreated) {
      sender.tab.url =
      "chrome-extension://ppigooooicocpkikgggonplalbnnpkfj/options.html#nav=" +
      uuid +
      "+editor";
    }
    chrome.runtime.onMessage.dispatch(
      {
      auto_save: undefined,
      clean: false,
      code: scriptContent,
      force: undefined,
      lastModTime: isCreated ? undefined : new Date().getTime(),
      method: "saveScript",
      new_script: isCreated ? true : false,
      reload: true,
      restore: undefined,
      uuid: uuid,
      },
      sender,
      (response) => {
      if (response.uuid !== undefined) {
          //成功
          resolve({ uuid: response.uuid });
      } else {
          //失败
          reject();
      }
      }
    );
});
}
```
然后在插件中声明一个socket监听发送脚本的数据,如果接收到了脚本就设置到油猴管理器中
```js
var socket = io("http://<%= socketURL %>");
async function init() {
const scriptData = {};
socket.on("saveScript", (name, scriptContent) => {
    console.log("saveScript", name, scriptContent);
    setTMScript(scriptData, scriptContent)
      .then(({ uuid }) => {
      scriptData = uuid;
      socket.emit("saveScriptResult", "success", name);
      })
      .catch(() => {
      socket.emit("saveScriptResult", "failed", name);
      });
});
}
init();
```
目前新建脚本已经搞定了,但是修改脚本会触发tampermonkey的冲突提示
![图片.png](data/attachment/forum/202404/14/232753yiuurf4iwmmd6rli.png)
这个经过调试我没有找到太好的解决办法
但是可以利用dispatch投递消息解除掉这个弹窗
```js
function allowAskCom(uuid) {
const form = {
    method: "askCom",
    data: {
      aid: uuid,
      message: undefined,
      method: "install",
    },
};
const sender = JSON.parse(fakeMessageSender);
   chrome.runtime.onMessage.dispatch(form, sender, (response) => {
    console.log("response", response);
});
}
```
但是必须在tabs开启后,所以可以对tabs.create做劫持,如果检测到ask.html启动就自动跳过
这里传入-1是因为根据调试必须给一个返回才能继续流程,而我们传入伪造的id,就会导致remove无法正常运行,所以必须也将remove劫持掉
```js
const tabsCreate = chrome.tabs.create;
const tabsRemovce = chrome.tabs.remove;

chrome.tabs.remove = function (id, callback, ...args) {
if (id === -1) {
    return;
}
const result = tabsCreate.call(this, id, callback, ...args);
return result;
};

chrome.tabs.create = function (obj, callback, ...args) {
const url = obj.url;
if (url.indexOf("ask.html?") !== -1) {
    const uuid = url.split("aid=");

    allowAskCom(uuid);

    //pass hook
    callback({
      id: -1,
    });
    return undefined;
}
const result = tabsCreate.call(this, obj, callback, ...args);
return result;
};
```
那我们在插件端的工作就大功搞成了,接下来只需要在本地发送脚本数据即可
```js
    function sendScriptContent(unionName, scriptContent) {
      if (unionName === undefined) {
      console.warn(unionName + "script unionName is not define");
      return;
      }
      io.emit("saveScript", unionName, scriptContent);
    }
```
其余的文件监听等等可以视为进一步的封装,我们就不继续谈了
页: [1]
查看完整版本: 尝试抹平Tampermonkey的VSCode开发体验(四)