首頁 >web前端 >js教程 >如何構建Trello Chrome擴展名 - 導出列表

如何構建Trello Chrome擴展名 - 導出列表

William Shakespeare
William Shakespeare原創
2025-02-20 11:23:13491瀏覽

如何構建Trello Chrome擴展名 - 導出列表

在上一部分中,我們構建了擴展的基礎知識,通過自定義基礎供電的設置屏幕實現身份驗證,並使用Trello的JavaScript客戶端庫來構建了身份驗證。在這一部分中,我們將通過添加導出邏輯和UI來完成擴展。

>

鑰匙要點

    >使用`chrome.extension.sendMessage`API進行安全令牌傳輸之間的“設置”頁面和Chrome Extension的背景頁面之間
  • >在初始安裝時或在沒有身份驗證的情況下訪問trello板時自動打開擴展程序的設置頁面。
  • >
  • >在Trello的UI中集成自定義菜單選項以啟用列表導出,使用jQuery處理動態DOM更改。
  • >通過涉及檢查列表中的卡元素的解決方案來檢索trello列表ID,這是由於trello ui限製而需要的。
  • >在獲取列表ID後,在背景腳本中傳遞消息以從Trello的API中獲取列表卡。 >
  • >使用定制的模態彈出窗口以顯示導出數據,並規避CSS與Trello的本機樣式衝突。
  • >
  • 消息傳遞
  • >當我們在設置屏幕上使用Trello進行身份驗證時,Trello令牌將保存在本地存儲中。但是,設置頁面是其自己的頁面,有效地是其自己的環境 - Ergo,擴展程序的背景頁面或擴展程序的內容腳本都無法訪問它。這是我們需要使用消息傳遞的地方。

chrome.extension.sendmessage API用於從背景頁面發送消息。在我們的情況下,我們將使用它將令牌從設置頁面發送到我們的背景頁面。 由於我們的設置冒險就完成後就完成了,因此我們不妨自動關閉選項卡,以提高用戶友好。

>

>在設置中更新初始函數的第一部分。

使用此邏輯,我們告訴Trello庫在身份驗證完成時向擴展發送消息,並且一旦收到返回消息,說明消息已收到(這是功能(數據)部分),我們就會關閉該消息當前選項卡。

>現在讓我們處理背景頁面。首先,將背景內容的內容更改為:

<span>// Check if page load is a redirect back from the auth procedure
</span>    <span>if (HashSearch.keyExists('token')) {
</span>        <span>Trello.authorize(
</span>            <span>{
</span>                <span>name: "Trello Helper Extension",
</span>                <span>expiration: "never",
</span>                <span>interactive: false,
</span>                <span>scope: {read: true, write: false},
</span>                <span>success: function () {
</span>                    chrome<span>.extension.sendMessage({
</span>                        <span>command: 'saveToken',
</span>                        <span>token: localStorage.getItem('trello_token')
</span>                    <span>}, function(data) {
</span>                        chrome<span>.tabs.getCurrent(function (tab) {
</span>                            chrome<span>.tabs.remove(tab.id)
</span>                        <span>});
</span>                    <span>});
</span>                <span>},
</span>                <span>error: function () {
</span>                    <span>alert("Failed to authorize with Trello.")
</span>                <span>}
</span>            <span>});
</span>    <span>}</span>

>我們像以前一樣加載應用程序密鑰,我們將用於邏輯的背景腳本以及Trello客戶端。顯然,我們也需要jQuery - 這是Trello的依賴。

> 然後,將腳本/background.js更改為:

<span><span><!doctype html></span>
</span><span><span><span><script</span> type<span>="text/javascript"</span> src<span>="scripts/key.js"</span>></span><span><span></script</span>></span>
</span><span><span><span><script</span> type<span>="text/javascript"</span> src<span>="scripts/background.js"</span>></span><span><span></script</span>></span>
</span><span><span><span><script</span> type<span>="text/javascript"</span> src<span>="lib/jquery-2.1.1.min.js"</span>></span><span><span></script</span>></span>
</span><span><span><span><script</span> type<span>="text/javascript"</span> src<span>="lib/trello_client.js"</span>></span><span><span></script</span>></span></span>
這是從設置頁面接收消息的部分。它從請求中獲取令牌,並將其保存到LocalStorage中以供將來使用。我們將對象形成與命令用作主要密鑰,因為我們打算稍後將其他命令發送到背景頁面。

>自動安裝

在Savetkoken命令上方,讓我們另一個塊:

<span>// Check if page load is a redirect back from the auth procedure
</span>    <span>if (HashSearch.keyExists('token')) {
</span>        <span>Trello.authorize(
</span>            <span>{
</span>                <span>name: "Trello Helper Extension",
</span>                <span>expiration: "never",
</span>                <span>interactive: false,
</span>                <span>scope: {read: true, write: false},
</span>                <span>success: function () {
</span>                    chrome<span>.extension.sendMessage({
</span>                        <span>command: 'saveToken',
</span>                        <span>token: localStorage.getItem('trello_token')
</span>                    <span>}, function(data) {
</span>                        chrome<span>.tabs.getCurrent(function (tab) {
</span>                            chrome<span>.tabs.remove(tab.id)
</span>                        <span>});
</span>                    <span>});
</span>                <span>},
</span>                <span>error: function () {
</span>                    <span>alert("Failed to authorize with Trello.")
</span>                <span>}
</span>            <span>});
</span>    <span>}</span>
如果我們沒有發出特定命令,並且我們的用戶尚未使用Trello進行身份驗證,請在新選項卡中打開“設置”頁面。這確保在擴展程序初始安裝後立即打開“設置”頁面,一旦在瀏覽器中訪問了trello板。

>

添加菜單選項

Trello的UI對自定義非常非常友好。這些列表在其元素中沒有ID,無論是數據屬性還是任何形式的鏈接,而卡片則沒有。單擊右上角的“列表選項”按鈕時產生的上下文菜單每次被稱為(過重的殺傷性?),而全部從一個盒子中歸類為“ pop-over”,這是如果您幾乎單擊UI中的所有其他菜單,也可以召喚。更糟糕的是,一旦您調用了列表的彈出菜單,菜單本身就沒有列出的列表的標識符,因此您對其上下文一無所知,這使得很難輕鬆獲取列表的ID,以便正確查詢trello api圍繞它,並獲取出口卡。這就是為什麼接下來的事情看起來像是很多可怕的黑客,但這是因為,

>要將菜單選項添加到上下文菜單,我們需要編輯main.js內容腳本。將其變成:

>

>從var popover = $(“。pop-over”);,我們設置了一個變量以容納彈出對象,這樣我們就不必繼續重新提出它。然後,當單擊列表上的菜單按鈕(.list-header-menu-icon)時,我們召喚一個間隔,不斷注意是否可見彈出聲。一旦可見,檢查停止和菜單選項就會附加到所有選項的底部,專門設計為其餘的,因此適合。最後,單擊事件處理程序綁定到此選項,以便我們可以單擊選項時調用“導出”。但是..我們怎麼知道我們需要出口什麼?我們以哪種格式導出?
<span><span><!doctype html></span>
</span><span><span><span><script</span> type<span>="text/javascript"</span> src<span>="scripts/key.js"</span>></span><span><span></script</span>></span>
</span><span><span><span><script</span> type<span>="text/javascript"</span> src<span>="scripts/background.js"</span>></span><span><span></script</span>></span>
</span><span><span><span><script</span> type<span>="text/javascript"</span> src<span>="lib/jquery-2.1.1.min.js"</span>></span><span><span></script</span>></span>
</span><span><span><span><script</span> type<span>="text/javascript"</span> src<span>="lib/trello_client.js"</span>></span><span><span></script</span>></span></span>

查找列表ID

就像我之前說過的,Trello的UI眾所周知,開發人員不友好。它沒有提供帶有DOM元素的列表ID,因此找到它們的ID遠不及直接。為什麼我們需要列表ID?要查詢trello api並獲取卡片,以便我們可以導出它們 - 我們已經說,由於它在大型板上的不穩定性,我們不會在UI上解析,但會依靠API。

>幸運的是,如果我們在各個列表中檢查卡片,我們可以看到實際上確實具有HREF屬性,並且它包含卡ID。通過了解卡ID,我們可以查詢Trello的信息並獲取其父列表的ID。但是..如果彈出菜單未連接到列表中,我們如何查找單擊的列表?我們不能只抓住我們遇到的第一張卡片,那太隨機了。

>

