@@ -5,7 +5,7 @@ import Data from '../BootstrapBlazor/modules/data.js';
55import EventHandler from '../BootstrapBlazor/modules/event-handler.js' ;
66
77if ( pdfjsLib != null ) {
8- pdfjsLib . GlobalWorkerOptions . workerSrc = '. /pdf.worker.min.mjs' ;
8+ pdfjsLib . GlobalWorkerOptions . workerSrc = '/_content/BootstrapBlazor.PdfReader/lib /pdf.worker.min.mjs' ;
99}
1010
1111export async function init ( id , invoke , options ) {
@@ -101,9 +101,120 @@ const loadPdf = async (el, invoke, options) => {
101101 const pdfDocument = await loadingTask . promise ;
102102 pdfViewer . setDocument ( pdfDocument ) ;
103103
104+ pdfDocument . getMetadata ( ) . then ( metadata => {
105+ loadMetadata ( el , pdfViewer , metadata ) ;
106+ } ) ;
107+
104108 return pdfViewer ;
105109}
106110
111+ const loadMetadata = ( el , pdfViewer , metadata ) => {
112+ console . log ( metadata ) ;
113+
114+ const filename = el . querySelector ( '.bb-view-pdf-dialog-filename' ) ;
115+ const docTitle = el . querySelector ( '.bb-view-subject' ) ;
116+ filename . textContent = docTitle . textContent ;
117+
118+ const filesize = el . querySelector ( '.bb-view-pdf-dialog-filesize' ) ;
119+ filesize . textContent = getFilesize ( metadata ) ;
120+
121+ const title = el . querySelector ( '.bb-view-pdf-dialog-title' ) ;
122+ const author = el . querySelector ( '.bb-view-pdf-dialog-author' ) ;
123+ const subject = el . querySelector ( '.bb-view-pdf-dialog-subject' ) ;
124+ const keywords = el . querySelector ( '.bb-view-pdf-dialog-keywords' ) ;
125+ const created = el . querySelector ( '.bb-view-pdf-dialog-created' ) ;
126+ created . textContent = parsePdfDate ( metadata . info . CreationDate ) ?. toLocaleString ( ) ;
127+
128+ const modified = el . querySelector ( '.bb-view-pdf-dialog-modified' ) ;
129+
130+ const application = el . querySelector ( '.bb-view-pdf-dialog-application' ) ;
131+ application . textContent = metadata . info . Creator ;
132+
133+ const producer = el . querySelector ( '.bb-view-pdf-dialog-producer' ) ;
134+ producer . textContent = metadata . info . Producer ;
135+
136+ const version = el . querySelector ( '.bb-view-pdf-dialog-version' ) ;
137+ version . textContent = metadata . info . PDFFormatVersion ;
138+
139+ const count = el . querySelector ( '.bb-view-pdf-dialog-count' ) ;
140+ count . textContent = pdfViewer . pagesCount ;
141+
142+ const size = el . querySelector ( '.bb-view-pdf-dialog-size' ) ;
143+ pdfViewer . pdfDocument . getPage ( pdfViewer . currentPageNumber ) . then ( page => {
144+ const viewport = page . getViewport ( { scale : 1 } ) ;
145+ size . textContent = `${ ( viewport . width / 72 ) . toFixed ( 2 ) } * ${ ( viewport . height / 72 ) . toFixed ( 2 ) } in (portrait)` ;
146+ } ) ;
147+
148+ const webview = el . querySelector ( '.bb-view-pdf-dialog-webview' ) ;
149+ }
150+
151+ function parsePdfDate ( pdfDateString ) {
152+ if ( ! pdfDateString || typeof pdfDateString !== 'string' ) {
153+ return null ;
154+ }
155+
156+ let dateStr = pdfDateString . startsWith ( 'D:' ) ? pdfDateString . substring ( 2 ) : pdfDateString ;
157+
158+ const pdfDateRegex = / ^ ( \d { 4 } ) ( \d { 2 } ) ( \d { 2 } ) ( \d { 2 } ) ( \d { 2 } ) ( \d { 2 } ) ( [ Z z + - ] ) ( \d { 2 } ) ' ? ( \d { 2 } ) ' ? $ / ;
159+ const match = dateStr . match ( pdfDateRegex ) ;
160+
161+ if ( ! match ) {
162+ return null ;
163+ }
164+
165+ const [ , year , month , day , hours , minutes , seconds , timezoneSign , timezoneHours , timezoneMinutes ] = match ;
166+
167+ const date = new Date (
168+ parseInt ( year ) ,
169+ parseInt ( month ) - 1 ,
170+ parseInt ( day ) ,
171+ parseInt ( hours ) ,
172+ parseInt ( minutes ) ,
173+ parseInt ( seconds )
174+ ) ;
175+
176+ if ( timezoneSign === 'Z' || timezoneSign === 'z' ) {
177+ const utcTime = Date . UTC (
178+ parseInt ( year ) ,
179+ parseInt ( month ) - 1 ,
180+ parseInt ( day ) ,
181+ parseInt ( hours ) ,
182+ parseInt ( minutes ) ,
183+ parseInt ( seconds )
184+ ) ;
185+ date . setTime ( utcTime ) ;
186+ }
187+ else if ( timezoneSign === '+' || timezoneSign === '-' ) {
188+ const offsetHours = parseInt ( timezoneHours ) ;
189+ const offsetMinutes = parseInt ( timezoneMinutes || 0 ) ;
190+ const totalOffsetMinutes = offsetHours * 60 + offsetMinutes ;
191+
192+ if ( timezoneSign === '+' ) {
193+ date . setMinutes ( date . getMinutes ( ) - totalOffsetMinutes ) ;
194+ }
195+ else {
196+ date . setMinutes ( date . getMinutes ( ) + totalOffsetMinutes ) ;
197+ }
198+ }
199+ return date ;
200+ }
201+
202+ const getFilesize = metadata => {
203+ const length = metadata . contentLength ;
204+ if ( length < 1024 ) {
205+ return `${ Math . round ( length ) } B` ;
206+ }
207+ else if ( length < 1024 * 1024 ) {
208+ return `${ Math . round ( length / 1024 ) } KB` ;
209+ }
210+ else if ( length < 1024 * 1024 * 1024 ) {
211+ return `${ length / 1024 / 1024 } MB` ;
212+ }
213+ else if ( length < 1024 * 1024 * 1024 * 1024 ) {
214+ return `${ length / 1024 / 1024 / 1024 } GB` ;
215+ }
216+ }
217+
107218const setObserver = el => {
108219 const observer = new ResizeObserver ( entries => {
109220 relayoutToolbar ( el ) ;
@@ -325,6 +436,20 @@ const addToolbarEventHandlers = (el, pdfViewer, invoke, options) => {
325436 // el.requestFullscreen();
326437 //}
327438 } ) ;
439+ EventHandler . on ( toolbar , "click" , ".dropdown-item-doc" , e => {
440+ const dialog = el . querySelector ( ".bb-view-pdf-info" ) ;
441+ if ( dialog ) {
442+ dialog . classList . add ( "show" ) ;
443+ }
444+ } ) ;
445+
446+ const closeButton = el . querySelector ( ".btn-close-doc" ) ;
447+ EventHandler . on ( closeButton , 'click' , e => {
448+ const dialog = el . querySelector ( ".bb-view-pdf-info" ) ;
449+ if ( dialog ) {
450+ dialog . classList . remove ( "show" ) ;
451+ }
452+ } ) ;
328453}
329454
330455const resetToolbarView = ( el , pdfViewer ) => {
@@ -402,7 +527,7 @@ const updateScaleValue = (el, value) => {
402527 const scaleEl = el . querySelector ( ".bb-view-scale-input" ) ;
403528
404529 const scale = value * 100 ;
405- scaleEl . value = `${ Math . round ( scale , 0 ) } %` ;
530+ scaleEl . value = `${ Math . round ( scale ) } %` ;
406531
407532 if ( scale === 25 ) {
408533 minus . classList . add ( "disabled" ) ;
@@ -422,7 +547,7 @@ const updateScale = (pdfViewer, button, rate) => {
422547 }
423548
424549 const scale = pdfViewer . currentScale ;
425- const current = Math . round ( parseFloat ( scale * 100 ) , 0 ) ;
550+ const current = Math . round ( parseFloat ( scale * 100 ) ) ;
426551 const step = [ 25 , 33 , 50 , 67 , 75 , 80 , 90 , 100 , 110 , 125 , 150 , 175 , 200 , 250 , 300 , 400 , 500 ] ;
427552 const findValues = step . filter ( s => rate > 0 ? current < s : current > s ) ;
428553 if ( findValues . length === 0 ) {
@@ -462,7 +587,7 @@ const printPdf = url => {
462587 }
463588
464589 iframe = document . createElement ( "iframe" ) ;
465- iframe . classList = "bb-view-print-iframe" ;
590+ iframe . classList . add ( "bb-view-print-iframe" ) ;
466591 iframe . style . position = "fixed" ;
467592 iframe . style . right = "100%" ;
468593 iframe . style . bottom = "100%" ;
@@ -506,5 +631,10 @@ export function dispose(id) {
506631 if ( iframe ) {
507632 iframe . remove ( ) ;
508633 }
634+
635+ const closeButton = el . querySelector ( ".btn-close-doc" ) ;
636+ if ( closeButton ) {
637+ EventHandler . off ( closeButton , "click" ) ;
638+ }
509639 }
510640}
0 commit comments