1+ /*
2+ https://gitlab.com/antora/antora-ui-default/-/merge_requests/126/
3+ Lightbox functionality: a user clicks on an image, and it will open full screen until user closes it again.
4+
5+ Supported functionality:
6+
7+ when lightbox is closed for all images:
8+ * if the image has a link, the standard behavior for hovering and clicking is unchanged.
9+
10+ when lightbox is closed for standard block image:
11+ * when hovering over image AND if original size of image is greater than displayed image,
12+ THEN change mouse pointer to pointer
13+ (works for both bitmap images the same way as for SVG images)
14+ * when clicking on image AND if original size of image is greater than displayed image, THEN open lightbox
15+ (works for both bitmap images the same way as for SVG images)
16+
17+ when lightbox is closed for inlined or interactive SVG image:
18+ * when hovering over image THEN change mouse pointer to pointer
19+ * when clicking on image THEN open lightbox
20+
21+ when lightbox is open for all images:
22+ * when user clicks on close icon, lightbox will close
23+ * when user presses Escape, lightbox will close
24+ * when user presses Tab to select the close button and presses Space or Enter, lightbox will close
25+
26+ when lightbox is opened for standard block image:
27+ * when user clicks enlarged image, lightbox will close
28+
29+ when lightbox is opened for interactive SVG:
30+ * when user clicks enlarged image AND if the SVG doesn't contain any hyperlinks, lightbox will close
31+ * when user clicks enlarged image AND if the SVG contain a hyperlinks AND the user clicks outside of a hyperlink,
32+ nothing happens (the lightbox will stay open)
33+ * when user clicks enlarged image AND if the SVG contains hyperlinks AND the user clicks on a hyperlink,
34+ the hyperlinks will work as before
35+
36+ when lightbox is opened for inlined SVG:
37+ * when user clicks on links included in the SVG, the hyperlinks will work as before
38+ * when user clicks outside of the links withing the SVG, the lightbox will close
39+
40+ */
41+
42+ ; ( function ( ) {
43+ 'use strict'
44+ var lightbox
45+ var config = ( document . getElementById ( 'site-script' ) || { dataset : { } } ) . dataset
46+ var content
47+
48+ function init ( ) {
49+ if ( ! lightbox ) {
50+ lightbox = document . createElement ( 'div' )
51+ lightbox . setAttribute ( 'aria-modal' , 'true' )
52+ lightbox . className = 'modal'
53+ var closeLink = document . createElement ( 'a' )
54+ // set href to make it selectable with tab / assistive technologies
55+ closeLink . href = '#'
56+ closeLink . className = 'close'
57+ closeLink . setAttribute ( 'title' , 'Close lightbox' )
58+ if ( config . svgAs === 'svg' ) {
59+ var svg = document . createElementNS ( 'http://www.w3.org/2000/svg' , 'svg' )
60+ svg . setAttribute ( 'class' , 'copy-icon' )
61+ var use = document . createElementNS ( 'http://www.w3.org/2000/svg' , 'use' )
62+ use . setAttribute ( 'href' , window . uiRootPath + '/img/octicons-16.svg#icon-x' )
63+ svg . appendChild ( use )
64+ closeLink . appendChild ( svg )
65+ } else {
66+ // https://codepen.io/marianab/pen/gOPJOjJ
67+ let svgIcon = `<svg xmlns="http://www.w3.org/2000/svg" height="329pt" viewBox="0 0 329.26933 329" width="329pt">
68+ <path d="m194.800781 164.769531 128.210938-128.214843c8.34375-8.339844 8.34375-21.824219
69+ 0-30.164063-8.339844-8.339844-21.824219-8.339844-30.164063 0l-128.214844
70+ 128.214844-128.210937-128.214844c-8.34375-8.339844-21.824219-8.339844-30.164063
71+ 0-8.34375 8.339844-8.34375 21.824219 0 30.164063l128.210938 128.214843-128.210938
72+ 128.214844c-8.34375 8.339844-8.34375 21.824219 0 30.164063 4.15625 4.160156 9.621094
73+ 6.25 15.082032 6.25 5.460937 0 10.921875-2.089844 15.082031-6.25l128.210937-128.214844
74+ 128.214844 128.214844c4.160156 4.160156 9.621094 6.25 15.082032 6.25 5.460937 0
75+ 10.921874-2.089844 15.082031-6.25 8.34375-8.339844 8.34375-21.824219 0-30.164063zm0 0"/></svg>`
76+ var img = document . createElement ( 'img' )
77+ img . src = `data:image/svg+xml;utf-8,${ svgIcon } `
78+ img . alt = 'close icon'
79+ img . className = 'x-icon'
80+ closeLink . appendChild ( img )
81+ }
82+ lightbox . appendChild ( closeLink )
83+ content = document . createElement ( 'div' )
84+ content . className = 'content'
85+ lightbox . appendChild ( content )
86+ var body = document . getElementsByTagName ( 'body' ) [ 0 ]
87+ body . appendChild ( lightbox )
88+ body . addEventListener ( 'keydown' , function ( e ) {
89+ if ( e . code === 'Escape' && isOpen ( ) ) {
90+ close ( e )
91+ }
92+ } )
93+
94+ content . addEventListener ( 'click' , close )
95+ closeLink . addEventListener ( 'click' , function ( e ) {
96+ close ( e )
97+ e . preventDefault ( )
98+ } )
99+ closeLink . addEventListener ( 'keydown' , function ( e ) {
100+ if ( e . code === 'Space' || e . code === 'Enter' ) {
101+ close ( e )
102+ e . preventDefault ( )
103+ }
104+ } )
105+ }
106+ }
107+
108+ function open ( ) {
109+ lightbox . style . display = 'flex'
110+ document . body . style . overflow = 'hidden'
111+ }
112+
113+ function isOpen ( ) {
114+ return lightbox && lightbox . style . display === 'flex'
115+ }
116+
117+ function close ( e ) {
118+ lightbox . style . display = 'none'
119+ content . firstChild . remove ( )
120+ document . body . style . overflow = ''
121+ // don't prevent default here, as that will allow links in SVGs to work
122+ }
123+
124+ // depending on ratio of source vs target element, make the lightbox content 90% of height or width
125+ function setImageSize ( img , source , target ) {
126+ var ratioSource = source . offsetWidth / source . offsetHeight
127+ var ratioTarget = target . offsetWidth / target . offsetHeight
128+ if ( ratioSource < ratioTarget ) {
129+ img . style . height = '70vh'
130+ } else {
131+ img . style . width = '70vw'
132+ }
133+ }
134+ /* swiper slider img*/
135+ document . querySelectorAll ( '.slide img' ) . forEach ( function ( element ) {
136+ if ( element . parentNode . nodeName === 'A' ) {
137+ // if parent node is an anchor, keep the anchor instead of opening lightbox
138+ return
139+ }
140+ element . parentNode . className += ' lightbox'
141+ if ( typeof element . parentNode . classList . remove === 'function' ) {
142+ element . parentNode . addEventListener ( 'mouseover' , function ( e ) {
143+ if ( element . naturalWidth <= element . offsetWidth && element . naturalHeight <= element . offsetHeight ) {
144+ element . parentNode . classList . remove ( 'lightbox' )
145+ } else {
146+ element . parentNode . classList . add ( 'lightbox' )
147+ }
148+ } )
149+ }
150+ element . style . cursor = 'pointer'
151+ element . addEventListener ( 'click' , function ( e ) {
152+ if ( element . naturalWidth <= element . offsetWidth && element . naturalHeight <= element . offsetHeight ) {
153+ // don't open lightbox is already shown at 100% or more
154+ return
155+ }
156+ init ( )
157+ var img = document . createElement ( 'img' )
158+ img . src = e . currentTarget . src
159+ img . alt = e . currentTarget . alt
160+ setImageSize ( img , element . parentNode , content . parentNode )
161+
162+ /* Render swiper
163+ let str = e.currentTarget.closest('.swiper').className
164+ let index = parseInt(str.match(/slider-(\d+)/i)[1]);
165+ content.appendChild(sliderBlock[index])*/
166+ content . appendChild ( img )
167+ open ( )
168+ } )
169+ } )
170+
171+ document . querySelectorAll ( '.imageblock img' ) . forEach ( function ( element ) {
172+ if ( element . parentNode . nodeName === 'A' ) {
173+ // if parent node is an anchor, keep the anchor instead of opening lightbox
174+ return
175+ }
176+ element . parentNode . className += ' lightbox'
177+ if ( typeof element . parentNode . classList . remove === 'function' ) {
178+ element . parentNode . addEventListener ( 'mouseover' , function ( e ) {
179+ if ( element . naturalWidth <= element . offsetWidth && element . naturalHeight <= element . offsetHeight ) {
180+ element . parentNode . classList . remove ( 'lightbox' )
181+ } else {
182+ element . parentNode . classList . add ( 'lightbox' )
183+ }
184+ } )
185+ }
186+ element . addEventListener ( 'click' , function ( e ) {
187+ if ( element . naturalWidth <= element . offsetWidth && element . naturalHeight <= element . offsetHeight ) {
188+ // don't open lightbox is already shown at 100% or more
189+ return
190+ }
191+ init ( )
192+ var img = document . createElement ( 'img' )
193+ img . src = e . currentTarget . src
194+ img . alt = e . currentTarget . alt
195+ setImageSize ( img , element . parentNode , content . parentNode )
196+ content . appendChild ( img )
197+ open ( )
198+ } )
199+ } )
200+
201+ document . querySelectorAll ( '.imageblock object' ) . forEach ( function ( element ) {
202+ if ( element . parentNode . nodeName === 'A' ) {
203+ // if parent node is an anchor, keep the anchor instead of opening lightbox
204+ return
205+ }
206+ element . parentNode . className += ' lightbox'
207+ element . parentNode . addEventListener ( 'click' , function ( e ) {
208+ init ( )
209+ var img = document . createElement ( 'object' )
210+ img . type = element . type
211+ img . data = element . data
212+ open ( )
213+ setImageSize ( img , element , content . parentNode )
214+ if ( element . getSVGDocument ( ) && element . getSVGDocument ( ) . querySelectorAll ( 'a' ) . length === 0 ) {
215+ // if the SVG doesn't contain any links, allow user to click on image to close the image
216+ img . style . pointerEvents = 'none'
217+ }
218+ content . appendChild ( img )
219+ // prevent links in SVGs to open, as this should only open the lightbox
220+ e . preventDefault ( )
221+ } )
222+ } )
223+ document . querySelectorAll ( '.imageblock svg' ) . forEach ( function ( element ) {
224+ if ( element . parentNode . nodeName === 'A' ) {
225+ // if parent node is an anchor, keep the anchor instead of opening lightbox
226+ return
227+ }
228+ element . parentNode . className += ' lightbox'
229+ element . parentNode . addEventListener ( 'click' , function ( e ) {
230+ init ( )
231+ var img = element . cloneNode ( true )
232+ open ( )
233+ // override height/width from cloned element
234+ img . style . height = 'auto'
235+ img . style . width = 'auto'
236+ // need to select element's parent node, as offsetWidth/offsetHeight not available on SVG
237+ setImageSize ( img , element . parentNode , content . parentNode )
238+ content . appendChild ( img )
239+ // prevent links in SVGs to open, as this should only open the lightbox
240+ e . preventDefault ( )
241+ } )
242+ } )
243+ } ) ( )
0 commit comments