Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【探讨】一种通用翻译替换脚本 #62

Closed
xioxin opened this issue Jan 3, 2020 · 9 comments
Closed

【探讨】一种通用翻译替换脚本 #62

xioxin opened this issue Jan 3, 2020 · 9 comments

Comments

@xioxin
Copy link
Collaborator

xioxin commented Jan 3, 2020

{
  "name": "",
  "version": "0.1",
  "author": [""],
  "description": [""],
  "match": ["example.com", "*.example.com"],
  "data": { // 存储数据
    "tags": [
      {"namespace": "parody","key": "touhou project", "name": "东方系列"}
    ]
  },
  "modules": [ // 模块
    {
      "performer": "DOMReplace", // dom替换模块
      "parameter": {
        "rules": [
          {
            "nodeName": ["#TEXT"], // 遍历节点匹配nodename
            "$dictionary": "JSONATA:tags{namespace & ':' & key: name}", // http://try.jsonata.org/BkFU1x6k8
            "dictionary": {
              "内容a": "内容b"
            },
            "read": "textContent", // 从什么地方读取 attr:title textContent innerHTML innerText
            "write": "textContent", // 写入什么地方 attr:title textContent innerHTML innerText
            "replaces": [ // 正则替换
              {
                "pattern": "([0-9.]+) star",
                "flags": "i",
                "replace": "$1 星"
              }
            ]
          },
          {
            "matches": [ // 指定匹配的节点
              "#list>li .title",
              "#list2>li .title"
            ],
            "replaces": [ // 正则替换
              {
                "pattern": "([0-9.]+) star",
                "flags": "i",
                "replace": "$1 星"
              }
            ],
            "cloneNode": true // 复制一个新的节点,来存储翻译,旧节点display:none隐藏掉,用于兼容其他插件
          }
        ]
      }
    },
    {
      "performer": "InputHint",  // 输入提示模块
      "parameter": {
        "matches": [ // 指定输入框
          "input#search"
        ],
        "$dataset": "JSONATA:tags.{'label': name,'value': namespace & ':' & key}", // http://try.jsonata.org/SJD-ye6y8
        "dataset": [
          {"label": "aaa", "value": "bbb"}
        ]
      }
    },
    {
      "performer": "???",
      "parameter": {

      }
    }
  ]
}
@xioxin xioxin changed the title 一种通用替换脚本 【探讨】一种通用翻译替换脚本 Jan 3, 2020
@xioxin
Copy link
Collaborator Author

xioxin commented Jan 3, 2020

输入框提示等等功能就不好实现了

@Mapaler
Copy link
Collaborator

Mapaler commented Jan 3, 2020

这是数据库的json格式吗?

@xioxin
Copy link
Collaborator Author

xioxin commented Jan 3, 2020 via email

@OpportunityLiu
Copy link
Collaborator

只要你的node能匹配attribute node,其实翻译内容和属性没啥区别

@xioxin
Copy link
Collaborator Author

xioxin commented Jan 4, 2020

更新了结构

@xioxin
Copy link
Collaborator Author

xioxin commented Jan 4, 2020

不知道能不能用eval

@Mapaler
Copy link
Collaborator

Mapaler commented Jan 4, 2020

脚本内可以用eval的

@xioxin
Copy link
Collaborator Author

xioxin commented Jan 4, 2020

另外 可以使用tabs.executeScript 替代现在用的content_scripts 将数据直接构建到代码里,就可以摆脱对localStorage的依赖还能简化数据同步的逻辑,executeScript是异步的,不知道的可靠性怎么样,如果代码没有在body的dom加载之前注入的话可能会导致翻译失效。

browser.tabs.onUpdated.addListener(async (tabId: number, changeInfo, tab) => {
    if(changeInfo['status'] != 'loading') return;
    const id = tabId;
    console.log('tab onUpdated', tabId, changeInfo, tab);
    console.log(tagDatabase.tagList.value);
    const code = `
    console.log('test');
        window.tagData = ${JSON.stringify(tagDatabase.tagList.value, null, 2)};
        function test(node) {
            if(node.nodeName == '#text' && node.parentNode && node.parentNode.nodeName != 'SCRIPT' )node.textContent = node.textContent + '🐹';
        }
        const observer = new MutationObserver(mutations => mutations.forEach(mutation =>
            mutation.addedNodes.forEach(node1 => {
                test(node1);
                if (this.documentEnd && node1.childNodes) {
                    const nodeIterator = document.createNodeIterator(node1);
                    let node = nodeIterator.nextNode();
                    while (node) {
                        test(node);
                        node = nodeIterator.nextNode();
                    }
                }
            })
        ));
        observer.observe(window.document, {
            attributes: true,
            childList: true,
            subtree: true
        });
     `;
    await browser.tabs.executeScript(id, {
        code: `
            const script = document.createElement('script');
            script.innerHTML = \`${code.replace(/`/igm, '\\`').replace(/\\/igm, "\\\\")}\`;
            document.head.appendChild(script);
        `,
        runAt: "document_start",
    });
});

@DiamondYuan
Copy link

是不是可以通过拦截 HTTP 请求来实现翻译。

@xioxin xioxin closed this as completed Apr 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants