jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/400834 )
Change subject: Add popup showing midi DL link on score click ...................................................................... Add popup showing midi DL link on score click Remove `link_midi` from $options passed to Score::generateHTML. Add `ext.score.popup.css` file with styles for score popup and its container and add `ext.score.popup.js` file with event handlers and functions handling showing&iflling and hiding score popup. Bug: T183736 Change-Id: Id9b213d073ba9ea7cc4c753a714f0b3aafbb0f63 --- M README M extension.json M i18n/en.json M i18n/qqq.json M includes/Score.php A modules/ext.score.popup.css A modules/ext.score.popup.js 7 files changed, 155 insertions(+), 17 deletions(-) Approvals: Ebe123: Looks good to me, approved jenkins-bot: Verified diff --git a/README b/README index fdd7a12..a06ab1f 100644 --- a/README +++ b/README @@ -19,6 +19,9 @@ for more information. +The extension also provides a way to download MIDI file generated from the score +from the popup that is shown on score click. + This extension was tested with LilyPond 2.12.3 through 2.18.2. @@ -81,10 +84,6 @@ C, D, E, F,|G, A, B, C|D E F G|A B c d| e f g a|b c' d' e'|f' g' a' b'|] </score>. - -* Attribute: midi - Effect: If included in the tag, the rendered image(s) will be embedded into a - hyperlink to an appropriate MIDI file. * Attribute: override_midi Allowed values: Known file name, that is, if override_midi="name" is given, diff --git a/extension.json b/extension.json index 64d1677..29b7755 100644 --- a/extension.json +++ b/extension.json @@ -55,6 +55,17 @@ "desktop", "mobile" ] + }, + "ext.score.popup": { + "scripts": "ext.score.popup.js", + "styles": "ext.score.popup.css", + "position": "bottom", + "dependencies": [ + "mediawiki.api" + ], + "messages": [ + "score-download-midi-file" + ] } }, "ResourceFileModulePaths": { diff --git a/i18n/en.json b/i18n/en.json index f454639..0129a0b 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -9,6 +9,7 @@ "score-compilererr": "Unable to compile LilyPond input file:\n$1", "score-backend-error": "Unable to copy the generated files to their final location:\n$1", "score-desc": "Adds a tag for rendering musical scores with LilyPond", + "score-download-midi-file": "Download MIDI file", "score-error-category": "Pages with score rendering errors", "score-error-category-desc": "There was an error while rendering the score.", "score-getcwderr": "Unable to obtain current working directory", diff --git a/i18n/qqq.json b/i18n/qqq.json index c87c392..b2fb0bc 100644 --- a/i18n/qqq.json +++ b/i18n/qqq.json @@ -15,6 +15,7 @@ "score-compilererr": "Displayed if the LilyPond code could not be compiled. $1 is the error (generally big block of text in a pre tag)", "score-backend-error": "Parameters:\n* $1 - result message which was returned", "score-desc": "{{desc|name=Score|url=https://www.mediawiki.org/wiki/Extension:Score}}", + "score-download-midi-file": "Content of link to download MIDI file of score shown in score popup", "score-error-category": "Name of [[mw:Help:Tracking categories|tracking category]] to list pages where there was an error rendering the <code><nowiki><score></nowiki></code> tag.", "score-error-category-desc": "Description on [[Special:TrackingCategories]] for the {{msg-mw|score-error-category}} tracking category.", "score-getcwderr": "Displayed if the extension cannot obtain the current working directory.", diff --git a/includes/Score.php b/includes/Score.php index 778467b..740d2e0 100644 --- a/includes/Score.php +++ b/includes/Score.php @@ -242,9 +242,6 @@ // Raw rendering? $options['raw'] = array_key_exists( 'raw', $args ); - /* Midi linking? */ - $options['link_midi'] = array_key_exists( 'midi', $args ); - /* Override OGG file? */ if ( array_key_exists( 'override_ogg', $args ) ) { $t = Title::newFromText( $args['override_ogg'], NS_FILE ); @@ -324,7 +321,6 @@ * - file_name_prefix: The filename prefix used for all files * in the default destination directory. Required. * - lang: string Score language. Required. - * - link_midi: bool Whether to link to a MIDI file. Required. * - override_midi: bool Whether to use a user-provided MIDI file. * Required. * - midi_file: If override_midi is true, MIDI file object. @@ -349,6 +345,8 @@ */ private static function generateHTML( &$parser, $code, $options ) { try { + $parser->getOutput()->addModules( 'ext.score.popup' ); + $backend = self::getBackend(); $fileIter = $backend->getFileList( [ 'dir' => $options['dest_storage_path'], 'topOnly' => true ] ); @@ -449,14 +447,6 @@ /* No images; this may happen in raw mode or when the user omits the score code */ throw new ScoreException( wfMessage( 'score-noimages' ) ); } - if ( $options['link_midi'] ) { - if ( $options['override_midi'] ) { - $url = $options['midi_file']->getUrl(); - } else { - $url = "{$options['dest_url']}/{$options['file_name_prefix']}.midi"; - } - $link = Html::rawElement( 'a', [ 'href' => $url ], $link ); - } if ( $options['generate_ogg'] ) { $length = $metaData[basename( $oggPath )]['length']; $player = new TimedMediaTransformOutput( [ @@ -481,6 +471,14 @@ } self::eraseFactory( $options['factory_directory'] ); + + // Wrap score in div container. + $link = HTML::rawElement( 'div', [ + 'class' => 'mw-ext-score', + 'data-midi' => $options['override_midi'] ? + $options['midi_file']->getUrl() + : "{$options['dest_url']}/{$options['file_name_prefix']}.midi" + ], $link ); return $link; } @@ -570,7 +568,7 @@ } $needMidi = false; if ( !$options['raw'] || - ( $options['generate_ogg'] || ( $options['link_midi'] && !$options['override_midi'] ) ) + ( $options['generate_ogg'] || !$options['override_midi'] ) ) { $needMidi = true; if ( !file_exists( $factoryMidi ) ) { diff --git a/modules/ext.score.popup.css b/modules/ext.score.popup.css new file mode 100644 index 0000000..61802b7 --- /dev/null +++ b/modules/ext.score.popup.css @@ -0,0 +1,44 @@ +.mw-ext-score { + position: relative; + display: inline-block; +} + +.mw-ext-score img { + cursor: pointer; +} + +.mw-ext-score-popup { + box-sizing: border-box; + position: absolute; + bottom: calc( 100% + 9px ); + left: 0; + right: 0; + width: 300px; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; + max-width: 100%; + margin: 0 auto; + border: 1px solid #ccc; + border-radius: 3px; + padding: 15px; + background: #fff; + box-shadow: 0 3px 15px rgba( 0, 0, 0, 0.2 ); + text-align: center; +} + +/* Triangle on the bottom of popup */ +.mw-ext-score-popup:after { + content: ''; + position: absolute; + bottom: -9px; + right: 0; + left: 0; + margin: auto; + width: 15px; + height: 15px; + border: 1px solid #ccc; + border-width: 0 1px 1px 0; + background: #fff; + transform: rotate( 45deg ); +} diff --git a/modules/ext.score.popup.js b/modules/ext.score.popup.js new file mode 100644 index 0000000..ab81595 --- /dev/null +++ b/modules/ext.score.popup.js @@ -0,0 +1,84 @@ +( function ( $ ) { + var popupShown = false; + + function showPopup( $score ) { + var $popup, midi = $score.data( 'midi' ); + $popup = $( '<div>' ) + .addClass( 'mw-ext-score-popup' ) + .attr( 'id', 'mw-ext-score-popup' ) + .html( + $( '<a>' ) + .attr( 'href', midi ) + .text( mw.msg( 'score-download-midi-file' ) ) + ) + .css( 'opacity', 0 ); + + $score.append( $popup ); + + $popup.animate( { + opacity: 1 + }, { + duration: 300, + step: function ( now ) { + $( this ).css( 'transform', 'translateY( ' + ( -20 + now * 20 ) + 'px )' ); + } + } ); + + popupShown = true; + $score.children( 'img' ).attr( 'aria-describedby', 'mw-ext-score-popup' ); + } + + function hidePopups( callback ) { + var $popup = $( '.mw-ext-score-popup' ), $score = $popup.closest( '.mw-ext-score' ); + + $popup.animate( { + opacity: 0 + }, { + duration: 300, + step: function ( now ) { + $( this ).css( 'transform', 'translateY( ' + ( -20 + now * 20 ) + 'px )' ); + }, + complete: function () { + $score.children( 'img' ).removeAttr( 'aria-describedby' ); + $popup.remove(); + popupShown = false; + + if ( callback ) { + callback(); + } + } + } ); + } + + $( document ).on( 'click', '.mw-ext-score img', function ( e ) { + var $target = $( e.target ), $score = $target.parent(), sameScore; + + e.stopPropagation(); + + // Hide popup on second click, and if it was on the other score, then show new popup immediately. + if ( popupShown ) { + sameScore = $score.is( $( '.mw-ext-score-popup' ).parent() ); + + hidePopups( function () { + if ( !sameScore ) { + showPopup( $score ); + } + } ); + + return; + } + + showPopup( $score ); + } ); + + $( document ).click( 'click', function ( e ) { + var $target = $( e.target ); + + // Don't hide popup when clicked inside it. + if ( $target.closest( '.mw-ext-score-popup' ).length ) { + return; + } + + hidePopups(); + } ); +}( jQuery ) ); -- To view, visit https://gerrit.wikimedia.org/r/400834 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id9b213d073ba9ea7cc4c753a714f0b3aafbb0f63 Gerrit-PatchSet: 10 Gerrit-Project: mediawiki/extensions/Score Gerrit-Branch: master Gerrit-Owner: Albert221 <w.albert...@gmail.com> Gerrit-Reviewer: Albert221 <w.albert...@gmail.com> Gerrit-Reviewer: Ebe123 <beauleetien...@gmail.com> Gerrit-Reviewer: Siebrand <siebr...@kitano.nl> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits