diff --git a/xwiki-platform-core/xwiki-platform-oldcore/src/main/resources/ApplicationResources.properties b/xwiki-platform-core/xwiki-platform-oldcore/src/main/resources/ApplicationResources.properties index 5e39c4ab3554..ab39f17febe6 100644 --- a/xwiki-platform-core/xwiki-platform-oldcore/src/main/resources/ApplicationResources.properties +++ b/xwiki-platform-core/xwiki-platform-oldcore/src/main/resources/ApplicationResources.properties @@ -1396,6 +1396,7 @@ core.widgets.gallery.previousImage=Show previous image core.widgets.gallery.nextImage=Show next image core.widgets.gallery.maximize=Maximize core.widgets.gallery.minimize=Minimize +core.widgets.gallery.index.description=Press the right and left arrow keys to quickly navigate through the images. core.widgets.suggest.noResults=No results! core.widgets.suggest.showResults=Go to search page\u2026 diff --git a/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/uicomponents/widgets/gallery/gallery.css b/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/uicomponents/widgets/gallery/gallery.css index a4c2d77501a1..9bb5071b6940 100644 --- a/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/uicomponents/widgets/gallery/gallery.css +++ b/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/uicomponents/widgets/gallery/gallery.css @@ -2,6 +2,7 @@ background-color: black; max-width: 100%; padding: 10px; + border-radius: 7px; /* Same value as @border-radius-base from Flamingo. */ /* Position relative is required because some of the inner elements have position absolute and the gallery container must be their offset parent. */ position: relative; @@ -10,13 +11,9 @@ /* Those width/height values can be overridden by the inline styling added with the macro parameters */ width: 620px; height: 349px; -} - -.xGallery:before { - content: ""; - display: inline-block; - height: 100%; - vertical-align: middle; + display: grid; + grid-template-columns: 1fr 10fr 1fr; + grid-template-rows: 1fr 10fr 1fr; } .xGallery.maximized { @@ -26,28 +23,33 @@ top: 0; z-index: 1001; width: 100% !important; + border-radius: 0; } .xGallery .currentImage { - max-height: 100%; + grid-area: 2 / 2 / 3 / 3; + align-self: center; + justify-self: center; + object-fit: scale-down; max-width: 100%; - padding: 22px; - vertical-align: middle; + max-height: 100%; +} + +/* Transparent buttons that should fill the space they've been given on the grid */ +.xGallery .previous, .xGallery .next, +.xGallery .maximize, .xGallery .minimize { + background-color: transparent; + border-color: transparent; + width: 100%; + height: 100%; } .xGallery .previous, .xGallery .next { color: #A0A0A0; - cursor: pointer; font-family: courier,monospace; font-size: 32px; font-weight: 100; - height: 124px; - line-height: 124px; - margin-top: -64px; - position: absolute; text-align: center; - top: 50%; - width: 32px; } .xGallery .previous:hover, .xGallery .next:hover { @@ -55,54 +57,48 @@ } .xGallery .previous { - left: 0; + grid-area: 2 / 1 / 3 / 2; } .xGallery .next { - right: 0; + grid-area: 2 / 3 / 3 / 4; } .xGallery .index { - bottom: 10px; color: #C0C0C0; font-family: sans-serif; font-size: smaller; - left: 10px; line-height: 1; - position: absolute; + grid-area: 3 / 1 / 4 / 2; + align-self: end; } .xGallery .loading { background-image: url('loading.gif') !important; } -.xGallery .focusCatcher { - background-color: black; - border: 0 none; - color: black; - height: 1px; - left: 0; - overflow: hidden; - position: absolute; - top: 0; - width: 1px; - z-index: -1; -} - .xGallery .maximize, .xGallery .minimize { - cursor: pointer; height: 16px; opacity: .5; - position: absolute; - right: 10px; - top: 10px; width: 16px; + grid-area: 1 / 3 / 2 / 4; + justify-self: end; } .xGallery .maximize:hover, .xGallery .minimize:hover { opacity: 1; } +/* Elements on the left of the grid are left aligned */ +.xGallery .index, .xGallery .previous { + text-align: start; +} + +/* Elements on the right of the grid are right aligned */ +.xGallery .maximize, .xGallery .minimize, .xGallery .next { + text-align: end; +} + .xGallery .maximize { background: transparent url('maximize.gif') no-repeat scroll center; } diff --git a/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/uicomponents/widgets/gallery/gallery.js b/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/uicomponents/widgets/gallery/gallery.js index e50e1bfe3af8..59293125e5aa 100644 --- a/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/uicomponents/widgets/gallery/gallery.js +++ b/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/uicomponents/widgets/gallery/gallery.js @@ -22,25 +22,29 @@ var XWiki = (function (XWiki) { XWiki.Gallery = Class.create({ initialize : function(container) { this.images = this._collectImages(container); - this.container = container.update( - '' + + '' + + '' + '${escapetool.xml($services.localization.render(' + - '' + - '' + - '
0 / 0
' + - '
' + '' + + '
0 / 0
' ); - this.container.addClassName('xGallery'); - - this.focusCatcher = this.container.down('.focusCatcher'); + this.container.addClassName('xGallery'); + + // Instead of an arbitrary element to catch focus, we use the index. + // This index already stores the current image state, might as well be responsible for providing quick controls and + // explanations about these quick controls. + // Note that wrapping the image in an interactive container to handle this would have been a good solution too. + // However, this wrapping caused the image to overflow the CSS grid vertically when in maximized mode. + // Technically I couldn't find a CSS solution to prevent this, so I decided to make do without wrapping. + this.focusCatcher = this.container.down('.index'); this.focusCatcher.observe('keydown', this._onKeyDown.bindAsEventListener(this)); - this.container.observe('click', function() { - this.focusCatcher.focus(); - }.bind(this)); this.container.down('.previous').observe('click', this._onPreviousImage.bind(this)); this.container.down('.next').observe('click', this._onNextImage.bind(this)); + this.container.observe('click', function() { + this.focusCatcher.focus(); + }.bind(this)); this.currentImage = this.container.down('.currentImage'); this.currentImage.observe('load', this._onLoadImage.bind(this));