@@ -12,7 +12,8 @@ const DEFAULTS = {
12
12
pagemode : 'none' ,
13
13
locale : '' ,
14
14
textLayer : '' ,
15
- viewerCssTheme : 'AUTOMATIC'
15
+ viewerCssTheme : 'AUTOMATIC' ,
16
+ viewerExtraStyles : ''
16
17
} as const
17
18
18
19
export const ViewerCssTheme = {
@@ -21,27 +22,37 @@ export const ViewerCssTheme = {
21
22
DARK : 2 ,
22
23
} as const
23
24
25
+ export type ToolbarButtonId = 'sidebarToggle' | ''
26
+
24
27
export class PdfjsViewerElement extends HTMLElement {
25
28
constructor ( ) {
26
29
super ( )
27
30
const shadowRoot = this . attachShadow ( { mode : 'open' } )
28
31
const template = document . createElement ( 'template' )
29
32
template . innerHTML = `
30
- <iframe frameborder="0" width="100%"></iframe>
31
33
<style>:host{width:100%;display:block;overflow:hidden}:host iframe{height:100%}</style>
34
+ <iframe frameborder="0" width="100%" loading="lazy"></iframe>
32
35
`
33
36
shadowRoot . appendChild ( template . content . cloneNode ( true ) )
34
37
}
35
38
36
- private iframe ! : PdfjsViewerElementIframe
39
+ public iframe ! : PdfjsViewerElementIframe
37
40
38
41
static get observedAttributes ( ) {
39
- return [ 'src' , 'viewer-path' , 'locale' , 'page' , 'search' , 'phrase' , 'zoom' , 'pagemode' , 'text-layer' , 'viewer-css-theme' ]
42
+ return [ 'src' , 'viewer-path' , 'locale' , 'page' , 'search' , 'phrase' , 'zoom' , 'pagemode' , 'text-layer' , 'viewer-css-theme' , 'viewer-extra-styles' ]
40
43
}
41
44
42
45
connectedCallback ( ) {
43
46
this . iframe = this . shadowRoot ! . querySelector ( 'iframe' ) as PdfjsViewerElementIframe
44
- this . setEventListeners ( )
47
+ document . addEventListener ( 'webviewerloaded' , ( ) => {
48
+ this . dispatchEvent ( new Event ( 'loaded' ) )
49
+ this . setViewerExtraStyles ( this . getAttribute ( 'viewer-extra-styles' ) )
50
+ if ( this . getAttribute ( 'src' ) !== DEFAULTS . src ) this . iframe . contentWindow ?. PDFViewerApplicationOptions ?. set ( 'defaultUrl' , '' )
51
+ this . iframe . contentWindow ?. PDFViewerApplicationOptions ?. set ( 'viewerCssTheme' , this . getCssThemeOption ( ) )
52
+ this . iframe . contentWindow ?. PDFViewerApplicationOptions ?. set ( 'disablePreferences' , true )
53
+ this . iframe . contentWindow ?. PDFViewerApplicationOptions ?. set ( 'pdfBugEnabled' , true )
54
+ this . iframe . contentWindow ?. PDFViewerApplicationOptions ?. set ( 'eventBusDispatchToDOM' , true )
55
+ } ) ;
45
56
}
46
57
47
58
attributeChangedCallback ( ) {
@@ -64,8 +75,9 @@ export class PdfjsViewerElement extends HTMLElement {
64
75
const locale = this . getAttribute ( 'locale' ) || DEFAULTS . locale
65
76
const textLayer = this . getAttribute ( 'text-layer' ) || DEFAULTS . textLayer
66
77
const viewerCssTheme = this . getAttribute ( 'viewer-css-theme' ) || DEFAULTS . viewerCssTheme
78
+ const viewerExtraStyles = Boolean ( this . getAttribute ( 'viewer-extra-styles' ) || DEFAULTS . viewerExtraStyles )
67
79
68
- const updatedSrc = `${ viewerPath } ${ DEFAULTS . viewerEntry } ?file=${ encodeURIComponent ( src ) } #page=${ page } &zoom=${ zoom } &pagemode=${ pagemode } &search=${ search } &phrase=${ phrase } &textLayer=${ textLayer } ${ locale ? '&locale=' + locale : '' } &viewerCssTheme=${ viewerCssTheme } `
80
+ const updatedSrc = `${ viewerPath } ${ DEFAULTS . viewerEntry } ?file=${ encodeURIComponent ( src ) } #page=${ page } &zoom=${ zoom } &pagemode=${ pagemode } &search=${ search } &phrase=${ phrase } &textLayer=${ textLayer } ${ locale ? '&locale=' + locale : '' } &viewerCssTheme=${ viewerCssTheme } &viewerExtraStyles= ${ viewerExtraStyles } `
69
81
if ( updatedSrc !== this . iframe . getAttribute ( 'src' ) ) return updatedSrc
70
82
return ''
71
83
}
@@ -77,16 +89,6 @@ export class PdfjsViewerElement extends HTMLElement {
77
89
this . iframe . src = src
78
90
}
79
91
80
- private setEventListeners ( ) {
81
- document . addEventListener ( 'webviewerloaded' , async ( ) => {
82
- if ( this . getAttribute ( 'src' ) !== DEFAULTS . src ) this . iframe . contentWindow ?. PDFViewerApplicationOptions ?. set ( 'defaultUrl' , '' )
83
- this . iframe . contentWindow ?. PDFViewerApplicationOptions ?. set ( 'viewerCssTheme' , this . getCssThemeOption ( ) )
84
- this . iframe . contentWindow ?. PDFViewerApplicationOptions ?. set ( 'disablePreferences' , true )
85
- this . iframe . contentWindow ?. PDFViewerApplicationOptions ?. set ( 'pdfBugEnabled' , true )
86
- this . iframe . contentWindow ?. PDFViewerApplicationOptions ?. set ( 'eventBusDispatchToDOM' , true )
87
- } ) ;
88
- }
89
-
90
92
private getFullPath ( path : string ) {
91
93
return path . startsWith ( '/' ) ? `${ window . location . origin } ${ path } ` : path
92
94
}
@@ -98,6 +100,18 @@ export class PdfjsViewerElement extends HTMLElement {
98
100
: ViewerCssTheme [ DEFAULTS . viewerCssTheme ]
99
101
}
100
102
103
+ private setViewerExtraStyles = ( styles ?: string | null ) => {
104
+ if ( ! styles ) {
105
+ this . iframe . contentDocument ?. head . querySelector ( 'style[extra]' ) ?. remove ( )
106
+ return
107
+ }
108
+ if ( this . iframe . contentDocument ?. head . querySelector ( 'style[extra]' ) ?. innerHTML === styles ) return
109
+ const style = document . createElement ( 'style' )
110
+ style . innerHTML = styles
111
+ style . setAttribute ( 'extra' , '' )
112
+ this . iframe . contentDocument ?. head . appendChild ( style )
113
+ }
114
+
101
115
public initialize = ( ) : Promise < PdfjsViewerElementIframeWindow [ 'PDFViewerApplication' ] > => new Promise ( async ( resolve ) => {
102
116
await elementReady ( 'iframe' , this . shadowRoot ! )
103
117
this . iframe ?. addEventListener ( 'load' , async ( ) => {
0 commit comments