>當單擊菜單按鈕時,我們可以使用jQuery發射的事件。這很重要!我們使用原始單擊菜單按鈕,而不是單擊“導出”選項,因為當原始按鈕綁定到我們有興趣導出的列表時,所產生的實際菜單不是,因此,使我們幾乎不可能找出我們要處理的列表。代替上述代碼中的//導出列表註釋,添加以下內容:

>
<span>// Check if page load is a redirect back from the auth procedure
</span>    <span>if (HashSearch.keyExists('token')) {
</span>        <span>Trello.authorize(
</span>            <span>{
</span>                <span>name: "Trello Helper Extension",
</span>                <span>expiration: "never",
</span>                <span>interactive: false,
</span>                <span>scope: {read: true, write: false},
</span>                <span>success: function () {
</span>                    chrome<span>.extension.sendMessage({
</span>                        <span>command: 'saveToken',
</span>                        <span>token: localStorage.getItem('trello_token')
</span>                    <span>}, function(data) {
</span>                        chrome<span>.tabs.getCurrent(function (tab) {
</span>                            chrome<span>.tabs.remove(tab.id)
</span>                        <span>});
</span>                    <span>});
</span>                <span>},
</span>                <span>error: function () {
</span>                    <span>alert("Failed to authorize with Trello.")
</span>                <span>}
</span>            <span>});
</span>    <span>}</span>
然後,創建函數:

<span><span><!doctype html></span>
</span><span><span><span><script</span> type<span>="text/javascript"</span> src<span>="scripts/key.js"</span>></span><span><span></script</span>></span>
</span><span><span><span><script</span> type<span>="text/javascript"</span> src<span>="scripts/background.js"</span>></span><span><span></script</span>></span>
</span><span><span><span><script</span> type<span>="text/javascript"</span> src<span>="lib/jquery-2.1.1.min.js"</span>></span><span><span></script</span>></span>
</span><span><span><span><script</span> type<span>="text/javascript"</span> src<span>="lib/trello_client.js"</span>></span><span><span></script</span>></span></span>
最後,創建FindfirstCardid函數:

chrome<span>.extension.onMessage.addListener(
</span>    <span>function (request<span>, sender, sendResponse</span>) {
</span>        chrome<span>.pageAction.show(sender.tab.id);
</span>
        <span>// Now we have a token saved locally, as fetched from the settings page after authorization.
</span>        <span>if (request.command == 'saveToken') {
</span>            <span>localStorage.setItem('trello_token', request.token);
</span>            <span>sendResponse();
</span>            <span>return true;
</span>        <span>}
</span>
    <span>});</span>
>我們獲取了活動目標的祖父母(列表),並在其中找到第一個卡標題。標題包含以下形狀的HREF:

>

如何構建Trello Chrome擴展名 - 導出列表

如果找不到標題,我們會提醒用戶列表無法導出。否則,我們提取並返回卡的ID。

>現在,我們的導出列表功能具有卡ID,我們可以使用它來找出列表ID。如果查看API文檔,我們可以使用URL卡/{{id}}來獲取我們需要的東西。為了最大程度地減少我們要求Trello返回的數據量,我們還可以將查詢限制在帶有字段參數的iDlist屬性中。讓我們在背景中添加一個新命令。

我們也需要定義trelloinit函數。我們可以在調用與Trello交互的命令之前每次都可以打電話,因此設置了令牌和密鑰,我們100%確定我們的請求已得到認證。
<span>if (!request.command && !localStorage.getItem('trello_token')) {
</span>            chrome<span>.tabs.create({url: chrome.extension.getURL('settings/index.html')});
</span>            <span>sendResponse();
</span>            <span>return true;
</span>        <span>}</span>

我們現在正在成功獲取列表ID。

chrome<span>.extension.sendMessage({}, function (response) {
</span>    <span>var readyStateCheckInterval = setInterval(function () {
</span>        <span>if (document.readyState === "complete") {
</span>            <span>clearInterval(readyStateCheckInterval);
</span>
            <span>var popover = $(".pop-over");
</span>            <span>$('.list-header-menu-icon').click(function(event) {
</span>                <span>var popover_summoned_interval = setInterval(function () {
</span>                    <span>if ($(popover).is(':visible')) {
</span>                        <span>clearInterval(popover_summoned_interval);
</span>                        <span>$(".pop-over .content").append('<hr><ul > <li><a  href="#">Export This List</a></li> </ul>');
</span>                        <span>$(".js-export-list").click(function(e){
</span>                            <span>// EXPORT LIST
</span>                        <span>});
</span>                    <span>}
</span>                <span>}, 50);
</span>            <span>});
</span>        <span>}
</span>    <span>}, 10);
</span><span>});</span>
獲取列表卡

