zkz098's blog

shoka主题-对shoka主题的小修小补

发布于 字数统计 4.9k 字 阅读时长 17 分钟

shoka主题-对shoka主题的小修小补

发布于 字数统计 4,866 阅读时长 25 分钟

本篇为本站LTS文章,会长期更新

引言

最近摸了一个月鱼没有更新什么正经文章,基本都是shoka的改造
近期在 摸鱼 时发现shoka主题的js有近200个弱警告和10余个警告,就想处理一下这些警告

本文基本是兼容性换性能和未来支持,基本IE系列就全系不支持了

ES6语法

升级uglifyjs

建议使用hexo-renderer-multi-next-markdown-it,卸载hexo-renderer-multi-markdown-it后安装即可

铺面而来的就是使用了var而非let或const这个警告,随后就直接使用了WebStorm的快速修复,然后hexo g:

ERROR: Unexpected token: keyword «const»

网上针对这个的教程都是替换为uglify-es,但在npm主页 中明确写道: support for ECMAScript is superseded by 'uglify-js' as of v3.13.0
所以直接升级uglify-js即可:
打开yourblog\node_modules\hexo-renderer-multi-markdown-it\,随后运行cnpm i uglify-js,等待安装完毕。
随后打开node_modules\hexo-renderer-multi-markdown-it\lib\filter.js,打开第90行左右:

var result = UglifyJS.minify(str, options);
var saved = (((str.length - result.code.length) / str.length) * 100).toFixed(2);
if (options.logger) {
  var log = hexo.log || console.log;
  log.log("minify the js: %s [ %s saved]", path, saved + "%");
}
var js_result = result.code;
if (options.stamp) {
  var prefix = "// build time:" + Date().toLocaleString() + "\n";
  var end = "\n//rebuild by hrmmi ";
  js_result = prefix + js_result + end;
}
return js_result;

更改为:

const uglify_v3_allow_options = [
  "parse",
  "compress",
  "mangle",
  "output",
  "sourceMap",
  "nameCache",
  "toplevel",
  "warnings",
];
const uglify_options = {};
for (let key of uglify_v3_allow_options) {
  if (options[key] !== undefined) uglify_options[key] = options[key];
}

var result = UglifyJS.minify(str, uglify_options);
if (!result.error) {
  var saved = (((str.length - result.code.length) / str.length) * 100).toFixed(2);
  if (options.logger) {
    var log = hexo.log || console.log;
    log.log("minify the js: %s [ %s saved]", path, saved + "%");
  }
  var js_result = result.code;
  if (options.stamp) {
    var prefix = "// build time:" + Date().toLocaleString() + "\n";
    var end = "\n//rebuild by kaitaku";
    js_result = prefix + js_result + end;
  }
} else throw result.error;
return js_result;

替换var

建议直接使用WebStorm的快速修复替换,没有更快的方法了
但是需要将以下几行代码重新排序:

$.each(p + ' .md img:not(.emoji):not(.vemoji)', function (element) {
                const $image = q(element); // 放到这个位置
                const imageLink = $image.attr('data-src') || $image.attr('src'); // 放到这个位置
                const $imageWrapLink = $image.wrap('<a class="fancybox" href="' + imageLink + '" itemscope itemtype="http://schema.org/ImageObject" itemprop="url"></a>').parent('a');
                let info, captionClass = 'image-info';
                if (!$image.is('a img')) {
                    $image.data('safe-src', imageLink)
                    if (!$image.is('.gallery img')) {
                        $imageWrapLink.attr('data-fancybox', 'default').attr('rel', 'default');
                    } else {
                        captionClass = 'jg-caption'
                    }
                }

下面的代码块是错误的代码块,请手动替换下面函数内的constlet,不要使用WebStorm的自动替换

$.each('figure.highlight', function (element) {
        const code_container = element.child('.code-container'); // 放到这
        const showBtn = code_container.child('.show-btn');
        const hideCode = function () {
            code_container.style.maxHeight = "300px"
            showBtn.removeClass('open')
        };

处理部分弃用语法

杂项属性

global.js中第196行的pageYOffset已经被标记为了弃用,可以使用scrollY代替,直接全局替换即可
player.js第470行的webkitTransform已被标记为弃用,可以直接删除

execCommand处理

主题使用了execCommand进行代码块复制操作,但现在execCommand已经被标记为了弃用
现在已经推出了新的ClipboardAPI 来进行剪切板操作,这个API有以下优点:

  • 底层为异步,速度较快
  • 代码复杂度低,逻辑简单
  • 主流浏览器支持较好(对于一个新兴API而言)

clipboardAPI只能在安全上下文(HTTPS)中使用

打开global.js第276行,找到如下代码:

const clipBoard = function (str, callback) {
  const ta = BODY.createChild("textarea", {
    style: {
      top: window.scrollY + "px", // Prevent page scrolling
      position: "absolute",
      opacity: "0",
    },
    readOnly: true,
    value: str,
  });

  const selection = document.getSelection();
  const selected = selection.rangeCount > 0 ? selection.getRangeAt(0) : false;
  ta.select();
  ta.setSelectionRange(0, str.length);
  ta.readOnly = false;
  const result = document.execCommand("copy");
  callback && callback(result);
  ta.blur(); // For iOS
  if (selected) {
    selection.removeAllRanges();
    selection.addRange(selected);
  }
  BODY.removeChild(ta);
};

将其更改为如下代码:

const clipBoard = function (str, callback) {
  if (navigator.clipboard && window.isSecureContext) {
    console.log("使用clipboard复制"); //测试
    navigator.clipboard.writeText(str).then(
      function () {
        callback && callback(true);
      },
      function () {
        callback && callback(false);
      },
    );
  } else {
    console.log("使用execCommand复制"); //测试
    const ta = BODY.createChild("textarea", {
      style: {
        top: window.scrollY + "px", // Prevent page scrolling
        position: "absolute",
        opacity: "0",
      },
      readOnly: true,
      value: str,
    });

    const selection = document.getSelection();
    const selected = selection.rangeCount > 0 ? selection.getRangeAt(0) : false;
    ta.select();
    ta.setSelectionRange(0, str.length);
    ta.readOnly = false;
    const result = document.execCommand("copy");
    callback && callback(result);
    ta.blur(); // For iOS
    if (selected) {
      selection.removeAllRanges();
      selection.addRange(selected);
    }
    BODY.removeChild(ta);
  }
};

随后重新生成静态文件,打开任意界面复制代码,如果控制台输出了使用clipboard复制,就可以把两行带有测试注释的代码删掉了

目前修补仍在缓慢进行中,此文章会不定期更新