動手寫一個簡單的瀏覽器擴充套件外掛
平時寫文件的時候,一些簡單的文件都用 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_start
、document_end
、document_idle
,這裡選取 document_end
,意思是在建立完DOM之後,在還沒有載入類似於圖片或frame等的子資源前立即執行。
icons
用於指示外掛在不同場景的 size
下 icon
圖示的所在地址路徑。
其他配置項都是輔助功能,就不詳細說明了,具體含義可見Manifest檔案
外掛指令碼
上面在 manifest.json
的 content_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"],
}
],
marked
和 highlight.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.css
和 github.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.js
和 highlight.pack.js
這兩個外掛。
想要在自己的 webkit
核心的瀏覽器上(例如 Chrome、360瀏覽器)安裝此擴充套件程式,可以參照 Chrome擴充套件及應用開發,因為我懶得上傳到 Chrome網上應用商店了,所以也沒有打包成 ctx
檔案,直接安裝原始檔也是可以的。
專案程式碼已經放在 Github上了,感興趣的可以下載下來安裝試試。