【Hexo】复制代码不换行

1. 问题描述

在博客文章中复制代码块时,发现不换行。

<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>${mybatis.version}</version> </dependency>
来源: 叶遮沉阳
作者: 叶遮沉阳
链接: http://localhost:4000/2020/072722410.html
本文章著作权归作者所有,任何形式的转载都请注明出处。

看看源码是怎么实现的,然后在浏览器F12调试一下。

2. 解决过程

themes\matery\_config.yml中,可以看到配置如下:

# 是否激活复制文章时追加博客和作者的版权信息.
copyright:
  enable: true
  minCharNumber: 120 # 至少复制多少个字符就追加版权信息.
  description: 本文章著作权归作者所有,任何形式的转载都请注明出处。

复制文章字数超过120就会追加版权信息。

IDEA中根据内容查找文件还是挺方便的,
ctrl+shift+f
在输入框输入copyright.enable,就找到位置了。

原来在themes\matery\layout\_partial\post-detail.ejs中。

看看源代码是怎么实现的:

<% if (theme.copyright.enable) { %>
<script>
    $('#articleContent').on('copy', function (e) {
        // IE8 or earlier browser is 'undefined'
        if (typeof window.getSelection === 'undefined') return;

        var selection = window.getSelection();
        // if the selection is short let's not annoy our users.
        if (('' + selection).length < Number.parseInt('<%- theme.copyright.minCharNumber %>')) {
            return;
        }

        // create a div outside of the visible area and fill it with the selected text.
        var bodyElement = document.getElementsByTagName('body')[0];
        var newdiv = document.createElement('div');
        newdiv.style.position = 'absolute';
        newdiv.style.left = '-99999px';
        bodyElement.appendChild(newdiv);
        newdiv.appendChild(selection.getRangeAt(0).cloneContents());

        // we need a <pre> tag workaround.
        // otherwise the text inside "pre" loses all the line breaks!
        if (selection.getRangeAt(0).commonAncestorContainer.nodeName === 'PRE') {
            newdiv.innerHTML = "<pre>" + newdiv.innerHTML + "</pre>";
        }

        if (selection.getRangeAt(0).commonAncestorContainer.nodeName === 'CODE') {
            newdiv.innerHTML = "<pre>" + newdiv.innerHTML + "</pre>";
        }

        var url = document.location.href;
        newdiv.innerHTML += '<br />'
            + '<%- __("from")  %>: <%- config.title %><br />'
            + '<%- __("author")  %>: <%- config.author %><br />'
            + '<%- __("link")  %>: <a href="' + url + '">' + url + '</a><br />'
            + '<%- theme.copyright.description %>';

        selection.selectAllChildren(newdiv);
        window.setTimeout(function () {bodyElement.removeChild(newdiv);}, 200);
    });
</script>
<% } %>

可以发现换行的代码在这:

// we need a <pre> tag workaround.
// otherwise the text inside "pre" loses all the line breaks!
if (selection.getRangeAt(0).commonAncestorContainer.nodeName === 'PRE') {
    newdiv.innerHTML = "<pre>" + newdiv.innerHTML + "</pre>";
}

接下来就在浏览器调试了。

  1. 本地启动项目后,打开要复制的代码所在文章;
  2. F12,打开开发者工具;
  3. 在开发者工具的顶部菜单栏,在点击source
  4. 根据你的文章url,在左侧Page找到你的文章页面并双击打开;
  5. 在中间源码窗口可以看到文章的源码,在按ctrl+f,搜索selection,找到复制文章添加版权的源码;
  6. 上面我们已经找到是添加PRE实现换行的,所以在行号点击一下打个断点;
  7. 然后刷一下,复制一块代码,页面会在你的断点处停顿;
  8. 接下来,按F10一步步往下执行;
  9. 一番调试,发现根本没进入if (selection.getRangeAt(0).commonAncestorContainer.nodeName === 'PRE')这个条件代码块,所以导致不换行;
  10. 找到原因就好办了,先看看selection.getRangeAt(0).commonAncestorContainer.nodeName的值是什么来着;
  11. 你可以在调试的时候,运行到它的下一行,在完整选中selection.getRangeAt(0).commonAncestorContainer.nodeName,然后看看值是多少;
  12. 经过多次验证,发现它的值不稳定,有时候是CODE,有时候是DIV
  13. 既然如此,那就不管了,直接将条件干掉就得了;

3. 解决方案

修改themes\matery\layout\_partial\post-detail.ejs

修改前:

// we need a <pre> tag workaround.
// otherwise the text inside "pre" loses all the line breaks!
if (selection.getRangeAt(0).commonAncestorContainer.nodeName === 'PRE') {
    newdiv.innerHTML = "<pre>" + newdiv.innerHTML + "</pre>";
}

修改后:

// we need a <pre> tag workaround.
// otherwise the text inside "pre" loses all the line breaks!
// if (selection.getRangeAt(0).commonAncestorContainer.nodeName === 'PRE') {
//     newdiv.innerHTML = "<pre>" + newdiv.innerHTML + "</pre>";
// }

//注释掉上面的if,将if中的内容释放出来
newdiv.innerHTML = "<pre>" + newdiv.innerHTML + "</pre>";

文章作者: 叶遮沉阳
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 叶遮沉阳 !
  目录