mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/SyntaxHighlight_GeSHi
synced 2024-11-23 22:13:40 +00:00
Implement copy buttons for code blocks
<syntaxhighlight> blocks with a boolean "copy" param will now have a button next to them for copying the code to the clipboard. Not applicable for inline code blocks. Adapted from the mediawiki.org gadget written by Krinkle. Bug: T40932 Change-Id: Ic8ef030514c3b6dd2cb9b137f032588869ab3762
This commit is contained in:
parent
f2d0dde88c
commit
55630cc5ea
|
@ -41,7 +41,15 @@
|
||||||
"ext.pygments.view": {
|
"ext.pygments.view": {
|
||||||
"scripts": [
|
"scripts": [
|
||||||
"pygments.linenumbers.js",
|
"pygments.linenumbers.js",
|
||||||
"pygments.links.js"
|
"pygments.links.js",
|
||||||
|
"pygments.copy.js"
|
||||||
|
],
|
||||||
|
"styles": [
|
||||||
|
"pygments.copy.css"
|
||||||
|
],
|
||||||
|
"messages": [
|
||||||
|
"syntaxhighlight-button-copy",
|
||||||
|
"syntaxhighlight-button-copied"
|
||||||
],
|
],
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"mediawiki.util"
|
"mediawiki.util"
|
||||||
|
|
|
@ -20,5 +20,7 @@
|
||||||
"syntaxhighlight-visualeditor-mwsyntaxhighlightinspector-title": "Code block",
|
"syntaxhighlight-visualeditor-mwsyntaxhighlightinspector-title": "Code block",
|
||||||
"syntaxhighlight-error-pygments-invocation-failure": "Failed to invoke Pygments",
|
"syntaxhighlight-error-pygments-invocation-failure": "Failed to invoke Pygments",
|
||||||
"syntaxhighlight-error-unknown-language": "Unknown language \"$1\"",
|
"syntaxhighlight-error-unknown-language": "Unknown language \"$1\"",
|
||||||
"syntaxhighlight-error-exceeds-size-limit": "Code size of $1 {{PLURAL:$1|bytes}} exceeds allowed maximum of $2 {{PLURAL:$2|bytes}}"
|
"syntaxhighlight-error-exceeds-size-limit": "Code size of $1 {{PLURAL:$1|bytes}} exceeds allowed maximum of $2 {{PLURAL:$2|bytes}}",
|
||||||
|
"syntaxhighlight-button-copy": "Copy",
|
||||||
|
"syntaxhighlight-button-copied": "Copied!"
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,5 +29,7 @@
|
||||||
"syntaxhighlight-visualeditor-mwsyntaxhighlightinspector-title": "Title for the VisualEditor syntax highlighter inspector, above the text area for the code",
|
"syntaxhighlight-visualeditor-mwsyntaxhighlightinspector-title": "Title for the VisualEditor syntax highlighter inspector, above the text area for the code",
|
||||||
"syntaxhighlight-error-pygments-invocation-failure": "Error message shown when the syntax highlighting library failed with an unspecified error",
|
"syntaxhighlight-error-pygments-invocation-failure": "Error message shown when the syntax highlighting library failed with an unspecified error",
|
||||||
"syntaxhighlight-error-unknown-language": "Error message shown when the programming language name was not recognized by the syntax highlighting library. Parameters:\n* $1 - the language name",
|
"syntaxhighlight-error-unknown-language": "Error message shown when the programming language name was not recognized by the syntax highlighting library. Parameters:\n* $1 - the language name",
|
||||||
"syntaxhighlight-error-exceeds-size-limit": "Error message shown when the block of code to be highlighted exceeds the size limit. Parameters:\n* $1 - the size of the code block, in bytes\n* $2 - the maximum size allowed, in bytes."
|
"syntaxhighlight-error-exceeds-size-limit": "Error message shown when the block of code to be highlighted exceeds the size limit. Parameters:\n* $1 - the size of the code block, in bytes\n* $2 - the maximum size allowed, in bytes.",
|
||||||
|
"syntaxhighlight-button-copy": "Label for button to copy the highlighted code",
|
||||||
|
"syntaxhighlight-button-copied": "Label shown when the highlighted code has been copied"
|
||||||
}
|
}
|
||||||
|
|
|
@ -387,6 +387,7 @@ class SyntaxHighlight extends ExtensionTagHandler implements
|
||||||
* If it contains a 'inline' key, the output will not be wrapped in `<div><pre/></div>`.
|
* If it contains a 'inline' key, the output will not be wrapped in `<div><pre/></div>`.
|
||||||
* If it contains a 'linelinks' key, lines will have links and anchors with a prefix
|
* If it contains a 'linelinks' key, lines will have links and anchors with a prefix
|
||||||
* of the value. Similar to the lineanchors+linespans features in Pygments.
|
* of the value. Similar to the lineanchors+linespans features in Pygments.
|
||||||
|
* If it contains a 'copy' key, a link will be shown for copying content to the clipboard.
|
||||||
* @param Parser|null $parser Parser, if generating content to be parsed.
|
* @param Parser|null $parser Parser, if generating content to be parsed.
|
||||||
* @return Status Status object, with HTML representing the highlighted
|
* @return Status Status object, with HTML representing the highlighted
|
||||||
* code as its value.
|
* code as its value.
|
||||||
|
@ -440,6 +441,9 @@ class SyntaxHighlight extends ExtensionTagHandler implements
|
||||||
if ( $showLines ) {
|
if ( $showLines ) {
|
||||||
$classList[] = self::HIGHLIGHT_CSS_CLASS . '-lines';
|
$classList[] = self::HIGHLIGHT_CSS_CLASS . '-lines';
|
||||||
}
|
}
|
||||||
|
if ( !$isInline && isset( $args['copy'] ) ) {
|
||||||
|
$classList[] = 'mw-highlight-copy';
|
||||||
|
}
|
||||||
$htmlAttribs['class'] = implode( ' ', $classList );
|
$htmlAttribs['class'] = implode( ' ', $classList );
|
||||||
$htmlAttribs['dir'] = $dir;
|
$htmlAttribs['dir'] = $dir;
|
||||||
'@phan-var array{class:string,dir:string} $htmlAttribs';
|
'@phan-var array{class:string,dir:string} $htmlAttribs';
|
||||||
|
|
38
modules/pygments.copy.css
Normal file
38
modules/pygments.copy.css
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/**
|
||||||
|
* Adapted from https://www.mediawiki.org/wiki/MediaWiki:Gadget-site-tpl-copy.css
|
||||||
|
* Original author: Krinkle
|
||||||
|
*/
|
||||||
|
|
||||||
|
.mw-highlight-copy {
|
||||||
|
position: relative;
|
||||||
|
min-width: 40%;
|
||||||
|
max-width: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://doc.wikimedia.org/oojs-ui/master/demos/ (2023-11-13)
|
||||||
|
* https://design.wikimedia.org/style-guide/components/buttons.html
|
||||||
|
*/
|
||||||
|
.mw-highlight-copy--bound button {
|
||||||
|
position: absolute;
|
||||||
|
top: -1em;
|
||||||
|
right: -0.9em;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 5px 7px;
|
||||||
|
border-radius: 2px;
|
||||||
|
background: #fff;
|
||||||
|
color: #36c;
|
||||||
|
border: 1px solid #eaecf0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mw-highlight-copy--bound button:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #447ff5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mw-highlight-copy--bound button:active {
|
||||||
|
background: #eff3fa;
|
||||||
|
color: #2a4b8d;
|
||||||
|
border-color: #2a4b8d;
|
||||||
|
}
|
35
modules/pygments.copy.js
Normal file
35
modules/pygments.copy.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
* Adapted from https://www.mediawiki.org/wiki/MediaWiki:Gadget-site-tpl-copy.js
|
||||||
|
* Original author: Krinkle
|
||||||
|
*/
|
||||||
|
|
||||||
|
// eslint-disable-next-line compat/compat
|
||||||
|
const hasFeature = navigator.clipboard && 'writeText' in navigator.clipboard;
|
||||||
|
if ( hasFeature ) {
|
||||||
|
// Add type=button to avoid form submission in preview
|
||||||
|
const $btn = $( '<button>' )
|
||||||
|
.attr( 'type', 'button' )
|
||||||
|
.text( mw.msg( 'syntaxhighlight-button-copy' ) )
|
||||||
|
.on( 'click', function () {
|
||||||
|
const btn = this;
|
||||||
|
const wrapper = btn.closest( '.mw-highlight-copy' );
|
||||||
|
const preNode = wrapper && wrapper.querySelector( 'pre' );
|
||||||
|
const content = preNode && preNode.textContent.trim();
|
||||||
|
try {
|
||||||
|
navigator.clipboard.writeText( content );
|
||||||
|
} catch ( e ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const prevLabel = btn.textContent;
|
||||||
|
btn.textContent = mw.msg( 'syntaxhighlight-button-copied' );
|
||||||
|
setTimeout( () => {
|
||||||
|
btn.textContent = prevLabel;
|
||||||
|
}, 5000 );
|
||||||
|
} );
|
||||||
|
|
||||||
|
mw.hook( 'wikipage.content' ).add( ( $content ) => {
|
||||||
|
$content.find( '.mw-highlight-copy:not(.mw-highlight-copy--bound)' )
|
||||||
|
.append( $btn.clone( true ) )
|
||||||
|
.addClass( 'mw-highlight-copy--bound' );
|
||||||
|
} );
|
||||||
|
}
|
Loading…
Reference in a new issue