>帶有另外幾行代碼,返回Main.js,我們現在擁有一個看起來像這樣的導出函數:>

在“人類”中,這是:

獲取第一張卡的ID
<span>exportList(event);</span>

如果找不到ID,列表顯然為空

    如果找到ID,請致電背景頁面,並告訴我們通過呼叫Trello API
  • 給我們列表ID
  • 如果列表ID很好,請再次呼叫背景頁面獲取列表的卡,然後在控制台中輸出結果。
  • >回到背景頁面,我們現在可以根據API文檔構建GetListCards命令。
  • >如果您現在重新加載並測試擴展程序,則不僅可以看到列表中的導出選項出現在您的列表中,而且還可以在單​​擊該選項後在控制台中尋找導出的數據。
  • >
>導出格式

>目前,我們將採用一種簡化的方法來導出,因為本教程的運行時間要長。我們將為用戶提供TXT或JSON的選擇,並具有形狀和形式,並由我們預定。現在,文本輸出將看起來像這樣:
<span>function exportList(event) {
</span>
    <span>var first_card_id = findFirstCardId(event);
</span>    <span>if (!first_card_id) {
</span>        <span>alert('No cards found in the list.');
</span>        <span>return false;
</span>    <span>}
</span><span>}</span>
>

> JSON將滿足從Trello收到的滿足,即:>

如何構建Trello Chrome擴展名 - 導出列表

顯然,JSON數據將產生更多的信息,但是編輯也更容易 - 只需將其粘貼到任何IDE或JSON Editor Online或JSON之類的工具中,您就可以使用。 >

要導出,我們需要一個模態窗口來粘貼數據。 這裡的一個吸引人的選擇是基礎框架,因為我們已經在設置頁面上使用了它,並且它具有自己的模態彈出組件,但是Foundation的和Trello的CSS均未適當地命名為空位,並且在Trello的CSS中包括Trello的CSS引起衝突。我們也有jQuery預先包含的,但是要再次進行對話框,我們需要包括jQuery UI,甚至還不夠- Chrome Extensions不支持通過相對URL中的CSS加載圖像( )語法,這是jQuery UI使用的- 我們必須重寫jQuery UI的CSS來使用本地擴展URL或使用Base64編碼圖像,都沒有吸引力接近。

相反,我們將製作自己的彈出窗口,並使用Trello的一些現有樣式,忽略一路上的所有衝突。我將最終代碼放在這裡,然後進行解釋。請創建lib/trellohelper/js/exportpopup.js,並給出以下內容:>

>我選擇在主腳本之外具有彈出邏輯,以便以後可以輕鬆地改進它。我還選擇了一種“面向對象的”方法,只是因為我喜歡它。我們通過三種方法定義了一個新的TrelloexportPopup“ class”:INIT,顯示和隱藏。內容腳本加載後,初始化將立即調用。這是負責構建彈出窗口,附加正確的事件聽眾並將整個內容添加到Trello板的HTML的方法。將.button類添加到彈出窗口標題的按鈕上,請確保我們獲得與當前Trello UI一致的外觀。我要在這裡尋找的外觀是一種“選項卡”接口 - 單擊文本,文本導出顯示,單擊JSON和JSON。

隱藏方法將隱藏彈出窗口,但前提是它以可見的形式存在於頁面上的某個地方。 Show方法自動激活第一個(JSON)選項卡視圖,並使用所需數據填充導出區域。 JSON區域是一個簡單的Stringify轉儲- JSON數據以字符串形式的輸出,而文本區域目前僅在單獨的行上輸出該卡的標題和描述,在卡之間有兩個空行- 高度“複製- 帕斯特友好”。

