@@ -1769,9 +1769,37 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
17691769} ( ) ) ;
17701770
17711771// This section handles the copy button that appears next to the path breadcrumbs
1772+ // and the copy buttons on the code examples.
17721773( function ( ) {
1773- let reset_button_timeout = null ;
1774+ // Common functions to copy buttons.
1775+ function copyContentToClipboard ( content ) {
1776+ const el = document . createElement ( "textarea" ) ;
1777+ el . value = content ;
1778+ el . setAttribute ( "readonly" , "" ) ;
1779+ // To not make it appear on the screen.
1780+ el . style . position = "absolute" ;
1781+ el . style . left = "-9999px" ;
1782+
1783+ document . body . appendChild ( el ) ;
1784+ el . select ( ) ;
1785+ document . execCommand ( "copy" ) ;
1786+ document . body . removeChild ( el ) ;
1787+ }
1788+
1789+ function copyButtonAnimation ( button ) {
1790+ button . classList . add ( "clicked" ) ;
1791+
1792+ if ( button . reset_button_timeout !== undefined ) {
1793+ window . clearTimeout ( button . reset_button_timeout ) ;
1794+ }
1795+
1796+ button . reset_button_timeout = window . setTimeout ( ( ) => {
1797+ button . reset_button_timeout = undefined ;
1798+ button . classList . remove ( "clicked" ) ;
1799+ } , 1000 ) ;
1800+ }
17741801
1802+ // Copy button that appears next to the path breadcrumbs.
17751803 const but = document . getElementById ( "copy-path" ) ;
17761804 if ( ! but ) {
17771805 return ;
@@ -1786,29 +1814,54 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
17861814 }
17871815 } ) ;
17881816
1789- const el = document . createElement ( "textarea" ) ;
1790- el . value = path . join ( "::" ) ;
1791- el . setAttribute ( "readonly" , "" ) ;
1792- // To not make it appear on the screen.
1793- el . style . position = "absolute" ;
1794- el . style . left = "-9999px" ;
1795-
1796- document . body . appendChild ( el ) ;
1797- el . select ( ) ;
1798- document . execCommand ( "copy" ) ;
1799- document . body . removeChild ( el ) ;
1800-
1801- but . classList . add ( "clicked" ) ;
1817+ copyContentToClipboard ( path . join ( "::" ) ) ;
1818+ copyButtonAnimation ( but ) ;
1819+ } ;
18021820
1803- if ( reset_button_timeout !== null ) {
1804- window . clearTimeout ( reset_button_timeout ) ;
1821+ // Copy buttons on code examples.
1822+ function copyCode ( codeElem ) {
1823+ if ( ! codeElem ) {
1824+ // Should never happen, but the world is a dark and dangerous place.
1825+ return ;
18051826 }
1827+ let text = "" ;
1828+ onEachLazy ( codeElem . childNodes , elem => {
1829+ if ( elem . nodeType === Node . TEXT_NODE ) {
1830+ text += elem . textContent ;
1831+ }
1832+ } ) ;
1833+ copyContentToClipboard ( text ) ;
1834+ }
18061835
1807- function reset_button ( ) {
1808- reset_button_timeout = null ;
1809- but . classList . remove ( "clicked" ) ;
1836+ function addCopyButton ( event ) {
1837+ let elem = event . target ;
1838+ while ( ! hasClass ( elem , "example-wrap" ) ) {
1839+ elem = elem . parentElement ;
1840+ if ( elem . tagName === "body" || hasClass ( elem , "docblock" ) ) {
1841+ return ;
1842+ }
1843+ }
1844+ // Since the button will be added, no need to keep this listener around.
1845+ elem . removeEventListener ( "mouseover" , addCopyButton ) ;
1846+
1847+ const parent = document . createElement ( "div" ) ;
1848+ parent . className = "button-holder" ;
1849+ const runButton = elem . querySelector ( ".test-arrow" ) ;
1850+ if ( runButton !== null ) {
1851+ // If there is a run button, we move it into the same div.
1852+ parent . appendChild ( runButton ) ;
18101853 }
1854+ elem . appendChild ( parent ) ;
1855+ const copyButton = document . createElement ( "button" ) ;
1856+ copyButton . className = "copy-button" ;
1857+ copyButton . addEventListener ( "click" , ( ) => {
1858+ copyCode ( parent . querySelector ( "pre > code" ) ) ;
1859+ copyButtonAnimation ( copyButton ) ;
1860+ } ) ;
1861+ parent . appendChild ( copyButton ) ;
1862+ }
18111863
1812- reset_button_timeout = window . setTimeout ( reset_button , 1000 ) ;
1813- } ;
1864+ onEachLazy ( document . querySelectorAll ( ".docblock .example-wrap" ) , elem => {
1865+ elem . addEventListener ( "mouseover" , addCopyButton ) ;
1866+ } ) ;
18141867} ( ) ) ;
0 commit comments