微信小程序基于 Parser 添加长按复制、代码高亮等功能

小程序 About 3,272 words

功能展示

longpresscopy.gif

引入Parser

微信小程序中引入Parser可直接在项目主页查阅。

代码高亮

高亮插件

Prism官网下载prism.jsprism.css,默认只有css代码有渲染样式,注意选择需要渲染的语言。

小程序所用样式下载路径

https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript+bash+c+csharp+cpp+dart+erlang+git+go+graphql+http+hpkp+hsts+ini+java+javadoc+javadoclike+javastacktrace+json+kotlin+lua+makefile+markup-templating+nginx+objectivec+php+phpdoc+php-extras+properties+python+rust+sql+swift+yaml

添加代码

Parser-libs-MpHtmlParser.jsparse函数中if (config.highlight)判断分支下,修改正则匹配。

因为本人的后端程序处理代码块在<pre><code class="language-java">code here</code></pre>中,所以正则匹配并提取文章中的代码。

  • $1class="language-java"
  • $2是代码整体内容
  • config.highlight是真正的高亮函数
this.data = this.data.replace(/<pre><code([\s\S]*?)>([\s\S]*?)<\/code[\s\S]*?><\/pre>/g, function($, $1, $2) {
    return "<pre><code" + $1 + '>' + config.highlight($2, "<code" + $1 + '>') + "</code><\/pre>";
})

Parser-libs-config.js中添加highlight高亮函数,并且把函数导出。

Parser默认使用js语法来高亮代码,这里稍作修改,对传入的class="language-java"提取出对应语言。

备注:因为后端对提交的文章内容进行了防注入,转换了<>&等符号,所以在高亮时转换回正常符号。

const Prism = require('../../utils/prism.js');
var highlight = function (content, attrs) {
  content = content.replace(/&lt;/g, '<');
  content = content.replace(/&gt;/g, '>');
  content = content.replace(/&amp;/g, '&');
  //提取出对应语言
  var m = attrs.match(/"languages?-(.*)"/i);
  var lang = m ? m[1] : 'js'
  return Prism.highlight(content, Prism.languages[lang], lang)
}

module.exports = {
  // 高亮处理函数
  highlight: highlight
  ...
}

长按复制

代码高亮功能已经是Parser提供的功能了,只是在此基础上修改了符号自己需求的代码。

长按复制功能是考虑到代码段较多,代码展示的区域又是可以滑动的,Parser提供的selectable选项需要手动拖动选择,出于此考虑做了一个增进。

  1. MpHtmlParser构造函数:自定义一个数组接收代码内容。
//MpHtmlParser构造函数
constructor(data, options = {}, cb) {
    ...
    this._parserCodeContent = [];
}
  1. MpHtmlParserparse函数:代码高亮匹配处保存代码至自定义数组中。
// 代码高亮匹配
if (config.highlight) {
  var that = this //注意用that接收
  this.data = this.data.replace(/<pre><code([\s\S]*?)>([\s\S]*?)<\/code[\s\S]*?><\/pre>/g, function($, $1, $2) {
      that._parserCodeContent.push($2)
    return "<pre><code" + $1 + '>' + config.highlight($2, "<code" + $1 + '>') + "</code><\/pre>";
  })
}
  1. MpHtmlParserpopNode函数:添加是否是pre标签,如果是则在node上添加一个content属性。
// 节点出栈处理
popNode(node) {
    ...

    //处理代码长按
    if (node.name == 'pre') {
      node.content = this._parserCodeContent.shift();
    }

    ...
}
  1. trees.wxml中添加pre标签,并且增加data-content等于从上一步node上添加的content属性,和bindlongpress="longPressEvent"长按事件绑定。
<rich-text wx:if="{{item.name=='pre'}}" data-content="{{item.content}}" id="{{item.attrs.id}}" class="__{{item.name}}" style="{{Handler.getStyle(item.attrs.style,'block')}}" nodes="{{Handler.setStyle(item)}}" bindlongpress="longPressEvent" />
  1. tree.jsmethods函数中添加:长按复制具体实现。
longPressEvent: function (e) {
  var content = e.currentTarget.dataset.content;
  wx.showActionSheet({
    itemList: ['复制代码'],
    success(res) {
      var tabIndex = res.tapIndex;
      if (tabIndex == 0) {
        wx.setClipboardData({
          data: content,
          success(res) {
              wx.showToast({
                  title: '代码已复制'
              })
          }
        })
      }
    }
  })
}

大功告成。

Views: 4,960 · Posted: 2020-02-10

————        END        ————

Give me a Star, Thanks:)

https://github.com/fendoudebb/LiteNote

扫描下方二维码关注公众号和小程序↓↓↓

扫描下方二维码关注公众号和小程序↓↓↓


Today On History
Browsing Refresh