<span>// Check if page load is a redirect back from the auth procedure
</span>    <span>if (HashSearch.keyExists('token')) {
</span>        <span>Trello.authorize(
</span>            <span>{
</span>                <span>name: "Trello Helper Extension",
</span>                <span>expiration: "never",
</span>                <span>interactive: false,
</span>                <span>scope: {read: true, write: false},
</span>                <span>success: function () {
</span>                    chrome<span>.extension.sendMessage({
</span>                        <span>command: 'saveToken',
</span>                        <span>token: localStorage.getItem('trello_token')
</span>                    <span>}, function(data) {
</span>                        chrome<span>.tabs.getCurrent(function (tab) {
</span>                            chrome<span>.tabs.remove(tab.id)
</span>                        <span>});
</span>                    <span>});
</span>                <span>},
</span>                <span>error: function () {
</span>                    <span>alert("Failed to authorize with Trello.")
</span>                <span>}
</span>            <span>});
</span>    <span>}</span>
我們現在需要做的就是樣式。這是lib/trellohelper/css/exportpopup.css的內容:

>確保彈出窗口是中心的,看起來像本機Trello彈出窗口。它還可以確保將向我們展示導出內容的文本方面填充了彈出窗口的其餘空間。現在,讓我們將這些文件包含在我們的內容腳本中:

<span>// Check if page load is a redirect back from the auth procedure
</span>    <span>if (HashSearch.keyExists('token')) {
</span>        <span>Trello.authorize(
</span>            <span>{
</span>                <span>name: "Trello Helper Extension",
</span>                <span>expiration: "never",
</span>                <span>interactive: false,
</span>                <span>scope: {read: true, write: false},
</span>                <span>success: function () {
</span>                    chrome<span>.extension.sendMessage({
</span>                        <span>command: 'saveToken',
</span>                        <span>token: localStorage.getItem('trello_token')
</span>                    <span>}, function(data) {
</span>                        chrome<span>.tabs.getCurrent(function (tab) {
</span>                            chrome<span>.tabs.remove(tab.id)
</span>                        <span>});
</span>                    <span>});
</span>                <span>},
</span>                <span>error: function () {
</span>                    <span>alert("Failed to authorize with Trello.")
</span>                <span>}
</span>            <span>});
</span>    <span>}</span>

>最後,讓我們使用新的彈出邏輯來調整main.js。 main.js的最終版本看起來像這樣:

<span><span><!doctype html></span>
</span><span><span><span><script</span> type<span>="text/javascript"</span> src<span>="scripts/key.js"</span>></span><span><span></script</span>></span>
</span><span><span><span><script</span> type<span>="text/javascript"</span> src<span>="scripts/background.js"</span>></span><span><span></script</span>></span>
</span><span><span><span><script</span> type<span>="text/javascript"</span> src<span>="lib/jquery-2.1.1.min.js"</span>></span><span><span></script</span>></span>
</span><span><span><span><script</span> type<span>="text/javascript"</span> src<span>="lib/trello_client.js"</span>></span><span><span></script</span>></span></span>

>我們首先“實例化”了TrelloexportPopup,因此我們可以在代碼中使用其方法。然後,在將點擊事件偵聽器綁定到菜單之前,我們將使用tep.init()初始化彈出窗口,以便在需要之前就可以在DOM中進行準備。單擊導出鏈接後,我們像以前一樣稱呼我們的導出函數。

>

>在導出列表函數中,我們首先使用tep.hide()隱藏彈出窗口,以防萬一我們在瀏覽另一個列表的菜單時開放,然後,一旦我們從背景頁面上獲得卡,我們就會顯示帶有tep.show的導出彈出窗口(數據)。就是這樣!

>現在重新加載擴展名,刷新Trello頁面,您應該具有功能功能的導出選項!

>

如何構建Trello Chrome擴展名 - 導出列表

>錯誤和改進

>我故意留下了一些錯誤和警告。如果有足夠的興趣,我們將與以後的帖子中的那些人打交道,調整和優化故障安全的擴展。這是一些仍然可以的改進:

>

緩存

>為將來的用途加快速度,我們可以使用LocalStorage記住列表所屬的板。請注意,如果您將列表從董事會轉移到董事會,請仔細實現此功能 - 請確保添加另一個偵聽器以進行列表移動,因此您可以將緩存數據無效!

重複導出選項spawns

>如果您在菜單仍打開時手動單擊菜單圖標,則將繼續在菜單底部添加新的“導出”選項。需要實現故障安全,以檢查該選項是否已經存在。

>

初始問題

