1. 程式人生 > >動手寫一個簡單的瀏覽器擴充套件外掛

動手寫一個簡單的瀏覽器擴充套件外掛

平時寫文件的時候,一些簡單的文件都用 markdown來寫,編輯工具自然是隨便用的,記事本、vs code或者專門的 md編輯器都可以,但是想要預覽的時候,卻有一定的限制,例如我想用 vs code預覽 md檔案,就必須裝一個專門的外掛,或者乾脆就要開啟一個 md編輯器才行,而我的本意其實僅僅是想預覽一個寫好的 md文件,不會做任何的改動,上面幾種做法也不費什麼事,但未免有些多餘,畢竟,程式碼編輯器是用來寫程式碼的,而且是本就已經開了很多個視窗了,不想再開一個了,至於專門的 md編輯器更是要開啟一個編輯器,更麻煩。
而瀏覽器幾乎是時時刻刻開著的,並且在瀏覽器上預覽更敞亮,於是想著能不能找一個瀏覽器的md預覽外掛,結果找了半天沒找到(可能是我找的方法有問題),於是還是決定自己寫一個吧。

參考文件:

manifest.json 配置檔案

首先,一個 Chrome外掛,肯定要有 manifest.json這個檔案,此檔案可以看做是外掛的配置檔案,外掛所需載入的指令碼檔案、樣式檔案、圖示、啟動時刻、版本號等都在此檔案中定義,一個最簡單的 Chrome外掛,只需要一個 manifest.json就足夠了。

所以,在專案根目錄新建 manifest.json,寫入以下基本配置:

{
  "manifest_version": 2,
  "name": "MdPriview",
  "version": "1.0",
  "description": "預覽本地 markdown檔案"
, "content_scripts": [ { "matches": ["file:///*.md"], "js": ["js/index.js"], "run_at": "document_end", } ], "icons": { "16": "img/16.png", "48": "img/48.png", "128": "img/128.png" }, "browser_action": { "default_icon": { "19": "img/16.png", "38"
: "img/48.png" }, "default_title": "MdPriview" } }

其中,content_scripts配置項中,matches屬性用於指示外掛在什麼型別的頁面上執行,可選值參照模式匹配
本文所要解析是本地的 mardown檔案,所以選用 file:///*.md,意思是隻有當前頁面的訪問協議為 file,字尾為 .md的時候,才啟動外掛。
js配置了外掛在執行的時候,向頁面注入的指令碼所在路徑,此配置項比較重要,外掛的功能大部分由指令碼實現。
run_at指示外掛執行的時刻,可選值有 document_startdocument_enddocument_idle,這裡選取 document_end,意思是在建立完DOM之後,在還沒有載入類似於圖片或frame等的子資源前立即執行。
icons用於指示外掛在不同場景的 sizeicon圖示的所在地址路徑。
其他配置項都是輔助功能,就不詳細說明了,具體含義可見Manifest檔案

外掛指令碼

上面在 manifest.jsoncontent_scripts配置項中定義了外掛的指令碼路徑 js/index.js,所以需要在根目錄建立一個 js資料夾,並且在其中建立一個 index.js檔案。 90
想要將 mardown原始檔,轉化為可預覽的介面形式,流程很清晰,一共分三步:
第一步,把冰箱門開啟

  • 讀取 mardown檔案的內容
  • 解析內容,將 md文字內容轉化為 DOM形式,方便定製
  • 將解析好並且設定好樣式的DOM內容替換掉原本頁面上的 mardown源文字

讀取 mardown檔案的內容

使用 Chrome瀏覽器開啟一個 markdown檔案,F12外掛原始碼,如下:
這裡寫圖片描述

可以看到,瀏覽器實際上就是把 markdown檔案的內容當成一整段文字內容(string),在這段文字內容外面加了一層 <pre>標籤,然後顯示在<body>元素中,<pre>元素中的內容就是所需要獲取的 md檔案內容。

讀取元素內容很簡單:

document.querySelector('pre').textContent

解析內容,將 md文字內容轉化為 DOM形式,方便定製

讀取到的內容是 md原始檔內容,需要將其轉換為 DOM內容,至於如何把 md轉化為 DOM形式,也不是什麼有難度的事情,功能類似於模板字串,就是比較複雜,這裡就不自己去寫這個東西了,有現成的東西可用:marked

marked是一個 markdown解析和編譯器,專注於速度。

