From ba377654f304c8d0e9861110b334d96b4d444890 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Fri, 13 Mar 2026 14:31:50 +0900 Subject: [PATCH 1/8] add types-mediawiki --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 654d398f4d8..47c480ed10f 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,8 @@ "sass": "^1.97.3", "stylelint": "^17.4.0", "stylelint-config-wikimedia": "^0.18.0", - "stylelint-scss": "^7.x.x" + "stylelint-scss": "^7.x.x", + "types-mediawiki": "^2.0.0" }, "jest": { "reporters": [ From 6d47f5bfabe7da2d15bb39a00b7934b1b1109983 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Fri, 13 Mar 2026 16:40:17 +0900 Subject: [PATCH 2/8] adjust selectall --- javascript/commons/Selectall.js | 113 ++++++++++++++++++-------------- 1 file changed, 64 insertions(+), 49 deletions(-) diff --git a/javascript/commons/Selectall.js b/javascript/commons/Selectall.js index 99998f181b7..06527a432c2 100644 --- a/javascript/commons/Selectall.js +++ b/javascript/commons/Selectall.js @@ -1,59 +1,74 @@ /******************************************************************************* * Template(s): Select all for pre elements - * Author(s): FO-nTTaX ******************************************************************************/ + +class SelectAllContainer { + /** + * @param {HTMLElement} selectAllElement + */ + constructor( selectAllElement ) { + this.element = selectAllElement; + } + + createWrapper() { + const wrapper = document.createElement( 'div' ); + wrapper.classList.add( 'selectall-wrapper' ); + const buttonWrapper = document.createElement( 'div' ); + buttonWrapper.classList.add( 'selectall-buttons' ); + wrapper.appendChild( buttonWrapper ); + this.element.parentNode.replaceChild( wrapper, this.element ); + wrapper.appendChild( this.element ); + buttonWrapper.append( this.createSelectButton(), this.createSelectAllButton() ); + } + + createSelectButton() { + const selectButton = document.createElement( 'button' ); + selectButton.classList.add( 'btn' ); + selectButton.classList.add( 'btn-secondary' ); + selectButton.innerHTML = 'Select'; + selectButton.addEventListener( 'click', () => this.selectElementText() ); + return selectButton; + } + + createSelectAllButton() { + const selectCopyButton = document.createElement( 'button' ); + selectCopyButton.classList.add( 'btn' ); + selectCopyButton.classList.add( 'btn-primary' ); + selectCopyButton.innerHTML = 'Select and copy'; + + selectCopyButton.addEventListener( 'click', async () => { + if ( !window.ClipboardItem || !navigator.clipboard || !navigator.clipboard.write ) { + mw.notify( 'This browser does not support copying text to the clipboard.', { type: 'error' } ); + return; + } + + this.selectElementText(); + + const type = 'text/plain'; + const clipboardItemData = { + [ type ]: this.element.innerText + }; + const clipboardItem = new ClipboardItem( clipboardItemData ); + await navigator.clipboard.write( [ clipboardItem ] ); + } ); + return selectCopyButton; + } + + selectElementText() { + const range = document.createRange(); + range.selectNodeContents( this.element ); + const selection = window.getSelection(); + selection.removeAllRanges(); + selection.addRange( range ); + } +} + liquipedia.selectall = { init: function() { document.querySelectorAll( '.selectall' ).forEach( ( selectall ) => { - const wrapper = document.createElement( 'div' ); - wrapper.classList.add( 'selectall-wrapper' ); - const buttonwrapper = document.createElement( 'div' ); - buttonwrapper.classList.add( 'selectall-buttons' ); - wrapper.appendChild( buttonwrapper ); - const relative = document.createElement( 'div' ); - relative.classList.add( 'selectall-relative' ); - wrapper.appendChild( relative ); - selectall.parentNode.replaceChild( wrapper, selectall ); - relative.appendChild( selectall ); - const selectbutton = document.createElement( 'button' ); - selectbutton.classList.add( 'btn' ); - selectbutton.classList.add( 'btn-secondary' ); - selectbutton.innerHTML = 'Select'; - selectbutton.onclick = function() { - liquipedia.selectall.selectText( this ); - }; - buttonwrapper.appendChild( selectbutton ); - buttonwrapper.appendChild( document.createTextNode( ' ' ) ); - const selectcopybutton = document.createElement( 'button' ); - selectcopybutton.classList.add( 'btn' ); - selectcopybutton.classList.add( 'btn-primary' ); - selectcopybutton.innerHTML = 'Select and copy'; - selectcopybutton.onclick = function() { - liquipedia.selectall.selectText( this ); - document.execCommand( 'copy' ); - }; - buttonwrapper.appendChild( selectcopybutton ); + new SelectAllContainer( selectall ).createWrapper(); } ); - }, - removeTextarea: function() { - this.parentNode.removeChild( this ); - }, - selectText: function( button ) { - const wrapper = button.closest( '.selectall-wrapper' ); - const selectall = wrapper.querySelector( '.selectall' ); - const textarea = document.createElement( 'textarea' ); - textarea.readOnly = true; - textarea.classList.add( 'selectall-duplicate' ); - textarea.innerHTML = selectall.innerHTML; - textarea.style.padding = window.getComputedStyle( selectall ).padding; - textarea.style.lineHeight = window.getComputedStyle( selectall ).lineHeight; - textarea.style.fontFamily = window.getComputedStyle( selectall ).fontFamily; - textarea.style.fontSize = window.getComputedStyle( selectall ).fontSize; - textarea.style.height = window.getComputedStyle( selectall ).height; - textarea.onblur = liquipedia.selectall.removeTextarea; - wrapper.querySelector( '.selectall-relative' ).appendChild( textarea ); - textarea.focus(); - textarea.select(); } }; + liquipedia.core.modules.push( 'selectall' ); From 3f7ae2820e4e3b2a5897dcb85bdfaaa35c7c0378 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Fri, 13 Mar 2026 16:52:28 +0900 Subject: [PATCH 3/8] use writeText --- javascript/commons/Selectall.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/javascript/commons/Selectall.js b/javascript/commons/Selectall.js index 06527a432c2..f230e0b0923 100644 --- a/javascript/commons/Selectall.js +++ b/javascript/commons/Selectall.js @@ -37,19 +37,13 @@ class SelectAllContainer { selectCopyButton.innerHTML = 'Select and copy'; selectCopyButton.addEventListener( 'click', async () => { - if ( !window.ClipboardItem || !navigator.clipboard || !navigator.clipboard.write ) { + if ( !navigator.clipboard || !navigator.clipboard.writeText ) { mw.notify( 'This browser does not support copying text to the clipboard.', { type: 'error' } ); return; } this.selectElementText(); - - const type = 'text/plain'; - const clipboardItemData = { - [ type ]: this.element.innerText - }; - const clipboardItem = new ClipboardItem( clipboardItemData ); - await navigator.clipboard.write( [ clipboardItem ] ); + await navigator.clipboard.writeText( this.element.innerText ); } ); return selectCopyButton; } From 8a2a79efaa694f78e22bae4d80ec849336563c6f Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Fri, 13 Mar 2026 16:57:47 +0900 Subject: [PATCH 4/8] adjust selector --- javascript/commons/Selectall.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/commons/Selectall.js b/javascript/commons/Selectall.js index f230e0b0923..dda87857768 100644 --- a/javascript/commons/Selectall.js +++ b/javascript/commons/Selectall.js @@ -59,7 +59,7 @@ class SelectAllContainer { liquipedia.selectall = { init: function() { - document.querySelectorAll( '.selectall' ).forEach( ( selectall ) => { + document.querySelectorAll( 'pre.selectall' ).forEach( ( selectall ) => { new SelectAllContainer( selectall ).createWrapper(); } ); } From 5cb4fc97ec71be657ead7229488bdaf450a652e4 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Fri, 13 Mar 2026 17:00:04 +0900 Subject: [PATCH 5/8] remove deprecated fallback --- javascript/commons/CopyToClipboard.js | 32 +++++---------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/javascript/commons/CopyToClipboard.js b/javascript/commons/CopyToClipboard.js index 28d225869e1..df75b7b592f 100644 --- a/javascript/commons/CopyToClipboard.js +++ b/javascript/commons/CopyToClipboard.js @@ -11,39 +11,19 @@ liquipedia.copytoclipboard = { } } ); }, - buttonEventListener: function( e ) { + buttonEventListener: async function( e ) { const parent = e.target.closest( '.copy-to-clipboard' ); const text = parent.querySelector( '.copy-this' ); if ( text !== null ) { - const rawText = text.textContent; - if ( navigator.clipboard && navigator.clipboard.writeText ) { - navigator.clipboard.writeText( rawText ); - } else { - liquipedia.copytoclipboard.createInputBox( parent, rawText ); - liquipedia.copytoclipboard.selectAndCopy(); - liquipedia.copytoclipboard.removeInputBox(); + if ( !navigator.clipboard || !navigator.clipboard.writeText ) { + mw.notify( 'This browser does not support copying text to the clipboard.', { type: 'error' } ); + return; } + const rawText = text.textContent; + await navigator.clipboard.writeText( rawText ); liquipedia.copytoclipboard.showNotification( parent ); } }, - inputBox: null, - createInputBox: function( parent, text ) { - const input = document.createElement( 'input' ); - input.value = text; - liquipedia.copytoclipboard.inputBox = input; - parent.appendChild( input ); - }, - removeInputBox: function() { - const input = liquipedia.copytoclipboard.inputBox; - liquipedia.copytoclipboard.inputBox = null; - input.parentNode.removeChild( input ); - }, - selectAndCopy: function() { - const input = liquipedia.copytoclipboard.inputBox; - input.focus(); - input.select(); - document.execCommand( 'copy' ); - }, showNotification: function( copy ) { const timeout = 2000; let text = 'Copied...'; From 6a3368e162bbf6131806b2f943ed36478de5f6cd Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Fri, 13 Mar 2026 17:04:52 +0900 Subject: [PATCH 6/8] update stylesheet --- stylesheets/commons/Selectall.scss | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/stylesheets/commons/Selectall.scss b/stylesheets/commons/Selectall.scss index ace2d5c265a..5650809b203 100644 --- a/stylesheets/commons/Selectall.scss +++ b/stylesheets/commons/Selectall.scss @@ -1,23 +1,13 @@ /******************************************************************************* Template(s): Select all for pre elements -Author(s): Chapatiyaq *******************************************************************************/ -div.selectall-relative { - position: relative; +.selectall-wrapper { + display: flex; + flex-direction: column; + gap: 0.25rem; } -textarea.selectall-duplicate { - -moz-box-sizing: border-box; - box-sizing: border-box; - background: #ffffff; - border: 1px solid transparent; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - overflow: hidden; - white-space: pre; - -moz-tab-size: 13; - tab-size: 13; +.selectall-buttons { + display: flex; + gap: 0.25rem; } From 53ddd40687b08be2f1745f46ed293222f3a6e722 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Mon, 16 Mar 2026 08:54:37 +0900 Subject: [PATCH 7/8] better error handling --- javascript/commons/CopyToClipboard.js | 7 ++++++- javascript/commons/Selectall.js | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/javascript/commons/CopyToClipboard.js b/javascript/commons/CopyToClipboard.js index df75b7b592f..5451079a2e3 100644 --- a/javascript/commons/CopyToClipboard.js +++ b/javascript/commons/CopyToClipboard.js @@ -20,7 +20,12 @@ liquipedia.copytoclipboard = { return; } const rawText = text.textContent; - await navigator.clipboard.writeText( rawText ); + try { + await navigator.clipboard.writeText( rawText ); + } catch { + mw.notify( 'Failed to copy text to the clipboard.', { type: 'error' } ); + return; + } liquipedia.copytoclipboard.showNotification( parent ); } }, diff --git a/javascript/commons/Selectall.js b/javascript/commons/Selectall.js index dda87857768..87a6de99148 100644 --- a/javascript/commons/Selectall.js +++ b/javascript/commons/Selectall.js @@ -43,7 +43,11 @@ class SelectAllContainer { } this.selectElementText(); - await navigator.clipboard.writeText( this.element.innerText ); + try { + await navigator.clipboard.writeText( this.element.innerText ); + } catch { + mw.notify( 'Failed to copy text to the clipboard.', { type: 'error' } ); + } } ); return selectCopyButton; } From 1cde451eecc97272774f2e74a37b6887f52249b4 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Mon, 16 Mar 2026 08:55:38 +0900 Subject: [PATCH 8/8] use textContent --- javascript/commons/Selectall.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/commons/Selectall.js b/javascript/commons/Selectall.js index 87a6de99148..dcd4f849dd3 100644 --- a/javascript/commons/Selectall.js +++ b/javascript/commons/Selectall.js @@ -44,7 +44,7 @@ class SelectAllContainer { this.selectElementText(); try { - await navigator.clipboard.writeText( this.element.innerText ); + await navigator.clipboard.writeText( this.element.textContent ); } catch { mw.notify( 'Failed to copy text to the clipboard.', { type: 'error' } ); }