在擁有數百個董事會和成員的巨大董事會上,Trello的UI變得非常慢。這會導致對文檔準備就緒事件的失誤,並且在有任何UI元素可以綁定聽眾之前,我們的腳本的初始部分執行。因此,菜單有時沒有導出選項,並且在刷新之前才能獲得。

>

更改板

更換板殺死了當前的UI並為新董事會重建。但是,問題在於,與活動聽眾的元素也被殺死 - 因此我們的菜單不再召喚出口選項。與上面的問題類似,需要在板上觸發重新引導才能使一切正常工作。

> unifinite循環

>在菜單點擊菜單之後,彈出窗口不會呈現的天文數字很小- 也許Trello更改了UI中的某些內容,也許他們更改了班級,或者也許他們只是某種UI錯誤- 在這種情況下循環檢查其可見性將變得無限,佔用大量的CPU資源,直到TAB的過程被殺死為止。對此的保障會很好。

>

結論

在這個簡短的系列中,我們為Trello構建了一個簡單的Chrome擴展名,使我們可以從給定列表中導出作為JSON或TXT列表的卡片。使用此示例在其上構建,並創建自己的Trello擴展名 - 您可以完成的事情僅受您的想像力(以及Trello的API提供的功能)的限制:)。身份驗證已經為您解決,並且邏輯模板已經到位 - 開始編碼!

我們在本教程系列中編寫的代碼可在GitHub上找到。 您想看到本教程的延續嗎?實施了更多功能?讓我知道!反饋讚賞!

經常詢問有關導出Trello列表的問題(常見問題解答)

>如何將Trello列表導出到Excel?

>將Trello列表導出到Excel是一個簡單的過程。首先,您需要安裝稱為“ Trello的導出”的鍍鉻擴展名。安裝後,您可以導航到Trello板,然後單擊擴展圖標。您將看到一個選項來導出trello列表。選擇Excel格式,您的Trello列表將作為Excel文件下載。該文件將包含您的TRELLO列表的所有詳細信息,包括卡名稱,描述,標籤等。

我可以將Trello列表導出到PDF?

是的,您可以將Trello列表導出到Trello列表中PDF。類似於導出到Excel,您需要安裝“ Trello” Chrome擴展名的“導出”。安裝後,導航到Trello板,單擊擴展圖標,然後選擇用於導出的PDF格式。您的trello列表將被下載為PDF文件。

>

>是否可以將Trello列表導出到CSV?

>是的,可以將Trello列表導出到CSV格式。該過程類似於導出到Excel或PDF。您需要安裝“ trello for Trello” Chrome擴展名,導航到Trello板,單擊擴展圖標,然後選擇用於導出的CSV格式。您的trello列表將被下載為CSV文件。

我可以將Trello列表導出到圖像嗎?

是的,可以將Trello列表導出為圖像。可以使用“ Trello的導出” Chrome Extension完成此操作。安裝擴展程序後,導航到Trello板,單擊擴展圖標,然後選擇用於導出的圖像格式。您的trello列表將被下載為圖像文件。

>我可以用標籤導出trello列表嗎?

是的,當您使用“ Trello” Chrome Extension的“導出Trello”列表時,所有這些包括標籤在內的Trello列表的詳細信息已導出。這意味著即使導出了trello列表,您也可以跟踪您的標籤。

>

>我可以用卡描述導出trello列表嗎?這意味著您即使導出了trello列表,您也可以跟踪卡描述。

我可以以適當的日期導出trello列表? Trello” Chrome Extension,包括到期日期的Trello列表中的所有詳細信息均已導出。這意味著您即使導出了trello列表,您也可以跟踪到期日期。

我可以帶有附件的trello列表嗎?

不幸的是,“ trello” Chromeexension的“導出”不支持出口附件。但是,可以導出包括卡名稱,描述,標籤和到期日的所有其他詳細信息。 Trello” Chrome擴展名不支持導出評論。但是,可以導出trello列表的所有其他詳細信息,包括卡名稱,描述,標籤和到期日期。

>

>我可以一次從多個板上導出trello列表嗎?對於Trello”,Chrome擴展程序使您可以一次從一個板上導出Trello列表。如果您想從多個董事會導出列表,則需要導航到每個板並分別導出列表。

以上是如何構建Trello Chrome擴展名 - 導出列表的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn