笑尘天雨 发表于 2022-9-10 16:46:53

不想动脑子了,大佬们请进,求教油猴的include是如何实现的

起因如下:
目前已经有一个rollup-plugin实现注释提升到头部。但是如果是多网站的话是需要判断具体是哪一个网站的,对应的网站运行对应的代码。
所以我想着,既然能注释提升到头部,那么只要在写代码的时候把注释写到函数内部,然后进行判断就可以省去手动判断网站了,达到一注释多用的目的。
目前已经能拿到注释内容,接下来就是实现油猴的@include来做判断是否命中网站,但是由于我没怎么写过油猴脚本[之前只是写的类似via脚本不需要@include功能],所以需要大佬们提供一下@include实现源码或者具体思路。
附当前代码:
```
function parseComment(comment) {
comment = comment.trim().substring(2).trim();
if (comment.startsWith("@")) {
    const index = comment.indexOf(" ");
    if (index === -1) return ;
    return ;
}
return ["", ""];
}
function AtInclude(value){
        // 需要在此实现@include命中功能
return true;
}
function isInclude(comment){
        const = parseComment(comment);
        if(key !== 'include') return false;
        return AtInclude(value);
}
function include(callback){
        const comments = callback.toString().match(/^[^"'`\n]+\/\/(.*)/gm);
        if (!comments || !comments.some(isInclude)) return;
        callback();
}
```

使用方法如下:
```
include(() => {
    // @include http*://bbs.tampermonkey.net.cn/*
    document.querySelectorAll('#hd #comiis_nv a')?.?.click()
})
```

李恒道 发表于 2022-9-10 18:05:23

@王一之 太硬了,我答不动,王总上

steven026 发表于 2022-9-10 18:54:01

本帖最后由 steven026 于 2022-9-10 19:01 编辑

```
// ==UserScript==
// @name         New Userscript
// @version      1.0
// @descriptiontry to take over the world!
// @match      *://*/*
// @grant      none
// ==/UserScript==

AtInclude(() => {
    // @include http*://bbs.tampermonkey.net.cn/*
    alert("AtInclude: true")
})


//////////////////////

function AtInclude(value){
    let commentHref=value.toString().match(/\/\/ @(include|match) (.+)\n/)?.;
    let regHref=new RegExp(commentHref?.replace(/\?/g,".")?.replace(/\*/g,".*?"));
    if(!regHref.test(location.href)) return;
    value();
}
```

这样?
一般油猴同时匹配多个网址又要针对不同网址运行不同代码时,可以通过对比location.href来判断网址,然后调用相应函数
这样写太复杂了,一般都是这么写
```
// ==UserScript==
// @name         New Userscript
// @version      1.0
// @descriptiontry to take over the world!
// @match      *://*/*
// @grant      none
// ==/UserScript==

if(location.href.includes("bbs.tampermonkey.net.cn")){
    油中()
}

function 油中(){
    alert("bbs.tampermonkey.net.cn")
    //code here
}
```

笑尘天雨 发表于 2022-9-10 20:05:33

steven026 发表于 2022-9-10 18:54
```
// ==UserScript==
// @name         New Userscript


不是这样。
比如说原来的是这样的写法:
```
// ==UserScript==
// @name         New Userscript
// @version      1.0
// @descriptiontry to take over the world!
// @include      http*://bbs.tampermonkey.net.cn/*
// @include      https://m.hafuktxt.com/chapter/*/*
// ==/UserScript==

if(location.href.includes("bbs.tampermonkey.net.cn")){
    document.querySelectorAll("#hd #comiis_nv a")?.?.click();
}

if (location.href.includes("https://m.hafuktxt.com/chapter/*/*")) {
document
    .querySelectorAll("#__dfdsdefsdb")
    ?.forEach((el) => (el.style.display = "none"));
document.querySelector(
    "#chaptercontent"
).previousElementSibling.style.display = "none";
document.querySelector("#chaptercontent").nextElementSibling.style.display =
    "none";
}
```

比如说现在是这样
utils.js
```
function parseComment(comment) {
comment = comment.trim().substring(2).trim();
if (comment.startsWith("@")) {
    const index = comment.indexOf(" ");
    if (index === -1) return ;
    return ;
}
return ["", ""];
}
function AtInclude(value){
    // 需要在此实现@include命中功能
return true;
}
function isInclude(comment){
    const = parseComment(comment);
    if(key !== 'include') return false;
    return AtInclude(value);
}
function include(callback){
    const comments = callback.toString().match(/^[^"'`\n]+\/\/(.*)/gm);
    if (!comments || !comments.some(isInclude)) return;
    callback();
}

```
main.js
```
// @version      1.2

import { include } from './utils'
include(() => {
    // @include http*://bbs.tampermonkey.net.cn/*
    document.querySelectorAll('#hd #comiis_nv a')?.?.click()
})
include(() => {
    // @include         https://m.hafuktxt.com/chapter/*/*
    document.querySelectorAll('#__dfdsdefsdb')?.forEach( el => el.style.display = 'none');
      document.querySelector('#chaptercontent').previousElementSibling.style.display = 'none';
          document.querySelector('#chaptercontent').nextElementSibling.style.display = 'none';
})
```
使用rollup插件打包之后会自动把// @include这一行提到头部,大概就是
```
// ==UserScript==
// @name         New Userscript
// @version      1.2
// @descriptiontry to take over the world!
// @include      http*://bbs.tampermonkey.net.cn/*
// @include      https://m.hafuktxt.com/chapter/*/*
// ==/UserScript==

