Μελέτη · Electron

Πώς το Notion αντιγράφει
κείμενο και HTML.

Ακολουθήστε μια κλήση στο πρόχειρο από το API σελίδας του Notion, μέσω της προφόρτωσης και της κύριας διεργασίας, μέχρι τη λειτουργία εγγραφής στο πρόχειρο του Electron.

Notion Desktop 7.6.1 · JavaScript · REA

Η γέφυρα μέσα στο πακέτο της εφαρμογής υπολογιστή του Notion

  1. 01 · API που εκτίθεται στη σελίδα clipboard.write(data) Η προφόρτωση εκθέτει μια μέθοδο που μπορεί να κληθεί.
  2. 02 · Περίβλημα προφόρτωσης ipcRenderer.invoke Το περίβλημα στέλνει το κανάλι και τα ορίσματα.
  3. 03 · Χειριστής κύριας διεργασίας ipcMain.handle Ο παραλήπτης ελέγχει ποια σελίδα το έστειλε.
  4. 04 · Πρόχειρο συστήματος clipboard.write(data) Το Electron γράφει το παρεχόμενο κείμενο και HTML.

Ένα κανάλι ενώνει τις δύο πλευρές: notion:clipboard:write

Ο συσκευασμένος κώδικας χρησιμοποιεί το ίδιο κανάλι στην προφόρτωση και την κύρια διεργασία. Η εξέταση των περιβλημάτων αποκαλύπτει τις κλήσεις Electron πίσω από αυτά τα ονόματα.

Πού καταλήγει η λειτουργία αντιγραφής;

Η σελίδα βλέπει μια μέθοδο που ονομάζεται clipboard.write. Η υλοποίησή της στην προφόρτωση είναι ένα περίβλημα. Το χρήσιμο ερώτημα είναι τι στέλνει αυτό το περίβλημα και ποιος κώδικας το λαμβάνει.

Ο βοηθός προγραμματισμού σας

Χρησιμοποιήστε το REA για να ακολουθήσετε πώς το Notion αντιγράφει κείμενο και HTML στο πρόχειρο του συστήματος. Δείξτε τον κώδικα σε κάθε βήμα.

Παράδειγμα προτροπής με το τοπικό πακέτο εφαρμογής του Notion διαθέσιμο στον βοηθό προγραμματισμού σας.

Το REA βρίσκει από πού να ξεκινήσετε την ανάγνωση

Η ανάλυση της προφόρτωσης καρτέλας με το REA εντοπίζει το API που εκτίθεται στη σελίδα και την κλήση που στέλνει ένα αίτημα IPC. Και τα δύο ευρήματα συνοδεύονται από περιοχές πηγαίου κώδικα στο ελαχιστοποιημένο πακέτο:

Ευρήματα REA → δύο σημεία για άνοιγμα

Εκτεθειμένο API σελίδας
api_key: "__electronApi"
api_status: "dynamic"
source: preload.js:1:22764–22828
Κλήση IPC της διεργασίας απόδοσης
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, με ευανάγνωστα ονόματα μεταβλητών. Τα άσχετα μέλη παραλείπονται.

  1. Ξεκινήστε από το 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 μας δείχνει πώς το αίτημα φεύγει από τη διεργασία της σελίδας.

  2. Εξετάστε το περίβλημα της προφόρτωσης

    tab_browser_view/preload.js · βοηθητική συνάρτηση IPC
    function invokerInMain(channel) {
      return (...args) => invokeInMainAndReturnResult(channel, ...args);
    }
    
    function invokeInMainAndReturnResult(channel, ...args) {
      return ipcRenderer.invoke(channel, ...args);
    }

    Η επιστρεφόμενη συνάρτηση προωθεί τα ορίσματα μέσω του IPC αιτήματος και απόκρισης του Electron. Μπορούμε πλέον να αναζητήσουμε το notion:clipboard:write στην πλευρά της κύριας διεργασίας.

  3. Ελέγξτε πώς καταχωρίζεται ο παραλήπτης

    main/index.js · βοηθητική συνάρτηση χειριστή
    const handleRequestFromRenderer = {
      addListener(channel, handler) {
        ipcMain.handle(channel, handler);
      }
    };

    Η κύρια διεργασία χρησιμοποιεί άλλο ένα περίβλημα. Η μέθοδός του addListener καταχωρίζει έναν παραλήπτη ipcMain.handle για αυτό το κανάλι.

  4. Βρείτε την εγγραφή και τον έλεγχο αποστολέα της

    main/index.js · παραλήπτης προχείρου
    handleRequestFromRenderer.addListener(
      "notion:clipboard:write",
      (event, data) =>
        isNotionWebContents(event.sender)
          ? clipboard.write(data)
          : undefined
    );

    Αυτός είναι ο προορισμός. Αφού ελέγξει τον αποστολέα, ο χειριστής περνά τα παρεχόμενα δεδομένα στο API προχείρου του Electron. Το κανάλι και τα δύο περιβλήματα που εξετάστηκαν συνδέουν την εκτεθειμένη μέθοδο με αυτή την κλήση.

Πώς ένα αντιγραμμένο μπλοκ διατηρεί τη δομή του;

Ο επεξεργαστής ιστού του Notion στέλνει κείμενο και HTML μέσω της electronApi.clipboard.write. Κρατά τα δεδομένα του μπλοκ τοπικά και τοποθετεί ένα αναγνωριστικό στο αντιγραμμένο HTML για να τα συνδέσει.

Το HTML συνδέεται με αποθηκευμένα δεδομένα μπλοκ

Αποστέλλεται στο πρόχειρο του συστήματος
text: "Project notes"
html: "<p>Project notes</p>"
    + "<!-- notionvc: <copy-id> -->"
Αποθηκεύεται τοπικά από το Notion
id: <copy-id>
mimeTypes:
  text/_notion-blocks-v3-production
    → structured block data
  1. Διαβάστε το αναγνωριστικό του HTML
  2. Βρείτε το ίδιο τοπικό αναγνωριστικό
  3. Επαναφέρετε τα δεδομένα μπλοκ του Notion
Ενδεικτικό κείμενο και αναγνωριστικό. Η καταγεγραμμένη δοκιμή μονάδας επαναφέρει τα δεδομένα του μπλοκ όταν τα αναγνωριστικά συμφωνούν· μια παλιά εγγραφή επιστρέφει μόνο κείμενο και HTML.

Κατά την επικόλληση, το Notion αναζητά το αναγνωριστικό του HTML και το συγκρίνει με το αποθηκευμένο αντίγραφο. Τα ίδια αναγνωριστικά επαναφέρουν τα δεδομένα του μπλοκ.

Μορφή προχείρου καταγεγραμμένη από πόρους ιστού που αποθηκεύτηκαν στην προσωρινή μνήμη στις 13 Ιουλίου 2026.

Περισσότερα παραδείγματα και πηγές

Άλλο παράδειγμα: πίνακες Markdown

Το Notion αναλύει το Markdown σε δεδομένα μπλοκ. Αυτό το παράδειγμα δείχνει πώς ένας πίνακας γίνεται γραμμές κεφαλίδων και δεδομένων.

Ένας πίνακας μέσα από τον αναλυτή Markdown του Notion

Είσοδος Markdown
| A | B |
| - | - |
| 1 | 2 |
Δομημένη έξοδος αναλυτή · απόσπασμα
table · headerRow: true
  table_row
    cells: ["A"], ["B"]
  table_row
    cells: ["1"], ["2"]
Καταγεγραμμένη έξοδος από εξαγόμενο αναλυτή Markdown. Ο πίνακας γίνεται γραμμές και κελιά.
Μια άλλη διαδρομή: η σύνδεση SQLite εκτός δικτύου

Η διεργασία απόδοσης του Notion ζητά την getSqliteMeta μέσω IPC. Η κύρια διεργασία δημιουργεί ένα κανάλι μηνυμάτων και δίνει το ένα άκρο στη διεργασία απόδοσης και το άλλο σε μια βοηθητική διεργασία SQLite. Οι επόμενες παρτίδες εντολών και τα αποτελέσματα μεταφέρονται μέσω αυτού του άκρου.

Η παρακολούθηση αυτής της παράδοσης εξηγεί πού εκτελείται η εργασία της βάσης δεδομένων και γιατί η ιχνηλάτηση μόνο του αρχικού αιτήματος IPC χάνει τη μεταγενέστερη επικοινωνία.

Πηγές και τρόπος ανάγνωσης των αποσπασμάτων

Η γέφυρα του προχείρου προέρχεται από το app.asar του Notion Desktop 7.6.1: την προφόρτωση καρτέλας και το main/index.js. Τα αποσπάσματα αναπτύσσουν τα ελαχιστοποιημένα ονόματα μεταβλητών και παραλείπουν άσχετο κώδικα· η βοηθητική συνάρτηση ελέγχου αποστολέα εμφανίζεται με την υποκείμενη κλήση της isNotionWebContents.

Τα παραδείγματα εικονικού προχείρου και Markdown προέρχονται από πόρους ιστού που αποθηκεύτηκαν στην προσωρινή μνήμη στις 13 Ιουλίου 2026, συμπεριλαμβανομένων των μονάδων 747001, 58169, 736810 και 422457. Αυτοί οι πόροι έχουν τη δική τους έκδοση. Οι αποθηκευμένοι διερευνητικοί έλεγχοι εκτέλεσαν εξαγόμενες μονάδες και μικρά προγράμματα δοκιμής· οι έξοδοί τους περιγράφουν αυτούς τους ελέγχους και όχι μια καταγεγραμμένη συνεδρία του γραφικού περιβάλλοντος της εφαρμογής υπολογιστή.

Το αποτέλεσμα REA που εμφανίζεται εδώ είναι μια εστιασμένη ανάλυση της αποθηκευμένης προφόρτωσης καρτέλας, καταγεγραμμένη με το δημοσιευμένο πακέτο REA 4.1.0. Εντοπίζει το API και τη λειτουργία κλήσης. Το μέλος του προχείρου και ο αντίστοιχος παραλήπτης συνδέονται διαβάζοντας τις υλοποιήσεις των περιβλημάτων τους στο πακέτο.

Το παράδειγμα Markdown χρησιμοποιεί τη μονάδα αναλυτή 422457. Οι αποθηκευμένες δοκιμές μονάδας δείχνουν ότι τόσο τα φίλτρα σελίδας όσο και τα φίλτρα συνομιλίας διατηρούν αυτόν τον πίνακα. Οι αναλυτές επικόλλησης/εισαγωγής, δομημένου Markdown και AI/συνομιλίας έχουν ξεχωριστά σημεία εισόδου και ενδιάμεσες μορφές.

Κορυφή