@@ -3,17 +3,26 @@ import { getTextContent } from 'notion-utils'
33const indentLevels = {
44 header : 0 ,
55 sub_header : 1 ,
6- sub_sub_header : 2
6+ sub_sub_header : 2 ,
7+ heading_1 : 0 ,
8+ heading_2 : 1 ,
9+ heading_3 : 2
710}
811
12+ const unknownHeadingStats = new Map ( )
13+
914/**
1015 * @see https://github.com/NotionX/react-notion-x/blob/master/packages/notion-utils/src/get-page-table-of-contents.ts
1116 * Gets the metadata for a table of contents block by parsing the page's
1217 * H1, H2, and H3 elements.
1318 */
1419export const getPageTableOfContents = ( page , recordMap ) => {
20+ const pageId = page ?. id
21+ if ( process . env . NODE_ENV !== 'production' && pageId ) {
22+ unknownHeadingStats . set ( pageId , 0 )
23+ }
1524 const contents = page . content ?? [ ]
16- const toc = getBlockHeader ( contents , recordMap )
25+ const toc = getBlockHeader ( contents , recordMap , [ ] , pageId )
1726 const indentLevelStack = [
1827 {
1928 actual : - 1 ,
@@ -25,11 +34,18 @@ export const getPageTableOfContents = (page, recordMap) => {
2534 // This is a little tricky, but the key is that when increasing indent levels,
2635 // they should never jump more than one at a time.
2736 for ( const tocItem of toc ) {
28- const { indentLevel } = tocItem
29- const actual = indentLevel
37+ const actual = Number . isInteger ( tocItem . indentLevel ) ? tocItem . indentLevel : 0
3038
3139 do {
3240 const prevIndent = indentLevelStack [ indentLevelStack . length - 1 ]
41+ if ( ! prevIndent ) {
42+ tocItem . indentLevel = 0
43+ indentLevelStack . push ( {
44+ actual,
45+ effective : 0
46+ } )
47+ break
48+ }
3349 const { actual : prevActual , effective : prevEffective } = prevIndent
3450
3551 if ( actual > prevActual ) {
@@ -49,13 +65,21 @@ export const getPageTableOfContents = (page, recordMap) => {
4965 } while ( true )
5066 }
5167
68+ if ( process . env . NODE_ENV !== 'production' && pageId ) {
69+ const unknownCount = unknownHeadingStats . get ( pageId ) || 0
70+ if ( unknownCount > 0 ) {
71+ console . warn ( '[TOC] unknown heading summary' , { pageId, unknownCount } )
72+ }
73+ unknownHeadingStats . delete ( pageId )
74+ }
75+
5276 return toc
5377}
5478
5579/**
5680 * 重写获取目录方法
5781 */
58- function getBlockHeader ( contents , recordMap , toc ) {
82+ function getBlockHeader ( contents , recordMap , toc , pageId ) {
5983 if ( ! toc ) {
6084 toc = [ ]
6185 }
@@ -69,27 +93,55 @@ function getBlockHeader(contents, recordMap, toc) {
6993 continue
7094 }
7195 const { type } = block
96+ const isHeading =
97+ typeof type === 'string' &&
98+ ( type . indexOf ( 'header' ) >= 0 || / ^ h e a d i n g _ [ 1 2 3 ] $ / . test ( type ) )
99+
72100 if ( block . content ?. length > 0 ) {
73- getBlockHeader ( block . content , recordMap , toc )
101+ getBlockHeader ( block . content , recordMap , toc , pageId )
74102 } else {
75- if ( type . indexOf ( 'header' ) >= 0 ) {
103+ if ( isHeading ) {
76104 const existed = toc . find ( e => e . id === blockId )
105+ const indentLevel = indentLevels [ type ]
106+ if ( ! Number . isInteger ( indentLevel ) ) {
107+ // Emit debug signal only in development for quick reproduction.
108+ if ( process . env . NODE_ENV !== 'production' ) {
109+ if ( pageId ) {
110+ unknownHeadingStats . set (
111+ pageId ,
112+ ( unknownHeadingStats . get ( pageId ) || 0 ) + 1
113+ )
114+ }
115+ console . warn ( '[TOC] unknown heading type' , {
116+ pageId,
117+ blockId,
118+ type,
119+ title : getTextContent ( block . properties ?. title ) ,
120+ parentId : block . parent_id
121+ } )
122+ }
123+ continue
124+ }
77125 if ( ! existed ) {
78126 toc . push ( {
79127 id : blockId ,
80128 type,
81129 text : getTextContent ( block . properties ?. title ) ,
82- indentLevel : indentLevels [ type ]
130+ indentLevel
83131 } )
84132 }
85- } else if ( type === 'transclusion_reference' ) {
133+ } else if (
134+ type === 'transclusion_reference' &&
135+ block . format ?. transclusion_reference_pointer ?. id
136+ ) {
86137 getBlockHeader (
87138 [ block . format . transclusion_reference_pointer . id ] ,
88139 recordMap ,
89- toc
140+ toc ,
141+ pageId
90142 )
91143 } else if ( type === 'transclusion_container' ) {
92- getBlockHeader ( block . content , recordMap , toc )
144+ getBlockHeader ( block . content , recordMap , toc , pageId )
93145 }
94146 }
95147 }
0 commit comments