@@ -994,6 +994,10 @@ pub struct OfficePreviewQuery {
source_map_path : Option < String > ,
#[ serde(default, alias = " blockId " ) ]
block_id : Option < String > ,
#[ serde(default, alias = " evidenceText " ) ]
evidence_text : Option < String > ,
#[ serde(default, alias = " searchQuery " ) ]
search_query : Option < String > ,
}
pub async fn office_preview_page ( Query ( query ) : Query < OfficePreviewQuery > ) -> Response {
@@ -1028,6 +1032,8 @@ pub async fn office_preview_page(Query(query): Query<OfficePreviewQuery>) -> Res
let target_bbox = query . bbox . unwrap_or_default ( ) ;
let target_source_map_path = query . source_map_path . unwrap_or_default ( ) ;
let target_block_id = query . block_id . unwrap_or_default ( ) ;
let target_evidence_text = query . evidence_text . unwrap_or_default ( ) ;
let target_search_query = query . search_query . unwrap_or_default ( ) ;
let html = format! (
r #" <!doctype html>
< html lang = " zh-CN " >
@@ -1074,7 +1080,7 @@ pub async fn office_preview_page(Query(query): Query<OfficePreviewQuery>) -> Res
} }
< / style >
< / head >
< body data - file - url = " {file_url} " data - file - name = " {file_name} " data - file - type = " {file_type} " data - page - width - content - type = " {page_width_content_type} " data - workspace - id = " {workspace_id} " data - mnote - source - kind = " {source_kind} " data - mnote - root - uri = " {root_uri} " data - document - id = " {document_id} " data - evidence - page = " {target_page} " data - evidence - bbox = " {target_bbox} " data - evidence - source - map - path = " {target_source_map_path} " data - evidence - block - id = " {target_block_id} " >
< body data - file - url = " {file_url} " data - file - name = " {file_name} " data - file - type = " {file_type} " data - page - width - content - type = " {page_width_content_type} " data - workspace - id = " {workspace_id} " data - mnote - source - kind = " {source_kind} " data - mnote - root - uri = " {root_uri} " data - document - id = " {document_id} " data - evidence - page = " {target_page} " data - evidence - bbox = " {target_bbox} " data - evidence - source - map - path = " {target_source_map_path} " data - evidence - block - id = " {target_block_id} " data - evidence - text = " {target_evidence_text} " data - evidence - search - query = " {target_search_query} " >
< main class = " mnote-office-preview " >
< section class = " mnote-office-viewer " id = " mnote-office-viewer " > < / section >
< / main >
@@ -1093,6 +1099,8 @@ pub async fn office_preview_page(Query(query): Query<OfficePreviewQuery>) -> Res
let evidenceBbox = body . dataset . evidenceBbox | | ' ' ;
let evidenceSourceMapPath = body . dataset . evidenceSourceMapPath | | ' ' ;
let evidenceBlockId = body . dataset . evidenceBlockId | | ' ' ;
let evidenceText = body . dataset . evidenceText | | ' ' ;
let evidenceSearchQuery = body . dataset . evidenceSearchQuery | | ' ' ;
let currentPptxBuffer = null ;
let pptxRenderToken = 0 ;
let pptxResizeTimer = 0 ;
@@ -1160,7 +1168,13 @@ pub async fn office_preview_page(Query(query): Query<OfficePreviewQuery>) -> Res
} }
function normalizeEvidenceText ( value ) { {
return String ( value | | ' ' ) . replace ( / \ s + / g , ' ' ) . trim ( ) ;
return String ( value | | ' ' )
. replace ( / < [ ^ > ] + > / g , ' ' )
. replace ( / & nbsp ; | & #160 ; / gi , ' ' )
. replace ( / [ #* _ ` ~ > \ [ \ ] ( ) { { } } ] + / g , ' ' )
. replace ( / [ \ u200B - \ u200D \ uFEFF ] / g , ' ' )
. replace ( / \ s + / g , ' ' )
. trim ( ) ;
} }
function markEvidenceTarget ( target ) { {
@@ -1266,6 +1280,7 @@ pub async fn office_preview_page(Query(query): Query<OfficePreviewQuery>) -> Res
if ( ! viewer ) return false ;
const compactNeedle = normalizeEvidenceText ( needle ) . replace ( / \ s + / g , ' ' ) ;
if ( ! compactNeedle ) return false ;
if ( compactNeedle . length > 160 ) return false ;
const refs = [ ] ;
let compactText = ' ' ;
const walker = document . createTreeWalker ( viewer , NodeFilter . SHOW_TEXT ) ;
@@ -1291,6 +1306,12 @@ pub async fn office_preview_page(Query(query): Query<OfficePreviewQuery>) -> Res
range . setEnd ( endRef . node , endRef . offset + 1 ) ;
const rect = range . getBoundingClientRect ( ) ;
if ( ! rect | | rect . width < = 0 | | rect . height < = 0 ) return false ;
const rects = Array . from ( range . getClientRects ( ) ) . filter ( item = > item & & item . width > 0 & & item . height > 0 ) ;
if ( rects . length > 6 | | rect . height > Math . min ( 140 , window . innerHeight * 0.35 ) ) return false ;
const paragraphTarget = startRef . node ? . parentElement ? . closest ( ' p , li , td , th , blockquote ' ) ;
if ( paragraphTarget instanceof HTMLElement & & normalizeEvidenceText ( paragraphTarget . textContent ) . length < 4000 ) { {
return markEvidenceTarget ( paragraphTarget ) ;
} }
let marker = viewer . querySelector ( ' [ data - mnote - office - evidence - marker = " true " ] ' ) ;
if ( ! ( marker instanceof HTMLElement ) ) { {
marker = document . createElement ( ' div ' ) ;
@@ -1361,13 +1382,17 @@ pub async fn office_preview_page(Query(query): Query<OfficePreviewQuery>) -> Res
let node = walker . nextNode ( ) ;
while ( node ) { {
if ( normalizeEvidenceText ( node . textContent ) . includes ( needle ) ) { {
const inlineTarget = wrapEvidenceTextNode ( node , needle ) ;
if ( inlineTarget ) return markEvidenceTarget ( inlineTarget ) ;
const target = node . parentElement & & node . parentElement . closest ( ' p , div , span , table , section ' ) | | node . parentElement ;
if ( target instanceof HTMLElement ) { {
const rect = target . getBoundingClientRect ( ) ;
if ( rect . height > window . innerHeight * 1.8 | | normalizeEvidenceText ( target . textContent ) . length > 4000 ) break ;
if ( needle . length < 20 ) { {
const paragraphTarget = node . parentElement & & node . parentElement . closest ( ' p , li , td , th , blockquote ' ) | | target ;
if ( paragraphTarget instanceof HTMLElement ) return markEvidenceTarget ( paragraphTarget ) ;
} }
} }
const inlineTarget = wrapEvidenceTextNode ( node , needle ) ;
if ( inlineTarget ) return markEvidenceTarget ( inlineTarget ) ;
return markEvidenceTarget ( target ) ;
} }
node = walker . nextNode ( ) ;
@@ -1376,6 +1401,278 @@ pub async fn office_preview_page(Query(query): Query<OfficePreviewQuery>) -> Res
return false ;
} }
function evidenceTextCandidates ( text ) { {
const raw = String ( text | | ' ' ) ;
const cleaned = raw
. replace ( / < [ ^ > ] + > / g , ' ' )
. replace ( / [ #* _ ` ~ > \ [ \ ] ( ) { { } } ] + / g , ' ' )
. replace ( / \ s + / g , ' ' )
. trim ( ) ;
const specific = [ ] ;
function pushSpecificEvidenceTerm ( term ) { {
let value = normalizeEvidenceText ( term ) ;
if ( ! value | | value . length < 3 ) return ;
const anchor = value . search ( / [ 一 二 三 四 五 六 七 八 九 十 甲 乙 丙 丁 戊 己 庚 辛 壬 癸 叔 仲 异 正 特 苯 ] [ \ u3400 - \ u9fffA - Za - z0 - 9 ( ) ( ) \ \ - ] { { 0 , 18 } } 硅 / ) ;
if ( anchor > 0 ) value = value . slice ( anchor ) ;
value = value . split ( / [ :: 。 ; ; , , \ n ] / ) [ 0 ] ;
if ( value . length < 3 | | value . length > 48 ) return ;
specific . push ( value ) ;
if ( / [ 基 酯 醚 ] $ / . test ( value ) & & value . length > 3 ) specific . push ( value . slice ( 0 , - 1 ) ) ;
} }
const withoutTags = raw . replace ( / < [ ^ > ] + > / g , ' ' ) . replace ( / \ s + / g , ' ' ) . trim ( ) ;
const siliconTerms = cleaned . match ( / [ \ u3400 - \ u9fffA - Za - z0 - 9 ( ) ( ) \ \ - ] { { 0 , 24 } } 硅 ( ? :基 | 酯 | 醚 ) ? / g ) | | [ ] ;
siliconTerms . forEach ( pushSpecificEvidenceTerm ) ;
const cjkTerms = cleaned . match ( / [ \ u3400 - \ u9fff ] [ \ u3400 - \ u9fffA - Za - z0 - 9 ( ) ( ) \ \ - ] { { 2 , 48 } } / g ) | | [ ] ;
const fallbackTerms = [ ] ;
cjkTerms . forEach ( term = > { {
const value = normalizeEvidenceText ( term ) ;
if ( value . length < 3 | | / ^ 参 考 文 献 $ / . test ( value ) | | / ^ 保 护 $ / . test ( value ) ) return ;
pushSpecificEvidenceTerm ( value ) ;
const rawIndex = withoutTags . indexOf ( value ) ;
if ( rawIndex > = 0 ) { {
const rawWindow = withoutTags . slice ( rawIndex , rawIndex + value . length + 36 ) . split ( / [ :: 。 ; ; , , \ n ] / ) [ 0 ] ;
specific . push ( normalizeEvidenceText ( rawWindow ) ) ;
} }
const cleanedIndex = cleaned . indexOf ( value ) ;
if ( cleanedIndex > = 0 ) { {
const cleanedWindow = cleaned . slice ( cleanedIndex , cleanedIndex + value . length + 36 ) . split ( / [ :: 。 ; ; , , \ n ] / ) [ 0 ] ;
specific . push ( normalizeEvidenceText ( cleanedWindow ) ) ;
} }
if ( value . endsWith ( '基' ) & & value . length > 3 ) specific . push ( value . slice ( 0 , - 1 ) ) ;
fallbackTerms . push ( value ) ;
} } ) ;
const candidates = [ ] ;
cleaned . split ( / [ 。 ; ; , , \ n ] / ) . forEach ( part = > { {
const value = normalizeEvidenceText ( part ) ;
if ( value . length > = 8 ) candidates . push ( value ) ;
if ( value . length > = 28 ) candidates . push ( value . slice ( 0 , 28 ) ) ;
} } ) ;
candidates . push ( .. . fallbackTerms ) ;
candidates . push ( cleaned , raw ) ;
const seen = new Set ( ) ;
return specific . concat ( candidates )
. map ( normalizeEvidenceText )
. filter ( value = > value . length > = 3 & & ! seen . has ( value ) & & seen . add ( value ) )
. sort ( ( left , right ) = > right . length - left . length ) ;
} }
function compactEvidenceText ( value ) { {
return normalizeEvidenceText ( value ) . replace ( / [ \ s \ p { { P } } \ p { { S } } ] + / gu , ' ' ) ;
} }
function compactEvidenceTextWithoutNumbers ( value ) { {
return normalizeEvidenceText ( value ) . replace ( / [ 0 - 9 0 - 9 ] + / g , ' ' ) . replace ( / [ \ s \ p { { P } } \ p { { S } } ] + / gu , ' ' ) ;
} }
function evidenceLeadingAnchors ( text ) { {
const raw = String ( text | | ' ' ) ;
const cleaned = normalizeEvidenceText ( raw ) ;
const anchors = [ ] ;
const queryCompact = compactEvidenceText ( evidenceSearchQuery ) ;
function push ( value , options ) { {
const normalized = normalizeEvidenceText ( value ) ;
const allowShort = options & & options . allowShort = = = true ;
if ( normalized . length < ( allowShort ? 3 : 6 ) ) return ;
anchors . push ( normalized . length > 80 ? normalized . slice ( 0 , 80 ) : normalized ) ;
if ( normalized . length > 24 ) anchors . push ( normalized . slice ( 0 , 24 ) ) ;
} }
function pushQueryNearPrefix ( value ) { {
const normalized = normalizeEvidenceText ( value ) ;
if ( ! normalized | | ! queryCompact | | ! compactEvidenceText ( normalized ) . includes ( queryCompact ) ) return ;
push ( normalized , { { allowShort : true } } ) ;
const queryIndex = compactEvidenceText ( normalized ) . indexOf ( queryCompact ) ;
if ( queryIndex > = 0 & & normalized . length > 24 ) push ( normalized . slice ( 0 , 36 ) , { { allowShort : true } } ) ;
} }
const prefixWindow = cleaned . slice ( 0 , 260 ) ;
const catalogMatches = prefixWindow . match ( / [ ^ , , 。 ; ; #] { { 2 , 56 } } [ , , ] \ s * [ 0 - 9 0 - 9 ] { { 1 , 5 } } / g ) | | [ ] ;
catalogMatches . slice ( 0 , 8 ) . forEach ( match = > { {
const value = normalizeEvidenceText ( match ) ;
push ( value , { { allowShort : true } } ) ;
const withoutPage = value . replace ( / [ , , ] \ s * [ 0 - 9 0 - 9 ] { { 1 , 5 } } \ s * $ / , ' ' ) ;
push ( withoutPage , { { allowShort : true } } ) ;
pushQueryNearPrefix ( withoutPage ) ;
} } ) ;
const headingMatches = prefixWindow . match ( / [ 0 - 9 0 - 9 ] + ( ? :\ . [ 0 - 9 0 - 9 ] + ) { { 1 , 5 } } \ s + [ ^ 。 ; ; ] { { 2 , 72 } } / g ) | | [ ] ;
headingMatches . slice ( 0 , 4 ) . forEach ( match = > { {
const firstPart = normalizeEvidenceText ( match ) . split ( / [ , , ] / ) [ 0 ] ;
push ( firstPart , { { allowShort : true } } ) ;
} } ) ;
raw . split ( / [ \ n 。 ; ; ] / ) . slice ( 0 , 4 ) . forEach ( part = > { {
const value = normalizeEvidenceText ( part ) ;
if ( value ) push ( value ) ;
} } ) ;
cleaned . split ( / [ 。 ; ; ] / ) . slice ( 0 , 4 ) . forEach ( part = > { {
const value = normalizeEvidenceText ( part ) ;
if ( value ) push ( value ) ;
} } ) ;
evidenceTextCandidates ( text ) . forEach ( candidate = > { {
if ( ! queryCompact | | compactEvidenceText ( candidate ) . includes ( queryCompact ) ) push ( candidate ) ;
} } ) ;
const seen = new Set ( ) ;
return anchors
. map ( normalizeEvidenceText )
. filter ( value = > { {
if ( ! value | | seen . has ( value ) ) return false ;
const compactValue = compactEvidenceText ( value ) ;
const shortQueryAnchor = queryCompact . length > = 2
& & compactValue . includes ( queryCompact )
& & compactValue . length > = queryCompact . length + 1
& & / [ 0 - 9 0 - 9 A - Za - z ] / . test ( value ) ;
if ( value . length < 6 & & ! shortQueryAnchor ) return false ;
seen . add ( value ) ;
return true ;
} } ) ;
} }
function shortLeadingAnchorTarget ( element , elements , index ) { {
const normalized = normalizeEvidenceText ( element & & element . textContent | | ' ' ) ;
if ( normalized . length > = 18 ) return element ;
for ( let offset = 1 ; offset < = 3 ; offset + = 1 ) { {
const next = elements [ index + offset ] ;
if ( ! ( next instanceof HTMLElement ) ) continue ;
const nextText = normalizeEvidenceText ( next . textContent | | ' ' ) ;
if ( nextText . length > = 18 & & evidenceElementMatchesSearchQuery ( next ) ) return next ;
} }
return element ;
} }
function scrollToEvidenceLeadingAnchor ( text ) { {
if ( ! viewer ) return false ;
const anchors = evidenceLeadingAnchors ( text ) ;
if ( ! anchors . length ) return false ;
const queryCompact = compactEvidenceText ( evidenceSearchQuery ) ;
const elements = Array . from ( viewer . querySelectorAll ( ' p , li , td , th , blockquote ' ) )
. filter ( node = > node instanceof HTMLElement )
. filter ( node = > { {
const normalized = normalizeEvidenceText ( node . textContent | | ' ' ) ;
return normalized . length > = 3 & & normalized . length < = 1200 ;
} } ) ;
for ( const anchor of anchors ) { {
const compactAnchor = compactEvidenceText ( anchor ) ;
const compactAnchorWithoutNumbers = compactEvidenceTextWithoutNumbers ( anchor ) ;
const shortQueryAnchor = queryCompact . length > = 2
& & compactAnchor . includes ( queryCompact )
& & compactAnchor . length > = queryCompact . length + 1
& & / [ 0 - 9 0 - 9 A - Za - z ] / . test ( anchor ) ;
if ( ! shortQueryAnchor & & compactAnchor . length < 6 & & compactAnchorWithoutNumbers . length < 6 ) continue ;
for ( const element of elements ) { {
const compactElement = compactEvidenceText ( element . textContent | | ' ' ) ;
if ( ( compactAnchor . length > = 6 | | shortQueryAnchor ) & & compactElement . includes ( compactAnchor ) ) { {
return markEvidenceTarget ( shortQueryAnchor ? shortLeadingAnchorTarget ( element , elements , elements . indexOf ( element ) ) : element ) ;
} }
if (
compactAnchorWithoutNumbers . length > = 8
& & / [ \ u3400 - \ u9fff ] / . test ( anchor )
& & compactEvidenceTextWithoutNumbers ( element . textContent | | ' ' ) . includes ( compactAnchorWithoutNumbers )
) { {
return markEvidenceTarget ( element ) ;
} }
} }
} }
return false ;
} }
function evidenceParagraphAnchors ( text ) { {
const cleaned = normalizeEvidenceText ( text ) ;
const anchors = [ ] ;
function push ( value ) { {
const normalized = normalizeEvidenceText ( value ) ;
if ( normalized . length < 6 ) return ;
anchors . push ( normalized . length > 140 ? normalized . slice ( 0 , 140 ) : normalized ) ;
} }
evidenceTextCandidates ( text ) . forEach ( push ) ;
cleaned . split ( / [ 。 ; ; , , \ n ] / ) . forEach ( part = > { {
const value = normalizeEvidenceText ( part ) ;
if ( value . length > = 10 ) push ( value ) ;
if ( value . length > = 36 ) push ( value . slice ( 0 , 36 ) ) ;
} } ) ;
if ( cleaned . length > = 24 ) { {
for ( let index = 0 ; index < cleaned . length ; index + = 48 ) { {
push ( cleaned . slice ( index , index + 96 ) ) ;
} }
} }
push ( cleaned ) ;
const seen = new Set ( ) ;
return anchors
. map ( normalizeEvidenceText )
. filter ( value = > value . length > = 6 & & ! seen . has ( value ) & & seen . add ( value ) )
. sort ( ( left , right ) = > right . length - left . length ) ;
} }
function scoreEvidenceParagraphElement ( element , anchors ) { {
if ( ! ( element instanceof HTMLElement ) ) return 0 ;
const text = normalizeEvidenceText ( element . textContent | | ' ' ) ;
if ( ! text | | text . length < 3 | | text . length > 6000 ) return 0 ;
const compactText = compactEvidenceText ( text ) ;
const compactSearchQuery = compactEvidenceText ( evidenceSearchQuery ) ;
let score = 0 ;
if ( compactSearchQuery . length > = 2 & & compactText . includes ( compactSearchQuery ) ) { {
score + = 2400 ;
} }
for ( const anchor of anchors ) { {
const compactAnchor = compactEvidenceText ( anchor ) ;
if ( ! compactAnchor | | compactAnchor . length < 4 ) continue ;
if ( text . includes ( anchor ) ) { {
score + = anchor . length * anchor . length * 4 ;
continue ;
} }
if ( compactText . includes ( compactAnchor ) ) { {
score + = compactAnchor . length * compactAnchor . length * 2 ;
continue ;
} }
if ( compactAnchor . length > = 14 ) { {
const prefix = compactAnchor . slice ( 0 , Math . min ( 36 , compactAnchor . length ) ) ;
if ( prefix . length > = 8 & & compactText . includes ( prefix ) ) score + = prefix . length * 20 ;
} }
} }
return score ;
} }
function evidenceElementMatchesSearchQuery ( element ) { {
if ( ! ( element instanceof HTMLElement ) ) return false ;
const compactSearchQuery = compactEvidenceText ( evidenceSearchQuery ) ;
if ( compactSearchQuery . length < 2 ) return false ;
return compactEvidenceText ( element . textContent | | ' ' ) . includes ( compactSearchQuery ) ;
} }
function scrollToEvidenceParagraph ( text ) { {
if ( ! viewer ) return false ;
if ( scrollToEvidenceLeadingAnchor ( text ) ) return true ;
const anchors = evidenceParagraphAnchors ( text ) ;
if ( ! anchors . length ) return false ;
const selector = ' p , li , td , th , blockquote , section . docx , section . mnote - docx , div ' ;
const elements = Array . from ( viewer . querySelectorAll ( selector ) )
. filter ( node = > node instanceof HTMLElement )
. filter ( node = > { {
const normalized = normalizeEvidenceText ( node . textContent | | ' ' ) ;
if ( normalized . length < 3 | | normalized . length > 6000 ) return false ;
const childBlocks = Array . from ( node . children | | [ ] ) . filter ( child = > child instanceof HTMLElement & & / ^ ( P | LI | TD | TH | BLOCKQUOTE ) $ / . test ( child . tagName ) ) ;
return childBlocks . length = = = 0 | | / ^ ( TD | TH | SECTION ) $ / . test ( node . tagName ) ;
} } ) ;
let best = null ;
let bestWithSearchQuery = null ;
for ( const element of elements ) { {
const score = scoreEvidenceParagraphElement ( element , anchors ) ;
if ( score < = 0 ) continue ;
if ( ! best | | score > best . score ) best = { { element , score } } ;
if ( evidenceElementMatchesSearchQuery ( element ) & & ( ! bestWithSearchQuery | | score > bestWithSearchQuery . score ) ) { {
bestWithSearchQuery = { { element , score } } ;
} }
} }
const threshold = Math . max ( 180 , Math . min ( 800 , anchors [ 0 ] . length * 4 ) ) ;
if ( bestWithSearchQuery & & bestWithSearchQuery . score > = threshold ) return markEvidenceTarget ( bestWithSearchQuery . element ) ;
if ( ! best ) return false ;
if ( best . score < threshold ) return false ;
return markEvidenceTarget ( best . element ) ;
} }
function scrollToEvidenceTextCandidates ( text ) { {
for ( const candidate of evidenceTextCandidates ( text ) ) { {
if ( scrollToEvidenceText ( candidate ) ) return true ;
} }
return false ;
} }
function scrollToEvidenceCoordinate ( sourceMap , block ) { {
if ( ! viewer | | ! sourceMap | | ! block ) return false ;
const page = pageForEvidenceBlock ( sourceMap , block ) ;
@@ -1422,13 +1719,18 @@ pub async fn office_preview_page(Query(query): Query<OfficePreviewQuery>) -> Res
} }
async function applyEvidenceLocator ( ) { {
if ( ! viewer | | ( ! evidencePage & & ! evidenceBlockId & & ! evidenceBbox ) ) return ;
if ( ! viewer | | ( ! evidencePage & & ! evidenceBlockId & & ! evidenceBbox & & ! evidenceText ) ) return ;
try { {
const sourceMap = await fetchEvidenceSourceMap ( ) ;
const block = findEvidenceBlockInSourceMap ( sourceMap ) ;
if ( block & & scrollToEvidenceText ( block . text ) ) return ;
if ( evidenceText & & scrollToEvidenceParagraph ( evidenceText ) ) return ;
if ( block & & scrollToEvidenceParagraph ( block . text ) ) return ;
if ( evidenceText & & scrollToEvidenceTextCandidates ( evidenceText ) ) return ;
if ( block & & scrollToEvidenceTextCandidates ( block . text ) ) return ;
if ( scrollToEvidenceCoordinate ( sourceMap , block ) ) return ;
} } catch ( _ ) { { } }
if ( evidenceText & & scrollToEvidenceParagraph ( evidenceText ) ) return ;
if ( evidenceText & & scrollToEvidenceTextCandidates ( evidenceText ) ) return ;
scrollToEvidencePageFallback ( ) ;
} }
@@ -1438,10 +1740,14 @@ pub async fn office_preview_page(Query(query): Query<OfficePreviewQuery>) -> Res
evidenceBbox = String ( next . bbox | | ' ' ) ;
evidenceSourceMapPath = String ( next . sourceMapPath | | ' ' ) ;
evidenceBlockId = String ( next . blockId | | ' ' ) ;
evidenceText = String ( next . evidenceText | | next . query | | ' ' ) ;
evidenceSearchQuery = String ( next . searchQuery | | ' ' ) ;
body . dataset . evidencePage = evidencePage ? String ( evidencePage ) : ' ' ;
body . dataset . evidenceBbox = evidenceBbox ;
body . dataset . evidenceSourceMapPath = evidenceSourceMapPath ;
body . dataset . evidenceBlockId = evidenceBlockId ;
body . dataset . evidenceText = evidenceText ;
body . dataset . evidenceSearchQuery = evidenceSearchQuery ;
document . documentElement . removeAttribute ( ' data - mnote - office - evidence - applied ' ) ;
void applyEvidenceLocator ( ) ;
} }
@@ -1663,6 +1969,7 @@ pub async fn office_preview_page(Query(query): Query<OfficePreviewQuery>) -> Res
target_bbox = escape_html ( & target_bbox ) ,
target_source_map_path = escape_html ( & target_source_map_path ) ,
target_block_id = escape_html ( & target_block_id ) ,
target_evidence_text = escape_html ( & target_evidence_text ) ,
) ;
let mut response = Html ( html ) . into_response ( ) ;
stamp_shell_headers ( response . headers_mut ( ) , " office-preview " ) ;