mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/DiscussionTools
synced 2024-11-27 17:51:09 +00:00
9d73c46d99
Bug: T357021 Change-Id: Ic71c030e6796695de5ff88a940adb86d63996e7f
68 lines
2 KiB
JavaScript
68 lines
2 KiB
JavaScript
function init( $pageContainer ) {
|
|
$pageContainer.find( '.ext-discussiontools-init-timestamplink' ).on( 'click', ( e ) => {
|
|
// Try to percent-decode the URL, so that non-Latin characters don't look so ugly (T357021)
|
|
let link = e.target.href;
|
|
try {
|
|
// decodeURI() may throw
|
|
const decodedLink = decodeURI( e.target.href );
|
|
// Check that the decoded URL is parsed to the same canonical URL
|
|
// new URL() may throw
|
|
if ( new URL( decodedLink ).toString() === link ) {
|
|
link = decodedLink;
|
|
}
|
|
} catch ( err ) {}
|
|
copyLink( link );
|
|
} ).attr( 'data-event-name', 'discussiontools.permalink-copied' );
|
|
}
|
|
|
|
function copyLink( link ) {
|
|
const $win = $( window );
|
|
const scrollTop = $win.scrollTop();
|
|
|
|
const $tmpInput = $( '<input>' )
|
|
.val( link )
|
|
.addClass( 'noime' )
|
|
.css( {
|
|
position: 'fixed',
|
|
top: 0
|
|
} )
|
|
.appendTo( 'body' )
|
|
.trigger( 'focus' );
|
|
$tmpInput[ 0 ].setSelectionRange( 0, link.length );
|
|
let copied;
|
|
try {
|
|
copied = document.execCommand( 'copy' );
|
|
} catch ( err ) {
|
|
copied = false;
|
|
}
|
|
if ( copied ) {
|
|
mw.notify( mw.msg( 'discussiontools-permalink-comment-copied' ) );
|
|
}
|
|
$tmpInput.remove();
|
|
|
|
// Restore scroll position, can be changed by setSelectionRange, or hash navigation
|
|
function afterNextScroll() {
|
|
// On desktop we can restore scroll immediately after the scroll
|
|
// event, preventing a scroll flicker.
|
|
$win.scrollTop( scrollTop );
|
|
// On mobile, we need to wait another execution cycle (setTimeout)
|
|
// before the scroll is rendered (and not requestAnimationFrame).
|
|
setTimeout( () => {
|
|
$win.scrollTop( scrollTop );
|
|
} );
|
|
}
|
|
// Restore scroll position when the scroll event fires.
|
|
// setTimeout does't reliably wait long enough for the native
|
|
// scroll to happen.
|
|
$win.one( 'scroll', afterNextScroll );
|
|
// If we happened to be in the exact correct position, 'scroll' won't fire,
|
|
// so clear the listener after a short delay
|
|
setTimeout( () => {
|
|
$win.off( 'scroll', afterNextScroll );
|
|
}, 1000 );
|
|
}
|
|
|
|
module.exports = {
|
|
init: init
|
|
};
|