amehime / hexo-theme-shoka

Just For https://shoka.lostyu.me/
MIT License
896 stars 206 forks source link

似乎不支持编辑链接title? #44

Open hxYuki opened 3 years ago

hxYuki commented 3 years ago

[aaa](https://example.com "a1 a2 a3")

引号内的title并未生效,仍然是aaa

YangLinzhuo commented 3 years ago

好像没见过这种格式,是主题里面提供的额外拓展吗? 一般的 markdown 格式就是 [link_title](url_link) 这种的,所以如果要用 title 的话,直接写在前面的方括号中就可以了

hxYuki commented 3 years ago

好像没见过这种格式,是主题里面提供的额外拓展吗? 一般的 markdown 格式就是 [link_title](url_link) 这种的,所以如果要用 title 的话,直接写在前面的方括号中就可以了

这样做会连同链接文字本身一起改变,我想的是用 title 进行些补充 标准似乎是 [link_text](link_url "link_title") ,像 github 这样: aaa 应该不算是额外扩展吧,但是主题并未实现该处理

YangLinzhuo commented 3 years ago

你说的是把鼠标放上去会显示详细信息这样的效果吧? 如果是的话,我自己试了下是可以的,是你那边渲染器的问题吗? image

hxYuki commented 3 years ago

是这样,那应该是渲染器的问题了 你是用的什么其他渲染器吗?

还是说同样的hexo-renderer-multi-markdown-it不同的行为 :innocent:

YangLinzhuo commented 3 years ago

我用的就是 hexo-renderer-multi-markdown-it ... 那这样就很奇怪了 (捂脸) 我应该是没有修改这个渲染器的,默认情况下应该是能解析的,因为这个算是 markdown 比较基本的语法 最好有其他人能够提供一下他的情况,看看问题出在哪里

hxYuki commented 3 years ago

今天重装了几次,其中第一次正确设置了 title ,但随后我把之前的文章复制过来后连带把问题也带过来了 后面都没能再重现正常的行为,太奇怪了

YangLinzhuo commented 3 years ago

emm,确实很奇怪。 如果重装之后第一次能够正确设置 title,我怀疑是之前的内容有哪里出了问题导致无法正确解析。 如果原来的内容不多的话,或许可以试着一点点复制内容,看看是哪里出了问题。

hxYuki commented 3 years ago

进一步发现问题在于文章内链接会生成为 <span class="exturl" data-url="aHR0cHM6Ly9oZXhvLmlvLw==">Hexo</span> ,链接本身被 base64 编码后放进了 span 中,在浏览器显示时又会被替换成 a ,这一步明显把设置的 title 给丢了

而我重新创建项目不使用主题,仅使用 hexo-renderer-multi-markdown-it 替换默认渲染器却并没有发现这样的行为

hxYuki commented 3 years ago

scripts/filters/posts.js 发现了该行为的代码,似乎是将站外链接进行转换,而站内链接不做处理,这样是有什么特殊用意吗

进一步发现问题在于文章内链接会生成为 <span class="exturl" data-url="aHR0cHM6Ly9oZXhvLmlvLw==">Hexo</span> ,链接本身被 base64 编码后放进了 span 中,在浏览器显示时又会被替换成 a ,这一步明显把设置的 title 给丢了

而我重新创建项目不使用主题,仅使用 hexo-renderer-multi-markdown-it 替换默认渲染器却并没有发现这样的行为

YangLinzhuo commented 3 years ago

嗯,我这里也发现了这个问题。之前那次能成功就很奇怪(捂脸) 实测把 posts.js 里面的内容注释掉就可以成功了,但是我不太了解这个 posts.js 为什么要把网址进行转换,不知道有没有什么安全上的考虑。 只使用 hexo-renderer-multi-markdown-it 能成功是因为这个脚本是在渲染器完成了转换后执行的,所以不使用主题的话不会执行这个脚本。

YangLinzhuo commented 3 years ago

想了想,之前可能是因为直接使用了 hexo s,引擎没有使用这个脚本进行转换,所以之前能够成功。 span 标签也有 title 属性,不知道在替换的时候也进行保留是否可行。我对 js 里面的正则表达式不是太熟悉,感觉改起来还挺麻烦的。

hxYuki commented 3 years ago

具体到 hexo 的运行方式我是没明白,不过后面发现 scripts/helpers/engine.js:52 中也有类似的处理行为,还设计了一条 exturl 的配置来控制行为,不过通过断点调试发现应该只针对全局布局内而非文章中的 url

hxYuki commented 3 years ago

想了想,之前可能是因为直接使用了 hexo s,引擎没有使用这个脚本进行转换,所以之前能够成功。 span 标签也有 title 属性,不知道在替换的时候也进行保留是否可行。我对 js 里面的正则表达式不是太熟悉,感觉改起来还挺麻烦的。

这个主要的问题是只找到了将 a 标签转换为 span 标签的代码,却没有 span 转回 a 的代码, hexo g 生成的文件里是 span 标签,浏览器显示出来的是 a 标签,不知道这里面有没有处理其他的 attr

YangLinzhuo commented 3 years ago

/source/js/_app/page.js 里面有这段代码:

const registerExtURL = function() {
  $.each('span.exturl', function(element) {
      var link = document.createElement('a');
      // https://stackoverflow.com/questions/30106476/using-javascripts-atob-to-decode-base64-doesnt-properly-decode-utf-8-strings
      link.href = decodeURIComponent(atob(element.dataset.url).split('').map(function(c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
      }).join(''));
      link.rel = 'noopener external nofollow noreferrer';
      link.target = '_blank';
      link.className = element.className;
      link.title = element.title || element.innerText;
      link.innerHTML = element.innerHTML;
      if(element.dataset.backgroundImage) {
        link.dataset.backgroundImage = element.dataset.backgroundImage;
      }
      element.parentNode.replaceChild(link, element);
    });
}

这个应该就是转换的代码了,这里设置了 title 属性,但是因为原来的 span 里面没有加 title,所以这里使用的就是 element.innerText 的内容直接替换了。

我觉得应该在 posts.js 里面把 title 补上的话应该就能够获得你想要的效果了。

image 我这里的标签属性和这段代码里面都是对应的,所以应该就是这里没错了

hxYuki commented 3 years ago

这样的话我回去改一下正则表达式看看,感觉可以水一个 pr (逃

YangLinzhuo commented 3 years ago

🤣 在线等一个 pr

YangLinzhuo commented 3 years ago
var reg = /title="([^"]+)"/im;
let result = reg.exec(match);
if (result !== null && result.length > 1) {
  return `<span class="exturl" data-url="${Buffer.from(href).toString('base64')}" title="${result[1]}">${html}</span>`;
}

自己动手了 🤣 凭我有限的 js 知识写的,在返回语句之前加上这一段。如果有隐藏问题的话可以帮忙订正一下,目前我测试的结果是可以的。

hxYuki commented 3 years ago

耗费了好几根头发,决定还是只写一个正则表达式 /<a[^>]* ((?:href)|(?:title))="([^"]+)"[^>]* ((?:href)|(?:title))="([^"]+)"[^>]*>([^<]*)<\/a>/img (致 命 高 雅

YangLinzhuo commented 3 years ago

耗费了好几根头发,决定还是只写一个正则表达式 /<a[^>]* ((?:href)|(?:title))="([^"]+)"[^>]* ((?:href)|(?:title))="([^"]+)"[^>]*>([^<]*)<\/a>/img (致 命 高 雅

👍 太强了 👏 来一手 pr 这个问题应该可以 close 了

hxYuki commented 3 years ago

等 pr 合并这个 issue 就自动关了,坐等 💤