複製操作去哪裡?
頁面可以呼叫名為 clipboard.write 的方法。它在預載入指令碼中的實現是一個包裝函式。關鍵問題是:它傳送了什麼,又由哪段程式碼接收?
使用REA跟蹤Notion如何將文字和HTML複製到系統剪貼簿。 在每個步驟顯示程式碼。
一個示例提示與Notion的本地應用程式包可供你的程式設計助手.
REA查詢從哪裡開始閱讀
用 REA 分析標籤頁的預載入指令碼,可以找到暴露給頁面的 API,以及傳送 IPC 請求的呼叫。兩個結果都給出了在壓縮程式碼中的位置:
REA 分析結果 → 兩個原始碼位置
api_key: "__electronApi"
api_status: "dynamic"
source: preload.js:1:22764–22828
operation: "invoke"
channel_expression: "e"
source: preload.js:1:6486–6522
analyze_javascript_application 分析結果中的部分欄位,來自 Notion 標籤頁的預載入指令碼,使用 REA 4.1.0 記錄。位置對應原始壓縮包中的行號和從零開始的列號。
助手開啟這些位置,在組裝的 API 中找到剪貼簿成員,再讀取 invokerInMain。呼叫處傳入 notion:clipboard:write,讓助手知道要在主程序程式碼中搜尋哪個名稱。下面四段程式碼展示這條呼叫鏈。
四段簡短程式碼
從打包的JavaScript簡化,具有可讀的變數名稱。 不相關的成員被省略。
-
從公開到頁面的API開始
tab_browser_view/preload.js · API 成員const clipboardApi = { write: invokerInMain("notion:clipboard:write") }; // Included in the API exposed through contextBridge: // window.__electronApi.clipboard此成員提供通道名稱。 的實施
invokerInMain告訴我們請求如何離開頁面的程序。 -
解析預載入的包裝器
tab_browser_view/preload.js · IPC 輔助函式function invokerInMain(channel) { return (...args) => invokeInMainAndReturnResult(channel, ...args); } function invokeInMainAndReturnResult(channel, ...args) { return ipcRenderer.invoke(channel, ...args); }返回的函式透過 Electron 的請求/響應 IPC 轉發引數。接下來可以在主程序中查詢
notion:clipboard:write。 -
檢查接收器是如何註冊的
主要/index.js · 處理程式助手const handleRequestFromRenderer = { addListener(channel, handler) { ipcMain.handle(channel, handler); } };主程序使用另一個包裝器。 其
addListener方法註冊一個ipcMain.handle那個頻道的接收器。 -
查詢寫入及其發件人檢查
主要/index.js · 剪貼簿接收器handleRequestFromRenderer.addListener( "notion:clipboard:write", (event, data) => isNotionWebContents(event.sender) ? clipboard.write(data) : undefined );這就是呼叫的終點。處理函式檢查傳送方後,把收到的資料交給 Electron 的剪貼簿 API。通道名和兩個解析後的包裝函式,把暴露給頁面的方法連線到了這裡。
複製的塊如何保持其結構?
Notion 的網頁編輯器透過 electronApi.clipboard.write 傳送文字和 HTML。它在本地保留內容塊資料,再在複製的 HTML 中放入一個 ID,將二者關聯起來。
儲存的塊資料的HTML連結
text: "Project notes"
html: "<p>Project notes</p>"
+ "<!-- notionvc: <copy-id> -->"
id: <copy-id>
mimeTypes:
text/_notion-blocks-v3-production
→ structured block data
- 讀取HTML ID
- 查詢相同的本地ID
- 恢復Notion塊資料
在貼上時,Notion查詢HTML ID並根據儲存的複製進行檢查。 匹配的Id恢復所述塊資料。
從2026年7月13日快取的web資產中記錄的剪貼簿格式。
更多示例和來源
另一個例子:Markdown 表格
Notion將Markdown解析為塊資料。 此示例顯示錶如何成為標題和資料行。
透過Notion的Markdown解析器的表格
| A | B |
| - | - |
| 1 | 2 |
table · headerRow: true
table_row
cells: ["A"], ["B"]
table_row
cells: ["1"], ["2"]
另一條路徑:離線SQLite連線
Notion 的渲染程序透過 IPC 請求 getSqliteMeta。主程序建立訊息通道,把一個埠交給渲染程序,另一個交給 SQLite 工具程序。後續的語句批次和結果直接透過這個埠傳輸。
追蹤這次交接,就能知道資料庫操作在哪個程序執行,也能解釋為什麼只跟蹤最初的 IPC 請求會漏掉後續通訊。
資料來源及如何閱讀摘錄
剪貼簿橋接程式碼來自 Notion Desktop 7.6.1 的 app.asar,包括標籤頁預載入指令碼和 main/index.js。節選中展開了壓縮後的變數名,並省略無關程式碼;傳送方檢查輔助函式展示了底層的 isNotionWebContents 呼叫。
虛擬剪貼簿和 Markdown 示例來自 2026 年 7 月 13 日快取的網頁資源,包括 747001、58169、736810 和 422457 模組。這些資源有獨立版本。儲存的測試執行提取出的模組和小型測試程式;輸出反映的是這些測試,沒有記錄桌面 UI 操作。
這裡的 REA 結果是對儲存的標籤頁預載入指令碼進行的專項分析,使用已釋出的 REA 4.1.0 記錄。它定位了 API 和呼叫操作。讀取包中的包裝函式實現後,就能把剪貼簿成員與匹配的接收方連線起來。
Markdown 示例使用解析器模組 422457。儲存的模組測試顯示,頁面和聊天過濾器都會保留這張表格。貼上/匯入、結構化標記和 AI/聊天解析器各自有不同入口與中間格式。
- JavaScript應用指南遵循一個小的Electron應用程式的匯出功能。
- DX-Ball 重建工程按照原生說明檢查c函式。