2 * Show gallery captions when focused. Copied directly from jquery.mw-jump.js.
3 * Also Dynamically resize images to justify them.
6 // Is there a better way to detect a touchscreen? Current check taken from stack overflow.
7 var isTouchScreen
= !!( window
.ontouchstart
!== undefined || window
.DocumentTouch
!== undefined && document
instanceof window
.DocumentTouch
),
10 // Now on to justification.
20 $gallery
.children( 'li' ).each( function () {
21 // Math.floor to be paranoid if things are off by 0.00000000001
22 var top
= Math
.floor( $( this ).position().top
),
25 if ( top
!== lastTop
) {
26 rows
[rows
.length
] = [];
30 $img
= $this.find( 'div.thumb a.image img' );
31 if ( $img
.length
&& $img
[0].height
) {
32 imgHeight
= $img
[0].height
;
33 imgWidth
= $img
[0].width
;
35 // If we don't have a real image, get the containing divs width/height.
36 // Note that if we do have a real image, using this method will generally
37 // give the same answer, but can be different in the case of a very
38 // narrow image where extra padding is added.
39 imgHeight
= $this.children().children( 'div:first' ).height();
40 imgWidth
= $this.children().children( 'div:first' ).width();
43 // Hack to make an edge case work ok
44 if ( imgHeight
< 30 ) {
45 // Don't try and resize this item.
49 captionWidth
= $this.children().children( 'div.gallerytextwrapper' ).width();
50 rows
[rows
.length
- 1][rows
[rows
.length
- 1].length
] = {
52 width
: $this.outerWidth(),
54 // XXX: can divide by 0 ever happen?
55 aspect
: imgWidth
/ imgHeight
,
56 captionWidth
: captionWidth
,
60 // Save all boundaries so we can restore them on window resize
61 $this.data( 'imgWidth', imgWidth
);
62 $this.data( 'imgHeight', imgHeight
);
63 $this.data( 'width', $this.outerWidth() );
64 $this.data( 'captionWidth', captionWidth
);
88 for ( i
= 0; i
< rows
.length
; i
++ ) {
89 maxWidth
= $gallery
.width();
95 for ( j
= 0; j
< curRow
.length
; j
++ ) {
96 if ( curRowHeight
=== 0 ) {
97 if ( isFinite( curRow
[j
].height
) ) {
98 // Get the height of this row, by taking the first
99 // non-out of bounds height
100 curRowHeight
= curRow
[j
].height
;
104 if ( curRow
[j
].aspect
=== 0 || !isFinite( curRow
[j
].aspect
) ) {
105 // One of the dimensions are 0. Probably should
106 // not try to resize.
107 combinedPadding
+= curRow
[j
].width
;
109 combinedAspect
+= curRow
[j
].aspect
;
110 combinedPadding
+= curRow
[j
].width
- curRow
[j
].imgWidth
;
114 // Add some padding for inter-element spacing.
115 combinedPadding
+= 5 * curRow
.length
;
116 wantedWidth
= maxWidth
- combinedPadding
;
117 preferredHeight
= wantedWidth
/ combinedAspect
;
119 if ( preferredHeight
> curRowHeight
* 1.5 ) {
120 // Only expand at most 1.5 times current size
121 // As that's as high a resolution as we have.
122 // Also on the off chance there is a bug in this
123 // code, would prevent accidentally expanding to
124 // be 10 billion pixels wide.
125 if ( i
=== rows
.length
- 1 ) {
126 // If its the last row, and we can't fit it,
127 // don't make the entire row huge.
128 avgZoom
= ( totalZoom
/ ( rows
.length
- 1 ) ) * curRowHeight
;
129 if ( isFinite( avgZoom
) && avgZoom
>= 1 && avgZoom
<= 1.5 ) {
130 preferredHeight
= avgZoom
;
132 // Probably a single row gallery
133 preferredHeight
= curRowHeight
;
136 preferredHeight
= 1.5 * curRowHeight
;
139 if ( !isFinite( preferredHeight
) ) {
140 // This *definitely* should not happen.
144 if ( preferredHeight
< 5 ) {
145 // Well something clearly went wrong...
150 if ( preferredHeight
/ curRowHeight
> 1 ) {
151 totalZoom
+= preferredHeight
/ curRowHeight
;
153 // If we shrink, still consider that a zoom of 1
157 for ( j
= 0; j
< curRow
.length
; j
++ ) {
158 newWidth
= preferredHeight
* curRow
[j
].aspect
;
159 padding
= curRow
[j
].width
- curRow
[j
].imgWidth
;
160 $outerDiv
= curRow
[j
].$elm
;
161 $innerDiv
= $outerDiv
.children( 'div' ).first();
162 $imageDiv
= $innerDiv
.children( 'div.thumb' );
163 $imageElm
= $imageDiv
.find( 'img' ).first();
164 imageElm
= $imageElm
.length
? $imageElm
[0] : null;
165 $caption
= $outerDiv
.find( 'div.gallerytextwrapper' );
167 // Since we are going to re-adjust the height, the vertical
168 // centering margins need to be reset.
169 $imageDiv
.children( 'div' ).css( 'margin', '0px auto' );
171 if ( newWidth
< 60 || !isFinite( newWidth
) ) {
172 // Making something skinnier than this will mess up captions,
173 if ( newWidth
< 1 || !isFinite( newWidth
) ) {
174 $innerDiv
.height( preferredHeight
);
175 // Don't even try and touch the image size if it could mean
176 // making it disappear.
180 $outerDiv
.width( newWidth
+ padding
);
181 $innerDiv
.width( newWidth
+ padding
);
182 $imageDiv
.width( newWidth
);
183 $caption
.width( curRow
[j
].captionWidth
+ ( newWidth
- curRow
[j
].imgWidth
) );
187 // We don't always have an img, e.g. in the case of an invalid file.
188 imageElm
.width
= newWidth
;
189 imageElm
.height
= preferredHeight
;
192 $imageDiv
.height( preferredHeight
);
199 mw
.hook( 'wikipage.content' ).add( function ( $content
) {
200 if ( isTouchScreen
) {
201 // Always show the caption for a touch screen.
202 $content
.find( 'ul.mw-gallery-packed-hover' )
203 .addClass( 'mw-gallery-packed-overlay' )
204 .removeClass( 'mw-gallery-packed-hover' );
206 // Note use of just "a", not a.image, since we want this to trigger if a link in
207 // the caption receives focus
208 $content
.find( 'ul.mw-gallery-packed-hover li.gallerybox' ).on( 'focus blur', 'a', function ( e
) {
209 // Confusingly jQuery leaves e.type as focusout for delegated blur events
210 var gettingFocus
= e
.type
!== 'blur' && e
.type
!== 'focusout';
211 $( this ).closest( 'li.gallerybox' ).toggleClass( 'mw-gallery-focused', gettingFocus
);
215 $galleries
= $content
.find( 'ul.mw-gallery-packed-overlay, ul.mw-gallery-packed-hover, ul.mw-gallery-packed' );
216 // Call the justification asynchronous because live preview fires the hook with detached $content.
217 setTimeout( function () {
218 $galleries
.each( justify
);
223 $( window
).resize( $.debounce( 300, true, function () {
224 $galleries
.children( 'li' ).each( function () {
225 var imgWidth
= $( this ).data( 'imgWidth' ),
226 imgHeight
= $( this ).data( 'imgHeight' ),
227 width
= $( this ).data( 'width' ),
228 captionWidth
= $( this ).data( 'captionWidth' ),
229 $innerDiv
= $( this ).children( 'div' ).first(),
230 $imageDiv
= $innerDiv
.children( 'div.thumb' ),
233 // Restore original sizes so we can arrange the elements as on freshly loaded page
234 $( this ).width( width
);
235 $innerDiv
.width( width
);
236 $imageDiv
.width( imgWidth
);
237 $( this ).find( 'div.gallerytextwrapper' ).width( captionWidth
);
239 $imageElm
= $( this ).find( 'img' ).first();
240 imageElm
= $imageElm
.length
? $imageElm
[0] : null;
242 imageElm
.width
= imgWidth
;
243 imageElm
.height
= imgHeight
;
245 $imageDiv
.height( imgHeight
);
249 $( window
).resize( $.debounce( 300, function () {
250 $galleries
.each( justify
);
253 }( mediaWiki
, jQuery
) );