function parseComment(comment) {
comment = comment.trim().substring(2).trim();
if (comment.startsWith("@")) {
    const index = comment.indexOf(" ");
    if (index === -1) return ;
    return ;
}
return ["", ""];
}
function AtInclude(value){
    // 需要在此实现@include命中功能
return true;
}
function isInclude(comment){
    const = parseComment(comment);
    if(key !== 'include') return false;
    return AtInclude(value);
}
function include(callback){
    const comments = callback.toString().match(/^[^"'`\n]+\/\/(.*)/gm);
    if (!comments || !comments.some(isInclude)) return;
    callback();
}
include(() => {
    // @include http*://bbs.tampermonkey.net.cn/*
    document.querySelectorAll('#hd #comiis_nv a')?.?.click()
})
include(() => {
    // @include         https://m.hafuktxt.com/chapter/*/*
    document.querySelectorAll('#__dfdsdefsdb')?.forEach( el => el.style.display = 'none');
      document.querySelector('#chaptercontent').previousElementSibling.style.display = 'none';
          document.querySelector('#chaptercontent').nextElementSibling.style.display = 'none';
})
```
所以我需要完成@include和@match的命中逻辑

steven026 发表于 2022-9-10 20:24:50

笑尘天雨 发表于 2022-9-10 20:05
不是这样。
比如说原来的是这样的写法:
```


```
// ==UserScript==
// @name         New Userscript
// @version      1.2
// @descriptiontry to take over the world!
// @include      http*://bbs.tampermonkey.net.cn/*
// @include      https://m.hafuktxt.com/chapter/*/*
// ==/UserScript==

function parseComment(comment) {
    comment = comment.trim().substring(2).trim();
    if (comment.startsWith("@")) {
      const index = comment.indexOf(" ");
      if (index === -1) return ;
      return ;
    }
    return ["", ""];
}
function AtInclude(value){
    let regHref=new RegExp(value?.replace(/\?/g,".")?.replace(/\*/g,".*?"));
    if(regHref.test(location.href)) return true
}
function isInclude(comment){
    const = parseComment(comment);
    if(key !== 'include') return false;
    return AtInclude(value);
}
function include(callback){
    const comments = callback.toString().match(/^[^"'`\n]+\/\/(.*)/gm);
    if (!comments || !comments.some(isInclude)) return;
    callback();
}
include(() => {
    // @include http*://bbs.tampermonkey.net.cn/*
    document.querySelectorAll('#hd #comiis_nv a')?.?.click()
})
include(() => {
    // @include         https://m.hafuktxt.com/chapter/*/*
    document.querySelectorAll('#__dfdsdefsdb')?.forEach( el => el.style.display = 'none');
    document.querySelector('#chaptercontent').previousElementSibling.style.display = 'none';
    document.querySelector('#chaptercontent').nextElementSibling.style.display = 'none';
})
```

笑尘天雨 发表于 2022-9-10 21:53:22

steven026 发表于 2022-9-10 20:24
```
// ==UserScript==
// @name         New Userscript


@match和@include有什么不同吗?还有@exclude
是之前考虑不周了,这三个得同时实现才行,不然和tampermonkey的命中规则不一样。

steven026 发表于 2022-9-10 22:30:00

笑尘天雨 发表于 2022-9-10 21:53
@match和@include有什么不同吗?还有@exclude
是之前考虑不周了,这三个得同时实现才行,不然和tampermon ...

大概就是@include的*匹配不安全可能会被钓鱼,@match的*匹配限制更严格
油猴的eslint说 明年年初@include可能会被弃用建议用@match
@exclude是匹配黑名单,从@match或者@include匹配结果中剔除

笑尘天雨 发表于 2022-9-10 22:47:10

steven026 发表于 2022-9-10 22:30
大概就是@include的*匹配不安全可能会被钓鱼,@match的*匹配限制更严格
油猴的eslint说 明年年初@include ...

为啥要把[?]替换成[.]?
@match咋写

王一之 发表于 2022-9-11 00:30:55

推荐使用@match

https://docs.scriptcat.org/dev/meta.html#match

实现的话,我是分为四段使用正则实现的

:///?

steven026 发表于 2022-9-11 11:39:40

本帖最后由 steven026 于 2022-9-11 12:00 编辑

> 本帖最后由 steven026 于 2022-9-11 11:55 编辑

> 本帖最后由 steven026 于 2022-9-11 11:54 编辑

因为用的是正则去判断网址,通配符的`?`在正则里面就是`.`

@match和@include主要有2个区别
一是通配符\*的区别,写成正则形式应该是一样的
不建议用@include,比如`@include *bbs.tampermonkey.net.cn*`可能会被`https://钓鱼网站.com/bbs.tampermonkey.net.cn`钓鱼
如果写成`@include *://bbs.tampermonkey.net.cn/*`就不会被钓鱼,但写法就和@match一样了

(还有一个是油猴include可以用正则、match不能用正则;脚本猫include、match都不能用正则)
页: [1] 2
查看完整版本: 不想动脑子了,大佬们请进,求教油猴的include是如何实现的