Blog #5

Mình đã custom code block trên blog page của mình như thế nào

# Reason

Mình có tạo vài blog liên quan đến shell commands mà như mọi người biết Shell thì bắt đầu bằng $. Mà button copy trên code block lại copy luôn $ như vậy thì sẽ phiền phức đối với người làm theo hướng dẫn trên blog. Họ phải copy rồi remove $ ra khỏi command line.

# Getting started

Tìm nguyên nhân và khắc phục

Như mọi người thấy thì khi bôi đen nó bôi luôn cả $

Cách khắc phục → Dùng css ngăn chặn việc user select $ như sau:

Đầu tiên F12 tìm class của code block → Tìm class của thằng chứa $.hljs-meta

CSS thằng đó lại như sau:

.hljs-meta {
    user-select: none;
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    pointer-events: none;
}

Sau khi custom CSS:

Như vậy là thằng $ đã bị loại bỏ khỏi khi chúng ta bôi đen command line :))
Nhưng…

Cuộc đời nó khác với cuộc sống, cái nút copy khốn nạn ở góc phải của code block nó vẫn copy chứa $ 

Vì mình dùng thư viện bên ngoài để custom code block nên mình phải đào lại cái js để custom tiếp
Ban đầu mình dùng CDNjs nên bây giờ mình hướng dẫn cách import file js thủ công luôn ha.
Tìm dòng script import js đó

Copy url paste lên browser 

May quá nó cũng k nhiều lắm nên có thể custom được chứ không thì :))
Copy nó về đặt tên là copy.js

Xuống dòng các thứ để cho nó gọn

File này nó viết thuần Javascript, mình thì quen dùng jQuery nên các bạn import thư viện jQuery trước khi custom giống mình nha
Thêm 3 lines này vào sau line 16 

if ($(this).siblings('code').attr('class').includes('shell')) {
    newText = text.substring(2)
}

Đại ý là tìm thằng anh chị em của thằng button rồi check coi nó có phải là language shell hay không.

Nếu là shell thì remove 2 kí tự đầu tiên của text copy được nha (Dấu $ và dấu cách ‘ ’ ) còn không thì để im.

Chứ không những languages khác cũng chứa $ như jQuery thì xoá đi thì lại bug nha :D

Tới đây cũng chưa xong nếu các bạn dùng Rails App. Các bạn thêm keyword export vào trước class thì mới dùng được như sau:

export class CopyButtonPlugin {
  constructor(options = {}) {
    self.hook = options.hook;
    self.callback = options.callback
  }
  "after:highlightElement"({ el, text }) {
    let button = Object.assign(document.createElement("button"), {
      innerHTML: "Copy", className: "hljs-copy-button"
    });
    button.dataset.copied = false;
    el.parentElement.classList.add("hljs-copy-wrapper");
    el.parentElement.appendChild(button);
    el.parentElement.style.setProperty("--hljs-theme-background", window.getComputedStyle(el).backgroundColor);
    button.onclick = function () {
      if (!navigator.clipboard) return;
      let newText = text;
      if ($(this).siblings('code').attr('class').includes('shell')) {
        newText = text.substring(2)
      }
      if (hook && typeof hook === "function") { newText = hook(text, el) || text } navigator.clipboard.writeText(newText).then(function () {
        button.innerHTML = "Copied!";
        button.dataset.copied = true;
        let alert = Object.assign(document.createElement("div"), { role: "status", className: "hljs-copy-alert", innerHTML: "Copied to clipboard" });
        el.parentElement.appendChild(alert);
        setTimeout(() => {
          button.innerHTML = "Copy";
          button.dataset.copied = false;
          el.parentElement.removeChild(alert);
          alert = null
        }, 2e3)
      }).then(function () { if (typeof callback === "function") return callback(newText, el) })
    }
  }
}

Tiếp theo vào edit file application.js thêm 2 dòng sau:

import { CopyButtonPlugin } from "./copy"
window.CopyButtonPlugin = CopyButtonPlugin

Như vậy là đã custom thành công rồi nha các bạn.