diff --git a/extension.json b/extension.json
index 1c595e5..d6dad95 100644
--- a/extension.json
+++ b/extension.json
@@ -6,7 +6,7 @@
],
"url": "https://github.com/Luqgreg/mediawiki-PortableInfobox",
"descriptionmsg": "portable-infobox-desc",
- "version": "0.2.1",
+ "version": "0.2.1-audio_support",
"type": "parserhook",
"license-name": "GPL-3.0-or-later",
"config": {
@@ -51,13 +51,16 @@
"PortableInfobox\\Parser\\MediaWikiParserService": "includes/services/Parser/MediaWikiParserService.php",
"PortableInfobox\\Parser\\Nodes\\NodeFactory": "includes/services/Parser/Nodes/NodeFactory.class.php",
"PortableInfobox\\Parser\\Nodes\\Node": "includes/services/Parser/Nodes/Node.php",
- "PortableInfobox\\Parser\\Nodes\\NodeNavigation": "includes/services/Parser/Nodes/NodeNavigation.php",
+ "PortableInfobox\\Parser\\Nodes\\NodeAudio": "includes/services/Parser/Nodes/NodeAudio.php",
+ "PortableInfobox\\Parser\\Nodes\\NodeData": "includes/services/Parser/Nodes/NodeData.php",
+ "PortableInfobox\\Parser\\Nodes\\NodeInfobox": "includes/services/Parser/Nodes/NodeInfobox.php",
"PortableInfobox\\Parser\\Nodes\\NodeGroup": "includes/services/Parser/Nodes/NodeGroup.php",
"PortableInfobox\\Parser\\Nodes\\NodeHeader": "includes/services/Parser/Nodes/NodeHeader.php",
"PortableInfobox\\Parser\\Nodes\\NodeImage": "includes/services/Parser/Nodes/NodeImage.php",
- "PortableInfobox\\Parser\\Nodes\\NodeInfobox": "includes/services/Parser/Nodes/NodeInfobox.php",
- "PortableInfobox\\Parser\\Nodes\\NodeData": "includes/services/Parser/Nodes/NodeData.php",
+ "PortableInfobox\\Parser\\Nodes\\NodeMedia": "includes/services/Parser/Nodes/NodeMedia.php",
+ "PortableInfobox\\Parser\\Nodes\\NodeNavigation": "includes/services/Parser/Nodes/NodeNavigation.php",
"PortableInfobox\\Parser\\Nodes\\NodeTitle": "includes/services/Parser/Nodes/NodeTitle.php",
+ "PortableInfobox\\Parser\\Nodes\\NodeVideo": "includes/services/Parser/Nodes/NodeVideo.php",
"PortableInfobox\\Parser\\Nodes\\NodeUnimplemented": "includes/services/Parser/Nodes/NodeUnimplemented.php",
"PortableInfobox\\Helpers\\FileNamespaceSanitizeHelper": "includes/services/Helpers/FileNamespaceSanitizeHelper.php",
"PortableInfobox\\Helpers\\HtmlHelper": "includes/services/Helpers/HtmlHelper.class.php",
diff --git a/includes/services/Helpers/PortableInfoboxImagesHelper.php b/includes/services/Helpers/PortableInfoboxImagesHelper.php
index 3dbe98b..6d0e455 100644
--- a/includes/services/Helpers/PortableInfoboxImagesHelper.php
+++ b/includes/services/Helpers/PortableInfoboxImagesHelper.php
@@ -21,18 +21,20 @@ class PortableInfoboxImagesHelper {
$title = $data['name'];
$file = $this->getFileFromTitle( $title );
- if (
- !$file || !$file->exists() ||
- !in_array( $file->getMediaType(), [ MEDIATYPE_BITMAP, MEDIATYPE_DRAWING, MEDIATYPE_VIDEO ] )
- ) {
+ if ( !$file || !$file->exists() ) {
return false;
}
- // we don't need failing thumbnail creation for videos
- if( $file->getMediaType() == MEDIATYPE_VIDEO ) {
- return array_merge( $data, [
- 'ref' => ++self::$count
- ] );
+ $mediatype = $file->getMediaType();
+ $data['isImage'] = in_array( $mediatype, [ MEDIATYPE_BITMAP, MEDIATYPE_DRAWING ] );
+ $data['isVideo'] = $mediatype === MEDIATYPE_VIDEO;
+ $data['isAudio'] = $mediatype === MEDIATYPE_AUDIO;
+
+ $data['ref'] = ++self::$count;
+
+ // we don't need failing thumbnail creation for videos and audio files
+ if( !$data['isImage'] ) {
+ return $data;
}
// get dimensions
@@ -65,7 +67,6 @@ class PortableInfoboxImagesHelper {
}
return array_merge( $data, [
- 'ref' => ++self::$count,
'height' => intval( $imgTagDimensions['height'] ),
'width' => intval( $imgTagDimensions['width'] ),
'thumbnail' => $thumbnail->getUrl(),
diff --git a/includes/services/Helpers/PortableInfoboxTemplateEngine.php b/includes/services/Helpers/PortableInfoboxTemplateEngine.php
index 2793574..d88caf5 100644
--- a/includes/services/Helpers/PortableInfoboxTemplateEngine.php
+++ b/includes/services/Helpers/PortableInfoboxTemplateEngine.php
@@ -13,13 +13,16 @@ class PortableInfoboxTemplateEngine {
'wrapper' => 'PortableInfoboxWrapper.hbs',
'title' => 'PortableInfoboxItemTitle.hbs',
'header' => 'PortableInfoboxItemHeader.hbs',
- 'image' => 'PortableInfoboxItemImage.hbs',
+ 'media' => 'PortableInfoboxItemMedia.hbs',
+ 'audio' => 'PortableInfoboxItemMedia.hbs',
+ 'image' => 'PortableInfoboxItemMedia.hbs',
+ 'video' => 'PortableInfoboxItemMedia.hbs',
'data' => 'PortableInfoboxItemData.hbs',
'group' => 'PortableInfoboxItemGroup.hbs',
'smart-group' => 'PortableInfoboxItemSmartGroup.hbs',
'horizontal-group-content' => 'PortableInfoboxHorizontalGroupContent.hbs',
'navigation' => 'PortableInfoboxItemNavigation.hbs',
- 'image-collection' => 'PortableInfoboxItemImageCollection.hbs',
+ 'media-collection' => 'PortableInfoboxItemMediaCollection.hbs',
'xml-parse-error' => 'PortableInfoboxMarkupDebug.hbs'
];
@@ -48,7 +51,7 @@ class PortableInfoboxTemplateEngine {
if ( !empty( self::$cache[ $type ] ) ) {
return self::$cache[ $type ];
}
-
+
$path = self::getTemplatesDir() . DIRECTORY_SEPARATOR . self::$templates[ $type ];
// @see https://github.com/wikimedia/mediawiki-vendor/tree/master/zordius/lightncandy
diff --git a/includes/services/Parser/Nodes/NodeAudio.php b/includes/services/Parser/Nodes/NodeAudio.php
new file mode 100644
index 0000000..257b1ea
--- /dev/null
+++ b/includes/services/Parser/Nodes/NodeAudio.php
@@ -0,0 +1,25 @@
+getGallery( $marker );
- return isset( $gallery ) ? array_map( function ( $image ) {
- return [
- 'label' => $image[1] ?: $image[0]->getText(),
- 'title' => $image[0]
- ];
- }, $gallery->getimages() ) : [];
- }
-
- public static function getTabberData( $html ) {
- $data = [];
- $doc = HtmlHelper::createDOMDocumentFromText( $html );
- $sxml = simplexml_import_dom( $doc );
- $divs = $sxml->xpath( '//div[@class=\'tabbertab\']' );
- foreach ( $divs as $div ) {
- if ( preg_match( '/ src="(?:[^"]*\/)?([^"]*?)"/', $div->asXML(), $out ) ) {
- $data[] = [
- 'label' => (string) $div['title'],
- 'title' => $out[1]
- ];
- }
- }
- return $data;
- }
-
- public function getData() {
- if ( !isset( $this->data ) ) {
- $this->data = [];
-
- // value passed to source parameter (or default)
- $value = $this->getRawValueWithDefault( $this->xmlNode );
-
- if ( $this->containsTabberOrGallery( $value ) ) {
- $this->data = $this->getImagesData( $value );
- } else {
- $this->data = [ $this->getImageData(
- $value,
- $this->getValueWithDefault( $this->xmlNode->{self::ALT_TAG_NAME} ),
- $this->getValueWithDefault( $this->xmlNode->{self::CAPTION_TAG_NAME} )
- ) ];
- }
- }
- return $this->data;
- }
-
- /**
- * @desc Checks if parser preprocessed string containg Tabber or Gallery extension
- * @param string $str String to check
+class NodeImage extends NodeMedia {
+ /*
* @return bool
*/
- private function containsTabberOrGallery( $str ) {
- return !empty( self::getMarkers( $str, self::TABBER ) ) || !empty( self::getMarkers( $str, self::GALLERY ) );
- }
-
- private function getImagesData( $value ) {
- $data = [];
- $items = array_merge( $this->getGalleryItems( $value ), $this->getTabberItems( $value ) );
- foreach( $items as $item ) {
- $data[] = $this->getImageData( $item['title'], $item['label'], $item['label'] );
- }
- return $data;
- }
-
- private function getGalleryItems( $value ) {
- $galleryItems = [];
- $galleryMarkers = self::getMarkers( $value, self::GALLERY );
- foreach ( $galleryMarkers as $marker ) {
- $galleryItems = array_merge( $galleryItems, self::getGalleryData( $marker ) );
- }
- return $galleryItems;
- }
-
- private function getTabberItems( $value ) {
- $tabberItems = [];
- $tabberMarkers = self::getMarkers( $value, self::TABBER );
- foreach ( $tabberMarkers as $marker ) {
- $tabberHtml = $this->getExternalParser()->parseRecursive( $marker );
- $tabberItems = array_merge( $tabberItems, self::getTabberData( $tabberHtml ) );
- }
- return $tabberItems;
- }
-
- /**
- * @desc prepare infobox image node data.
- *
- * @param $title
- * @param $alt
- * @param $caption
- * @return array
- */
- private function getImageData( $title, $alt, $caption ) {
- $titleObj = $title instanceof \Title ? $title : $this->getImageAsTitleObject( $title );
- $fileObj = $this->getFileFromTitle( $titleObj );
-
- if ( $titleObj instanceof \Title ) {
- $this->getExternalParser()->addImage( $titleObj->getDBkey() );
- }
-
- $image = [
- 'url' => $this->resolveImageUrl( $fileObj ),
- 'name' => $titleObj ? $titleObj->getText() : '',
- 'key' => $titleObj ? $titleObj->getDBKey() : '',
- 'alt' => $alt ?? ( $titleObj ? $titleObj->getText() : null ),
- 'caption' => SanitizerBuilder::createFromType( 'image' )
- ->sanitize( [ 'caption' => $caption ] )['caption'] ?: null,
- 'isVideo' => $this->isVideo( $fileObj )
- ];
-
- return $image;
- }
-
- public function isEmpty() {
- $data = $this->getData();
- foreach ( $data as $dataItem ) {
- if ( !empty( $dataItem[ 'url' ] ) ) {
- return false;
- }
- }
+ protected function allowImage() {
return true;
}
- public function getSources() {
- $sources = $this->extractSourcesFromNode( $this->xmlNode );
- if ( $this->xmlNode->{self::ALT_TAG_NAME} ) {
- $sources = array_merge( $sources,
- $this->extractSourcesFromNode( $this->xmlNode->{self::ALT_TAG_NAME} ) );
- }
- if ( $this->xmlNode->{self::CAPTION_TAG_NAME} ) {
- $sources = array_merge( $sources,
- $this->extractSourcesFromNode( $this->xmlNode->{self::CAPTION_TAG_NAME} ) );
- }
-
- return array_unique( $sources );
- }
-
- private function getImageAsTitleObject( $imageName ) {
- global $wgContLang;
- $title = \Title::makeTitleSafe(
- NS_FILE,
- FileNamespaceSanitizeHelper::getInstance()->sanitizeImageFileName( $imageName, $wgContLang )
- );
-
- return $title;
- }
-
- /**
- * NOTE: Protected to override in unit tests
- *
- * @desc get file object from title object
- * @param Title|null $title
- * @return File|null
- */
- protected function getFileFromTitle( $title ) {
- if( is_string( $title ) ) {
- $title = \Title::newFromText( $title, NS_FILE );
- }
-
- if( $title instanceof \Title ) {
- $file = wfFindFile( $title );
- if( $file instanceof \File && $file->exists() ) {
- return $file;
- }
- }
-
- return null;
- }
-
- /**
- * @desc returns image url for given image title
- * @param File|null $file
- * @return string url or '' if image doesn't exist
- */
- public function resolveImageUrl( $file ) {
- return $file ? $file->getUrl() : '';
- }
-
- /**
- * @desc checks if file media type is VIDEO
- * @param File|null $file
+ /*
* @return bool
*/
- private function isVideo( $file ) {
- return $file ? $file->getMediaType() === MEDIATYPE_VIDEO : false;
+ protected function allowAudio() {
+ return false;
}
-}
+}
\ No newline at end of file
diff --git a/includes/services/Parser/Nodes/NodeMedia.php b/includes/services/Parser/Nodes/NodeMedia.php
new file mode 100644
index 0000000..fa67b95
--- /dev/null
+++ b/includes/services/Parser/Nodes/NodeMedia.php
@@ -0,0 +1,252 @@
+getGallery( $marker );
+ return isset( $gallery ) ? array_map( function ( $image ) {
+ return [
+ 'label' => $image[1] ?: $image[0]->getText(),
+ 'title' => $image[0]
+ ];
+ }, $gallery->getimages() ) : [];
+ }
+
+ public static function getTabberData( $html ) {
+ $data = [];
+ $doc = HtmlHelper::createDOMDocumentFromText( $html );
+ $sxml = simplexml_import_dom( $doc );
+ $divs = $sxml->xpath( '//div[@class=\'tabbertab\']' );
+ foreach ( $divs as $div ) {
+ if ( preg_match( '/ src="(?:[^"]*\/)?([^"]*?)"/', $div->asXML(), $out ) ) {
+ $data[] = [
+ 'label' => (string) $div['title'],
+ 'title' => $out[1]
+ ];
+ }
+ }
+ return $data;
+ }
+
+ public function getData() {
+ if ( !isset( $this->data ) ) {
+ $this->data = [];
+
+ // value passed to source parameter (or default)
+ $value = $this->getRawValueWithDefault( $this->xmlNode );
+
+ if ( $this->containsTabberOrGallery( $value ) ) {
+ $this->data = $this->getImagesData( $value );
+ } else {
+ $this->data = [ $this->getImageData(
+ $value,
+ $this->getValueWithDefault( $this->xmlNode->{self::ALT_TAG_NAME} ),
+ $this->getValueWithDefault( $this->xmlNode->{self::CAPTION_TAG_NAME} )
+ ) ];
+ }
+ }
+ return $this->data;
+ }
+
+ /**
+ * @desc Checks if parser preprocessed string containg Tabber or Gallery extension
+ * @param string $str String to check
+ * @return bool
+ */
+ private function containsTabberOrGallery( $str ) {
+ return !empty( self::getMarkers( $str, self::TABBER ) ) || !empty( self::getMarkers( $str, self::GALLERY ) );
+ }
+
+ private function getImagesData( $value ) {
+ $data = [];
+ $items = array_merge( $this->getGalleryItems( $value ), $this->getTabberItems( $value ) );
+ foreach( $items as $item ) {
+ $data[] = $this->getImageData( $item['title'], $item['label'], $item['label'] );
+ }
+ return $data;
+ }
+
+ private function getGalleryItems( $value ) {
+ $galleryItems = [];
+ $galleryMarkers = self::getMarkers( $value, self::GALLERY );
+ foreach ( $galleryMarkers as $marker ) {
+ $galleryItems = array_merge( $galleryItems, self::getGalleryData( $marker ) );
+ }
+ return $galleryItems;
+ }
+
+ private function getTabberItems( $value ) {
+ $tabberItems = [];
+ $tabberMarkers = self::getMarkers( $value, self::TABBER );
+ foreach ( $tabberMarkers as $marker ) {
+ $tabberHtml = $this->getExternalParser()->parseRecursive( $marker );
+ $tabberItems = array_merge( $tabberItems, self::getTabberData( $tabberHtml ) );
+ }
+ return $tabberItems;
+ }
+
+ /**
+ * @desc prepare infobox image node data.
+ *
+ * @param $title
+ * @param $alt
+ * @param $caption
+ * @return array
+ */
+ private function getImageData( $title, $alt, $caption ) {
+ $titleObj = $title instanceof \Title ? $title : $this->getImageAsTitleObject( $title );
+ $fileObj = $this->getFileFromTitle( $titleObj );
+
+ if( !isset( $fileObj ) || !$this->isTypeAllowed( $fileObj->getMediaType() ) ) {
+ return [];
+ }
+
+ if ( $titleObj instanceof \Title ) {
+ $this->getExternalParser()->addImage( $titleObj->getDBkey() );
+ }
+
+ $image = [
+ 'url' => $this->resolveImageUrl( $fileObj ),
+ 'name' => $titleObj ? $titleObj->getText() : '',
+ 'alt' => $alt ?? ( $titleObj ? $titleObj->getText() : null ),
+ 'caption' => SanitizerBuilder::createFromType( 'image' )
+ ->sanitize( [ 'caption' => $caption ] )['caption'] ?: null
+ ];
+
+ return $image;
+ }
+
+ public function isEmpty() {
+ $data = $this->getData();
+ foreach ( $data as $dataItem ) {
+ if ( !empty( $dataItem[ 'url' ] ) ) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public function getSources() {
+ $sources = $this->extractSourcesFromNode( $this->xmlNode );
+ if ( $this->xmlNode->{self::ALT_TAG_NAME} ) {
+ $sources = array_merge( $sources,
+ $this->extractSourcesFromNode( $this->xmlNode->{self::ALT_TAG_NAME} ) );
+ }
+ if ( $this->xmlNode->{self::CAPTION_TAG_NAME} ) {
+ $sources = array_merge( $sources,
+ $this->extractSourcesFromNode( $this->xmlNode->{self::CAPTION_TAG_NAME} ) );
+ }
+
+ return array_unique( $sources );
+ }
+
+ private function getImageAsTitleObject( $imageName ) {
+ global $wgContLang;
+ $title = \Title::makeTitleSafe(
+ NS_FILE,
+ FileNamespaceSanitizeHelper::getInstance()->sanitizeImageFileName( $imageName, $wgContLang )
+ );
+
+ return $title;
+ }
+
+ /**
+ * NOTE: Protected to override in unit tests
+ *
+ * @desc get file object from title object
+ * @param Title|null $title
+ * @return File|null
+ */
+ protected function getFileFromTitle( $title ) {
+ if( is_string( $title ) ) {
+ $title = \Title::newFromText( $title, NS_FILE );
+ }
+
+ if( $title instanceof \Title ) {
+ $file = wfFindFile( $title );
+ if( $file instanceof \File && $file->exists() ) {
+ return $file;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @desc returns image url for given image title
+ * @param File|null $file
+ * @return string url or '' if image doesn't exist
+ */
+ public function resolveImageUrl( $file ) {
+ return $file ? $file->getUrl() : '';
+ }
+
+ /**
+ * @desc checks if file media type is allowed
+ * @param string $type
+ * @return bool
+ */
+ private function isTypeAllowed( $type ) {
+ switch( $type ) {
+ case MEDIATYPE_BITMAP:
+ case MEDIATYPE_DRAWING:
+ return $this->allowImage();
+ case MEDIATYPE_VIDEO:
+ return $this->allowVideo();
+ case MEDIATYPE_AUDIO:
+ return $this->allowAudio();
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * @return bool
+ */
+ protected function allowImage() {
+ $attr = $this->getXmlAttribute( $this->xmlNode, self::ALLOWIMAGE_ATTR_NAME );
+
+ return !( isset( $attr ) && strtolower( $attr ) === 'false' );
+ }
+
+ /**
+ * @return bool
+ */
+ protected function allowVideo() {
+ $attr = $this->getXmlAttribute( $this->xmlNode, self::ALLOWVIDEO_ATTR_NAME );
+
+ return !( isset( $attr ) && strtolower( $attr ) === 'false' );
+ }
+
+ /*
+ * @return bool
+ */
+ protected function allowAudio() {
+ $attr = $this->getXmlAttribute( $this->xmlNode, self::ALLOWAUDIO_ATTR_NAME );
+
+ return !( isset( $attr ) && strtolower( $attr ) === 'false' );
+ }
+}
diff --git a/includes/services/Parser/Nodes/NodeVideo.php b/includes/services/Parser/Nodes/NodeVideo.php
new file mode 100644
index 0000000..126a826
--- /dev/null
+++ b/includes/services/Parser/Nodes/NodeVideo.php
@@ -0,0 +1,25 @@
+renderHeader( $data );
break;
+ case 'media':
+ case 'audio':
case 'image':
- $result = $this->renderImage( $data );
+ case 'video':
+ $result = $this->renderMedia( $data );
break;
case 'title':
$result = $this->renderTitle( $data );
@@ -104,7 +107,7 @@ class PortableInfoboxRenderService {
* @return string - group HTML markup
*/
protected function renderGroup( $groupData ) {
- $cssClasses = [ ];
+ $cssClasses = [];
$groupHTMLContent = '';
$children = $groupData['value'];
$layout = $groupData['layout'];
@@ -140,15 +143,13 @@ class PortableInfoboxRenderService {
* @param $data
* @return string
*/
- protected function renderImage( $data ) {
+ protected function renderMedia( $data ) {
$helper = $this->getImageHelper();
- $data = $this->filterImageData( $data );
- $images = [ ];
+ $images = [];
foreach ( $data as $dataItem ) {
$extendedItem = $dataItem;
- $extendedItem['context'] = null;
$extendedItem = $helper->extendImageData( $extendedItem, $this->imagesWidth, $this->infoboxWidth );
if ( !!$extendedItem ) {
@@ -162,11 +163,11 @@ class PortableInfoboxRenderService {
if ( count( $images ) === 1 ) {
$data = $images[0];
- $templateName = 'image';
+ $templateName = 'media';
} else {
// More than one image means image collection
$data = $helper->extendImageCollectionData( $images );
- $templateName = 'image-collection';
+ $templateName = 'media-collection';
}
return $this->render( $templateName, $data );
@@ -196,22 +197,6 @@ class PortableInfoboxRenderService {
return $result;
}
- private function filterImageData( $data ) {
- $dataWithCaption = array_filter($data, function( $item ) {
- return !empty( $item['caption'] );
- });
-
- $result = [];
-
- if ( !empty( $dataWithCaption ) ) {
- $result = $dataWithCaption;
- } elseif ( !empty( $data ) ) {
- $result = [ $data[0] ];
- }
-
- return $result;
- }
-
private function getInlineStyles( $accentColor, $accentColorText ) {
$backgroundColor = empty( $accentColor ) ? '' : "background-color:{$accentColor};";
$color = empty( $accentColorText ) ? '' : "color:{$accentColorText};";
@@ -221,8 +206,8 @@ class PortableInfoboxRenderService {
private function createHorizontalGroupData( $groupData ) {
$horizontalGroupData = [
- 'labels' => [ ],
- 'values' => [ ],
+ 'labels' => [],
+ 'values' => [],
'renderLabels' => false
];
@@ -246,9 +231,9 @@ class PortableInfoboxRenderService {
}
private function createSmartGroups( $groupData, $rowCapacity ) {
- $result = [ ];
+ $result = [];
$rowSpan = 0;
- $rowItems = [ ];
+ $rowItems = [];
foreach ( $groupData as $item ) {
$data = $item['data'];
@@ -258,7 +243,7 @@ class PortableInfoboxRenderService {
if ( !empty( $rowItems ) && $rowSpan + $data['span'] > $rowCapacity ) {
$result[] = $this->createSmartGroupItem( $rowItems, $rowSpan );
$rowSpan = 0;
- $rowItems = [ ];
+ $rowItems = [];
}
$rowSpan += $data['span'];
$rowItems[] = $item;
@@ -298,6 +283,6 @@ class PortableInfoboxRenderService {
$result['values'][] = [ 'value' => $item['data']['value'], 'inlineStyles' => $styles ];
return $result;
- }, [ 'labels' => [ ], 'values' => [ ], 'renderLabels' => false ] );
+ }, [ 'labels' => [], 'values' => [], 'renderLabels' => false ] );
}
}
diff --git a/resources/PortableInfobox.js b/resources/PortableInfobox.js
index 5b84ba2..6addb20 100644
--- a/resources/PortableInfobox.js
+++ b/resources/PortableInfobox.js
@@ -1,14 +1,14 @@
(function (window, $) {
'use strict';
- var ImageCollection = {
+ var MediaCollection = {
init: function($content) {
- var $imageCollections = $content.find('.pi-image-collection');
+ var $mediaCollections = $content.find('.pi-media-collection');
- $imageCollections.each( function( index ) {
- var $collection = $imageCollections.eq(index),
- $tabs = $collection.find('ul.pi-image-collection-tabs li'),
- $tabContent = $collection.find('.pi-image-collection-tab-content');
+ $mediaCollections.each( function( index ) {
+ var $collection = $mediaCollections.eq(index),
+ $tabs = $collection.find('ul.pi-media-collection-tabs li'),
+ $tabContent = $collection.find('.pi-media-collection-tab-content');
$tabs.click( function() {
var $target = $(this),
@@ -43,7 +43,7 @@
};
mw.hook('wikipage.content').add(function($content) {
- ImageCollection.init($content);
+ MediaCollection.init($content);
CollapsibleGroup.init($content);
});
})(window, jQuery);
diff --git a/resources/PortableInfobox.less b/resources/PortableInfobox.less
index 9e854b8..1e168da 100644
--- a/resources/PortableInfobox.less
+++ b/resources/PortableInfobox.less
@@ -44,7 +44,7 @@
font-weight: bold;
line-height: 1.3;
}
- .pi-image {
+ .pi-media {
margin: 0;
max-width: 100%;
text-align: center;
@@ -71,54 +71,55 @@
}
}
.pi {
- &-image {
- &-thumbnail {
- max-width: var(--pi-width);
- height: auto;
+ &-media-collection {
+ overflow: hidden;
+ margin: 0;
+ padding-top: 1px;
+ & &-tabs {
+ list-style: none;
+ margin: 0 -1px;
+ padding: 1px 0;
+ text-align: center;
}
- &-collection {
- overflow: hidden;
- margin: 0;
- padding-top: 1px;
- & &-tabs {
- list-style: none;
- margin: 0 -1px;
- padding: 1px 0;
- text-align: center;
+ &-tabs {
+ li {
+ border: 1px solid var(--pi-secondary-background);
+ box-sizing: border-box;
+ cursor: pointer;
+ display: inline-block;
+ margin: -1px -1px 0 0;
+ max-width: 50%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ vertical-align: bottom;
+ white-space: nowrap;
}
- &-tabs {
- li {
- border: 1px solid var(--pi-secondary-background);
- box-sizing: border-box;
- cursor: pointer;
- display: inline-block;
- margin: -1px -1px 0 0;
- max-width: 50%;
- overflow: hidden;
- text-overflow: ellipsis;
- vertical-align: bottom;
- white-space: nowrap;
- }
- li.current {
- background: var(--pi-secondary-background);
- font-weight: bold;
- }
- }
- &-tab-content {
- display: none;
- .video-thumbnail {
- display: block;
- }
- &.current {
- display: inherit;
- }
+ li.current {
+ background: var(--pi-secondary-background);
+ font-weight: bold;
}
}
+ &-tab-content {
+ display: none;
+ &.current {
+ display: inherit;
+ }
+ }
+ }
+ &-image-thumbnail {
+ max-width: var(--pi-width);
+ height: auto;
}
&-video-player {
width: var(--pi-width);
height: auto;
}
+ &-audio-player {
+ width: var(--pi-width);
+ &::-webkit-media-controls-enclosure {
+ border-radius: 0;
+ }
+ }
&-caption {
-webkit-hyphens: auto;
-moz-hyphens: auto;
diff --git a/resources/spec/PortableInfobox.spec.js b/resources/spec/PortableInfobox.spec.js
deleted file mode 100644
index 35e7744..0000000
--- a/resources/spec/PortableInfobox.spec.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* global beforeEach, describe, it, expect, jasmine, mw, $ */
-
-describe('Portable Infobox', function () {
- describe('collapsible sections', function () {
- var portableInfoboxHtml = `
- Bugged
-