將此外掛引入到外掛專案中,可以直接引用此外掛的網路地址 https://cdn.jsdelivr.net/npm/marked/marked.min.js,但考慮到外掛可能需要在無網路的狀態下也能正常使用,所以將外掛程式碼下載到本地,放入 /js資料夾下,並在 manifest.json檔案中配置引入:

"content_scripts": [
  {
    // ...
    "js": ["js/marked.min.js", "js/index.js"],
  }
],

然後就可以在 /js/index.js中使用此外掛了:

// marked 就是引入的 `js/marked.min.js`外掛暴露出來的全域性方法名
"<div id='wrapper'>" + marked(document.querySelector('pre').textContent) + "</div>";

使用 marked解析獲取到的 md文字內容,為了方便後面對其的控制,額外在解析出來的 DOM內容外包了一層 div

這裡主要功能已經實現了,不過還有個小問題,一些可以預覽 makdown檔案的網站,例如 Github,不僅可以預覽正常的文字內容,甚至還可以給文字內包含的示例程式碼高亮顯示,就像是在編輯器內閱讀程式碼一樣直觀,而如果只是上一步的操作,也就只能正常顯示程式碼內容,並不具備高亮程式碼的能力。

想要具備此功能,也很簡單,引入另外一個外掛:highlight.js

highlight.js 是一個由 JavaScript編寫的語法高亮外掛,適用於包括 JavaScript HTML CSS C/C++ python php C# Java在內的各種程式語言。

如何使用 highlight.js就不多說了,其官網已經講解地很清楚了。

和上面引入 marked相同,將 highlight.js外掛程式碼下載到本地,放入 /js資料夾下,並在 manifest.json檔案中配置引入:

"content_scripts": [
  {
    // ...
    "js": ["js/marked.min.js", "js/highlight.pack.js", "js/index.js"],
  }
],

markedhighlight.js是一對常用的組合,以至於 marked的文件上專門給出了二者配合使用的示例,本文外掛想要結合這二者也很簡單:

"<div id='wrapper'>" + marked(document.querySelector('pre').textContent, {
  breaks: true,
  highlight: function(code) {
    return hljs.highlightAuto(code).value;
  }
}) + "</div>";

想要 highlight.js像期待的那樣正常執行,還需要額外新增樣式,在根目錄下新建 /css資料夾,並在其中建立 base.cssgithub.css兩個檔案,這兩個檔案的名字你可以自定義,只要能正常引入就行了。

在頁面中注入 css檔案:

"content_scripts": [
  {
    // ...
    "js": ["js/marked.min.js", "js/highlight.pack.js", "js/index.js"],
    "css": ["style/base.css", "style/github.css"]
  }
],

將解析好並且設定好樣式的DOM內容替換掉原本頁面上的 mardown源文字

上述已經解析好了 md檔案,並設定了樣式,最後一步就很簡單了。

document.body.innerHTML= "<div id='wrapper'>" + marked(document.querySelector('pre').textContent, {
  breaks: true,
  highlight: function(code) {
    return hljs.highlightAuto(code).value;
  }
}) + "</div>";

還有一點小優化,由於頁面在載入的時候,會首先顯示未經處理的 md內容,然後外掛才會啟動執行開始解析,並替換頁面上的內容,這個過程會發生頁面整體內容的變化,會導致頁面跳動,所以我們可以先將 #wrapper元素設定 display: none;,在外掛解析完成後,再將其顯示出來:

document.body.style.display = 'block';

至此,一個 預覽本地 markdown檔案Chrome外掛就完成了。

總結

整體專案結構如下:

/img資料夾存放擴充套件的圖示

/js資料夾下存放相關指令碼檔案,其中 highlight.pack.js 用於高亮程式碼,marked.min.js 用於將 md文字轉為 html元素,index.js則是相應的初始化程式碼

/style資料夾下是樣式檔案, github.css給 程式碼檔案 設定樣式,base.css用於 其他的 html樣式.

/manifest.json是擴充套件程式的配置檔案。

專案很簡單,需要自己寫的程式碼就幾行而已,主要是引用了 marked.min.jshighlight.pack.js這兩個外掛。

想要在自己的 webkit核心的瀏覽器上(例如 Chrome、360瀏覽器)安裝此擴充套件程式,可以參照 Chrome擴充套件及應用開發,因為我懶得上傳到 Chrome網上應用商店了,所以也沒有打包成 ctx檔案,直接安裝原始檔也是可以的。

專案程式碼已經放在 Github上了,感興趣的可以下載下來安裝試試。