wiki.techinc.nl/resources/src/mediawiki.page.gallery.js

290 lines
9 KiB
JavaScript
Raw Normal View History

/*!
* Enhance MediaWiki galleries (from the `<gallery>` parser tag).
*
* - Toggle gallery captions when focused.
* - Dynamically resize images to fill horizontal space.
New more slick gallery display This extension adds a "mode" parameter to the gallery tag, allowing different formats for the gallery tag (galleries in the ui can be controlled by a global) The added modes are: *traditional - The original gallery *nolines - Like the original, no borders, less padding *packed - All images aligned by having same height. JS also justifies the images. (I think this one is the one that will go over best with users.) *packed-overlay - like packed, but caption goes over top the image in a transloucent box. *packed-hover - like packed-overlay, but caption only visible on hover. Degrades gracefully on screen readers, and falls back to packed-overlay if you are using a touch screen. I kind of like this mode when the caption is not that important (ex a category where its just the file name). This also adds a hook to allow people to make their own gallery version. I believe there would be interest in this, as different people have done different experiments. For example: * Wikia: http://community.wikia.com/wiki/Help:Galleries,_Slideshows,_and_Sliders/wikitext * Wikinews: https://en.wikinews.org/wiki/Template:Picture_select What I would like to see for this patch, is first it gets enabled, with the default still "traditional". After about a month or two we consult with users. If feedback is positive, we change the default mode to one of the others (probably "packed"). Adds a "mode" parameter to gallery for different mode, including one 'height-constrained-overlay' which looks much more like other modern websites. Note: This makes one change to the old gallery format. It makes Nonexistent files be rendered like thumbnails (i.e. they are rendered with a little grey border). One thing I'm slightly worried about with this patch, is that I added an option to MediaTransformOutput::toHtml to override the width attribute. I'm not sure if that is the best approach, and would appreciate thoughts on that. This should be merged at the same time as Ie82c1548 Change-Id: I33462a8b52502ed76aeb163b66e3704c8618ba23
2013-06-08 04:47:07 +00:00
*/
( function () {
var $galleries,
bound = false,
lastWidth = window.innerWidth,
justifyNeeded = false,
// Is there a better way to detect a touchscreen? Current check taken from stack overflow.
isTouchScreen = !!( window.ontouchstart !== undefined ||
window.DocumentTouch !== undefined && document instanceof window.DocumentTouch
);
/**
* Perform the layout justification.
*
* @ignore
* @this {HTMLElement} A `ul.mw-gallery-*` element
*/
function justify() {
var lastTop,
rows = [],
$gallery = $( this );
$gallery.children( 'li.gallerybox' ).each( function () {
var $img, imgWidth, imgHeight, outerWidth, captionWidth,
// Math.floor, to be paranoid if things are off by 0.00000000001
top = Math.floor( $( this ).position().top ),
$this = $( this );
if ( top !== lastTop ) {
rows.push( [] );
lastTop = top;
}
$img = $this.find( 'div.thumb img' );
if ( $img.length && $img[ 0 ].height ) {
imgHeight = $img[ 0 ].height;
imgWidth = $img[ 0 ].width;
} else {
// If we don't have a real image, get the containing divs width/height.
// Note that if we do have a real image, using this method will generally
// give the same answer, but can be different in the case of a very
// narrow image where extra padding is added.
imgHeight = $this.children().children( 'div' ).first().height();
imgWidth = $this.children().children( 'div' ).first().width();
}
// Hack to make an edge case work ok
if ( imgHeight < 30 ) {
// Don't try and resize this item.
imgHeight = 0;
}
captionWidth = $this.children().children( 'div.gallerytextwrapper' ).width();
outerWidth = $this.outerWidth();
rows[ rows.length - 1 ].push( {
$elm: $this,
width: outerWidth,
imgWidth: imgWidth,
// FIXME: Deal with devision by 0.
aspect: imgWidth / imgHeight,
captionWidth: captionWidth,
height: imgHeight
} );
// Save all boundaries so we can restore them on window resize
$this.data( 'imgWidth', imgWidth );
$this.data( 'imgHeight', imgHeight );
$this.data( 'width', outerWidth );
$this.data( 'captionWidth', captionWidth );
} );
( function () {
var maxWidth,
combinedAspect,
combinedPadding,
curRow,
curRowHeight,
wantedWidth,
preferredHeight,
newWidth,
padding,
$outerDiv,
$innerDiv,
$imageDiv,
$imageElm,
imageElm,
$caption,
i,
j,
avgZoom,
totalZoom = 0;
for ( i = 0; i < rows.length; i++ ) {
maxWidth = $gallery.width();
combinedAspect = 0;
combinedPadding = 0;
curRow = rows[ i ];
curRowHeight = 0;
for ( j = 0; j < curRow.length; j++ ) {
if ( curRowHeight === 0 ) {
if ( isFinite( curRow[ j ].height ) ) {
// Get the height of this row, by taking the first
// non-out of bounds height
curRowHeight = curRow[ j ].height;
New more slick gallery display This extension adds a "mode" parameter to the gallery tag, allowing different formats for the gallery tag (galleries in the ui can be controlled by a global) The added modes are: *traditional - The original gallery *nolines - Like the original, no borders, less padding *packed - All images aligned by having same height. JS also justifies the images. (I think this one is the one that will go over best with users.) *packed-overlay - like packed, but caption goes over top the image in a transloucent box. *packed-hover - like packed-overlay, but caption only visible on hover. Degrades gracefully on screen readers, and falls back to packed-overlay if you are using a touch screen. I kind of like this mode when the caption is not that important (ex a category where its just the file name). This also adds a hook to allow people to make their own gallery version. I believe there would be interest in this, as different people have done different experiments. For example: * Wikia: http://community.wikia.com/wiki/Help:Galleries,_Slideshows,_and_Sliders/wikitext * Wikinews: https://en.wikinews.org/wiki/Template:Picture_select What I would like to see for this patch, is first it gets enabled, with the default still "traditional". After about a month or two we consult with users. If feedback is positive, we change the default mode to one of the others (probably "packed"). Adds a "mode" parameter to gallery for different mode, including one 'height-constrained-overlay' which looks much more like other modern websites. Note: This makes one change to the old gallery format. It makes Nonexistent files be rendered like thumbnails (i.e. they are rendered with a little grey border). One thing I'm slightly worried about with this patch, is that I added an option to MediaTransformOutput::toHtml to override the width attribute. I'm not sure if that is the best approach, and would appreciate thoughts on that. This should be merged at the same time as Ie82c1548 Change-Id: I33462a8b52502ed76aeb163b66e3704c8618ba23
2013-06-08 04:47:07 +00:00
}
}
New more slick gallery display This extension adds a "mode" parameter to the gallery tag, allowing different formats for the gallery tag (galleries in the ui can be controlled by a global) The added modes are: *traditional - The original gallery *nolines - Like the original, no borders, less padding *packed - All images aligned by having same height. JS also justifies the images. (I think this one is the one that will go over best with users.) *packed-overlay - like packed, but caption goes over top the image in a transloucent box. *packed-hover - like packed-overlay, but caption only visible on hover. Degrades gracefully on screen readers, and falls back to packed-overlay if you are using a touch screen. I kind of like this mode when the caption is not that important (ex a category where its just the file name). This also adds a hook to allow people to make their own gallery version. I believe there would be interest in this, as different people have done different experiments. For example: * Wikia: http://community.wikia.com/wiki/Help:Galleries,_Slideshows,_and_Sliders/wikitext * Wikinews: https://en.wikinews.org/wiki/Template:Picture_select What I would like to see for this patch, is first it gets enabled, with the default still "traditional". After about a month or two we consult with users. If feedback is positive, we change the default mode to one of the others (probably "packed"). Adds a "mode" parameter to gallery for different mode, including one 'height-constrained-overlay' which looks much more like other modern websites. Note: This makes one change to the old gallery format. It makes Nonexistent files be rendered like thumbnails (i.e. they are rendered with a little grey border). One thing I'm slightly worried about with this patch, is that I added an option to MediaTransformOutput::toHtml to override the width attribute. I'm not sure if that is the best approach, and would appreciate thoughts on that. This should be merged at the same time as Ie82c1548 Change-Id: I33462a8b52502ed76aeb163b66e3704c8618ba23
2013-06-08 04:47:07 +00:00
if ( curRow[ j ].aspect === 0 || !isFinite( curRow[ j ].aspect ) ) {
// One of the dimensions are 0. Probably should
// not try to resize.
combinedPadding += curRow[ j ].width;
} else {
combinedAspect += curRow[ j ].aspect;
combinedPadding += curRow[ j ].width - curRow[ j ].imgWidth;
New more slick gallery display This extension adds a "mode" parameter to the gallery tag, allowing different formats for the gallery tag (galleries in the ui can be controlled by a global) The added modes are: *traditional - The original gallery *nolines - Like the original, no borders, less padding *packed - All images aligned by having same height. JS also justifies the images. (I think this one is the one that will go over best with users.) *packed-overlay - like packed, but caption goes over top the image in a transloucent box. *packed-hover - like packed-overlay, but caption only visible on hover. Degrades gracefully on screen readers, and falls back to packed-overlay if you are using a touch screen. I kind of like this mode when the caption is not that important (ex a category where its just the file name). This also adds a hook to allow people to make their own gallery version. I believe there would be interest in this, as different people have done different experiments. For example: * Wikia: http://community.wikia.com/wiki/Help:Galleries,_Slideshows,_and_Sliders/wikitext * Wikinews: https://en.wikinews.org/wiki/Template:Picture_select What I would like to see for this patch, is first it gets enabled, with the default still "traditional". After about a month or two we consult with users. If feedback is positive, we change the default mode to one of the others (probably "packed"). Adds a "mode" parameter to gallery for different mode, including one 'height-constrained-overlay' which looks much more like other modern websites. Note: This makes one change to the old gallery format. It makes Nonexistent files be rendered like thumbnails (i.e. they are rendered with a little grey border). One thing I'm slightly worried about with this patch, is that I added an option to MediaTransformOutput::toHtml to override the width attribute. I'm not sure if that is the best approach, and would appreciate thoughts on that. This should be merged at the same time as Ie82c1548 Change-Id: I33462a8b52502ed76aeb163b66e3704c8618ba23
2013-06-08 04:47:07 +00:00
}
}
New more slick gallery display This extension adds a "mode" parameter to the gallery tag, allowing different formats for the gallery tag (galleries in the ui can be controlled by a global) The added modes are: *traditional - The original gallery *nolines - Like the original, no borders, less padding *packed - All images aligned by having same height. JS also justifies the images. (I think this one is the one that will go over best with users.) *packed-overlay - like packed, but caption goes over top the image in a transloucent box. *packed-hover - like packed-overlay, but caption only visible on hover. Degrades gracefully on screen readers, and falls back to packed-overlay if you are using a touch screen. I kind of like this mode when the caption is not that important (ex a category where its just the file name). This also adds a hook to allow people to make their own gallery version. I believe there would be interest in this, as different people have done different experiments. For example: * Wikia: http://community.wikia.com/wiki/Help:Galleries,_Slideshows,_and_Sliders/wikitext * Wikinews: https://en.wikinews.org/wiki/Template:Picture_select What I would like to see for this patch, is first it gets enabled, with the default still "traditional". After about a month or two we consult with users. If feedback is positive, we change the default mode to one of the others (probably "packed"). Adds a "mode" parameter to gallery for different mode, including one 'height-constrained-overlay' which looks much more like other modern websites. Note: This makes one change to the old gallery format. It makes Nonexistent files be rendered like thumbnails (i.e. they are rendered with a little grey border). One thing I'm slightly worried about with this patch, is that I added an option to MediaTransformOutput::toHtml to override the width attribute. I'm not sure if that is the best approach, and would appreciate thoughts on that. This should be merged at the same time as Ie82c1548 Change-Id: I33462a8b52502ed76aeb163b66e3704c8618ba23
2013-06-08 04:47:07 +00:00
// Add some padding for inter-element spacing.
combinedPadding += 5 * curRow.length;
wantedWidth = maxWidth - combinedPadding;
preferredHeight = wantedWidth / combinedAspect;
if ( preferredHeight > curRowHeight * 1.5 ) {
// Only expand at most 1.5 times current size
// As that's as high a resolution as we have.
// Also on the off chance there is a bug in this
// code, would prevent accidentally expanding to
// be 10 billion pixels wide.
if ( i === rows.length - 1 ) {
// If its the last row, and we can't fit it,
// don't make the entire row huge.
avgZoom = ( totalZoom / ( rows.length - 1 ) ) * curRowHeight;
if ( isFinite( avgZoom ) && avgZoom >= 1 && avgZoom <= 1.5 ) {
preferredHeight = avgZoom;
} else {
// Probably a single row gallery
preferredHeight = curRowHeight;
}
} else {
preferredHeight = 1.5 * curRowHeight;
}
}
if ( !isFinite( preferredHeight ) ) {
// This *definitely* should not happen.
// Skip this row.
continue;
}
if ( preferredHeight < 5 ) {
// Well something clearly went wrong...
// Skip this row.
continue;
}
if ( preferredHeight / curRowHeight > 1 ) {
totalZoom += preferredHeight / curRowHeight;
} else {
// If we shrink, still consider that a zoom of 1
totalZoom += 1;
}
New more slick gallery display This extension adds a "mode" parameter to the gallery tag, allowing different formats for the gallery tag (galleries in the ui can be controlled by a global) The added modes are: *traditional - The original gallery *nolines - Like the original, no borders, less padding *packed - All images aligned by having same height. JS also justifies the images. (I think this one is the one that will go over best with users.) *packed-overlay - like packed, but caption goes over top the image in a transloucent box. *packed-hover - like packed-overlay, but caption only visible on hover. Degrades gracefully on screen readers, and falls back to packed-overlay if you are using a touch screen. I kind of like this mode when the caption is not that important (ex a category where its just the file name). This also adds a hook to allow people to make their own gallery version. I believe there would be interest in this, as different people have done different experiments. For example: * Wikia: http://community.wikia.com/wiki/Help:Galleries,_Slideshows,_and_Sliders/wikitext * Wikinews: https://en.wikinews.org/wiki/Template:Picture_select What I would like to see for this patch, is first it gets enabled, with the default still "traditional". After about a month or two we consult with users. If feedback is positive, we change the default mode to one of the others (probably "packed"). Adds a "mode" parameter to gallery for different mode, including one 'height-constrained-overlay' which looks much more like other modern websites. Note: This makes one change to the old gallery format. It makes Nonexistent files be rendered like thumbnails (i.e. they are rendered with a little grey border). One thing I'm slightly worried about with this patch, is that I added an option to MediaTransformOutput::toHtml to override the width attribute. I'm not sure if that is the best approach, and would appreciate thoughts on that. This should be merged at the same time as Ie82c1548 Change-Id: I33462a8b52502ed76aeb163b66e3704c8618ba23
2013-06-08 04:47:07 +00:00
for ( j = 0; j < curRow.length; j++ ) {
newWidth = preferredHeight * curRow[ j ].aspect;
padding = curRow[ j ].width - curRow[ j ].imgWidth;
$outerDiv = curRow[ j ].$elm;
$innerDiv = $outerDiv.children( 'div' ).first();
$imageDiv = $innerDiv.children( 'div.thumb' );
$imageElm = $imageDiv.find( 'img' ).first();
$caption = $outerDiv.find( 'div.gallerytextwrapper' );
// Since we are going to re-adjust the height, the vertical
// centering margins need to be reset.
$imageDiv.children( 'div' ).css( 'margin', '0px auto' );
if ( newWidth < 60 || !isFinite( newWidth ) ) {
// Making something skinnier than this will mess up captions,
if ( newWidth < 1 || !isFinite( newWidth ) ) {
$innerDiv.height( preferredHeight );
// Don't even try and touch the image size if it could mean
// making it disappear.
continue;
New more slick gallery display This extension adds a "mode" parameter to the gallery tag, allowing different formats for the gallery tag (galleries in the ui can be controlled by a global) The added modes are: *traditional - The original gallery *nolines - Like the original, no borders, less padding *packed - All images aligned by having same height. JS also justifies the images. (I think this one is the one that will go over best with users.) *packed-overlay - like packed, but caption goes over top the image in a transloucent box. *packed-hover - like packed-overlay, but caption only visible on hover. Degrades gracefully on screen readers, and falls back to packed-overlay if you are using a touch screen. I kind of like this mode when the caption is not that important (ex a category where its just the file name). This also adds a hook to allow people to make their own gallery version. I believe there would be interest in this, as different people have done different experiments. For example: * Wikia: http://community.wikia.com/wiki/Help:Galleries,_Slideshows,_and_Sliders/wikitext * Wikinews: https://en.wikinews.org/wiki/Template:Picture_select What I would like to see for this patch, is first it gets enabled, with the default still "traditional". After about a month or two we consult with users. If feedback is positive, we change the default mode to one of the others (probably "packed"). Adds a "mode" parameter to gallery for different mode, including one 'height-constrained-overlay' which looks much more like other modern websites. Note: This makes one change to the old gallery format. It makes Nonexistent files be rendered like thumbnails (i.e. they are rendered with a little grey border). One thing I'm slightly worried about with this patch, is that I added an option to MediaTransformOutput::toHtml to override the width attribute. I'm not sure if that is the best approach, and would appreciate thoughts on that. This should be merged at the same time as Ie82c1548 Change-Id: I33462a8b52502ed76aeb163b66e3704c8618ba23
2013-06-08 04:47:07 +00:00
}
} else {
$outerDiv.width( newWidth + padding );
$innerDiv.width( newWidth + padding );
$imageDiv.width( newWidth );
$caption.width( curRow[ j ].captionWidth + ( newWidth - curRow[ j ].imgWidth ) );
}
// We don't always have an img, e.g. in the case of an invalid file.
if ( $imageElm[ 0 ] ) {
imageElm = $imageElm[ 0 ];
imageElm.width = newWidth;
imageElm.height = preferredHeight;
} else {
// Not a file box.
$imageDiv.height( preferredHeight );
New more slick gallery display This extension adds a "mode" parameter to the gallery tag, allowing different formats for the gallery tag (galleries in the ui can be controlled by a global) The added modes are: *traditional - The original gallery *nolines - Like the original, no borders, less padding *packed - All images aligned by having same height. JS also justifies the images. (I think this one is the one that will go over best with users.) *packed-overlay - like packed, but caption goes over top the image in a transloucent box. *packed-hover - like packed-overlay, but caption only visible on hover. Degrades gracefully on screen readers, and falls back to packed-overlay if you are using a touch screen. I kind of like this mode when the caption is not that important (ex a category where its just the file name). This also adds a hook to allow people to make their own gallery version. I believe there would be interest in this, as different people have done different experiments. For example: * Wikia: http://community.wikia.com/wiki/Help:Galleries,_Slideshows,_and_Sliders/wikitext * Wikinews: https://en.wikinews.org/wiki/Template:Picture_select What I would like to see for this patch, is first it gets enabled, with the default still "traditional". After about a month or two we consult with users. If feedback is positive, we change the default mode to one of the others (probably "packed"). Adds a "mode" parameter to gallery for different mode, including one 'height-constrained-overlay' which looks much more like other modern websites. Note: This makes one change to the old gallery format. It makes Nonexistent files be rendered like thumbnails (i.e. they are rendered with a little grey border). One thing I'm slightly worried about with this patch, is that I added an option to MediaTransformOutput::toHtml to override the width attribute. I'm not sure if that is the best approach, and would appreciate thoughts on that. This should be merged at the same time as Ie82c1548 Change-Id: I33462a8b52502ed76aeb163b66e3704c8618ba23
2013-06-08 04:47:07 +00:00
}
}
}
}() );
}
function handleResizeStart() {
// Only do anything if window width changed. We don't care about the height.
if ( lastWidth === window.innerWidth ) {
return;
}
justifyNeeded = true;
// Temporarily set min-height, so that content following the gallery is not reflowed twice
$galleries.css( 'min-height', function () {
return $( this ).height();
} );
$galleries.children( 'li.gallerybox' ).each( function () {
var imgWidth = $( this ).data( 'imgWidth' ),
imgHeight = $( this ).data( 'imgHeight' ),
width = $( this ).data( 'width' ),
captionWidth = $( this ).data( 'captionWidth' ),
$innerDiv = $( this ).children( 'div' ).first(),
$imageDiv = $innerDiv.children( 'div.thumb' ),
$imageElm, imageElm;
// Restore original sizes so we can arrange the elements as on freshly loaded page
$( this ).width( width );
$innerDiv.width( width );
$imageDiv.width( imgWidth );
$( this ).find( 'div.gallerytextwrapper' ).width( captionWidth );
$imageElm = $( this ).find( 'img' ).first();
if ( $imageElm[ 0 ] ) {
imageElm = $imageElm[ 0 ];
imageElm.width = imgWidth;
imageElm.height = imgHeight;
} else {
$imageDiv.height( imgHeight );
}
} );
}
function handleResizeEnd() {
// If window width never changed during the resize, don't do anything.
if ( justifyNeeded ) {
justifyNeeded = false;
lastWidth = window.innerWidth;
$galleries
// Remove temporary min-height
.css( 'min-height', '' )
// Recalculate layout
.each( justify );
}
}
mw.hook( 'wikipage.content' ).add( function ( $content ) {
if ( isTouchScreen ) {
// Always show the caption for a touch screen.
$content.find( 'ul.mw-gallery-packed-hover' )
.addClass( 'mw-gallery-packed-overlay' )
.removeClass( 'mw-gallery-packed-hover' );
} else {
// Note use of just `a`, not `a.image`, since we also want this to trigger if a link
// within the caption text receives focus.
$content.find( 'ul.mw-gallery-packed-hover li.gallerybox' ).on( 'focus blur', 'a', function ( e ) {
// Confusingly jQuery leaves e.type as focusout for delegated blur events
var gettingFocus = e.type !== 'blur' && e.type !== 'focusout';
$( this ).closest( 'li.gallerybox' ).toggleClass( 'mw-gallery-focused', gettingFocus );
} );
}
$galleries = $content.find( 'ul.mw-gallery-packed-overlay, ul.mw-gallery-packed-hover, ul.mw-gallery-packed' );
// Call the justification asynchronous because live preview fires the hook with detached $content.
setTimeout( function () {
$galleries.each( justify );
// Bind here instead of in the top scope as the callbacks use $galleries.
if ( !bound ) {
bound = true;
$( window )
.on( 'resize', $.debounce( 300, true, handleResizeStart ) )
.on( 'resize', $.debounce( 300, handleResizeEnd ) );
}
} );
New more slick gallery display This extension adds a "mode" parameter to the gallery tag, allowing different formats for the gallery tag (galleries in the ui can be controlled by a global) The added modes are: *traditional - The original gallery *nolines - Like the original, no borders, less padding *packed - All images aligned by having same height. JS also justifies the images. (I think this one is the one that will go over best with users.) *packed-overlay - like packed, but caption goes over top the image in a transloucent box. *packed-hover - like packed-overlay, but caption only visible on hover. Degrades gracefully on screen readers, and falls back to packed-overlay if you are using a touch screen. I kind of like this mode when the caption is not that important (ex a category where its just the file name). This also adds a hook to allow people to make their own gallery version. I believe there would be interest in this, as different people have done different experiments. For example: * Wikia: http://community.wikia.com/wiki/Help:Galleries,_Slideshows,_and_Sliders/wikitext * Wikinews: https://en.wikinews.org/wiki/Template:Picture_select What I would like to see for this patch, is first it gets enabled, with the default still "traditional". After about a month or two we consult with users. If feedback is positive, we change the default mode to one of the others (probably "packed"). Adds a "mode" parameter to gallery for different mode, including one 'height-constrained-overlay' which looks much more like other modern websites. Note: This makes one change to the old gallery format. It makes Nonexistent files be rendered like thumbnails (i.e. they are rendered with a little grey border). One thing I'm slightly worried about with this patch, is that I added an option to MediaTransformOutput::toHtml to override the width attribute. I'm not sure if that is the best approach, and would appreciate thoughts on that. This should be merged at the same time as Ie82c1548 Change-Id: I33462a8b52502ed76aeb163b66e3704c8618ba23
2013-06-08 04:47:07 +00:00
} );
}() );